diff --git a/.editorconfig b/.editorconfig index e7fcfa6c07e..cafbc72a35a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -184,6 +184,9 @@ csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimenta dotnet_diagnostic.IDE0090.severity = error csharp_style_deconstructed_variable_declaration = true:suggestion +# RS0016: Add public types and members to the declared API +dotnet_diagnostic.RS0016.severity = silent + # Visual Basic files [*.vb] diff --git a/.gitignore b/.gitignore index 610c49c806d..c8a18b3ad19 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,9 @@ *.userosscache *.sln.docstates +#Visual Studio creates .bak files when editing resource files. Ignore these +*.bak + # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs @@ -29,6 +32,9 @@ bld/ [Oo]bj/ [Ll]og/ +# VSCode directory +.vscode/ + # Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot diff --git a/Build.xml b/Build.xml new file mode 100644 index 00000000000..74b41ed1b39 --- /dev/null +++ b/Build.xml @@ -0,0 +1,17 @@ + + + + + + + powershell.exe -ExecutionPolicy Bypass .\DeploymentSetup.ps1 + + + + + + + + + + \ No newline at end of file diff --git a/BuildAndPackage.cmd b/BuildAndPackage.cmd new file mode 100644 index 00000000000..e929307dbaf --- /dev/null +++ b/BuildAndPackage.cmd @@ -0,0 +1,33 @@ +@echo off +echo Custom NuGet Package Build Script for System.Windows.Forms +echo ========================================================= +echo. + +REM Clean the workspace +echo Cleaning workspace... +git clean -dfx +if errorlevel 1 ( + echo Error: Failed to clean workspace + exit /b 1 +) + +REM Build the solution in Release configuration +echo Building solution in Release configuration... +dotnet build Winforms.sln -c Release +if errorlevel 1 ( + echo Error: Failed to build solution + exit /b 1 +) + +REM Run the custom packaging script +echo Running custom packaging... +powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0CreateCustomPackageStandalone.ps1" +if errorlevel 1 ( + echo Error: Failed to create custom package + exit /b 1 +) + +echo. +echo Build and packaging completed successfully! +echo Check the artifacts\packages\Release\Shipping folder for the System.Windows.Forms.*.nupkg file. +pause diff --git a/CreateCustomPackage.ps1 b/CreateCustomPackage.ps1 new file mode 100644 index 00000000000..b2e984b9a95 --- /dev/null +++ b/CreateCustomPackage.ps1 @@ -0,0 +1,213 @@ +# Custom NuGet Package Creation Script for System.Windows.Forms +# This script automates the manual process described in the requirements + +param( + [Parameter(Mandatory = $true)] + [string]$OriginalPackagePath, + + [Parameter(Mandatory = $true)] + [string]$CustomPackagePath, + + [Parameter(Mandatory = $true)] + [string]$DesignBinDir, + + [switch]$WhatIf = $false +) + +$ErrorActionPreference = "Stop" + +Write-Host "Starting custom NuGet package creation for System.Windows.Forms..." -ForegroundColor Green +Write-Host "Original package: $OriginalPackagePath" -ForegroundColor Yellow +Write-Host "Target package: $CustomPackagePath" -ForegroundColor Yellow +Write-Host "Design bin directory: $DesignBinDir" -ForegroundColor Yellow + +if ($WhatIf) { + Write-Host "WhatIf mode: Would process package but not make changes" -ForegroundColor Cyan + return +} + +# Validate inputs +if (-not (Test-Path $OriginalPackagePath)) { + Write-Error "Original package not found: $OriginalPackagePath" + exit 1 +} + +# Ensure the Design bin directory exists +if (-not (Test-Path $DesignBinDir)) { + Write-Error "System.Windows.Forms.Design output directory not found at: $DesignBinDir" + exit 1 +} + +Write-Host "Source directory: $DesignBinDir" -ForegroundColor Cyan + +# Validate that the required files exist in the source directory +$requiredFiles = @( + "System.Windows.Forms.Primitives.dll", + "System.Windows.Forms.Primitives.xml", + "System.Windows.Forms.Design.dll", + "System.Windows.Forms.Design.xml" +) + +$missingFiles = @() +foreach ($file in $requiredFiles) { + if (-not (Test-Path (Join-Path $DesignBinDir $file))) { + $missingFiles += $file + } +} + +if ($missingFiles.Count -gt 0) { + Write-Warning "Some required files are missing from the source directory:" + foreach ($file in $missingFiles) { + Write-Warning " - $file" + } + Write-Warning "The package will be created but may be incomplete. Ensure System.Windows.Forms.Design project is built correctly." +} + +# Create working directory +$WorkingDir = Join-Path ([System.IO.Path]::GetDirectoryName($CustomPackagePath)) "temp_package_work" +$ExtractedPackageDir = Join-Path $WorkingDir "extracted" + +if (Test-Path $WorkingDir) { + Remove-Item $WorkingDir -Recurse -Force +} +New-Item -ItemType Directory -Path $ExtractedPackageDir -Force | Out-Null + +try { + Write-Host "Extracting original package..." -ForegroundColor Yellow + + # Extract the nupkg (it's a zip file) + Add-Type -AssemblyName System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::ExtractToDirectory($OriginalPackagePath, $ExtractedPackageDir) + + Write-Host "Renaming nuspec file..." -ForegroundColor Yellow + + # Rename the nuspec file + $originalNuspec = Join-Path $ExtractedPackageDir "WTG.System.Windows.Forms.nuspec" + $newNuspec = Join-Path $ExtractedPackageDir "System.Windows.Forms.nuspec" + + if (Test-Path $originalNuspec) { + Move-Item $originalNuspec $newNuspec -Force + } else { + Write-Error "Original nuspec file not found: $originalNuspec" + exit 1 + } + + Write-Host "Modifying nuspec content..." -ForegroundColor Yellow + + # Modify the nuspec file content + $content = Get-Content $newNuspec -Raw -Encoding UTF8 + + # Replace the package ID + $content = $content -replace 'WTG\.System\.Windows\.Forms', 'System.Windows.Forms' + + # Remove the System.Windows.Forms.Primitives dependency line + $content = $content -replace '\s*]*version="[^"]*"[^/]*/>\s*', '' + + # Clean up any extra whitespace + $content = $content -replace '\r?\n\s*\r?\n', "`r`n" + + Set-Content $newNuspec -Value $content -Encoding UTF8 + + Write-Host "Copying additional files from System.Windows.Forms.Design..." -ForegroundColor Yellow + + $libNetDir = Join-Path $ExtractedPackageDir "lib\net8.0" + Write-Host " Target directory: $libNetDir" -ForegroundColor Cyan + + # Copy the main files (these should replace any existing files) + $filesToCopy = @( + "System.Windows.Forms.Primitives.dll", + "System.Windows.Forms.Primitives.xml", + "System.Windows.Forms.Design.dll", + "System.Windows.Forms.Design.xml" + ) + + Write-Host " Copying main files..." -ForegroundColor Cyan + foreach ($file in $filesToCopy) { + $sourcePath = Join-Path $DesignBinDir $file + $destPath = Join-Path $libNetDir $file + + if (Test-Path $sourcePath) { + $existsAlready = Test-Path $destPath + Copy-Item $sourcePath $destPath -Force + if ($existsAlready) { + Write-Host " Replaced: $file" -ForegroundColor Green + } else { + Write-Host " Copied: $file" -ForegroundColor Green + } + } else { + Write-Warning " File not found: $sourcePath" + } + } + + # Copy resource folders (two-character country codes) + $resourceFolders = Get-ChildItem $DesignBinDir -Directory + + if ($resourceFolders.Count -gt 0) { + Write-Host " Found $($resourceFolders.Count) resource folders to copy" -ForegroundColor Cyan + } + + foreach ($folder in $resourceFolders) { + $destFolder = Join-Path $libNetDir $folder.Name + + # Create the destination folder + New-Item -ItemType Directory -Path $destFolder -Force | Out-Null + + # Copy all files from source folder to destination + $sourceFiles = Get-ChildItem $folder.FullName -File + if ($sourceFiles.Count -gt 0) { + Copy-Item $sourceFiles.FullName $destFolder -Force + Write-Host " Copied resource folder: $($folder.Name) ($($sourceFiles.Count) files)" -ForegroundColor Green + } else { + Write-Host " Resource folder $($folder.Name) is empty, skipping" -ForegroundColor DarkYellow + } + } + + Write-Host "Creating new package..." -ForegroundColor Yellow + + # Create the new package + if (Test-Path $CustomPackagePath) { + Remove-Item $CustomPackagePath -Force + } + + [System.IO.Compression.ZipFile]::CreateFromDirectory($ExtractedPackageDir, $CustomPackagePath) + + Write-Host "Package created successfully: $CustomPackagePath" -ForegroundColor Green + + # Display package info + $packageInfo = Get-ChildItem $CustomPackagePath + Write-Host "Package size: $([math]::Round($packageInfo.Length / 1MB, 2)) MB" -ForegroundColor Cyan + + # Show summary of what was included + Write-Host "" + Write-Host "Package contents summary:" -ForegroundColor Yellow + Write-Host " - Original System.Windows.Forms files from WTG package" -ForegroundColor White + Write-Host " - Additional files from System.Windows.Forms.Design:" -ForegroundColor White + $filesToCopy = @( + "System.Windows.Forms.Primitives.dll", + "System.Windows.Forms.Primitives.xml", + "System.Windows.Forms.Design.dll", + "System.Windows.Forms.Design.xml" + ) + foreach ($file in $filesToCopy) { + $sourcePath = Join-Path $DesignBinDir $file + if (Test-Path $sourcePath) { + Write-Host " [OK] $file" -ForegroundColor Green + } else { + Write-Host " [MISSING] $file (not found)" -ForegroundColor Red + } + } + + if ($resourceFolders.Count -gt 0) { + Write-Host " - Resource folders: $($resourceFolders.Name -join ', ')" -ForegroundColor White + } else { + Write-Host " - No resource folders found" -ForegroundColor DarkYellow + } + +} finally { + # Clean up working directory + if (Test-Path $WorkingDir) { + Remove-Item $WorkingDir -Recurse -Force + } +} + +Write-Host "Custom NuGet package creation completed!" -ForegroundColor Green diff --git a/CreateCustomPackageStandalone.ps1 b/CreateCustomPackageStandalone.ps1 new file mode 100644 index 00000000000..fa2f4562976 --- /dev/null +++ b/CreateCustomPackageStandalone.ps1 @@ -0,0 +1,57 @@ +# Standalone Custom NuGet Package Creation Script for System.Windows.Forms +# This script can be used independently for testing or manual package creation + +param( + [string]$Configuration = "Release", + [string]$ArtifactsDir = "$PSScriptRoot\artifacts", + [switch]$WhatIf = $false +) + +$ErrorActionPreference = "Stop" + +Write-Host "Standalone custom NuGet package creation for System.Windows.Forms..." -ForegroundColor Green + +# Define paths +$PackagesOutputDir = Join-Path $ArtifactsDir "packages\$Configuration\Shipping" +$DesignBinDir = Join-Path $ArtifactsDir "bin\System.Windows.Forms.Design\$Configuration\net8.0" + +# Find the original package +$OriginalPackages = Get-ChildItem $PackagesOutputDir -Filter "WTG.System.Windows.Forms.*.nupkg" -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending +if ($OriginalPackages.Count -eq 0) { + Write-Error "No WTG.System.Windows.Forms package found in $PackagesOutputDir. Make sure the solution is built in $Configuration configuration." + exit 1 +} + +$OriginalPackage = $OriginalPackages[0] +$OriginalPackagePath = $OriginalPackage.FullName +$PackageVersion = $OriginalPackage.Name -replace "WTG\.System\.Windows\.Forms\.(.*?)\.nupkg", '$1' +$CustomPackageName = "System.Windows.Forms.$PackageVersion.nupkg" +$CustomPackagePath = Join-Path $PackagesOutputDir $CustomPackageName + +Write-Host "Using the main PowerShell script..." -ForegroundColor Yellow + +# Call the main PowerShell script +$mainScriptPath = Join-Path $PSScriptRoot "CreateCustomPackage.ps1" +if (-not (Test-Path $mainScriptPath)) { + Write-Error "Main PowerShell script not found at: $mainScriptPath" + exit 1 +} + +$params = @{ + OriginalPackagePath = $OriginalPackagePath + CustomPackagePath = $CustomPackagePath + DesignBinDir = $DesignBinDir +} + +if ($WhatIf) { + $params.WhatIf = $true +} + +& $mainScriptPath @params + +if (-not $WhatIf) { + Write-Host "" + Write-Host "Next steps:" -ForegroundColor Cyan + Write-Host "1. To push to proget: dotnet nuget push `"$CustomPackagePath`" --api-key `"your-api-key`" --source `"https://proget.wtg.zone/nuget/WTG-Internal/v3/index.json`"" -ForegroundColor White + Write-Host "2. Verify at: https://proget.wtg.zone/feeds/WTG-Internal/System.Windows.Forms/versions" -ForegroundColor White +} diff --git a/CustomPackageCreation.md b/CustomPackageCreation.md new file mode 100644 index 00000000000..f6314ba8dce --- /dev/null +++ b/CustomPackageCreation.md @@ -0,0 +1,173 @@ +# Automated NuGet Package Creation for System.Windows.Forms + +This document describes the automated NuGet package creation process that replaces the manual steps previously required. + +## Overview + +The automated system creates a custom `System.Windows.Forms` NuGet package from the `WTG.System.Windows.Forms` package built by the standard MSBuild process. The automation includes: + +1. Extracting the original `WTG.System.Windows.Forms.*.nupkg` package +2. Renaming the `.nuspec` file from `WTG.System.Windows.Forms.nuspec` to `System.Windows.Forms.nuspec` +3. Modifying the package ID in the `.nuspec` file to `System.Windows.Forms` +4. Removing the `System.Windows.Forms.Primitives` dependency +5. Copying additional files from `System.Windows.Forms.Design` build output +6. Copying resource folders (localization files) +7. Creating the final `System.Windows.Forms.*.nupkg` package + +## Automated Methods + +### Method 1: MSBuild Integration (Recommended) + +The automation is integrated into the MSBuild process via custom targets that call a dedicated PowerShell script. + +**Files involved:** +- `eng/CustomPackaging.targets` - MSBuild targets file (calls PowerShell script) +- `CreateCustomPackage.ps1` - Core PowerShell script with packaging logic +- `src/System.Windows.Forms/src/System.Windows.Forms.csproj` - Updated to import the custom targets + +**How to use:** +```bash +# Build the solution in Release configuration +dotnet build Winforms.sln -c Release + +# The custom package will be automatically created in: +# artifacts/packages/Release/Shipping/System.Windows.Forms.*.nupkg +``` + +**What happens:** +1. Standard MSBuild packaging creates `WTG.System.Windows.Forms.*.nupkg` +2. Custom target `CreateCustomNuGetPackage` runs after packaging +3. MSBuild calls `CreateCustomPackage.ps1` with appropriate parameters +4. Final `System.Windows.Forms.*.nupkg` is created alongside the original + +### Method 2: Standalone PowerShell Script + +For more control, debugging, or manual package creation from existing build outputs. + +**File:** `CreateCustomPackageStandalone.ps1` + +**Usage:** +```powershell +# Run with default Release configuration (auto-discovers latest package) +.\CreateCustomPackageStandalone.ps1 + +# Run with specific configuration +.\CreateCustomPackageStandalone.ps1 -Configuration Release + +# Preview mode (shows what would be done without making changes) +.\CreateCustomPackageStandalone.ps1 -WhatIf +``` + +This script automatically finds the latest `WTG.System.Windows.Forms.*.nupkg` in the artifacts directory and processes it. + +### Method 3: Batch File (Simplest) + +For users who prefer a simple click-and-run approach. + +**File:** `BuildAndPackage.cmd` + +**Usage:** +1. Double-click the `BuildAndPackage.cmd` file, or +2. Run from command prompt: `BuildAndPackage.cmd` + +This will: +1. Clean the workspace (`git clean -dfx`) +2. Build the solution in Release configuration +3. Run the standalone custom packaging script + +## Output + +After running any of the methods above, you'll find: + +- **Original package:** `artifacts/packages/Release/Shipping/WTG.System.Windows.Forms.*.nupkg` +- **Custom package:** `artifacts/packages/Release/Shipping/System.Windows.Forms.*.nupkg` + +The custom package is the one you should push to ProGet. + +## Publishing to ProGet + +Once the custom package is created, push it to ProGet: + +```bash +dotnet nuget push "artifacts/packages/Release/Shipping/System.Windows.Forms.*.nupkg" \ + --api-key "your-api-key" \ + --source "https://proget.wtg.zone/nuget/WTG-Internal/v3/index.json" +``` + +Verify the package at: https://proget.wtg.zone/feeds/WTG-Internal/System.Windows.Forms/versions + +## Technical Details + +### Files Modified + +1. **System.Windows.Forms.csproj**: Added import for `CustomPackaging.targets` + +### Files Added + +1. **eng/CustomPackaging.targets**: MSBuild targets file that calls the PowerShell script +2. **CreateCustomPackage.ps1**: Core PowerShell script with all packaging logic +3. **CreateCustomPackageStandalone.ps1**: Standalone wrapper script for manual use +4. **BuildAndPackage.cmd**: Simple batch file wrapper +5. **CustomPackageCreation.md**: This documentation + +### Architecture + +The refactored solution uses a clean separation of concerns: + +- **MSBuild targets**: Handle integration with the build process and parameter passing +- **Core PowerShell script**: Contains all the packaging logic (can be called from MSBuild or standalone) +- **Standalone wrapper**: Provides auto-discovery and convenience for manual testing +- **Batch wrapper**: Simple entry point for non-technical users + +### Custom Target Details + +The `CreateCustomNuGetPackage` target: +- Only runs in Release configuration +- Only runs for the `System.Windows.Forms` project +- Validates that required files exist +- Calls `CreateCustomPackage.ps1` with the correct parameters +- Provides detailed logging + +### Dependencies + +The automation requires: +- PowerShell (available on Windows by default) +- .NET SDK (for the build process) +- Git (for workspace cleaning) + +## Troubleshooting + +### Common Issues + +1. **Package not found**: Ensure the solution builds successfully in Release configuration first +2. **Design files missing**: Verify that `System.Windows.Forms.Design` project builds correctly +3. **PowerShell execution policy**: If PowerShell scripts are blocked, run: `Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser` + +### Debug Mode + +To debug the packaging process: +1. Use the standalone PowerShell script with `-WhatIf` flag +2. Check MSBuild output for custom target messages +3. Look for temporary files in `artifacts/packages/Release/Shipping/temp_package_work` (if cleanup fails) + +### Manual Fallback + +If automation fails, the original manual process can still be used as documented in the original requirements. + +## Maintenance + +### Updating Package Dependencies + +If the dependencies in the `.nuspec` file need to be updated: +1. Update the original `WTG.System.Windows.Forms.nuspec` file +2. Update the PowerShell script in `CustomPackaging.targets` if new dependency removal logic is needed + +### Version Updates + +The automation automatically uses the version from the built package, so no manual version updates are required. + +### Adding New Files + +To include additional files in the custom package: +1. Update the `$filesToCopy` array in the PowerShell script +2. Ensure the files are available in the `System.Windows.Forms.Design` output directory diff --git a/Demo/Demo.csproj b/Demo/Demo.csproj new file mode 100644 index 00000000000..5afe319fe70 --- /dev/null +++ b/Demo/Demo.csproj @@ -0,0 +1,24 @@ + + + + WinExe + net8.0-windows;net48 + enable + preview + enable + SA1400;CS0649 + + + + true + + + + false + + + + + + + \ No newline at end of file diff --git a/Demo/Directory.Build.props b/Demo/Directory.Build.props new file mode 100644 index 00000000000..39c1b301948 --- /dev/null +++ b/Demo/Directory.Build.props @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Demo/Directory.Build.targets b/Demo/Directory.Build.targets new file mode 100644 index 00000000000..39c1b301948 --- /dev/null +++ b/Demo/Directory.Build.targets @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Demo/Form1.Designer.cs b/Demo/Form1.Designer.cs new file mode 100644 index 00000000000..e7e66aa1aff --- /dev/null +++ b/Demo/Form1.Designer.cs @@ -0,0 +1,264 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace Demo +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + private void InitializeStatusBar() + { + StatusBar mainStatusBar = new StatusBar(); + + mainStatusBar.Dock = DockStyle.Bottom; + mainStatusBar.Height = 70; + + StatusBarPanel statusPanel = new StatusBarPanel(); + StatusBarPanel datetimePanel = new StatusBarPanel(); + + // Set first panel properties and add to StatusBar + statusPanel.BorderStyle = StatusBarPanelBorderStyle.Sunken; + statusPanel.Text = "Status Bar Example"; + statusPanel.AutoSize = StatusBarPanelAutoSize.Spring; + mainStatusBar.Panels.Add(statusPanel); + + // Set second panel properties and add to StatusBar + datetimePanel.BorderStyle = StatusBarPanelBorderStyle.Raised; + + datetimePanel.Text = System.DateTime.Today.ToLongDateString(); + datetimePanel.AutoSize = StatusBarPanelAutoSize.Contents; + mainStatusBar.Panels.Add(datetimePanel); + + mainStatusBar.ShowPanels = true; + + Controls.Add(mainStatusBar); + } + + private void InitializeDataGrid() + { + this.button1 = new System.Windows.Forms.Button(); + this.button2 = new System.Windows.Forms.Button(); + this.myDataGrid = new DataGrid(); + + button1.Location = new Point(24, 60); + button1.Size = new Size(200, 30); + button1.Text = "Change Appearance"; + button1.Click += new System.EventHandler(Button1_Click); + + button2.Location = new Point(224, 60); + button2.Size = new Size(200, 30); + button2.Text = "Get Binding Manager"; + button2.Click += new System.EventHandler(Button2_Click); + + myDataGrid.Location = new Point(24, 100); + myDataGrid.Size = new Size(600, 400); + myDataGrid.CaptionText = "Microsoft DataGrid Control"; + myDataGrid.MouseUp += new MouseEventHandler(Grid_MouseUp); + + this.Controls.Add(button1); + this.Controls.Add(button2); + this.Controls.Add(myDataGrid); + } + + private void InitializeMenu() + { + // Create the main menu + mainMenu = new MainMenu(); + + // Create menu items + fileMenuItem = new MenuItem("File"); + newMenuItem = new MenuItem("New"); + openMenuItem = new MenuItem("Open"); + saveMenuItem = new MenuItem("Save", SaveMenuItem_Click, Shortcut.CtrlS); + exitMenuItem = new MenuItem("Exit"); + viewMenuItem = new MenuItem("View"); + toolboxMenuItem = new MenuItem("Toolbox"); + terminalMenuItem = new MenuItem("Terminal"); + outputMenuItem = new MenuItem("Output"); + + newProjectItem = new MenuItem("Project..."); + newRepositoryItem = new MenuItem("Repository..."); + newFileItem = new MenuItem("File..."); + + newMenuItem.MenuItems.Add(newProjectItem); + newMenuItem.MenuItems.Add(newRepositoryItem); + newMenuItem.MenuItems.Add(newFileItem); + + openMenuItem.Shortcut = Shortcut.AltF12; + openMenuItem.ShowShortcut = true; + + saveMenuItem.Checked = true; + saveMenuItem.RadioCheck = true; + //saveMenuItem.Shortcut = Shortcut.CtrlS; + //saveMenuItem.ShowShortcut = true; + + // Add sub-menu items to the "File" menu item + fileMenuItem.MenuItems.Add(newMenuItem); + fileMenuItem.MenuItems.Add(openMenuItem); + fileMenuItem.MenuItems.Add(saveMenuItem); + fileMenuItem.MenuItems.Add(exitMenuItem); + + viewMenuItem.MenuItems.Add(toolboxMenuItem); + viewMenuItem.MenuItems.Add(terminalMenuItem); + viewMenuItem.MenuItems.Add(outputMenuItem); + + // Add "File" and "View" menu item to the main menu + mainMenu.MenuItems.Add(fileMenuItem); + mainMenu.MenuItems.Add(viewMenuItem); + + var dynamicMenuItem = new MenuItem("Dynamic"); + dynamicMenuItem.MenuItems.Add(new MenuItem("Dynamic code has not run yet")); + dynamicMenuItem.Popup += DynamicMenuItem_Popup; + mainMenu.MenuItems.Add(dynamicMenuItem); + + // Add Owner Draw Demo menu + var ownerDrawDemoMenuItem = new MenuItem("Owner Draw Demo"); + + // Create owner-draw menu items + var ownerDrawItem3 = new OwnerDrawMenuItem(); + ownerDrawItem3.Text = "Custom Draw Item 1"; + ownerDrawItem3.Click += (s, e) => MessageBox.Show("Custom Owner Draw Item 1 clicked!"); + + // Add submenu items to ownerDrawItem3 + var subItem1_1 = new OwnerDrawMenuItem(); + subItem1_1.Text = "Submenu Item 1-1"; + subItem1_1.Click += (s, e) => MessageBox.Show("Submenu Item 1-1 clicked!"); + + var subItem1_2 = new OwnerDrawMenuItem(); + subItem1_2.Text = "Submenu Item 1-2"; + subItem1_2.Click += (s, e) => MessageBox.Show("Submenu Item 1-2 clicked!"); + + ownerDrawItem3.MenuItems.Add(subItem1_1); + ownerDrawItem3.MenuItems.Add(subItem1_2); + + var ownerDrawItem4 = new OwnerDrawMenuItem(); + ownerDrawItem4.Text = "Custom Draw Item 2"; + ownerDrawItem4.Click += (s, e) => MessageBox.Show("Custom Owner Draw Item 2 clicked!"); + + // Add submenu items to ownerDrawItem4 + var subItem2_1 = new OwnerDrawMenuItem(); + subItem2_1.Text = "Nested Custom Item A"; + subItem2_1.Click += (s, e) => MessageBox.Show("Nested Custom Item A clicked!"); + + var subItem2_2 = new OwnerDrawMenuItem(); + subItem2_2.Text = "Nested Custom Item B"; + subItem2_2.Click += (s, e) => MessageBox.Show("Nested Custom Item B clicked!"); + + ownerDrawItem4.MenuItems.Add(subItem2_1); + ownerDrawItem4.MenuItems.Add(subItem2_2); + + // Add a sub-submenu to test deeper nesting + var deepSubmenu = new MenuItem("Deep Submenu"); + var deepSubItem1 = new OwnerDrawMenuItem(); + deepSubItem1.Text = "Deep Custom Item 1"; + deepSubItem1.Click += (s, e) => MessageBox.Show("Deep Custom Item 1 clicked!\nThree levels deep with custom drawing!"); + + var deepSubItem2 = new OwnerDrawMenuItem(); + deepSubItem2.Text = "Deep Custom Item 2"; + deepSubItem2.Click += (s, e) => MessageBox.Show("Deep Custom Item 2 clicked!\nCustom drawing works at any depth!"); + + deepSubmenu.MenuItems.Add(deepSubItem1); + deepSubmenu.MenuItems.Add(deepSubItem2); + + ownerDrawItem4.MenuItems.Add(subItem2_1); + ownerDrawItem4.MenuItems.Add(subItem2_2); + ownerDrawItem4.MenuItems.Add(new MenuItem("-")); // Separator + ownerDrawItem4.MenuItems.Add(deepSubmenu); + + ownerDrawDemoMenuItem.MenuItems.Add(new MenuItem("Standard Item")); + ownerDrawDemoMenuItem.MenuItems.Add(new MenuItem("-")); + ownerDrawDemoMenuItem.MenuItems.Add(ownerDrawItem3); + ownerDrawDemoMenuItem.MenuItems.Add(ownerDrawItem4); + + mainMenu.MenuItems.Add(ownerDrawDemoMenuItem); + + // Set the form's main menu + this.Menu = mainMenu; + + newProjectItem.Click += NewProjectItem_Click; + newRepositoryItem.Click += NewRepositoryItem_Click; + newFileItem.Click += NewFileItem_Click; + + // Add event handlers for menu items + //newMenuItem.Click += NewMenuItem_Click; + openMenuItem.Click += OpenMenuItem_Click; + //saveMenuItem.Click += SaveMenuItem_Click; + exitMenuItem.Click += ExitMenuItem_Click; + + toolboxMenuItem.Click += ToolboxMenuItem_Click; + terminalMenuItem.Click += TerminalMenuItem_Click; + outputMenuItem.Click += OutputMenuItem_Click; + } + + private void DynamicMenuItem_Popup(object sender, EventArgs e) + { + MenuItem dynamicMenuItem = sender as MenuItem; + if (dynamicMenuItem != null) + { + dynamicMenuItem.MenuItems.Clear(); + for (int i = 1; i <= 5; i++) + { + dynamicMenuItem.MenuItems.Add(new MenuItem($"Dynamic Item {i}")); + } + } + } + + private void InitializeMenuStrip() + { + // Create a MenuStrip + MenuStrip menuStrip = new MenuStrip(); + + // Create "File" menu item + ToolStripMenuItem fileMenuItem = new ToolStripMenuItem("File"); + fileMenuItem.DropDownItems.Add("New"); + fileMenuItem.DropDownItems.Add("Open"); + fileMenuItem.DropDownItems.Add("Save"); + fileMenuItem.DropDownItems.Add("Exit"); + menuStrip.Items.Add(fileMenuItem); + + // Create "Edit" menu item + ToolStripMenuItem editMenuItem = new ToolStripMenuItem("Edit"); + editMenuItem.DropDownItems.Add("Cut"); + editMenuItem.DropDownItems.Add("Copy"); + editMenuItem.DropDownItems.Add("Paste"); + menuStrip.Items.Add(editMenuItem); + + // Attach the MenuStrip to the form + this.Controls.Add(menuStrip); + this.MainMenuStrip = menuStrip; + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1024, 768); + this.Text = "WTG WinForms Demo"; + } + + #endregion + } +} diff --git a/Demo/Form1.cs b/Demo/Form1.cs new file mode 100644 index 00000000000..a84ad6370f3 --- /dev/null +++ b/Demo/Form1.cs @@ -0,0 +1,394 @@ +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Windows.Forms; + +#nullable disable + +namespace Demo +{ + /// + /// Summary description for Form1. + /// + public partial class Form1 : Form + { + private DataGrid myDataGrid; + private DataSet myDataSet; + private bool TablesAlreadyAdded; + private Button button1; + private Button button2; + + private MainMenu mainMenu; + private MenuItem fileMenuItem; + private MenuItem newMenuItem; + private MenuItem openMenuItem; + private MenuItem saveMenuItem; + private MenuItem exitMenuItem; + private MenuItem newProjectItem; + private MenuItem newRepositoryItem; + private MenuItem newFileItem; + private MenuItem viewMenuItem; + private MenuItem toolboxMenuItem; + private MenuItem terminalMenuItem; + private MenuItem outputMenuItem; + + private ToolBar toolBar; + private TreeView treeView; + + /// + /// Summary description for Form1. + /// + public Form1() + { + InitializeComponent(); + + Shown += MainForm_Shown; + } + + private void MainForm_Shown(object sender, EventArgs e) + { + InitializeDataGrid(); + SetUp(); + InitializeMenu(); + InitializeStatusBar(); + //InitializeMenuStrip(); + + InitializeToolBar(); + InitializeTreeView(); + } + + private void InitializeTreeView() + { + this.treeView = new TreeView(); + this.treeView.Location = new Point(650, 100); + this.treeView.Size = new Size(200, 200); + this.treeView.CheckBoxes = true; + + TreeNode rootNode = new TreeNode("Root Node") + { + Nodes = + { + new TreeNode("Child Node 1") + { + Nodes = + { + new TreeNode("Sub Child Node 1"), + new TreeNode("Sub Child Node 2") + } + }, + new TreeNode("Child Node 2") + { + Nodes = + { + new TreeNode("Sub Child Node 3"), + new TreeNode("Sub Child Node 4") + } + }, + new TreeNode("Child Node 3") + } + }; + + this.treeView.Nodes.Add(rootNode); + + this.treeView.ContextMenu = new ContextMenu( + [ + new MenuItem("Option 1"), + new MenuItem("Option 2") + ]); + + AddContextMenuToNodes(treeView.Nodes); + + Controls.Add(this.treeView); + } + + private static void AddContextMenuToNodes(TreeNodeCollection nodes) + { + foreach (TreeNode node in nodes) + { + node.ContextMenu = new ContextMenu( + new MenuItem[] + { + new($"Option for {node.Text}"), + new($"Option 2 for {node.Text}") + }); + + if (node.Nodes.Count > 0) + { + AddContextMenuToNodes(node.Nodes); + } + } + } + + private void InitializeToolBar() + { + toolBar = new ToolBar(); + toolBar.Buttons.Add("1st button"); + var btn1 = toolBar.Buttons[0]; + btn1.ToolTipText = "This is the first button"; + + var sep1 = new ToolBarButton("sep1"); + sep1.Style = ToolBarButtonStyle.Separator; + toolBar.Buttons.Add(sep1); + + var btn2 = new ToolBarButton("btn2 toggle"); + btn2.Style = ToolBarButtonStyle.ToggleButton; + btn2.ToolTipText = "This is the second button"; + toolBar.Buttons.Add(btn2); + + var btn3 = new ToolBarButton("btn3 drop-down"); + btn3.Style = ToolBarButtonStyle.DropDownButton; + btn3.ToolTipText = "This is the third button"; + + MenuItem menuItem1 = new MenuItem("Wave"); + menuItem1.Click += (sender, e) => MessageBox.Show("Wave back"); + ContextMenu contextMenu1 = new ContextMenu(new MenuItem[] { menuItem1 }); + btn3.DropDownMenu = contextMenu1; + toolBar.Buttons.Add(btn3); + + ToolBarButtonClickEventHandler clickHandler = (object sender, ToolBarButtonClickEventArgs e) => + { + MessageBox.Show("Button clicked. text = " + e.Button.Text); + }; + + toolBar.ButtonClick += clickHandler; + + Controls.Add(toolBar); + } + + private void SetUp() + { + // Create a DataSet with two tables and one relation. + MakeDataSet(); + /* Bind the DataGrid to the DataSet. The dataMember + specifies that the Customers table should be displayed.*/ + myDataGrid.SetDataBinding(myDataSet, "Customers"); + } + + private void Button1_Click(object sender, System.EventArgs e) + { + if (TablesAlreadyAdded) + return; + AddCustomDataTableStyle(); + } + + private void AddCustomDataTableStyle() + { + DataGridTableStyle ts1 = new DataGridTableStyle + { + MappingName = "Customers", + // Set other properties. + AlternatingBackColor = Color.LightGray + }; + + /* Add a GridColumnStyle and set its MappingName + to the name of a DataColumn in the DataTable. + Set the HeaderText and Width properties. */ + + DataGridColumnStyle boolCol = new DataGridBoolColumn + { + MappingName = "Current", + HeaderText = "IsCurrent Customer", + Width = 150 + }; + ts1.GridColumnStyles.Add(boolCol); + + // Add a second column style. + DataGridColumnStyle TextCol = new DataGridTextBoxColumn + { + MappingName = "custName", + HeaderText = "Customer Name", + Width = 250 + }; + ts1.GridColumnStyles.Add(TextCol); + + // Create the second table style with columns. + DataGridTableStyle ts2 = new DataGridTableStyle + { + MappingName = "Orders", + + // Set other properties. + AlternatingBackColor = Color.LightBlue + }; + + // Create new ColumnStyle objects + DataGridColumnStyle cOrderDate = + new DataGridTextBoxColumn(); + cOrderDate.MappingName = "OrderDate"; + cOrderDate.HeaderText = "Order Date"; + cOrderDate.Width = 100; + ts2.GridColumnStyles.Add(cOrderDate); + + /* Use a PropertyDescriptor to create a formatted + column. First get the PropertyDescriptorCollection + for the data source and data member. */ + PropertyDescriptorCollection pcol = this.BindingContext[myDataSet, "Customers.custToOrders"].GetItemProperties(); + + /* Create a formatted column using a PropertyDescriptor. + The formatting character "c" specifies a currency format. */ + DataGridColumnStyle csOrderAmount = + new DataGridTextBoxColumn(pcol["OrderAmount"], "c", true); + csOrderAmount.MappingName = "OrderAmount"; + csOrderAmount.HeaderText = "Total"; + csOrderAmount.Width = 100; + ts2.GridColumnStyles.Add(csOrderAmount); + + /* Add the DataGridTableStyle instances to + the GridTableStylesCollection. */ + myDataGrid.TableStyles.Add(ts1); + myDataGrid.TableStyles.Add(ts2); + + // Sets the TablesAlreadyAdded to true so this doesn't happen again. + TablesAlreadyAdded = true; + } + + private void Button2_Click(object sender, System.EventArgs e) + { + BindingManagerBase bmGrid; + bmGrid = BindingContext[myDataSet, "Customers"]; + MessageBox.Show("Current BindingManager Position: " + bmGrid.Position); + } + + private void Grid_MouseUp(object sender, MouseEventArgs e) + { + // Create a HitTestInfo object using the HitTest method. + + // Get the DataGrid by casting sender. + DataGrid myGrid = (DataGrid)sender; + DataGrid.HitTestInfo myHitInfo = myGrid.HitTest(e.X, e.Y); + Console.WriteLine(myHitInfo); + Console.WriteLine(myHitInfo.Type); + Console.WriteLine(myHitInfo.Row); + Console.WriteLine(myHitInfo.Column); + } + + // Create a DataSet with two tables and populate it. + private void MakeDataSet() + { + // Create a DataSet. + myDataSet = new DataSet("myDataSet"); + + // Create two DataTables. + DataTable tCust = new DataTable("Customers"); + DataTable tOrders = new DataTable("Orders"); + + // Create two columns, and add them to the first table. + DataColumn cCustID = new DataColumn("CustID", typeof(int)); + DataColumn cCustName = new DataColumn("CustName"); + DataColumn cCurrent = new DataColumn("Current", typeof(bool)); + tCust.Columns.Add(cCustID); + tCust.Columns.Add(cCustName); + tCust.Columns.Add(cCurrent); + + // Create three columns, and add them to the second table. + DataColumn cID = + new DataColumn("CustID", typeof(int)); + DataColumn cOrderDate = + new DataColumn("orderDate", typeof(DateTime)); + DataColumn cOrderAmount = + new DataColumn("OrderAmount", typeof(decimal)); + tOrders.Columns.Add(cOrderAmount); + tOrders.Columns.Add(cID); + tOrders.Columns.Add(cOrderDate); + + // Add the tables to the DataSet. + myDataSet.Tables.Add(tCust); + myDataSet.Tables.Add(tOrders); + + // Create a DataRelation, and add it to the DataSet. + DataRelation dr = new DataRelation + ("custToOrders", cCustID, cID); + myDataSet.Relations.Add(dr); + + /* Populates the tables. For each customer and order, + creates two DataRow variables. */ + DataRow newRow1; + DataRow newRow2; + + // Create three customers in the Customers Table. + for (int i = 1; i < 4; i++) + { + newRow1 = tCust.NewRow(); + newRow1["custID"] = i; + // Add the row to the Customers table. + tCust.Rows.Add(newRow1); + } + + // Give each customer a distinct name. + tCust.Rows[0]["custName"] = "Customer1"; + tCust.Rows[1]["custName"] = "Customer2"; + tCust.Rows[2]["custName"] = "Customer3"; + + // Give the Current column a value. + tCust.Rows[0]["Current"] = true; + tCust.Rows[1]["Current"] = true; + tCust.Rows[2]["Current"] = false; + + // For each customer, create five rows in the Orders table. + for (int i = 1; i < 4; i++) + { + for (int j = 1; j < 6; j++) + { + newRow2 = tOrders.NewRow(); + newRow2["CustID"] = i; + newRow2["orderDate"] = new DateTime(2001, i, j * 2); + newRow2["OrderAmount"] = i * 10 + j * .1; + // Add the row to the Orders table. + tOrders.Rows.Add(newRow2); + } + } + } + + //private void NewMenuItem_Click(object sender, EventArgs e) + //{ + // MessageBox.Show("New menu item clicked!"); + //} + + private void OpenMenuItem_Click(object sender, EventArgs e) + { + MessageBox.Show("Open menu item clicked!"); + } + + private void SaveMenuItem_Click(object sender, EventArgs e) + { + MessageBox.Show("Save menu item clicked!"); + } + + private void ExitMenuItem_Click(object sender, EventArgs e) + { + Application.Exit(); + } + + private void NewProjectItem_Click(object sender, EventArgs e) + { + newProjectItem.Checked = !newProjectItem.Checked; + MessageBox.Show("Project sub-menu item clicked!"); + } + + private void NewRepositoryItem_Click(object sender, EventArgs e) + { + newRepositoryItem.Checked = !newRepositoryItem.Checked; + MessageBox.Show("Repository sub-menu item clicked!"); + } + + private void NewFileItem_Click(object sender, EventArgs e) + { + newFileItem.Checked = !newFileItem.Checked; + MessageBox.Show("File sub-menu item clicked!"); + } + + private void ToolboxMenuItem_Click(object sender, EventArgs e) + { + MessageBox.Show("Toolbox menu item clicked!"); + } + + private void TerminalMenuItem_Click(object sender, EventArgs e) + { + MessageBox.Show("Terminal menu item clicked!"); + } + + private void OutputMenuItem_Click(object sender, EventArgs e) + { + MessageBox.Show("Output menu item clicked!"); + } + } +} diff --git a/src/System.Windows.Forms/tests/IntegrationTests/ScratchProject/Form1.resx b/Demo/Form1.resx similarity index 100% rename from src/System.Windows.Forms/tests/IntegrationTests/ScratchProject/Form1.resx rename to Demo/Form1.resx diff --git a/Demo/OwnerDrawMenuItem.cs b/Demo/OwnerDrawMenuItem.cs new file mode 100644 index 00000000000..5e0fd7b3b9a --- /dev/null +++ b/Demo/OwnerDrawMenuItem.cs @@ -0,0 +1,109 @@ +#if NET +using System.Drawing; +using System.Windows.Forms; +#endif + +namespace Demo +{ + class OwnerDrawMenuItem : MenuItem + { + public OwnerDrawMenuItem() : base() + { + OwnerDraw = true; + } + + protected override void OnDrawItem(DrawItemEventArgs e) + { + // Get the drawing area + Rectangle bounds = e.Bounds; + Graphics g = e.Graphics; + + // Determine colors based on item state + Color backColor = e.BackColor; + Color textColor = e.ForeColor; + + // Custom styling for selected/highlighted state + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) + { + backColor = Color.LightBlue; + textColor = Color.DarkBlue; + } + + // Draw background + using (Brush backBrush = new SolidBrush(backColor)) + { + g.FillRectangle(backBrush, bounds); + } + + // Draw an icon area (simple colored rectangle as demo) + Rectangle iconRect = new Rectangle(bounds.X + 4, bounds.Y + 2, 16, 16); + using (Brush iconBrush = new SolidBrush(Color.Green)) + { + g.FillRectangle(iconBrush, iconRect); + } + + // Draw a simple "check mark" in the icon area + using (Pen checkPen = new Pen(Color.White, 2)) + { + Point[] checkPoints = { + new (iconRect.X + 3, iconRect.Y + 8), + new (iconRect.X + 7, iconRect.Y + 12), + new (iconRect.X + 13, iconRect.Y + 4) + }; + g.DrawLines(checkPen, checkPoints); + } + + // Calculate text area (leaving space for icon and margins) + Rectangle textRect = new Rectangle( + bounds.X + 24, // Start after icon area (4 + 16 + 4 spacing) + bounds.Y + 1, + bounds.Width - 28, // Total margin: 4 (left) + 16 (icon) + 4 (spacing) + 4 (right) = 28 + bounds.Height - 2 + ); + + // Draw the menu text + using (Brush textBrush = new SolidBrush(textColor)) + { + StringFormat format = new StringFormat() + { + Alignment = StringAlignment.Near, + LineAlignment = StringAlignment.Center + }; + + Font font = e.Font ?? SystemInformation.MenuFont; + g.DrawString(Text, font, textBrush, textRect, format); + } + + // Draw focus rectangle if the item has focus + if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) + { + e.DrawFocusRectangle(); + } + + // Draw a subtle shadow effect at the bottom + using (Pen shadowPen = new Pen(Color.FromArgb(50, 0, 0, 0))) + { + g.DrawLine(shadowPen, bounds.X, bounds.Bottom - 1, bounds.Right, bounds.Bottom - 1); + } + } + + protected override void OnMeasureItem(MeasureItemEventArgs e) + { + Font font = SystemInformation.MenuFont; + + string text = Text ?? string.Empty; + if (string.IsNullOrEmpty(text)) + { + text = " "; + } + + var stringSize = e.Graphics.MeasureString(text, font); + e.ItemWidth = (int)Math.Ceiling(stringSize.Width) + 28; + + int minHeightForIcon = 20; + int textHeight = (int)Math.Ceiling(stringSize.Height) + 4; + + e.ItemHeight = Math.Max(minHeightForIcon, textHeight); + } + } +} diff --git a/Demo/Program.cs b/Demo/Program.cs new file mode 100644 index 00000000000..624a9600932 --- /dev/null +++ b/Demo/Program.cs @@ -0,0 +1,38 @@ +#if NET +using System.Windows.Forms; +#endif + +namespace Demo +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + // Set High DPI mode to DpiUnaware, as currently there are some scaling issues when setting to other values + // https://github.com/WiseTechGlobal/Modernization.Content/blob/main/Controls/work-items/Difference%20display%20between%20migrated%20forms%20and%20original%20forms.md +#if NET + Application.SetHighDpiMode(HighDpiMode.DpiUnaware); +#endif + //ApplicationConfiguration.Initialize(); + Application.Run(new Form1()); + } + } +} + +#if NETFRAMEWORK +namespace System.Runtime.Versioning +{ + class SupportedOSPlatformAttribute : Attribute + { + public SupportedOSPlatformAttribute(string platformName) { } + } +} +#endif diff --git a/Demo/xlf/Form1.cs.xlf b/Demo/xlf/Form1.cs.xlf new file mode 100644 index 00000000000..aa40faef86f --- /dev/null +++ b/Demo/xlf/Form1.cs.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.de.xlf b/Demo/xlf/Form1.de.xlf new file mode 100644 index 00000000000..caab0ce76f7 --- /dev/null +++ b/Demo/xlf/Form1.de.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.es.xlf b/Demo/xlf/Form1.es.xlf new file mode 100644 index 00000000000..37761f811ce --- /dev/null +++ b/Demo/xlf/Form1.es.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.fr.xlf b/Demo/xlf/Form1.fr.xlf new file mode 100644 index 00000000000..366eb9d5436 --- /dev/null +++ b/Demo/xlf/Form1.fr.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.it.xlf b/Demo/xlf/Form1.it.xlf new file mode 100644 index 00000000000..e68d3fe2676 --- /dev/null +++ b/Demo/xlf/Form1.it.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.ja.xlf b/Demo/xlf/Form1.ja.xlf new file mode 100644 index 00000000000..2943ecce294 --- /dev/null +++ b/Demo/xlf/Form1.ja.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.ko.xlf b/Demo/xlf/Form1.ko.xlf new file mode 100644 index 00000000000..83cb763b8f6 --- /dev/null +++ b/Demo/xlf/Form1.ko.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.pl.xlf b/Demo/xlf/Form1.pl.xlf new file mode 100644 index 00000000000..58b6edd6da0 --- /dev/null +++ b/Demo/xlf/Form1.pl.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.pt-BR.xlf b/Demo/xlf/Form1.pt-BR.xlf new file mode 100644 index 00000000000..073f6c00557 --- /dev/null +++ b/Demo/xlf/Form1.pt-BR.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.ru.xlf b/Demo/xlf/Form1.ru.xlf new file mode 100644 index 00000000000..5d784e2bc56 --- /dev/null +++ b/Demo/xlf/Form1.ru.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.tr.xlf b/Demo/xlf/Form1.tr.xlf new file mode 100644 index 00000000000..9ae0ede5336 --- /dev/null +++ b/Demo/xlf/Form1.tr.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.zh-Hans.xlf b/Demo/xlf/Form1.zh-Hans.xlf new file mode 100644 index 00000000000..2dbdc8d0ce3 --- /dev/null +++ b/Demo/xlf/Form1.zh-Hans.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo/xlf/Form1.zh-Hant.xlf b/Demo/xlf/Form1.zh-Hant.xlf new file mode 100644 index 00000000000..8782e525d98 --- /dev/null +++ b/Demo/xlf/Form1.zh-Hant.xlf @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/DeploymentSetup.ps1 b/DeploymentSetup.ps1 new file mode 100644 index 00000000000..be37a841288 --- /dev/null +++ b/DeploymentSetup.ps1 @@ -0,0 +1,35 @@ +$pkgId = 'CargoWiseCloudDeployment' + +# this uses the latest version of the package, as listed at https://proget.wtg.zone/packages?PackageSearch=CargoWiseCloudDeployment +# if you need a specific version, you can use: +#$pkgVersion = "1.0.0.70" +#url = "https://proget.wtg.zone/nuget/WTG-Internal/package/${pkgId}/$pkgVersion" + +$Destination = '.\bin' + +$pkgVersion = "1.0.0.362" # Set this to $null for most recent package. +$pkgRoot = Join-Path $Destination ("$pkgId.$pkgVersion") +$url = "https://proget.wtg.zone/nuget/WTG-Internal/package/${pkgId}/$pkgVersion" + + +try { + Invoke-WebRequest -Uri $url -OutFile "$pkgRoot.zip" -ErrorAction Stop + Write-Host "download nuget successfully" +} +catch { + Write-Error "download nuget failed: $($_.Exception.Message)" +} + +try { + Expand-Archive -Path "$pkgRoot.zip" -DestinationPath $pkgRoot -Force + Write-Host "unzip successfully" -ForegroundColor Green +} +catch { + Write-Error "unzip failed: $($_.Exception.Message)" +} + +Copy-Item -Path (Join-Path (Join-Path $pkgRoot '\content') '*') -Destination $Destination -Recurse -Force +Copy-Item -Path (Join-Path (Join-Path $pkgRoot '\lib\net10.0-windows7.0') '*') -Destination $Destination -Recurse -Force + +Remove-Item -Path "$pkgRoot.zip" -Force +Remove-Item -Path $pkgRoot -Recurse -Force \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index 3191e3fac7f..9c5d942b758 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -17,19 +17,19 @@ false preview enable - true - - false - true - - true - false + + + + + + + + + + + + + @@ -44,16 +44,16 @@ Note, any components that aren't exposed as references in the targeting pack (like analyzers/generators) those should rev so that they can exist SxS, as the compiler relies on different version to change assembly version for caching purposes. --> - - $(MajorVersion).$(MinorVersion).0.0 - + + + - - true + + - - WINFORMS_ANALYZERS - + + + diff --git a/Directory.Build.targets b/Directory.Build.targets index cf183e46bd2..5885fe770b6 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -32,12 +32,12 @@ - + x64 diff --git a/NuGet.config b/NuGet.config index d496e7a4199..ff3297031be 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,29 +1,18 @@ - + - - - - - - - - - - - - + + - diff --git a/README.md b/README.md index 6f74230874e..3eee7b5285b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,41 @@ +# WTG Notes + +Migrating obsolete winforms controls to compile and run in Net 8 for CW1's ZArchitecture. + +# WTG ChangeLog + +| Version | What's changed | +|------------------|-------------| +| 0.0.6-dev.final | initial version for net7 and net8 | +| 0.0.7-dev.final | System.Windows.Forms.Design.dll added to package | +| 0.0.8-dev.final | net8.0: changed version of System.Drawing.Common.dll (v4.0.0.0 -> v8.0.0.0) to fix Dev build | +| 0.0.9-dev.final | net8.0: changed versions of all libraries in package to v8.0.0.0 | +| 0.0.10-dev.final | skipped due to error in publishing | +| 0.0.11-dev.final | net8.0: remove warning WFDEV001 | +| 0.0.12-dev.final | avoid type issue when instanciated from ZBindingContext (WI00826420) | +| 0.0.13-dev.final | comment out Debug.Fail in PaintEventArgs (WI00857973) | +| 0.0.14-dev.final | switched to using Release configuration assemblies instead of Debug, to avoid Microsoft's plentiful Debug.Assert checks (WI00876922) | +| 0.0.15-dev.final | removed need for forked System.Drawing.Common. We can use the public package listed on nuget.org now. | +| 0.0.16-dev.final | fixed issue with keyboard shortcuts associated with menus not being captured (WI00895180) | +| 0.0.17-dev.final | temporarily fixed WebBrowser memory leak (WI00938771) | +| 0.0.18-dev.final | fixed menu popup events not firing (WI00949199) | +| 0.0.19-dev.final | fixed menu bar size not taken into account in form sizing (WI00949199) | +| 0.0.20-dev.final | Menu property change should trigger size update (WI00949199) | +| 0.0.21-dev.final | fixed ToolBar tooltip moving the position of the toolbar (WI00951596) | +| 0.0.22-dev.final | fixed control's anchor info (WI00955507) | +| 0.0.23-dev.final | fixed disappearing Owner Draw MenuItem (WI00948012) | +| 0.0.24-dev.final | IT Customs - NET8 NRE on Customs Declaration MISC Tab (WI01005730) | + + +# WTG How to publish new version + +* Do changes in code you want to be published +* Increase version in $(LIB_ROOT)\eng\Versions.props +* CH0 on DAT +* Go to DAT deployments for the CH0 build and click deploy + +# End of WTG part, Microsoft part below + # Windows Forms [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/dotnet/winforms/blob/main/LICENSE.TXT) diff --git a/Tests/System.Windows.Forms.Tests/AdjustWindowRectTests.cs b/Tests/System.Windows.Forms.Tests/AdjustWindowRectTests.cs new file mode 100644 index 00000000000..e5fdfd57ac9 --- /dev/null +++ b/Tests/System.Windows.Forms.Tests/AdjustWindowRectTests.cs @@ -0,0 +1,185 @@ +namespace System.Windows.Forms.Tests +{ + using System.Drawing; + + [TestFixture] + [SingleThreaded] + public class AdjustWindowRectTests + { + [Test] + public void Form_WindowRectCalculation_HandlesDpiScaling() + { + // Test that menu consideration works across different DPI scenarios + + // Arrange + using var form = new Form(); + var menu = new MainMenu(); + menu.MenuItems.Add(new MenuItem("Test")); + form.Menu = menu; + + var baseClientSize = new Size(400, 300); + + // Act + form.ClientSize = baseClientSize; + var windowSize = form.Size; + + // Change the client size again to ensure consistency + form.ClientSize = new Size(600, 450); + var newWindowSize = form.Size; + + // Assert + // The window size should scale proportionally with client size + var clientSizeChange = new Size(200, 150); // 600-400, 450-300 + var windowSizeChange = new Size(newWindowSize.Width - windowSize.Width, newWindowSize.Height - windowSize.Height); + + Assert.That(windowSizeChange, Is.EqualTo(clientSizeChange), + "Window size changes should match client size changes when menu is present"); + } + + [Test] + public void Form_CreateParams_MenuConsideredInWindowRectCalculation() + { + // Test that CreateParams and window rect calculations are consistent + + // Arrange + using var formWithMenu = new Form(); + using var formWithoutMenu = new Form(); + + var menu = new MainMenu(); + menu.MenuItems.Add(new MenuItem("File")); + formWithMenu.Menu = menu; + + // Set same size and create handles to trigger CreateParams usage + var testSize = new Size(300, 200); + formWithMenu.Size = testSize; + formWithoutMenu.Size = testSize; + + // Force handle creation to trigger CreateParams + _ = formWithMenu.Handle; + _ = formWithoutMenu.Handle; + + // Act & Assert + // The forms should maintain their size relationships after handle creation + // which exercises the CreateParams path + formWithMenu.ClientSize = new Size(250, 150); + formWithoutMenu.ClientSize = new Size(250, 150); + + Assert.That(formWithMenu.Size.Height, Is.GreaterThan(formWithoutMenu.Size.Height), + "After handle creation, form with menu should still be taller"); + } + + [Test] + public void ToolStripTextBox_InFormWithMenu_IndependentSizing() + { + // Test that ToolStripTextBox in a form with menu isn't affected by the form's menu + + // Arrange + using var formWithMenu = new Form(); + using var formWithoutMenu = new Form(); + + var menu = new MainMenu(); + menu.MenuItems.Add(new MenuItem("File")); + formWithMenu.Menu = menu; + + using var toolStrip1 = new ToolStrip(); + using var toolStrip2 = new ToolStrip(); + using var textBox1 = new ToolStripTextBox(); + using var textBox2 = new ToolStripTextBox(); + + toolStrip1.Items.Add(textBox1); + toolStrip2.Items.Add(textBox2); + formWithMenu.Controls.Add(toolStrip1); + formWithoutMenu.Controls.Add(toolStrip2); + + // Act + textBox1.Size = new Size(120, 22); + textBox2.Size = new Size(120, 22); + + // Assert + Assert.That(textBox1.Size, Is.EqualTo(textBox2.Size), + "ToolStripTextBox should not be affected by parent form's menu"); + } + + [Test] + public void Control_SizeCalculations_ConsistentForDifferentControlTypes() + { + // Test various control types to ensure they handle menu considerations correctly + + // Arrange & Act & Assert + using var form1 = new Form(); // No menu + using var form2 = new Form(); // Menu with items + + var menuWithItems = new MainMenu(); + menuWithItems.MenuItems.Add(new MenuItem("File")); + form2.Menu = menuWithItems; + + var clientSize = new Size(400, 300); + + // Act + form1.ClientSize = clientSize; + form2.ClientSize = clientSize; + + var controlTypes = new Func[] + { + () => new Button(), + () => new Label(), + () => new TextBox(), + () => new Panel(), + () => new GroupBox() + }; + + foreach (var createControl in controlTypes) + { + using var control1 = createControl(); + using var control2 = createControl(); + + var testSize = new Size(100, 50); + control1.Size = testSize; + control2.Size = testSize; + + form1.Controls.Add(control1); + form2.Controls.Add(control2); + + Assert.That(control1.Size, Is.EqualTo(control2.Size), + $"{control1.GetType().Name} controls should have consistent sizing behavior"); + } + } + + [Test] + public void Form_MenuVisibility_AffectsWindowSizeCalculation() + { + // Test the specific logic: menu only affects size if it has items + + // Arrange + using var form1 = new Form(); // No menu + using var form2 = new Form(); // Empty menu + using var form3 = new Form(); // Menu with items + + var emptyMenu = new MainMenu(); + form2.Menu = emptyMenu; + + var menuWithItems = new MainMenu(); + menuWithItems.MenuItems.Add(new MenuItem("File")); + form3.Menu = menuWithItems; + + var clientSize = new Size(400, 300); + + // Act + form1.ClientSize = clientSize; + form2.ClientSize = clientSize; + form3.ClientSize = clientSize; + + // Assert + // Forms 1 and 2 should have same height (no menu or empty menu) + Assert.That(form1.Size.Height, Is.EqualTo(form2.Size.Height), + "Form with no menu and form with empty menu should have same height"); + + // Form 3 should be taller (has menu items) + Assert.That(form3.Size.Height, Is.GreaterThan(form1.Size.Height), + "Form with menu items should be taller than form without menu"); + + Assert.That(form3.Size.Height, Is.GreaterThan(form2.Size.Height), + "Form with menu items should be taller than form with empty menu"); + } + } +} diff --git a/Tests/System.Windows.Forms.Tests/MainMenuTests.cs b/Tests/System.Windows.Forms.Tests/MainMenuTests.cs new file mode 100644 index 00000000000..b184260b9b0 --- /dev/null +++ b/Tests/System.Windows.Forms.Tests/MainMenuTests.cs @@ -0,0 +1,148 @@ +namespace System.Windows.Forms.Tests +{ + using System.Drawing; + using System.Runtime.InteropServices; + + [TestFixture] + [SingleThreaded] + public class MainMenuTests + { + [Test] + public void MainMenu_SetAndGet_ReturnsCorrectValue() + { + // Arrange + var form = new Form(); + var mainMenu = new MainMenu(); + + // Act + form.Menu = mainMenu; + + // Assert + Assert.That(form.Menu, Is.EqualTo(mainMenu)); + } + + [Test] + public void MainMenu_AddMenuItem_ReturnsCorrectMenuItem() + { + // Arrange + var mainMenu = new MainMenu(); + var menuItem = new MenuItem("Test Item"); + + // Act + mainMenu.MenuItems.Add(menuItem); + + // Assert + Assert.That(mainMenu.MenuItems.Count, Is.EqualTo(1)); + Assert.That(mainMenu.MenuItems[0], Is.EqualTo(menuItem)); + } + + [Test] + public void MainMenu_FileMenuPopup_AddsMenuItemOnPopup() + { + // Arrange + using var form = new Form(); + var mainMenu = new MainMenu(); + var fileMenuItem = new MenuItem("File"); + + // Add popup event handler that adds a menu item when fired + bool popupEventFired = false; + MenuItem? addedMenuItem = null; + + fileMenuItem.Popup += (sender, e) => + { + popupEventFired = true; + addedMenuItem = new MenuItem("Dynamic Item"); + fileMenuItem.MenuItems.Add(addedMenuItem); + }; + + mainMenu.MenuItems.Add(fileMenuItem); + form.Menu = mainMenu; + form.Size = new Size(400, 300); + + // Initially, the File menu should have no items + Assert.That(fileMenuItem.MenuItems.Count, Is.EqualTo(0)); + + // Create the handle so we can send Windows messages + var handle = form.Handle; // Forces handle creation + + // Act - Simulate WM_INITMENUPOPUP message to trigger popup event + // This is what Windows sends when a menu is about to be displayed + const uint WM_INITMENUPOPUP = 0x0117; + + // Send the message to trigger the popup event + // The wParam contains the handle to the menu, lParam contains position info + IntPtr result = SendMessage(handle, WM_INITMENUPOPUP, fileMenuItem.Handle, IntPtr.Zero); + + // Assert + Assert.That(popupEventFired, Is.True, "Popup event should have been fired"); + Assert.That(fileMenuItem.MenuItems.Count, Is.EqualTo(1), "File menu should have one item after popup"); + + if (addedMenuItem is not null) + { + Assert.That(fileMenuItem.MenuItems[0], Is.EqualTo(addedMenuItem), "The added item should be in the file menu"); + Assert.That(fileMenuItem.MenuItems[0].Text, Is.EqualTo("Dynamic Item"), "The added item should have the correct text"); + } + + // Clean up + form.Dispose(); + } + + [Test] + public void MainMenu_FileMenuWithSubmenu_PopupAddsItemToFileMenu() + { + // Arrange + var form = new Form(); + var mainMenu = new MainMenu(); + var fileMenuItem = new MenuItem("File"); + var submenu = new MenuItem("Submenu"); + + // Add the submenu to the File menu first + fileMenuItem.MenuItems.Add(submenu); + + // Add popup event handler to the File menu (not the submenu) + bool popupEventFired = false; + MenuItem? addedMenuItem = null; + + fileMenuItem.Popup += (sender, e) => + { + popupEventFired = true; + addedMenuItem = new MenuItem("Dynamic Item Added to File"); + fileMenuItem.MenuItems.Add(addedMenuItem); + }; + + mainMenu.MenuItems.Add(fileMenuItem); + form.Menu = mainMenu; + form.Size = new Size(400, 300); + + // Initially, the File menu should have 1 item (the submenu) + Assert.That(fileMenuItem.MenuItems.Count, Is.EqualTo(1)); + Assert.That(fileMenuItem.MenuItems[0], Is.EqualTo(submenu)); + + // Create the handle so we can send Windows messages + var handle = form.Handle; // Forces handle creation + + // Act - Simulate WM_INITMENUPOPUP message to the File menu + const uint WM_INITMENUPOPUP = 0x0117; + + // Send the message to trigger the popup event on the File menu + IntPtr result = SendMessage(handle, WM_INITMENUPOPUP, fileMenuItem.Handle, IntPtr.Zero); + + // Assert + Assert.That(popupEventFired, Is.True, "Popup event should have been fired"); + Assert.That(fileMenuItem.MenuItems.Count, Is.EqualTo(2), "File menu should have two items after popup"); + Assert.That(fileMenuItem.MenuItems[0], Is.EqualTo(submenu), "The original submenu should still be there"); + + if (addedMenuItem is not null) + { + Assert.That(fileMenuItem.MenuItems[1], Is.EqualTo(addedMenuItem), "The added item should be in the file menu"); + Assert.That(fileMenuItem.MenuItems[1].Text, Is.EqualTo("Dynamic Item Added to File"), "The added item should have the correct text"); + } + + // Clean up + form.Dispose(); + } + + [DllImport("user32.dll")] + private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); + } +} diff --git a/Tests/System.Windows.Forms.Tests/MenuItemTests.cs b/Tests/System.Windows.Forms.Tests/MenuItemTests.cs new file mode 100644 index 00000000000..9c2b36db8b5 --- /dev/null +++ b/Tests/System.Windows.Forms.Tests/MenuItemTests.cs @@ -0,0 +1,139 @@ +namespace System.Windows.Forms.Tests +{ + [TestFixture] + public class MenuItemTests + { +#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. + [Test] + public void MenuItem_OnDrawItem_Invoke_Success() + { + var menuItem = new SubMenuItem(); + + // No handler. + menuItem.OnDrawItem(null); + + // Handler. + int callCount = 0; + DrawItemEventHandler handler = (sender, e) => + { + Assert.That(sender, Is.EqualTo(menuItem)); + callCount++; + }; + + menuItem.DrawItem += handler; + menuItem.OnDrawItem(null); + Assert.That(callCount, Is.EqualTo(1)); + + // Should not call if the handler is removed. + menuItem.DrawItem -= handler; + menuItem.OnDrawItem(null); + Assert.That(callCount, Is.EqualTo(1)); + } + + [Test] + public void MenuItem_OnDrawItem_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.OnDrawItem(null)); + } + + [Test] + public void MenuItem_DrawItem_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + DrawItemEventHandler handler = (sender, e) => { }; + Assert.Throws(() => menuItem.DrawItem += handler); + Assert.Throws(() => menuItem.DrawItem -= handler); + } + + [Test] + public void MenuItem_OnMeasureItem_Invoke_Success() + { + var menuItem = new SubMenuItem(); + + // No handler. + menuItem.OnMeasureItem(null); + + // Handler. + int callCount = 0; + MeasureItemEventHandler handler = (sender, e) => + { + Assert.That(sender, Is.EqualTo(menuItem)); + callCount++; + }; + + menuItem.MeasureItem += handler; + menuItem.OnMeasureItem(null); + Assert.That(callCount, Is.EqualTo(1)); + + // Should not call if the handler is removed. + menuItem.MeasureItem -= handler; + menuItem.OnMeasureItem(null); + Assert.That(callCount, Is.EqualTo(1)); + } + + [Test] + public void MenuItem_OnMeasureItem_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.OnMeasureItem(null)); + } + + [Test] + public void MenuItem_MeasureItem_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + MeasureItemEventHandler handler = (sender, e) => { }; + Assert.Throws(() => menuItem.MeasureItem += handler); + Assert.Throws(() => menuItem.MeasureItem -= handler); + } +#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. + + public class SubMenuItem : MenuItem + { + public SubMenuItem() + { + } + + public SubMenuItem(string text) : base(text) + { + } + + public SubMenuItem(string text, EventHandler onClick) : base(text, onClick) + { + } + + public SubMenuItem(string text, MenuItem[] items) : base(text, items) + { + } + + public SubMenuItem(string text, EventHandler onClick, Shortcut shortcut) : base(text, onClick, shortcut) + { + } + + public SubMenuItem(MenuMerge mergeType, int mergeOrder, Shortcut shortcut, string text, EventHandler onClick, EventHandler onPopup, EventHandler onSelect, MenuItem[] items) : base(mergeType, mergeOrder, shortcut, text, onClick, onPopup, onSelect, items) + { + } + + public new int MenuID => base.MenuID; + + public new void OnClick(EventArgs e) => base.OnClick(e); + + public new void OnDrawItem(DrawItemEventArgs e) => base.OnDrawItem(e); + + public new void OnInitMenuPopup(EventArgs e) => base.OnInitMenuPopup(e); + + public new void OnMeasureItem(MeasureItemEventArgs e) => base.OnMeasureItem(e); + + public new void OnPopup(EventArgs e) => base.OnPopup(e); + + public new void OnSelect(EventArgs e) => base.OnSelect(e); + + public new void CloneMenu(Menu menuSrc) => base.CloneMenu(menuSrc); + } + } +} diff --git a/Tests/System.Windows.Forms.Tests/MenuSizeCalculationTests.cs b/Tests/System.Windows.Forms.Tests/MenuSizeCalculationTests.cs new file mode 100644 index 00000000000..5fa9ecdc7e3 --- /dev/null +++ b/Tests/System.Windows.Forms.Tests/MenuSizeCalculationTests.cs @@ -0,0 +1,299 @@ +namespace System.Windows.Forms.Tests +{ + using System.Drawing; + + [TestFixture] + [SingleThreaded] + public class MenuSizeCalculationTests + { + [Test] + public void Form_WithMenu_HasCorrectWindowSize() + { + // Arrange + using var formWithMenu = new Form(); + using var formWithoutMenu = new Form(); + + var menu = new MainMenu(); + menu.MenuItems.Add(new MenuItem("File")); + formWithMenu.Menu = menu; + + var clientSize = new Size(400, 300); + + // Act + formWithMenu.ClientSize = clientSize; + formWithoutMenu.ClientSize = clientSize; + + // Assert + Assert.That(formWithMenu.ClientSize, Is.EqualTo(clientSize), "Form with menu should have correct client size"); + Assert.That(formWithoutMenu.ClientSize, Is.EqualTo(clientSize), "Form without menu should have correct client size"); + + // The key test: form with menu should be taller due to menu bar + Assert.That(formWithMenu.Size.Height, Is.GreaterThan(formWithoutMenu.Size.Height), + "Form with menu should be taller than form without menu (accounts for menu bar height)"); + + // Width should be the same (menu doesn't affect width) + Assert.That(formWithMenu.Size.Width, Is.EqualTo(formWithoutMenu.Size.Width), + "Form width should not be affected by menu presence"); + } + + [Test] + public void Form_WithEmptyMenu_SameHeightAsFormWithoutMenu() + { + // Arrange + using var formWithEmptyMenu = new Form(); + using var formWithoutMenu = new Form(); + + var emptyMenu = new MainMenu(); // No menu items + formWithEmptyMenu.Menu = emptyMenu; + + var clientSize = new Size(400, 300); + + // Act + formWithEmptyMenu.ClientSize = clientSize; + formWithoutMenu.ClientSize = clientSize; + + // Assert + // According to the implementation, empty menus should not affect window height + Assert.That(formWithEmptyMenu.Size.Height, Is.EqualTo(formWithoutMenu.Size.Height), + "Form with empty menu should have same height as form without menu"); + } + + [Test] + public void Form_MenuAddedAfterCreation_AdjustsSize() + { + // Arrange + using var form = new Form(); + var clientSize = new Size(400, 300); + form.ClientSize = clientSize; + + var initialHeight = form.Size.Height; + + // Act - Add menu with items + var menu = new MainMenu(); + menu.MenuItems.Add(new MenuItem("File")); + form.Menu = menu; + form.ClientSize = clientSize; // Trigger recalculation + + // Assert + Assert.That(form.Size.Height, Is.GreaterThan(initialHeight), + "Form height should increase when menu with items is added"); + Assert.That(form.ClientSize, Is.EqualTo(clientSize), + "Client size should remain consistent after menu addition"); + } + + [Test] + public void Form_MenuRemovedAfterCreation_AdjustsSize() + { + // Arrange + using var form = new Form(); + var menu = new MainMenu(); + menu.MenuItems.Add(new MenuItem("File")); + form.Menu = menu; + + var clientSize = new Size(400, 300); + form.ClientSize = clientSize; + var heightWithMenu = form.Size.Height; + + // Act - Remove menu + form.Menu = null; + form.ClientSize = clientSize; // Trigger recalculation + + // Assert + Assert.That(form.Size.Height, Is.LessThan(heightWithMenu), + "Form height should decrease when menu is removed"); + Assert.That(form.ClientSize, Is.EqualTo(clientSize), + "Client size should remain consistent after menu removal"); + } + + [Test] + public void Form_NonTopLevel_MenuDoesNotAffectSize() + { + // Arrange + using var parentForm = new Form(); + using var childForm = new Form(); + + var menu = new MainMenu(); + menu.MenuItems.Add(new MenuItem("File")); + childForm.Menu = menu; + childForm.TopLevel = false; + childForm.Parent = parentForm; + + var clientSize = new Size(200, 150); + + // Create a comparable form without menu but also non-toplevel + using var childFormNoMenu = new Form(); + childFormNoMenu.TopLevel = false; + childFormNoMenu.Parent = parentForm; + + // Act + childForm.ClientSize = clientSize; + childFormNoMenu.ClientSize = clientSize; + + // Assert + // Non-top-level forms should not account for menus in sizing + Assert.That(childForm.Size.Height, Is.EqualTo(childFormNoMenu.Size.Height), + "Non-top-level forms should not be affected by menu presence"); + } + + [Test] + public void MDIChild_MenuDoesNotAffectSize() + { + // Arrange + using var parentForm = new Form(); + parentForm.IsMdiContainer = true; + + using var mdiChild1 = new Form(); + using var mdiChild2 = new Form(); + + var menu = new MainMenu(); + menu.MenuItems.Add(new MenuItem("File")); + mdiChild1.Menu = menu; + + mdiChild1.MdiParent = parentForm; + mdiChild2.MdiParent = parentForm; + + var clientSize = new Size(200, 150); + + // Act + mdiChild1.ClientSize = clientSize; + mdiChild2.ClientSize = clientSize; + + // Assert + // MDI children should not account for menus in sizing + Assert.That(mdiChild1.Size.Height, Is.EqualTo(mdiChild2.Size.Height), + "MDI child forms should not be affected by menu presence"); + } + + [Test] + public void Form_MenuWithMultipleItems_SameHeightAsMenuWithOneItem() + { + // Arrange + using var formWithOneMenuItem = new Form(); + using var formWithMultipleMenuItems = new Form(); + + var menuOne = new MainMenu(); + menuOne.MenuItems.Add(new MenuItem("File")); + formWithOneMenuItem.Menu = menuOne; + + var menuMultiple = new MainMenu(); + menuMultiple.MenuItems.Add(new MenuItem("File")); + menuMultiple.MenuItems.Add(new MenuItem("Edit")); + menuMultiple.MenuItems.Add(new MenuItem("View")); + formWithMultipleMenuItems.Menu = menuMultiple; + + var clientSize = new Size(400, 300); + + // Act + formWithOneMenuItem.ClientSize = clientSize; + formWithMultipleMenuItems.ClientSize = clientSize; + + // Assert + // Number of menu items shouldn't affect form height (all in same menu bar) + Assert.That(formWithMultipleMenuItems.Size.Height, Is.EqualTo(formWithOneMenuItem.Size.Height), + "Forms should have same height regardless of number of menu items"); + } + + [Test] + public void Form_MenuWithSubmenus_SameHeightAsMenuWithoutSubmenus() + { + // Arrange + using var formWithSubmenu = new Form(); + using var formWithoutSubmenu = new Form(); + + var menuWithSubmenu = new MainMenu(); + var fileMenu = new MenuItem("File"); + fileMenu.MenuItems.Add(new MenuItem("New")); + fileMenu.MenuItems.Add(new MenuItem("Open")); + menuWithSubmenu.MenuItems.Add(fileMenu); + formWithSubmenu.Menu = menuWithSubmenu; + + var menuWithoutSubmenu = new MainMenu(); + menuWithoutSubmenu.MenuItems.Add(new MenuItem("File")); + formWithoutSubmenu.Menu = menuWithoutSubmenu; + + var clientSize = new Size(400, 300); + + // Act + formWithSubmenu.ClientSize = clientSize; + formWithoutSubmenu.ClientSize = clientSize; + + // Assert + // Submenus shouldn't affect form height (they're dropdowns) + Assert.That(formWithSubmenu.Size.Height, Is.EqualTo(formWithoutSubmenu.Size.Height), + "Forms should have same height regardless of submenu complexity"); + } + + [Test] + public void Form_SetClientSizeMultipleTimes_ConsistentBehavior() + { + // Test that the HasMenu logic is consistently applied + + // Arrange + using var form = new Form(); + var menu = new MainMenu(); + menu.MenuItems.Add(new MenuItem("File")); + form.Menu = menu; + + var clientSize1 = new Size(300, 200); + var clientSize2 = new Size(500, 400); + + // Act & Assert + form.ClientSize = clientSize1; + Assert.That(form.ClientSize, Is.EqualTo(clientSize1), "First client size setting should work correctly"); + var height1 = form.Size.Height; + + form.ClientSize = clientSize2; + Assert.That(form.ClientSize, Is.EqualTo(clientSize2), "Second client size setting should work correctly"); + var height2 = form.Size.Height; + + // The height difference should be proportional to client size difference + var clientHeightDiff = clientSize2.Height - clientSize1.Height; + var windowHeightDiff = height2 - height1; + Assert.That(windowHeightDiff, Is.EqualTo(clientHeightDiff), + "Window height difference should equal client height difference (menu bar height is constant)"); + } + + [Test] + public void Form_MenuRemovedBeforeHandleCreated_SizeUpdatesImmediately() + { + // This test verifies the fix for the issue where setting Menu to null + // before handle creation didn't update the form size immediately + + // Arrange + using var form = new Form(); + + // Create menu with items + var menu = new MainMenu(); + menu.MenuItems.Add(new MenuItem("File")); + menu.MenuItems.Add(new MenuItem("Edit")); + + // Set menu first + form.Menu = menu; + + // Set client size - this should trigger FormStateSetClientSize + var targetClientSize = new Size(400, 300); + form.ClientSize = targetClientSize; + + // Capture size with menu (before handle is created) + var sizeWithMenu = form.Size; + + // Act - Remove menu before handle is created + // This should trigger the fix in line 760: if FormStateSetClientSize == 1 && !IsHandleCreated + form.Menu = null; + + // Assert + var sizeWithoutMenu = form.Size; + + // The form size should be updated immediately when menu is removed + Assert.That(sizeWithoutMenu.Height, Is.LessThan(sizeWithMenu.Height), + "Form height should decrease immediately when menu is removed before handle creation"); + + Assert.That(form.ClientSize, Is.EqualTo(targetClientSize), + "Client size should remain the target size after menu removal"); + + // Width should remain the same + Assert.That(sizeWithoutMenu.Width, Is.EqualTo(sizeWithMenu.Width), + "Form width should not change when menu is removed"); + } + } +} diff --git a/Tests/System.Windows.Forms.Tests/MouseOperations.cs b/Tests/System.Windows.Forms.Tests/MouseOperations.cs new file mode 100644 index 00000000000..cfb7c1dac39 --- /dev/null +++ b/Tests/System.Windows.Forms.Tests/MouseOperations.cs @@ -0,0 +1,24 @@ +namespace System.Windows.Forms.Tests +{ + using System.Runtime.InteropServices; + + public static class MouseOperations + { + [Flags] + public enum MouseEventFlags + { + LeftDown = 0x00000002, + LeftUp = 0x00000004, + RightDown = 0x00000008, + RightUp = 0x00000010, + } + + [DllImport("user32.dll")] + private static extern void mouse_event(int dwFlags, uint dx, uint dy, int dwData, int dwExtraInfo); + + public static void MouseEvent(MouseEventFlags value, uint dx, uint dy) + { + mouse_event((int)value, dx, dy, 0, 0); + } + } +} diff --git a/Tests/System.Windows.Forms.Tests/System.Windows.Forms.Tests.csproj b/Tests/System.Windows.Forms.Tests/System.Windows.Forms.Tests.csproj new file mode 100644 index 00000000000..e46948ac6e1 --- /dev/null +++ b/Tests/System.Windows.Forms.Tests/System.Windows.Forms.Tests.csproj @@ -0,0 +1,31 @@ + + + + net8.0 + enable + enable + + false + true + $([System.IO.Path]::GetFullPath('$(RepoRoot)Bin\$(OutDirName)\')) + + ECMA + + + + + + + + + + + + + + + + + + + diff --git a/Tests/System.Windows.Forms.Tests/TabControlTests.cs b/Tests/System.Windows.Forms.Tests/TabControlTests.cs new file mode 100644 index 00000000000..77b91517390 --- /dev/null +++ b/Tests/System.Windows.Forms.Tests/TabControlTests.cs @@ -0,0 +1,48 @@ +namespace System.Windows.Forms.Tests +{ + [TestFixture] + [SingleThreaded] + public class TabControlTests + { + [Test] + public void TabControl_ClearTabsWhileSelected_DoesNotThrowNullReferenceException() + { + Exception? capturedException = null; + ThreadExceptionEventHandler handler = (_, e) => capturedException = e.Exception; + + Application.ThreadException += handler; + try + { + using Form form = new(); + using TabControl control = new(); + + control.TabPages.Add(new TabPage("Tab 1")); + control.TabPages.Add(new TabPage("Tab 2")); + control.TabPages.Add(new TabPage("Tab 3")); + + form.Controls.Add(control); + form.Show(); + _ = control.AccessibilityObject; + + control.SelectedIndex = 1; + Application.DoEvents(); + + control.TabPages.Clear(); + + Application.DoEvents(); + System.Threading.Thread.Sleep(10); + + Assert.That(control.TabPages.Count, Is.EqualTo(0)); + Assert.That(control.SelectedTab, Is.Null); + } + finally + { + Application.ThreadException -= handler; + if (capturedException is not null) + { + Assert.Fail($"Unhandled exception: {capturedException.GetType().Name}\n{capturedException.Message}\n{capturedException.StackTrace}"); + } + } + } + } +} diff --git a/Tests/System.Windows.Forms.Tests/ToolBarToolTipTests.cs b/Tests/System.Windows.Forms.Tests/ToolBarToolTipTests.cs new file mode 100644 index 00000000000..f834c08f47a --- /dev/null +++ b/Tests/System.Windows.Forms.Tests/ToolBarToolTipTests.cs @@ -0,0 +1,260 @@ +using System; +using System.Drawing; +using System.Runtime.InteropServices; +using Windows.Win32; +using Windows.Win32.Foundation; +using Windows.Win32.UI.WindowsAndMessaging; + +namespace System.Windows.Forms.Tests +{ + [TestFixture] + [SingleThreaded] + [Apartment(System.Threading.ApartmentState.STA)] + public class ToolBarToolTipTests + { + // Minimal interop needed for this test (use internal wrappers/constants where available) + + // Hot item flags + [Flags] + private enum HICF : uint + { + ENTERING = 0x0010, + } + + [StructLayout(LayoutKind.Sequential)] + private struct NMTBHOTITEM + { + public NativeMethods.NMHDR hdr; + public int idOld; + public int idNew; + public HICF dwFlags; + } + + // High DPI thread awareness helpers (User32) + [DllImport("user32.dll", EntryPoint = "SetThreadDpiAwarenessContext", ExactSpelling = true)] + private static extern IntPtr SetThreadDpiAwarenessContext(IntPtr dpiContext); + + [DllImport("user32.dll", EntryPoint = "GetThreadDpiAwarenessContext", ExactSpelling = true)] + private static extern IntPtr GetThreadDpiAwarenessContext(); + + // Known DPI_AWARENESS_CONTEXT values (casted from macros): + // https://learn.microsoft.com/windows/win32/hidpi/dpi-awareness-context + private static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = new IntPtr(-4); + + private sealed class DpiAwarenessScope : IDisposable + { + private readonly IntPtr _old; + private readonly bool _enabled; + + public DpiAwarenessScope(IntPtr newContext) + { + try + { + _old = GetThreadDpiAwarenessContext(); + _enabled = SetThreadDpiAwarenessContext(newContext) != IntPtr.Zero; + } + catch (EntryPointNotFoundException) + { + _enabled = false; // OS doesn't support per-thread DPI; proceed without changing + } + } + + public void Dispose() + { + if (_enabled) + { + try + { + SetThreadDpiAwarenessContext(_old); + } + catch (EntryPointNotFoundException) + { + /* ignore */ + } + } + } + } + + [Test] + public void ToolBar_ToolTip_Show_DoesNotMove_ToolBar() + { + using var form = new Form + { + StartPosition = FormStartPosition.Manual, + Location = new Point(100, 100), + Size = new Size(400, 200) + }; + + var toolBar = new ToolBar + { + ShowToolTips = true, + Dock = DockStyle.None, + Location = new Point(0, 0) + }; + + toolBar.Buttons.Add(new ToolBarButton("Btn") { ToolTipText = "Tip" }); + form.Controls.Add(toolBar); + + form.Show(); + Application.DoEvents(); + + // Precondition: toolbar starts at 0,0 + Assert.That(toolBar.Location, Is.EqualTo(new Point(0, 0))); + + // Get the native tooltip HWND created by the toolbar + var lres = PInvoke.SendMessage(toolBar, (MessageId)NativeMethods.TB_GETTOOLTIPS); + HWND tooltipHwnd = (HWND)lres; + Assert.That((IntPtr)tooltipHwnd.Value, Is.Not.EqualTo(IntPtr.Zero), "Expected native tooltip window"); + + // Force the tooltip window top-left at (0,0) so TTN_SHOW logic will try to reposition it + PInvoke.SetWindowPos(tooltipHwnd, HWND.Null, 0, 0, 0, 0, + SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOZORDER | SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE); + + // 1) Simulate hot item change so internal hotItem != -1 + var hot = new NMTBHOTITEM + { + hdr = new NativeMethods.NMHDR { hwndFrom = toolBar.Handle, idFrom = IntPtr.Zero, code = NativeMethods.TBN_HOTITEMCHANGE }, + idOld = -1, + idNew = 0, + dwFlags = HICF.ENTERING + }; + PInvoke.SendMessage(toolBar, (MessageId)MessageId.WM_REFLECT_NOTIFY, default, ref hot); + + Application.DoEvents(); + + // 2) Simulate TTN_SHOW from the tooltip window + var nmhdr = new NativeMethods.NMHDR { hwndFrom = (IntPtr)tooltipHwnd.Value, idFrom = IntPtr.Zero, code = NativeMethods.TTN_SHOW }; + PInvoke.SendMessage(toolBar, (MessageId)MessageId.WM_REFLECT_NOTIFY, default, ref nmhdr); + + Application.DoEvents(); + + // Assertion: Showing the tooltip must NOT move the toolbar. + // This would fail under the original bug where SetWindowPos targeted the toolbar HWND. + Assert.That(toolBar.Location, Is.EqualTo(new Point(0, 0)), "ToolBar moved unexpectedly during TTN_SHOW processing"); + + form.Close(); + } + + [Test] + public void ToolBar_ToolTip_Show_Returns_1_When_Tooltip_Is_At_0_0() + { + using var form = new Form + { + StartPosition = FormStartPosition.Manual, + Location = new Point(200, 200), + Size = new Size(400, 200) + }; + + var toolBar = new ToolBar + { + ShowToolTips = true, + Dock = DockStyle.None, + Location = new Point(10, 10) + }; + + toolBar.Buttons.Add(new ToolBarButton("Btn") { ToolTipText = "Tip" }); + form.Controls.Add(toolBar); + + form.Show(); + Application.DoEvents(); + + // Ensure toolbar is not at 0,0 so wrong GetWindowPlacement handle avoids the reposition branch + Assert.That(toolBar.Location, Is.EqualTo(new Point(10, 10))); + + // Acquire native tooltip HWND + var lres = PInvoke.SendMessage(toolBar, (MessageId)NativeMethods.TB_GETTOOLTIPS); + HWND tooltipHwnd = (HWND)lres; + Assert.That((IntPtr)tooltipHwnd.Value, Is.Not.EqualTo(IntPtr.Zero)); + + // Force the tooltip at (0,0) to trigger the reposition path when correct handle is used + PInvoke.SetWindowPos(tooltipHwnd, HWND.Null, 0, 0, 0, 0, + SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOZORDER | SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE); + + // Simulate hot item change so hotItem != -1 + var hot = new NMTBHOTITEM + { + hdr = new NativeMethods.NMHDR { hwndFrom = toolBar.Handle, idFrom = IntPtr.Zero, code = NativeMethods.TBN_HOTITEMCHANGE }, + idOld = -1, + idNew = 0, + dwFlags = HICF.ENTERING + }; + PInvoke.SendMessage(toolBar, (MessageId)MessageId.WM_REFLECT_NOTIFY, default, ref hot); + + Application.DoEvents(); + + // Simulate TTN_SHOW and capture the return value from WndProc + var nmhdr = new NativeMethods.NMHDR { hwndFrom = (IntPtr)tooltipHwnd.Value, idFrom = IntPtr.Zero, code = NativeMethods.TTN_SHOW }; + var retL = PInvoke.SendMessage(toolBar, (MessageId)MessageId.WM_REFLECT_NOTIFY, default, ref nmhdr); + IntPtr ret = (IntPtr)(nint)retL; + + // Expect: when the correct window (tooltip) is queried for placement, TTN_SHOW repositions and returns 1. + // With the buggy code that queries the toolbar's placement, the condition won't trigger and ret will be 0. + Assert.That(ret, Is.EqualTo(new IntPtr(1)), "TTN_SHOW did not signal reposition; expected m.Result==1 when tooltip at (0,0)"); + + form.Close(); + } + + [Test] + public void ToolBar_ToolTip_TTN_SHOW_PerMonitorV2_DoesNotMove_And_Returns_1() + { + // Enter Per-Monitor V2 DPI context for the thread (best effort; no-op on older OS) + using var scope = new DpiAwarenessScope(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + + using var form = new Form + { + StartPosition = FormStartPosition.Manual, + Location = new Point(300, 300), + Size = new Size(500, 300) + }; + + var toolBar = new ToolBar + { + ShowToolTips = true, + Dock = DockStyle.None, + Location = new Point(12, 12) + }; + + toolBar.Buttons.Add(new ToolBarButton("Btn") { ToolTipText = "Tip" }); + form.Controls.Add(toolBar); + + form.Show(); + Application.DoEvents(); + + var originalLocation = toolBar.Location; + + // Acquire native tooltip HWND + var lres = PInvoke.SendMessage(toolBar, (MessageId)NativeMethods.TB_GETTOOLTIPS); + HWND tooltipHwnd = (HWND)lres; + Assert.That((IntPtr)tooltipHwnd.Value, Is.Not.EqualTo(IntPtr.Zero)); + + // Force tooltip to (0,0) so TTN_SHOW reposition path is taken + PInvoke.SetWindowPos(tooltipHwnd, HWND.Null, 0, 0, 0, 0, + SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOZORDER | SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE); + + // Simulate hot item change so hotItem != -1 + var hot = new NMTBHOTITEM + { + hdr = new NativeMethods.NMHDR { hwndFrom = toolBar.Handle, idFrom = IntPtr.Zero, code = NativeMethods.TBN_HOTITEMCHANGE }, + idOld = -1, + idNew = 0, + dwFlags = HICF.ENTERING + }; + PInvoke.SendMessage(toolBar, (MessageId)MessageId.WM_REFLECT_NOTIFY, default, ref hot); + + Application.DoEvents(); + + // Simulate TTN_SHOW and capture return value + var nmhdr = new NativeMethods.NMHDR { hwndFrom = (IntPtr)tooltipHwnd.Value, idFrom = IntPtr.Zero, code = NativeMethods.TTN_SHOW }; + var retL = PInvoke.SendMessage(toolBar, (MessageId)MessageId.WM_REFLECT_NOTIFY, default, ref nmhdr); + IntPtr ret = (IntPtr)(nint)retL; + + Application.DoEvents(); + + // Assertions: TTN_SHOW is handled (ret==1) and the toolbar itself does not move + Assert.That(ret, Is.EqualTo(new IntPtr(1)), "TTN_SHOW should be handled under Per-Monitor V2 context"); + Assert.That(toolBar.Location, Is.EqualTo(originalLocation), "ToolBar moved unexpectedly during TTN_SHOW under Per-Monitor V2 context"); + + form.Close(); + } + } +} diff --git a/Tests/System.Windows.Forms.Tests/TreeNodeTests.cs b/Tests/System.Windows.Forms.Tests/TreeNodeTests.cs new file mode 100644 index 00000000000..7a4121a3280 --- /dev/null +++ b/Tests/System.Windows.Forms.Tests/TreeNodeTests.cs @@ -0,0 +1,155 @@ +namespace System.Windows.Forms.Tests +{ + using System.Drawing; + + [TestFixture] + [SingleThreaded] + public class TreeNodeTests + { + [Test] + public void Text_SetAndGet_ReturnsCorrectValue() + { + // Arrange + var treeNode = new TreeNode(); + var text = "Test Node"; + + // Act + treeNode.Text = text; + + // Assert + Assert.That(treeNode.Text, Is.EqualTo(text)); + } + + [Test] + public void Nodes_AddAndGet_ReturnsCorrectNodes() + { + // Arrange + var parentNode = new TreeNode(); + var childNode = new TreeNode("Child Node"); + + // Act + parentNode.Nodes.Add(childNode); + + // Assert + Assert.That(parentNode.Nodes.Count, Is.EqualTo(1)); + Assert.That(parentNode.Nodes[0], Is.EqualTo(childNode)); + } + + [Test] + public void Parent_SetAndGet_ReturnsCorrectParent() + { + // Arrange + var parentNode = new TreeNode("Parent Node"); + var childNode = new TreeNode("Child Node"); + + // Act + parentNode.Nodes.Add(childNode); + + // Assert + Assert.That(childNode.Parent, Is.EqualTo(parentNode)); + } + + [Test] + public void Remove_RemovesNodeFromParent() + { + // Arrange + var parentNode = new TreeNode("Parent Node"); + var childNode = new TreeNode("Child Node"); + parentNode.Nodes.Add(childNode); + + // Act + parentNode.Nodes.Remove(childNode); + + // Assert + Assert.That(parentNode.Nodes.Count, Is.EqualTo(0)); + Assert.That(childNode.Parent, Is.Null); + } + + [Test] + public void TreeView_SetAndGet_ReturnsCorrectTreeView() + { + // Arrange + var treeView = new TreeView(); + var treeNode = new TreeNode("Test Node"); + + // Act + treeView.Nodes.Add(treeNode); + + // Assert + Assert.That(treeNode.TreeView, Is.EqualTo(treeView)); + } + + [Test] + public void ContextMenu_SetAndGet_ReturnsCorrectValue() + { + // Arrange + var treeNode = new TreeNode(); + var contextMenu = new ContextMenu(); + + // Act + treeNode.ContextMenu = contextMenu; + + // Assert + Assert.That(treeNode.ContextMenu, Is.EqualTo(contextMenu)); + } + + // Commenting out this test, as it doesn't work in DAT + //[Test] + //public void ContextMenu_ShowsOnRightClick() + //{ + // // Arrange + // var form = new Form(); + // var treeView = new TreeView(); + // var treeNode = new TreeNode("Test Node"); + // var contextMenu = new ContextMenu(); + // contextMenu.MenuItems.Add(new MenuItem("Test Item")); + // treeNode.ContextMenu = contextMenu; + // treeView.Nodes.Add(treeNode); + // treeView.Bounds = new Rectangle(10, 10, 200, 200); + // form.Controls.Add(treeView); + + // bool contextMenuShown = false; + // contextMenu.Popup += (sender, e) => contextMenuShown = true; + + // // Ensure the Form and TreeView are created and visible + // form.Load += async (sender, e) => + // { + // // Need to wait for the form to be created and visible + // await Task.Delay(500); + + // // Get the bounds of the TreeNode + // var nodeBounds = treeNode.Bounds; + // var clickPointRelativeToTreeView = nodeBounds.Location + new Size(nodeBounds.Width / 2, nodeBounds.Y + nodeBounds.Height / 2); + // var clickPointRelativeToScreen = treeView.PointToScreen(clickPointRelativeToTreeView); + + // // Simulate right-click event on the TreeNode + // Cursor.Position = clickPointRelativeToScreen; + // MouseOperations.MouseEvent(MouseOperations.MouseEventFlags.RightDown, (uint)clickPointRelativeToScreen.X, (uint)clickPointRelativeToScreen.Y); + // await Task.Delay(100); + // MouseOperations.MouseEvent(MouseOperations.MouseEventFlags.RightUp, (uint)clickPointRelativeToScreen.X, (uint)clickPointRelativeToScreen.Y); + + // // Wait 1 second for the context menu to show + // await Task.Delay(1000); + + // var clickPointOutsideContextMenuRelative = new Point(50, 50); + // var clickPointOutsideContextMenuAbsolute = treeView.PointToScreen(clickPointOutsideContextMenuRelative); + + // Cursor.Position = clickPointOutsideContextMenuAbsolute; + // MouseOperations.MouseEvent(MouseOperations.MouseEventFlags.LeftDown, (uint)clickPointOutsideContextMenuAbsolute.X, (uint)clickPointOutsideContextMenuAbsolute.Y); + // await Task.Delay(100); + // MouseOperations.MouseEvent(MouseOperations.MouseEventFlags.LeftUp, (uint)clickPointOutsideContextMenuAbsolute.X, (uint)clickPointOutsideContextMenuAbsolute.Y); + + // // Wait 1 second for the context menu to close + // await Task.Delay(1000); + + // // Assert + // Assert.IsTrue(contextMenuShown); + // form.Close(); + // return; + // }; + + // // Show the form + // form.ShowDialog(); + //} + } +} diff --git a/Tests/System.Windows.Forms.Tests/TreeViewTests.cs b/Tests/System.Windows.Forms.Tests/TreeViewTests.cs new file mode 100644 index 00000000000..c6413d3cd38 --- /dev/null +++ b/Tests/System.Windows.Forms.Tests/TreeViewTests.cs @@ -0,0 +1,96 @@ +namespace System.Windows.Forms.Tests +{ + using System.Drawing; + + [TestFixture] + [SingleThreaded] + public class TreeViewTests + { + [Test] + public void ContextMenu_SetAndGet_ReturnsCorrectValue() + { + // Arrange + var treeView = new TreeView(); + var contextMenu = new ContextMenu(); + + // Act + treeView.ContextMenu = contextMenu; + + // Assert + Assert.That(treeView.ContextMenu, Is.EqualTo(contextMenu)); + } + + // Commenting out this test, as it doesn't work in DAT + //[Test] + //public void ContextMenu_ShowsOnRightClick() + //{ + // // Arrange + // var form = new Form(); + // var treeView = new TreeView(); + // var contextMenu = new ContextMenu(); + // contextMenu.MenuItems.Add(new MenuItem("Test Item")); + // treeView.ContextMenu = contextMenu; + // treeView.Bounds = new Rectangle(10, 10, 200, 200); + // form.Controls.Add(treeView); + + // bool contextMenuShown = false; + // contextMenu.Popup += (sender, e) => contextMenuShown = true; + + // // Ensure the Form and TreeView are created and visible + // form.Load += async (sender, e) => + // { + // // Wait for the tree view to be created + // await Task.Delay(500); + + // var clickPointRelativeToTreeView = treeView.Bounds.Location + new Size(treeView.Bounds.Width / 2, treeView.Bounds.Y + treeView.Bounds.Height / 2); + // var clickPointRelativeToScreen = treeView.PointToScreen(clickPointRelativeToTreeView); + + // // Simulate right-click event on the TreeNode + // Cursor.Position = clickPointRelativeToScreen; + // MouseOperations.MouseEvent(MouseOperations.MouseEventFlags.RightDown, (uint)clickPointRelativeToScreen.X, (uint)clickPointRelativeToScreen.Y); + // await Task.Delay(100); + // MouseOperations.MouseEvent(MouseOperations.MouseEventFlags.RightUp, (uint)clickPointRelativeToScreen.X, (uint)clickPointRelativeToScreen.Y); + + // // Wait 1 second for the context menu to show + // await Task.Delay(1000); + + // var clickPointOutsideContextMenuRelative = new Point(50, 50); + // var clickPointOutsideContextMenuAbsolute = treeView.PointToScreen(clickPointOutsideContextMenuRelative); + + // Cursor.Position = clickPointOutsideContextMenuAbsolute; + // MouseOperations.MouseEvent(MouseOperations.MouseEventFlags.LeftDown, (uint)clickPointOutsideContextMenuAbsolute.X, (uint)clickPointOutsideContextMenuAbsolute.Y); + // await Task.Delay(100); + // MouseOperations.MouseEvent(MouseOperations.MouseEventFlags.LeftUp, (uint)clickPointOutsideContextMenuAbsolute.X, (uint)clickPointOutsideContextMenuAbsolute.Y); + + // // Wait 1 second for the context menu to close + // await Task.Delay(1000); + + // // Assert + // Assert.IsTrue(contextMenuShown); + // form.Close(); + // return; + // }; + + // // Show the form + // form.ShowDialog(); + //} + + [Test] + public void ContextMenu_ContainsExpectedItems() + { + // Arrange + var treeView = new TreeView(); + var contextMenu = new ContextMenu(); + var menuItem = new MenuItem("Test Item"); + contextMenu.MenuItems.Add(menuItem); + treeView.ContextMenu = contextMenu; + + // Act + var items = treeView.ContextMenu.MenuItems; + + // Assert + Assert.That(items.Count, Is.EqualTo(1)); + Assert.That(items[0].Text, Is.EqualTo("Test Item")); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/Common/CommonMemberDataAttribute.cs b/WTG.System.Windows.Forms.Tests/Common/CommonMemberDataAttribute.cs new file mode 100644 index 00000000000..a4ba915c24f --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/Common/CommonMemberDataAttribute.cs @@ -0,0 +1,33 @@ +using System.Reflection; + +namespace WTG.System.Windows.Forms.Tests.Common +{ + /// + /// A custom MemberData attribute that is specialized for the CommonTestHelper type. + /// Useful to remove the need to suffix all attributes with "MemberType = ..." + /// We cannot inherit from MemberDataAttribute as it is sealed, so we have to reimplement + /// ConvertDataItem inheriting from MemberDataAttributeBase. + /// + public sealed class CommonMemberDataAttribute : MemberDataAttributeBase + { + public CommonMemberDataAttribute(string memberName, params object[] parameters) : base(memberName, parameters) + { + MemberType = typeof(CommonTestHelper); + } + + protected override object[] ConvertDataItem(MethodInfo testMethod, object item) + { + if (item is null) + { + return null; + } + + if (!(item is object[] array)) + { + throw new ArgumentException($"Property {MemberName} on {MemberType ?? testMethod.DeclaringType} yielded an item that is not an object[]"); + } + + return array; + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/CommonTestHelper.cs b/WTG.System.Windows.Forms.Tests/CommonTestHelper.cs new file mode 100644 index 00000000000..25b75c62de3 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/CommonTestHelper.cs @@ -0,0 +1,532 @@ +using System.ComponentModel.Design.Serialization; +using System.Drawing; +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.Tests +{ + public static class CommonTestHelper + { + // helper method to generate theory data from all values of an enum type + internal static TheoryData GetEnumTheoryData() where T : Enum + { + var data = new TheoryData(); + foreach (T item in Enum.GetValues(typeof(T))) + { + data.Add(item); + } + + return data; + } + + public static TheoryData GetEnumTypeTheoryData(Type enumType) + { + var data = new TheoryData(); + foreach (Enum item in Enum.GetValues(enumType)) + { + data.Add(item); + } + + return data; + } + + // helper method to generate invalid theory data for an enum type + // This method assumes that int.MinValue and int.MaxValue are not in the enum + internal static TheoryData GetEnumTheoryDataInvalid() where T : Enum + { + var data = new TheoryData + { + // This boxing is necessary because you can't cast an int to a generic, + // even if the generic is guaranteed to be an enum + (T)(object)int.MinValue, + (T)(object)int.MaxValue + }; + return data; + } + + public static TheoryData GetEnumTypeTheoryDataInvalid(Type enumType) + { + var data = new TheoryData(); + IEnumerable values = Enum.GetValues(enumType).Cast().OrderBy(p => p); + + // Assumes that the enum is sequential. + data.Add((Enum)Enum.ToObject(enumType, Convert.ToInt32(values.Min()) - 1)); + data.Add((Enum)Enum.ToObject(enumType, Convert.ToInt32(values.Max()) + 1)); + return data; + } + + #region Primitives + + // helper method to generate theory data for all values of a boolean + public static TheoryData GetBoolTheoryData() + { + var data = new TheoryData + { + true, + false + }; + return data; + } + + // helper method to generate theory data for some values of a int + public static TheoryData GetIntTheoryData() + { + var data = new TheoryData + { + int.MinValue, + int.MaxValue, + 0, + 1, + -1, + int.MaxValue / 2 + }; + return data; + } + + public static TheoryData GetNonNegativeIntTheoryData() + { + var data = new TheoryData + { + int.MaxValue, + 0, + 1, + int.MaxValue / 2 + }; + return data; + } + + // helper method to generate theory data for some values of a int + internal static TheoryData GetUIntTheoryData() + { + var data = new TheoryData + { + int.MaxValue, + 0, + 1, + int.MaxValue / 2 + }; + return data; + } + + // helper method to generate theory data for some values of a int + internal static TheoryData GetNIntTheoryData() + { + var data = new TheoryData + { + int.MinValue, + -1, + int.MinValue / 2 + }; + return data; + } + + // helper method to generate theory data for some values of a int + internal static TheoryData GetFloatTheoryData() + { + var data = new TheoryData + { + float.MaxValue, + float.MinValue, + float.Epsilon, + float.Epsilon * -1, + float.NegativeInfinity, // not sure about these two + float.PositiveInfinity, // 2 + 0, + -1, + 1, + float.MaxValue / 2 + }; + return data; + } + + // helper method to generate theory data for some values of a int + internal static TheoryData GetUFloatTheoryData() + { + var data = new TheoryData + { + float.MaxValue, + float.Epsilon, + float.PositiveInfinity, // not sure about this one + 0, + 1, + float.MaxValue / 2 + }; + return data; + } + + // helper method to generate theory data for a span of string values + private const string reasonable = nameof(reasonable); + + public static TheoryData GetStringTheoryData() + { + var data = new TheoryData + { + string.Empty, + reasonable + }; + return data; + } + + public static TheoryData GetStringWithNullTheoryData() + { + var data = new TheoryData + { + null, + string.Empty, + reasonable + }; + return data; + } + + public static TheoryData GetNullOrEmptyStringTheoryData() + { + var data = new TheoryData + { + null, + string.Empty + }; + return data; + } + + public static TheoryData GetStringNormalizedTheoryData() + { + var data = new TheoryData + { + { null, string.Empty }, + { string.Empty, string.Empty }, + { reasonable, reasonable } + }; + return data; + } + + public static TheoryData GetCtrlBackspaceData() + { + var data = new TheoryData + { + { "aaa", "", 0 }, + { "---", "", 0 }, + { " aaa", "", 0 }, + { " ---", "", 0 }, + { "aaa---", "", 0 }, + { "---aaa", "---", 0 }, + { "aaa---aaa", "aaa---", 0 }, + { "---aaa---", "---", 0 }, + { "a-a", "a-", 0 }, + { "-a-", "", 0 }, + { "--a-", "--", 0 }, + { "abc", "c", -1 }, + { "a,1-b", "a,b", -1 } + }; + return data; + } + + public static TheoryData GetCtrlBackspaceRepeatedData() + { + var data = new TheoryData + { + { "aaa", "", 2 }, + { "---", "", 2 }, + { "aaa---aaa", "", 2 }, + { "---aaa---", "", 2 }, + { "aaa bbb", "", 2 }, + { "aaa bbb ccc", "aaa ", 2 }, + { "aaa --- ccc", "", 2 }, + { "1 2 3 4 5 6 7 8 9 0", "1 ", 9 } + }; + return data; + } + + public static TheoryData GetCharTheoryData() + { + var data = new TheoryData + { + '\0', + 'a' + }; + return data; + } + + public static TheoryData GetIntPtrTheoryData() + { + var data = new TheoryData + { + (IntPtr)(-1), + IntPtr.Zero, + (IntPtr)1 + }; + return data; + } + + public static TheoryData GetGuidTheoryData() + { + var data = new TheoryData + { + Guid.Empty, + Guid.NewGuid() + }; + return data; + } + + public static TheoryData GetColorTheoryData() + { + var data = new TheoryData + { + Color.Red, + Color.Blue, + Color.Black + }; + return data; + } + + public static TheoryData GetColorWithEmptyTheoryData() + { + var data = new TheoryData + { + Color.Red, + Color.Empty + }; + return data; + } + + public static TheoryData GetBackColorTheoryData() + { + return new TheoryData + { + { Color.Red, Color.Red }, + { Color.Empty, Control.DefaultBackColor } + }; + } + + public static TheoryData GetForeColorTheoryData() + { + return new TheoryData + { + { Color.Red, Color.Red }, + { Color.FromArgb(254, 1, 2, 3), Color.FromArgb(254, 1, 2, 3) }, + { Color.Empty, Control.DefaultForeColor } + }; + } + + public static TheoryData GetImageTheoryData() + { + var data = new TheoryData + { + new Bitmap(10, 10), + null + }; + return data; + } + + public static TheoryData GetFontTheoryData() + { + var data = new TheoryData + { + SystemFonts.MenuFont, + null + }; + return data; + } + + public static TheoryData GetTypeWithNullTheoryData() + { + var data = new TheoryData + { + null, + typeof(int) + }; + return data; + } + + public static TheoryData GetRightToLeftTheoryData() + { + var data = new TheoryData + { + { RightToLeft.Inherit, RightToLeft.No }, + { RightToLeft.Yes, RightToLeft.Yes }, + { RightToLeft.No, RightToLeft.No } + }; + return data; + } + + public static TheoryData GetPointTheoryData() => GetPointTheoryData(TestIncludeType.All); + + public static TheoryData GetPointTheoryData(TestIncludeType includeType) + { + var data = new TheoryData(); + if (!includeType.HasFlag(TestIncludeType.NoPositives)) + { + data.Add(new Point()); + data.Add(new Point(10)); + data.Add(new Point(1, 2)); + } + + if (!includeType.HasFlag(TestIncludeType.NoNegatives)) + { + data.Add(new Point(int.MaxValue, int.MinValue)); + data.Add(new Point(-1, -2)); + } + + return data; + } + + public static TheoryData GetSizeTheoryData() => GetSizeTheoryData(TestIncludeType.All); + + public static TheoryData GetSizeTheoryData(TestIncludeType includeType) + { + var data = new TheoryData(); + if (!includeType.HasFlag(TestIncludeType.NoPositives)) + { + data.Add(new Size()); + data.Add(new Size(new Point(1, 1))); + data.Add(new Size(1, 2)); + } + + if (!includeType.HasFlag(TestIncludeType.NoNegatives)) + { + data.Add(new Size(-1, 1)); + data.Add(new Size(1, -1)); + } + + return data; + } + + public static TheoryData GetPositiveSizeTheoryData() + { + var data = new TheoryData + { + new(), + new(1, 2) + }; + return data; + } + + public static TheoryData GetRectangleTheoryData() + { + var data = new TheoryData + { + new(), + new(1, 2, 3, 4), + new(-1, -2, -3, -4) + }; + return data; + } + + public static TheoryData GetPaddingTheoryData() + { + var data = new TheoryData + { + new(), + new(1, 2, 3, 4), + new(1), + new(-1, -2, -3, -4) + }; + return data; + } + + public static TheoryData GetPaddingNormalizedTheoryData() + { + var data = new TheoryData + { + { new Padding(), new Padding() }, + { new Padding(1, 2, 3, 4), new Padding(1, 2, 3, 4) }, + { new Padding(1), new Padding(1) }, + { new Padding(-1, -2, -3, -4), Padding.Empty } + }; + return data; + } + + public static TheoryData GetConvertFromTheoryData() + { + var data = new TheoryData + { + { typeof(bool), false }, + { typeof(InstanceDescriptor), true }, + { typeof(int), false }, + { typeof(double), false }, + { null, false } + }; + return data; + } + + public static TheoryData GetCursorTheoryData() + { + var data = new TheoryData + { + null, + new((IntPtr)1) + }; + return data; + } + + public static TheoryData GetEventArgsTheoryData() + { + var data = new TheoryData + { + null, + new() + }; + return data; + } + + public static TheoryData GetPaintEventArgsTheoryData() + { + var image = new Bitmap(10, 10); + Graphics graphics = Graphics.FromImage(image); + return new TheoryData + { + null, + new(graphics, Rectangle.Empty) + }; + } + + public static TheoryData GetKeyEventArgsTheoryData() + { + var data = new TheoryData + { + null, + new(Keys.Cancel) + }; + return data; + } + + public static TheoryData GetKeyPressEventArgsTheoryData() + { + var data = new TheoryData + { + null, + new('1') + }; + return data; + } + + public static TheoryData GetLayoutEventArgsTheoryData() + { + var data = new TheoryData + { + null, + new(null, null), + new(new Control(), "affectedProperty") + }; + return data; + } + + public static TheoryData GetMouseEventArgsTheoryData() + { + return new TheoryData + { + null, + new(MouseButtons.Left, 1, 2, 3, 4), + new HandledMouseEventArgs(MouseButtons.Left, 1, 2, 3, 4) + }; + } + + #endregion + } + + [Flags] + public enum TestIncludeType + { + All, + NoPositives, + NoNegatives + } +} diff --git a/WTG.System.Windows.Forms.Tests/ContextMenuTests.cs b/WTG.System.Windows.Forms.Tests/ContextMenuTests.cs new file mode 100644 index 00000000000..a158fc5e873 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/ContextMenuTests.cs @@ -0,0 +1,299 @@ +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using WTG.System.Windows.Forms.Tests.Common; + +namespace WTG.System.Windows.Forms.Tests +{ + public class ContextMenuTests + { + [Fact] + public void ContextMenu_Ctor_Default() + { + var menu = new ContextMenu(); + Assert.Empty(menu.MenuItems); + Assert.False(menu.IsParent); + Assert.Equal(RightToLeft.No, menu.RightToLeft); + Assert.Null(menu.SourceControl); + Assert.Empty(menu.Name); + Assert.Null(menu.Site); + Assert.Null(menu.Container); + Assert.Null(menu.Tag); + } + + public static IEnumerable Ctor_MenuItemArray_TestData() + { + yield return new object[] { null, false }; + yield return new object[] { Array.Empty(), false }; + yield return new object[] { new MenuItem[] { new() }, true }; + } + + [Theory] + [MemberData(nameof(Ctor_MenuItemArray_TestData))] + public void ContextMenu_Ctor_MenuItemArray(MenuItem[] items, bool expectedIsParent) + { + var menu = new ContextMenu(items); + Assert.Equal(items ?? Array.Empty(), menu.MenuItems.Cast()); + for (int i = 0; i < (items?.Length ?? 0); i++) + { + Assert.Equal(i, menu.MenuItems[i].Index); + Assert.Equal(menu, menu.MenuItems[i].Parent); + } + + Assert.Equal(expectedIsParent, menu.IsParent); + Assert.Equal(RightToLeft.No, menu.RightToLeft); + Assert.Null(menu.SourceControl); + Assert.Empty(menu.Name); + Assert.Null(menu.Site); + Assert.Null(menu.Container); + Assert.Null(menu.Tag); + } + + [Fact] + public void ContextMenu_Ctor_NullItemInMenuItemArray_ThrowsArgumentNullException() + { + Assert.Throws("item", () => new ContextMenu(new MenuItem[] { null })); + } + + [Fact] + public void ContextMenu_SourceControl_GetProcessingKeyMessage_Succes() + { + var control = new Control + { + ContextMenu = new ContextMenu() + }; + + ContextMenu menu = control.ContextMenu; + Assert.Null(menu.SourceControl); + + var message = new Message + { + Msg = 0x0100 // WM_KEYDOWN + }; + control.PreProcessMessage(ref message); + Assert.Same(control, menu.SourceControl); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetRightToLeftTheoryData))] + public void ContextMenu_RightToLeft_SetWithoutSourceControl_GetReturnsExpected(RightToLeft value, RightToLeft expectedValue) + { + var menu = new ContextMenu + { + RightToLeft = value + }; + Assert.Equal(expectedValue, menu.RightToLeft); + } + + [Theory] + [InlineData(RightToLeft.Yes, RightToLeft.Yes)] + [InlineData(RightToLeft.No, RightToLeft.No)] + [InlineData(RightToLeft.Inherit, RightToLeft.Yes)] + public void ContextMenu_RightToLeft_SetWithSourceControl_GetReturnsExpected(RightToLeft value, RightToLeft expectedValue) + { + var control = new Control + { + ContextMenu = new ContextMenu(), + RightToLeft = RightToLeft.Yes + }; + + ContextMenu menu = control.ContextMenu; + var message = new Message + { + Msg = 0x0100 // WM_KEYDOWN + }; + control.PreProcessMessage(ref message); + + menu.RightToLeft = value; + Assert.Equal(expectedValue, menu.RightToLeft); + } + + [Fact] + public void ContextMenu_RightToLeft_SetCreated_GetReturnsExpected() + { + using (var menu = new ContextMenu(new MenuItem[] { new("text") })) + { + Assert.NotEqual(IntPtr.Zero, menu.Handle); + menu.RightToLeft = RightToLeft.Yes; + menu.RightToLeft = RightToLeft.No; + Assert.Equal(RightToLeft.No, menu.RightToLeft); + } + } + + [Theory] + [MemberData(nameof(CommonTestHelper.GetEnumTypeTheoryDataInvalid), typeof(RightToLeft), MemberType = typeof(CommonTestHelper))] + public void ContextMenu_RightToLeft_SetInvalid_ThrowsInvalidEnumArgumentException(RightToLeft value) + { + var menu = new ContextMenu(); + Assert.Throws("RightToLeft", () => menu.RightToLeft = value); + } + + public static IEnumerable ProcessCmdKey_TestData() + { + yield return new object[] { new MenuItem { Shortcut = Shortcut.CtrlA }, true, 1, 0 }; + yield return new object[] { new MenuItem { Shortcut = Shortcut.CtrlA, Enabled = false }, false, 0, 0 }; + yield return new object[] { new MenuItem("text", new MenuItem[] { new() }) { Shortcut = Shortcut.CtrlA }, true, 0, 1 }; + yield return new object[] { new MenuItem("text", new MenuItem[] { new() }) { Shortcut = Shortcut.CtrlA, Enabled = false }, false, 0, 0 }; + } + + [Theory] + [MemberData(nameof(ProcessCmdKey_TestData))] + public void ContextMenu_ProcessCmdKey_HasItemWithShoutcutKey_ReturnsExpected(MenuItem menuItem, bool expectedResult, int expectedOnClickCallCount, int expectedOnPopupCallCount) + { + var control = new Control(); + int onClickCallCount = 0; + menuItem.Click += (sender, e) => + { + onClickCallCount++; + Assert.Same(menuItem, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + int onPopupCallCount = 0; + menuItem.Popup += (sender, e) => + { + onPopupCallCount++; + Assert.Same(menuItem, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + var menu = new ContextMenu(new MenuItem[] { menuItem }); + var message = new Message(); + Assert.Equal(expectedResult, menu.ProcessCmdKey(ref message, Keys.Control | Keys.A, control)); + Assert.Same(control, menu.SourceControl); + Assert.Equal(expectedOnClickCallCount, onClickCallCount); + Assert.Equal(expectedOnPopupCallCount, onPopupCallCount); + } + + [Fact] + public void ContextMenu_Show_ControlPoint_Success() + { + var menu = new ContextMenu(); + var control = new Control + { + Visible = true + }; + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(menu, sender); + callCount++; + }; + menu.Popup += handler; + + Assert.NotEqual(IntPtr.Zero, control.Handle); + menu.Show(control, new Point(1, 2)); + Assert.Equal(1, callCount); + Assert.Same(control, menu.SourceControl); + } + + [Theory] + [MemberData(nameof(CommonTestHelper.GetEnumTypeTheoryData), typeof(LeftRightAlignment), MemberType = typeof(CommonTestHelper))] + [MemberData(nameof(CommonTestHelper.GetEnumTypeTheoryDataInvalid), typeof(LeftRightAlignment), MemberType = typeof(CommonTestHelper))] + public void ContextMenu_Show_ControlPointLeftRightAlignment_Success(LeftRightAlignment alignment) + { + var menu = new ContextMenu(); + var control = new Control + { + Visible = true + }; + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(menu, sender); + callCount++; + }; + menu.Popup += handler; + + Assert.NotEqual(IntPtr.Zero, control.Handle); + menu.Show(control, new Point(1, 2), alignment); + Assert.Equal(1, callCount); + Assert.Same(control, menu.SourceControl); + } + + [Fact] + public void ContextMenu_Show_NullControl_ThrowsArgumentNullException() + { + var menu = new ContextMenu(); + Assert.Throws("control", () => menu.Show(null, new Point(1, 2))); + Assert.Throws("control", () => menu.Show(null, new Point(1, 2), LeftRightAlignment.Left)); + } + + [Fact] + public void ContextMenu_Show_NotVisibleControl_ThrowsArgumentException() + { + var menu = new ContextMenu(); + var control = new Control + { + Visible = false + }; + Assert.NotEqual(IntPtr.Zero, control.Handle); + Assert.Throws("control", () => menu.Show(control, new Point(1, 2))); + Assert.Throws("control", () => menu.Show(control, new Point(1, 2), LeftRightAlignment.Left)); + } + + [Fact] + public void ContextMenu_Show_ControlHasNoHandle_ThrowsArgumentException() + { + var menu = new ContextMenu(); + var control = new Control + { + Visible = true + }; + Assert.Throws("control", () => menu.Show(control, new Point(1, 2))); + Assert.Throws("control", () => menu.Show(control, new Point(1, 2), LeftRightAlignment.Left)); + } + + [Fact] + public void ContextMenu_OnCollapse_Invoke_Success() + { + var menu = new ContextMenu(); + + // No handler. + menu.OnCollapse(null); + + // Handler. + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(menu, sender); + callCount++; + }; + + menu.Collapse += handler; + menu.OnCollapse(null); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menu.Collapse -= handler; + menu.OnCollapse(null); + Assert.Equal(1, callCount); + } + + [Fact] + public void ContextMenu_OnPopup_Invoke_Success() + { + var menu = new ContextMenu(); + + // No handler. + menu.OnPopup(null); + + // Handler. + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(menu, sender); + callCount++; + }; + + menu.Popup += handler; + menu.OnPopup(null); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menu.Popup -= handler; + menu.OnPopup(null); + Assert.Equal(1, callCount); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/DataGridCellTests.cs b/WTG.System.Windows.Forms.Tests/DataGridCellTests.cs new file mode 100644 index 00000000000..91930ed6562 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/DataGridCellTests.cs @@ -0,0 +1,89 @@ + +using System.Windows.Forms; +using WTG.System.Windows.Forms.Tests.Common; + +namespace WTG.System.Windows.Forms.Tests +{ + public class DataGridCellTests + { + [Fact] + public void DataGridCell_Ctor_Default() + { + var cell = new DataGridCell(); + Assert.Equal(0, cell.RowNumber); + Assert.Equal(0, cell.ColumnNumber); + } + + [Theory] + [InlineData(-1, -2)] + [InlineData(0, 0)] + [InlineData(1, 2)] + [InlineData(1, 0)] + [InlineData(0, 1)] + public void DataGridCell_Ctor_Int_Int(int rowNumber, int columnNumber) + { + var cell = new DataGridCell(rowNumber, columnNumber); + Assert.Equal(rowNumber, cell.RowNumber); + Assert.Equal(columnNumber, cell.ColumnNumber); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetIntTheoryData))] + public void DataGridCell_RowNumber_Set_GetReturnsExpected(int value) + { + var cell = new DataGridCell + { + RowNumber = value + }; + Assert.Equal(value, cell.RowNumber); + + // Set same. + cell.RowNumber = value; + Assert.Equal(value, cell.RowNumber); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetIntTheoryData))] + public void DataGridCell_ColumnNumber_Set_GetReturnsExpected(int value) + { + var cell = new DataGridCell + { + ColumnNumber = value + }; + Assert.Equal(value, cell.ColumnNumber); + + // Set same. + cell.ColumnNumber = value; + Assert.Equal(value, cell.ColumnNumber); + } + + public static IEnumerable Equals_TestData() + { + yield return new object[] { new DataGridCell(1, 2), new DataGridCell(1, 2), true }; + yield return new object[] { new DataGridCell(1, 2), new DataGridCell(2, 2), false }; + yield return new object[] { new DataGridCell(1, 2), new DataGridCell(1, 3), false }; + + yield return new object[] { new DataGridCell(1, 2), new(), false }; + yield return new object[] { new DataGridCell(1, 2), "null", false }; + } + + [Theory] + [MemberData(nameof(Equals_TestData))] + public void DataGridCell_Equals_Invoke_ReturnsExpected(DataGridCell cell, object other, bool expected) + { + if (other is DataGridCell otherCell) + { + Assert.Equal(expected, cell.GetHashCode().Equals(otherCell.GetHashCode())); + } + + Assert.Equal(expected, cell.Equals(other)); + } + + [Fact] + public void DataGridCell_ToString_Invoke_ReturnsExpected() + { + var cell = new DataGridCell(1, 2); + Assert.Equal("DataGridCell {RowNumber = 1, ColumnNumber = 2}", cell.ToString()); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/DataGridColumnHeaderAccessibleObjectTests.cs b/WTG.System.Windows.Forms.Tests/DataGridColumnHeaderAccessibleObjectTests.cs new file mode 100644 index 00000000000..390f9183e60 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/DataGridColumnHeaderAccessibleObjectTests.cs @@ -0,0 +1,55 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.Tests +{ + public class DataGridColumnHeaderAccessibleObjectTests : DataGridColumnStyle + { + [Fact] + public void Ctor_Default() + { + var accessibleObject = new DataGridColumnHeaderAccessibleObject(); + Assert.Equal(AccessibleRole.ColumnHeader, accessibleObject.Role); + } + + protected internal override void Abort(int rowNum) + { + throw new NotImplementedException(); + } + + protected internal override bool Commit(CurrencyManager dataSource, int rowNum) + { + throw new NotImplementedException(); + } + + protected internal override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText, bool cellIsVisible) + { + throw new NotImplementedException(); + } + + protected internal override Size GetPreferredSize(Graphics g, object value) + { + throw new NotImplementedException(); + } + + protected internal override int GetMinimumHeight() + { + throw new NotImplementedException(); + } + + protected internal override int GetPreferredHeight(Graphics g, object value) + { + throw new NotImplementedException(); + } + + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum) + { + throw new NotImplementedException(); + } + + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) + { + throw new NotImplementedException(); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/DataGridColumnStyleTests.cs b/WTG.System.Windows.Forms.Tests/DataGridColumnStyleTests.cs new file mode 100644 index 00000000000..834b164c306 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/DataGridColumnStyleTests.cs @@ -0,0 +1,1390 @@ +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using WTG.System.Windows.Forms.Tests.Common; + +namespace WTG.System.Windows.Forms.Tests +{ + public class DataGridColumnStyleTests + { + [Fact] + public void DataGridColumnStyle_Ctor_Default() + { + var style = new SubDataGridColumnStyle(); + Assert.Equal(HorizontalAlignment.Left, style.Alignment); + Assert.True(style.CanRaiseEvents); + Assert.Null(style.Container); + Assert.Null(style.DataGridTableStyle); + Assert.False(style.DesignMode); + Assert.NotNull(style.Events); + Assert.Same(style.Events, style.Events); + Assert.Equal(Control.DefaultFont.Height, style.FontHeight); + Assert.NotNull(style.HeaderAccessibleObject); + Assert.Same(style.HeaderAccessibleObject, style.HeaderAccessibleObject); + Assert.Empty(style.HeaderText); + Assert.Empty(style.MappingName); + Assert.Null(style.PropertyDescriptor); + Assert.False(style.ReadOnly); + Assert.Null(style.Site); + Assert.Equal(-1, style.Width); + } + + public static IEnumerable Ctor_PropertyDescriptor_TestData() + { + yield return new object[] { null, false }; + yield return new object[] { TypeDescriptor.GetProperties(typeof(DataClass))[0], false }; + yield return new object[] { TypeDescriptor.GetProperties(typeof(ReadOnlyDataClass))[0], true }; + } + + [Theory] + [MemberData(nameof(Ctor_PropertyDescriptor_TestData))] + public void Ctor_PropertyDescriptor(PropertyDescriptor descriptor, bool expectedReadOnly) + { + var style = new SubDataGridColumnStyle(descriptor); + Assert.Equal(HorizontalAlignment.Left, style.Alignment); + Assert.True(style.CanRaiseEvents); + Assert.Null(style.Container); + Assert.Null(style.DataGridTableStyle); + Assert.False(style.DesignMode); + Assert.NotNull(style.Events); + Assert.Same(style.Events, style.Events); + Assert.Equal(Control.DefaultFont.Height, style.FontHeight); + Assert.NotNull(style.HeaderAccessibleObject); + Assert.Same(style.HeaderAccessibleObject, style.HeaderAccessibleObject); + Assert.Empty(style.HeaderText); + Assert.Empty(style.MappingName); + Assert.Same(descriptor, style.PropertyDescriptor); + Assert.Equal(expectedReadOnly, style.ReadOnly); + Assert.Null(style.Site); + Assert.Equal(-1, style.Width); + } + + public static IEnumerable Ctor_PropertyDescriptor_Bool_TestData() + { + yield return new object[] { null, true, string.Empty, false }; + yield return new object[] { null, false, string.Empty, false }; + + yield return new object[] { TypeDescriptor.GetProperties(typeof(DataClass))[0], true, "Value1", false }; + yield return new object[] { TypeDescriptor.GetProperties(typeof(DataClass))[0], false, string.Empty, false }; + + yield return new object[] { TypeDescriptor.GetProperties(typeof(ReadOnlyDataClass))[0], true, "Value1", true }; + yield return new object[] { TypeDescriptor.GetProperties(typeof(ReadOnlyDataClass))[0], false, string.Empty, true }; + } + + [Theory] + [MemberData(nameof(Ctor_PropertyDescriptor_Bool_TestData))] + public void Ctor_PropertyDescriptor_Bool(PropertyDescriptor descriptor, bool isDefault, string expectedMappingName, bool expectedReadOnly) + { + var style = new SubDataGridColumnStyle(descriptor, isDefault); + Assert.Equal(HorizontalAlignment.Left, style.Alignment); + Assert.True(style.CanRaiseEvents); + Assert.Null(style.Container); + Assert.Null(style.DataGridTableStyle); + Assert.False(style.DesignMode); + Assert.NotNull(style.Events); + Assert.Same(style.Events, style.Events); + Assert.Equal(Control.DefaultFont.Height, style.FontHeight); + Assert.NotNull(style.HeaderAccessibleObject); + Assert.Same(style.HeaderAccessibleObject, style.HeaderAccessibleObject); + Assert.Equal(expectedMappingName, style.HeaderText); + Assert.Equal(expectedMappingName, style.MappingName); + Assert.Same(descriptor, style.PropertyDescriptor); + Assert.Equal(expectedReadOnly, style.ReadOnly); + Assert.Null(style.Site); + Assert.Equal(-1, style.Width); + } + + [Fact] + public void DataGridColumnStyle_DefaultProperty_Get_ReturnsExpected() + { + PropertyDescriptor property = TypeDescriptor.GetDefaultProperty(typeof(DataGridColumnStyle)); + Assert.Equal("HeaderText", property.Name); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEnumTypeTheoryData), typeof(HorizontalAlignment))] + public void Alignment_Set_GetReturnsExpected(HorizontalAlignment value) + { + var style = new SubDataGridColumnStyle + { + Alignment = value + }; + Assert.Equal(value, style.Alignment); + + // Set same. + style.Alignment = value; + Assert.Equal(value, style.Alignment); + } + + [Fact] + public void DataGridColumnStyle_Alignment_SetWithHandler_CallsAlignmentChanged() + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.AlignmentChanged += handler; + + // Set different. + style.Alignment = HorizontalAlignment.Center; + Assert.Equal(HorizontalAlignment.Center, style.Alignment); + Assert.Equal(1, callCount); + + // Set same. + style.Alignment = HorizontalAlignment.Center; + Assert.Equal(HorizontalAlignment.Center, style.Alignment); + Assert.Equal(1, callCount); + + // Set different. + style.Alignment = HorizontalAlignment.Left; + Assert.Equal(HorizontalAlignment.Left, style.Alignment); + Assert.Equal(2, callCount); + + // Remove handler. + style.AlignmentChanged -= handler; + style.Alignment = HorizontalAlignment.Center; + Assert.Equal(HorizontalAlignment.Center, style.Alignment); + Assert.Equal(2, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEnumTypeTheoryDataInvalid), typeof(HorizontalAlignment))] + public void Alignment_SetInvalid_ThrowsInvalidEnumArgumentException(HorizontalAlignment value) + { + var style = new SubDataGridColumnStyle(); + Assert.Throws("value", () => style.Alignment = value); + } + + [Fact] + public void DataGridColumnStyle_FontHeight_GetWithParentWithDataGrid_ReturnsExpected() + { + Font font = new Font(Control.DefaultFont.FontFamily, 15); + var dataGrid = new DataGrid + { + Font = font + }; + var tableStyle = new DataGridTableStyle(); + dataGrid.TableStyles.Add(tableStyle); + var style = new SubDataGridColumnStyle(); + tableStyle.GridColumnStyles.Add(style); + Assert.Equal(font.Height, style.FontHeight); + } + + [Fact] + public void DataGridColumnStyle_FontHeight_GetWithParentWithoutDataGrid_ReturnsExpected() + { + var tableStyle = new DataGridTableStyle(); + var style = new SubDataGridColumnStyle(); + tableStyle.GridColumnStyles.Add(style); + Assert.Equal(Control.DefaultFont.Height, style.FontHeight); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void HeaderText_Set_GetReturnsExpected(string value, string expected) + { + var style = new SubDataGridColumnStyle + { + HeaderText = value + }; + Assert.Equal(expected, style.HeaderText); + + // Set same. + style.HeaderText = value; + Assert.Equal(expected, style.HeaderText); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void HeaderText_SetWithPropertyDescriptor_GetReturnsExpected(string value, string expected) + { + PropertyDescriptor property = TypeDescriptor.GetProperties(typeof(DataClass))[0]; + var style = new SubDataGridColumnStyle(property) + { + HeaderText = value + }; + Assert.Equal(expected, style.HeaderText); + + // Set same. + style.HeaderText = value; + Assert.Equal(expected, style.HeaderText); + } + + [Fact] + public void DataGridColumnStyle_HeaderText_SetWithHandler_CallsHeaderTextChanged() + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.HeaderTextChanged += handler; + + // Set different. + style.HeaderText = "HeaderText"; + Assert.Equal("HeaderText", style.HeaderText); + Assert.Equal(1, callCount); + + // Set same. + style.HeaderText = "HeaderText"; + Assert.Equal("HeaderText", style.HeaderText); + Assert.Equal(1, callCount); + + // Set different. + style.HeaderText = "OtherHeaderText"; + Assert.Equal("OtherHeaderText", style.HeaderText); + Assert.Equal(2, callCount); + + // Set null. + style.HeaderText = null; + Assert.Empty(style.HeaderText); + Assert.Equal(3, callCount); + + // Set null again. + style.HeaderText = null; + Assert.Empty(style.HeaderText); + Assert.Equal(3, callCount); + + // Set empty. + style.HeaderText = string.Empty; + Assert.Empty(style.HeaderText); + Assert.Equal(3, callCount); + + // Remove handler. + style.HeaderTextChanged -= handler; + style.HeaderText = "HeaderText"; + Assert.Equal("HeaderText", style.HeaderText); + Assert.Equal(3, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void MappingName_Set_GetReturnsExpected(string value, string expected) + { + var style = new SubDataGridColumnStyle + { + MappingName = value + }; + Assert.Equal(expected, style.MappingName); + + style.MappingName = value; + Assert.Equal(expected, style.MappingName); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void MappingName_SetWithDataGridView_GetReturnsExpected(string value, string expected) + { + var dataGrid = new DataGrid(); + var tableStyle = new DataGridTableStyle(); + dataGrid.TableStyles.Add(tableStyle); + var style = new SubDataGridColumnStyle(); + tableStyle.GridColumnStyles.Add(style); + + style.MappingName = value; + Assert.Equal(expected, style.MappingName); + + style.MappingName = value; + Assert.Equal(expected, style.MappingName); + } + + [Fact] + public void DataGridColumnStyle_MappingName_SetWithHandler_CallsMappingNameChanged() + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.MappingNameChanged += handler; + + // Set different. + style.MappingName = "MappingName"; + Assert.Equal("MappingName", style.MappingName); + Assert.Equal(1, callCount); + + // Set same. + style.MappingName = "MappingName"; + Assert.Equal("MappingName", style.MappingName); + Assert.Equal(1, callCount); + + // Set different. + style.MappingName = "OtherMappingName"; + Assert.Equal("OtherMappingName", style.MappingName); + Assert.Equal(2, callCount); + + // Set null. + style.MappingName = null; + Assert.Empty(style.MappingName); + Assert.Equal(3, callCount); + + // Set null again. + style.MappingName = null; + Assert.Empty(style.MappingName); + Assert.Equal(3, callCount); + + // Set empty. + style.MappingName = string.Empty; + Assert.Empty(style.MappingName); + Assert.Equal(3, callCount); + + // Remove handler. + style.MappingNameChanged -= handler; + style.MappingName = "MappingName"; + Assert.Equal("MappingName", style.MappingName); + Assert.Equal(3, callCount); + } + + [Fact] + public void DataGridColumnStyle_MappingName_SetInvalid_ThrowsArgumentException() + { + var dataGrid = new DataGrid(); + var tableStyle = new DataGridTableStyle(); + dataGrid.TableStyles.Add(tableStyle); + + var style1 = new SubDataGridColumnStyle + { + MappingName = "MappingName1" + }; + var style2 = new SubDataGridColumnStyle + { + MappingName = "MappingName2" + }; + tableStyle.GridColumnStyles.Add(style1); + tableStyle.GridColumnStyles.Add(style2); + + Assert.Throws("column", () => style2.MappingName = "MappingName1"); + Assert.Equal("MappingName2", style2.MappingName); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringWithNullTheoryData))] + public void NullText_Set_GetReturnsExpected(string value) + { + var style = new SubDataGridColumnStyle + { + NullText = value + }; + Assert.Equal(value, style.NullText); + + // Set same. + style.NullText = value; + Assert.Equal(value, style.NullText); + } + + [Fact] + public void DataGridColumnStyle_NullText_SetWithHandler_CallsMappingNameChanged() + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.NullTextChanged += handler; + + // Set different. + style.NullText = "NullText"; + Assert.Equal("NullText", style.NullText); + Assert.Equal(1, callCount); + + // Set same. + style.NullText = "NullText"; + Assert.Equal("NullText", style.NullText); + Assert.Equal(1, callCount); + + // Set different. + style.NullText = "OtherMappingName"; + Assert.Equal("OtherMappingName", style.NullText); + Assert.Equal(2, callCount); + + // Set null. + style.NullText = null; + Assert.Null(style.NullText); + Assert.Equal(3, callCount); + + // Set null again. + style.NullText = null; + Assert.Null(style.NullText); + Assert.Equal(3, callCount); + + // Remove handler. + style.NullTextChanged -= handler; + style.NullText = "NullText"; + Assert.Equal("NullText", style.NullText); + Assert.Equal(3, callCount); + } + + public static IEnumerable PropertyDescriptor_Set_TestData() + { + yield return new object[] { null }; + yield return new object[] { TypeDescriptor.GetProperties(typeof(DataClass))[0] }; + } + + [Theory] + [MemberData(nameof(PropertyDescriptor_Set_TestData))] + public void PropertyDescriptor_Set_GetReturnsExpected(PropertyDescriptor value) + { + var style = new SubDataGridColumnStyle + { + PropertyDescriptor = value + }; + Assert.Same(value, style.PropertyDescriptor); + + // Set same. + style.PropertyDescriptor = value; + Assert.Same(value, style.PropertyDescriptor); + } + + [Fact] + public void DataGridColumnStyle_PropertyDescriptor_SetWithHandler_CallsPropertyDescriptorChanged() + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.PropertyDescriptorChanged += handler; + + // Set different. + PropertyDescriptor descriptor1 = TypeDescriptor.GetProperties(typeof(DataClass))[0]; + style.PropertyDescriptor = descriptor1; + Assert.Equal(descriptor1, style.PropertyDescriptor); + Assert.Equal(1, callCount); + + // Set same. + style.PropertyDescriptor = descriptor1; + Assert.Equal(descriptor1, style.PropertyDescriptor); + Assert.Equal(1, callCount); + + // Set different. + PropertyDescriptor descriptor2 = TypeDescriptor.GetProperties(typeof(DataClass))[1]; + style.PropertyDescriptor = descriptor2; + Assert.Equal(descriptor2, style.PropertyDescriptor); + Assert.Equal(2, callCount); + + // Set null. + style.PropertyDescriptor = null; + Assert.Null(style.PropertyDescriptor); + Assert.Equal(3, callCount); + + // Set null again. + style.PropertyDescriptor = null; + Assert.Null(style.PropertyDescriptor); + Assert.Equal(3, callCount); + + // Remove handler. + style.PropertyDescriptorChanged -= handler; + style.PropertyDescriptor = descriptor1; + Assert.Equal(descriptor1, style.PropertyDescriptor); + Assert.Equal(3, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void ReadOnly_Set_GetReturnsExpected(bool value) + { + var style = new SubDataGridColumnStyle + { + ReadOnly = value + }; + Assert.Equal(value, style.ReadOnly); + + // Set same. + style.ReadOnly = value; + Assert.Equal(value, style.ReadOnly); + + // Set different + style.ReadOnly = !value; + Assert.Equal(!value, style.ReadOnly); + } + + [Fact] + public void DataGridColumnStyle_ReadOnly_SetWithHandler_CallsMappingNameChanged() + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.ReadOnlyChanged += handler; + + // Set different. + style.ReadOnly = true; + Assert.True(style.ReadOnly); + Assert.Equal(1, callCount); + + // Set same. + style.ReadOnly = true; + Assert.True(style.ReadOnly); + Assert.Equal(1, callCount); + + // Set different. + style.ReadOnly = false; + Assert.False(style.ReadOnly); + Assert.Equal(2, callCount); + + // Remove handler. + style.ReadOnlyChanged -= handler; + style.ReadOnly = true; + Assert.True(style.ReadOnly); + Assert.Equal(2, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetIntTheoryData))] + public void Width_Set_GetReturnsExpected(int value) + { + var style = new SubDataGridColumnStyle + { + Width = value + }; + Assert.Equal(value, style.Width); + + // Set same. + style.Width = value; + Assert.Equal(value, style.Width); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetIntTheoryData))] + public void Width_SetWithTableStyleWithDataGrid_GetReturnsExpected(int value) + { + var dataGrid = new DataGrid(); + int callCount = 0; + dataGrid.Layout += (sender, e) => callCount++; + var tableStyle = new DataGridTableStyle(); + dataGrid.TableStyles.Add(tableStyle); + var style = new SubDataGridColumnStyle(); + tableStyle.GridColumnStyles.Add(style); + + style.Width = value; + Assert.Equal(value, style.Width); + Assert.Equal(1, callCount); + + // Set same. + style.Width = value; + Assert.Equal(value, style.Width); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetIntTheoryData))] + public void Width_SetWithTableStyleWithoutDataGrid_GetReturnsExpected(int value) + { + var tableStyle = new DataGridTableStyle(); + var style = new SubDataGridColumnStyle(); + tableStyle.GridColumnStyles.Add(style); + + style.Width = value; + Assert.Equal(value, style.Width); + + // Set same. + style.Width = value; + Assert.Equal(value, style.Width); + } + + [Fact] + public void DataGridColumnStyle_Width_SetWithHandler_CallsWidthChanged() + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.WidthChanged += handler; + + // Set different. + style.Width = 2; + Assert.Equal(2, style.Width); + Assert.Equal(1, callCount); + + // Set same. + style.Width = 2; + Assert.Equal(2, style.Width); + Assert.Equal(1, callCount); + + // Set different. + style.Width = 3; + Assert.Equal(3, style.Width); + Assert.Equal(2, callCount); + + // Remove handler. + style.WidthChanged -= handler; + style.Width = 2; + Assert.Equal(2, style.Width); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridColumnStyle_FontChanged_Add_Remove_Success() + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => callCount++; + + style.FontChanged += handler; + style.FontChanged -= handler; + Assert.Equal(0, callCount); + } + + [Fact] + public void DataGridColumnStyle_BeginUpdate_EndUpdate_DoesNotCallInvalidate() + { + var style = new InvalidateDataGridColumnStyle(); + style.BeginUpdate(); + style.EndUpdate(); + Assert.Equal(0, style.InvalidateCallCount); + } + + [Fact] + public void DataGridColumnStyle_BeginUpdate_SeveralTimes_DoesNotCallInvalidate() + { + var style = new InvalidateDataGridColumnStyle(); + style.BeginUpdate(); + style.BeginUpdate(); + Assert.Equal(0, style.InvalidateCallCount); + } + + [Fact] + public void DataGridColumnStyle_CheckValidDataSource_HasPropertyDescriptor_Nop() + { + PropertyDescriptor property = TypeDescriptor.GetProperties(typeof(DataClass))[0]; + var style = new SubDataGridColumnStyle(property); + var context = new BindingContext(); + var dataSource = new List { 1, 2, 3 }; + CurrencyManager value = Assert.IsType(context[dataSource]); + style.CheckValidDataSource(value); + } + + [Fact] + public void DataGridColumnStyle_CheckValidDataSource_NullValue_ThrowsArgumentNullException() + { + var style = new SubDataGridColumnStyle(); + Assert.Throws("value", () => style.CheckValidDataSource(null)); + } + + [Fact] + public void DataGridColumnStyle_CheckValidDataSource_NoPropertyDescriptor_ThrowsInvalidOperationException() + { + var style = new SubDataGridColumnStyle(); + var context = new BindingContext(); + var dataSource = new List { 1, 2, 3 }; + CurrencyManager value = Assert.IsType(context[dataSource]); + Assert.Throws(() => style.CheckValidDataSource(value)); + } + + public static IEnumerable ColumnStartedEditing_TestData() + { + yield return new object[] { null }; + yield return new object[] { new Control() }; + } + + [Theory] + [MemberData(nameof(ColumnStartedEditing_TestData))] + public void ColumnStartedEditing_WithTableStyleWithDataGridWithoutRows_Nop(Control editingControl) + { + var dataGrid = new DataGrid(); + var tableStyle = new DataGridTableStyle(); + dataGrid.TableStyles.Add(tableStyle); + var style = new SubDataGridColumnStyle(); + tableStyle.GridColumnStyles.Add(style); + style.ColumnStartedEditing(editingControl); + } + + [Theory] + [MemberData(nameof(ColumnStartedEditing_TestData))] + public void ColumnStartedEditing_WithTableStyle_Nop(Control editingControl) + { + var tableStyle = new DataGridTableStyle(); + var style = new SubDataGridColumnStyle(); + tableStyle.GridColumnStyles.Add(style); + style.ColumnStartedEditing(editingControl); + } + + [Theory] + [MemberData(nameof(ColumnStartedEditing_TestData))] + public void ColumnStartedEditing_NoTableStyle_Nop(Control editingControl) + { + var style = new SubDataGridColumnStyle(); + style.ColumnStartedEditing(editingControl); + } + + [Fact] + public void DataGridColumnStyle_ConcedeFocus_InvokeSeveralTimes_Nop() + { + var style = new SubDataGridColumnStyle(); + style.ConcedeFocus(); + style.ConcedeFocus(); + } + + [Fact] + public void DataGridColumnStyle_CreateHeaderAccessibleObject_Invoke_ReturnsExpected() + { + var style = new SubDataGridColumnStyle(); + AccessibleObject accessibleObject = style.CreateHeaderAccessibleObject(); + Assert.NotNull(accessibleObject); + Assert.NotSame(accessibleObject, style.CreateHeaderAccessibleObject()); + } + + public static IEnumerable Edit_CurrencyManagerIntRectangleBool_TestData() + { + yield return new object[] { null, -2, Rectangle.Empty, false }; + + var context = new BindingContext(); + var dataSource = new List { 1, 2, 3 }; + yield return new object[] { context[dataSource], -1, new Rectangle(1, 2, 3, 4), true }; + yield return new object[] { context[dataSource], 1, new Rectangle(-1, -2, -3, -4), true }; + } + + [Theory] + [MemberData(nameof(Edit_CurrencyManagerIntRectangleBool_TestData))] + public void Edit_InvokeCurrencyManagerIntRectangleBool_Success(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly) + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + style.EditAction = (actualSource, actualRowNum, actualBounds, actualReadOnly, actualDisplayText, actualCellIsVisible) => + { + Assert.Same(source, actualSource); + Assert.Equal(rowNum, actualRowNum); + Assert.Equal(bounds, actualBounds); + Assert.Equal(readOnly, actualReadOnly); + Assert.Null(actualDisplayText); + Assert.True(actualCellIsVisible); + callCount++; + }; + style.Edit(source, rowNum, bounds, readOnly); + Assert.Equal(1, callCount); + } + + public static IEnumerable Edit_CurrencyManagerIntRectangleBoolString_TestData() + { + yield return new object[] { null, -2, Rectangle.Empty, false, null }; + + var context = new BindingContext(); + var dataSource = new List { 1, 2, 3 }; + yield return new object[] { context[dataSource], -1, new Rectangle(1, 2, 3, 4), true, string.Empty }; + yield return new object[] { context[dataSource], 1, new Rectangle(-1, -2, -3, -4), true, "displayText" }; + } + + [Theory] + [MemberData(nameof(Edit_CurrencyManagerIntRectangleBoolString_TestData))] + public void Edit_InvokeCurrencyManagerIntRectangleBoolString_Success(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText) + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + style.EditAction = (actualSource, actualRowNum, actualBounds, actualReadOnly, actualDisplayText, actualCellIsVisible) => + { + Assert.Same(source, actualSource); + Assert.Equal(rowNum, actualRowNum); + Assert.Equal(bounds, actualBounds); + Assert.Equal(readOnly, actualReadOnly); + Assert.Same(displayText, actualDisplayText); + Assert.True(actualCellIsVisible); + callCount++; + }; + style.Edit(source, rowNum, bounds, readOnly, displayText); + Assert.Equal(1, callCount); + } + + [Fact] + public void DataGridColumnStyle_EndUpdate_BeganUpdateInvalidated_DoesNotCallInvalidate() + { + var style = new InvalidateDataGridColumnStyle(); + style.BeginUpdate(); + Assert.Equal(0, style.InvalidateCallCount); + + style.CallInvalidate(); + Assert.Equal(1, style.InvalidateCallCount); + + style.EndUpdate(); + Assert.Equal(2, style.InvalidateCallCount); + } + + [Fact] + public void DataGridColumnStyle_EndUpdate_NotCalledBeganUpdate_DoesNotCallInvalidate() + { + var style = new InvalidateDataGridColumnStyle(); + style.EndUpdate(); + Assert.Equal(0, style.InvalidateCallCount); + } + + [Fact] + public void DataGridColumnStyle_EndUpdate_SeveralTimes_DoesNotCallInvalidate() + { + var style = new InvalidateDataGridColumnStyle(); + style.BeginUpdate(); + style.EndUpdate(); + style.EndUpdate(); + Assert.Equal(0, style.InvalidateCallCount); + } + + [Fact] + public void DataGridColumnStyle_EnterNullValue_InvokeSeveralTimes_Nop() + { + var style = new SubDataGridColumnStyle(); + style.EnterNullValue(); + style.EnterNullValue(); + } + + [Theory] + [InlineData(0, 1)] + [InlineData(1, 2)] + [InlineData(2, 3)] + public void GetColumnValueAtRow_PropertyDescriptor_ReturnsExpected(int rowNum, int expected) + { + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(DataClass)).Find(nameof(DataClass.Value1), ignoreCase: false); + var style = new SubDataGridColumnStyle(descriptor); + var context = new BindingContext(); + var dataSource = new List { new() { Value1 = 1 }, new() { Value1 = 2 }, new() { Value1 = 3 } }; + CurrencyManager source = Assert.IsType(context[dataSource]); + Assert.Equal(expected, style.GetColumnValueAtRow(source, rowNum)); + } + + [Theory] + [InlineData(0, 1)] + [InlineData(1, 2)] + [InlineData(2, 3)] + public void GetColumnValueAtRow_PropertyDescriptorCalledTwice_ReturnsExpected(int rowNum, int expected) + { + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(DataClass)).Find(nameof(DataClass.Value1), ignoreCase: false); + var style = new NullPropertyDescriptorDataGridColumnStyle(descriptor, 2); + var context = new BindingContext(); + var dataSource = new List { new() { Value1 = 1 }, new() { Value1 = 2 }, new() { Value1 = 3 } }; + CurrencyManager source = Assert.IsType(context[dataSource]); + Assert.Equal(expected, style.GetColumnValueAtRow(source, rowNum)); + } + + [Fact] + public void DataGridColumnStyle_GetColumnValueAtRow_NullSource_ThrowsArgumentNullException() + { + var style = new SubDataGridColumnStyle(); + Assert.Throws("value", () => style.GetColumnValueAtRow(null, 0)); + } + + [Fact] + public void DataGridColumnStyle_GetColumnValueAtRow_NoPropertyDescriptor_ThrowsInvalidOperationException() + { + var style = new SubDataGridColumnStyle(); + var context = new BindingContext(); + var dataSource = new List { 1, 2, 3 }; + CurrencyManager source = Assert.IsType(context[dataSource]); + Assert.Throws(() => style.GetColumnValueAtRow(source, 0)); + } + + [Fact] + public void DataGridColumnStyle_GetColumnValueAtRow_NoPropertyDescriptorNoValidation_ThrowsInvalidOperationException() + { + var style = new NullPropertyDescriptorDataGridColumnStyle(1); + var context = new BindingContext(); + var dataSource = new List { 1, 2, 3 }; + CurrencyManager source = Assert.IsType(context[dataSource]); + Assert.Throws(() => style.GetColumnValueAtRow(source, 0)); + } + + [Theory] + [InlineData(-1)] + [InlineData(3)] + public void GetColumnValueAtRow_InvalidIndex_ThrowsIndexOutOfRangeException(int rowNum) + { + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(DataClass)).Find(nameof(DataClass.Value1), ignoreCase: false); + var style = new SubDataGridColumnStyle(descriptor); + var context = new BindingContext(); + var dataSource = new List { new() { Value1 = 1 }, new() { Value1 = 2 }, new() { Value1 = 3 } }; + CurrencyManager source = Assert.IsType(context[dataSource]); + Assert.Throws((() => style.GetColumnValueAtRow(source, rowNum))); + } + + [Fact] + public void DataGridColumnStyle_Invalidate_InvokeSeveralTimesWithTableStyleWithDataGrid_Nop() + { + var dataGrid = new DataGrid(); + var tableStyle = new DataGridTableStyle(); + dataGrid.TableStyles.Add(tableStyle); + var style = new SubDataGridColumnStyle(); + tableStyle.GridColumnStyles.Add(style); + style.Invalidate(); + style.Invalidate(); + } + + [Fact] + public void DataGridColumnStyle_Invalidate_InvokeSeveralTimesWithTableStyle_Nop() + { + var tableStyle = new DataGridTableStyle(); + var style = new SubDataGridColumnStyle(); + tableStyle.GridColumnStyles.Add(style); + style.Invalidate(); + style.Invalidate(); + } + + [Fact] + public void DataGridColumnStyle_Invalidate_InvokeSeveralTimes_Nop() + { + var style = new SubDataGridColumnStyle(); + style.Invalidate(); + style.Invalidate(); + } + + public static IEnumerable Paint_TestData() + { + yield return new object[] { null, Rectangle.Empty, null, -2, null, null, false }; + + var image = new Bitmap(10, 10); + var style = new SubDataGridColumnStyle(); + var context = new BindingContext(); + var dataSource = new List { new() { Value1 = 1 }, new() { Value1 = 2 }, new() { Value1 = 3 } }; + CurrencyManager source = Assert.IsType(context[dataSource]); + yield return new object[] { Graphics.FromImage(image), new Rectangle(1, 2, 3, 4), source, -1, new SolidBrush(Color.Red), new SolidBrush(Color.Blue), true }; + yield return new object[] { Graphics.FromImage(image), new Rectangle(-1, -2, -3, -4), source, 1, new SolidBrush(Color.Red), new SolidBrush(Color.Blue), false }; + } + + [Theory] + [MemberData(nameof(Paint_TestData))] + public void Paint_Invoke_Success(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight) + { + var style = new SubDataGridColumnStyle(); + int callCount = 0; + style.PaintAction = (actualG, actualBounds, actualSource, actualRowNum, actualAlignToRight) => + { + Assert.Same(g, actualG); + Assert.Same(source, actualSource); + Assert.Equal(bounds, actualBounds); + Assert.Equal(rowNum, actualRowNum); + Assert.Equal(alignToRight, actualAlignToRight); + callCount++; + }; + style.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight); + Assert.Equal(1, callCount); + } + + [Fact] + public void DataGridColumnStyle_ReleaseHostedControl_InvokeSeveralTimes_Nop() + { + var style = new SubDataGridColumnStyle(); + style.ReleaseHostedControl(); + style.ReleaseHostedControl(); + } + + [Fact] + public void DataGridColumnStyle_ResetHeaderText_Invoke_Success() + { + var style = new SubDataGridColumnStyle + { + HeaderText = "HeaderText" + }; + style.ResetHeaderText(); + Assert.Empty(style.HeaderText); + + // Reset again. + style.ResetHeaderText(); + Assert.Empty(style.HeaderText); + } + + [Theory] + [InlineData(0, 2)] + [InlineData(1, 3)] + [InlineData(2, 4)] + public void SetColumnValueAtRow_PropertyDescriptor_ReturnsExpected(int rowNum, int value) + { + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(DataClass)).Find(nameof(DataClass.Value1), ignoreCase: false); + var style = new SubDataGridColumnStyle(descriptor); + var context = new BindingContext(); + var dataSource = new List { new() { Value1 = 1 }, new() { Value1 = 2 }, new() { Value1 = 3 } }; + CurrencyManager source = Assert.IsType(context[dataSource]); + source.Position = rowNum; + + style.SetColumnValueAtRow(source, rowNum, value); + Assert.Equal(value, style.GetColumnValueAtRow(source, rowNum)); + Assert.Equal(value, dataSource[rowNum].Value1); + } + + [Theory] + [InlineData(0, 2)] + [InlineData(1, 3)] + [InlineData(2, 4)] + public void SetColumnValueAtRow_IEditablePropertyDescriptor_ReturnsExpected(int rowNum, int value) + { + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(EditableDataClass)).Find(nameof(EditableDataClass.Value), ignoreCase: false); + var style = new SubDataGridColumnStyle(descriptor); + var context = new BindingContext(); + var dataSource = new List { new() { Value = 1 }, new() { Value = 2 }, new() { Value = 3 } }; + CurrencyManager source = Assert.IsType(context[dataSource]); + source.Position = rowNum; + Assert.Equal(1, dataSource[rowNum].BeginEditCallCount); + + style.SetColumnValueAtRow(source, rowNum, value); + Assert.Equal(value, style.GetColumnValueAtRow(source, rowNum)); + Assert.Equal(value, dataSource[rowNum].Value); + Assert.Equal(2, dataSource[rowNum].BeginEditCallCount); + } + + [Theory] + [InlineData(0, 2)] + [InlineData(1, 3)] + [InlineData(2, 4)] + public void SetColumnValueAtRow_PropertyDescriptorCalledTwice_ReturnsExpected(int rowNum, int value) + { + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(DataClass)).Find(nameof(DataClass.Value1), ignoreCase: false); + var style = new NullPropertyDescriptorDataGridColumnStyle(descriptor, 2); + var context = new BindingContext(); + var dataSource = new List { new() { Value1 = 1 }, new() { Value1 = 2 }, new() { Value1 = 3 } }; + CurrencyManager source = Assert.IsType(context[dataSource]); + source.Position = rowNum; + + style.SetColumnValueAtRow(source, rowNum, value); + style.RequiredCallCount = int.MaxValue; + Assert.Equal(value, style.GetColumnValueAtRow(source, rowNum)); + Assert.Equal(value, dataSource[rowNum].Value1); + } + + [Fact] + public void DataGridColumnStyle_SetColumnValueAtRow_NullSource_ThrowsArgumentNullException() + { + var style = new SubDataGridColumnStyle(); + Assert.Throws("value", () => style.SetColumnValueAtRow(null, 0, 1)); + } + + [Fact] + public void DataGridColumnStyle_SetColumnValueAtRow_NoPropertyDescriptor_ThrowsInvalidOperationException() + { + var style = new SubDataGridColumnStyle(); + var context = new BindingContext(); + var dataSource = new List { 1, 2, 3 }; + CurrencyManager source = Assert.IsType(context[dataSource]); + Assert.Throws(() => style.SetColumnValueAtRow(source, 0, 1)); + } + + [Fact] + public void DataGridColumnStyle_SetColumnValueAtRow_NoPropertyDescriptorNoValidation_ThrowsInvalidOperationException() + { + var style = new NullPropertyDescriptorDataGridColumnStyle(1); + var context = new BindingContext(); + var dataSource = new List { 1, 2, 3 }; + CurrencyManager source = Assert.IsType(context[dataSource]); + Assert.Throws(() => style.SetColumnValueAtRow(source, 0, new object())); + } + + [Theory] + [InlineData(-1)] + [InlineData(1)] + [InlineData(2)] + [InlineData(3)] + public void SetColumnValueAtRow_InvalidIndex_ThrowsArgumentException(int rowNum) + { + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(DataClass)).Find(nameof(DataClass.Value1), ignoreCase: false); + var style = new SubDataGridColumnStyle(descriptor); + var context = new BindingContext(); + var dataSource = new List { new() { Value1 = 1 }, new() { Value1 = 2 }, new() { Value1 = 3 } }; + CurrencyManager source = Assert.IsType(context[dataSource]); + Assert.Throws("rowNum", () => style.SetColumnValueAtRow(source, rowNum, 1)); + } + + public static IEnumerable DataGrid_TestData() + { + yield return new object[] { null }; + yield return new object[] { new DataGrid() }; + } + + [Theory] + [MemberData(nameof(DataGrid_TestData))] + public void SetDataGrid_Invoke_CallsSetDataGridInColumn(DataGrid value) + { + var style = new SetDataGridInColumnDataGridColumnStyle(); + int callCount = 0; + style.SetDataGridInColumnAction = actualValue => + { + Assert.Same(value, actualValue); + callCount++; + }; + style.SetDataGrid(value); + Assert.Equal(1, callCount); + } + + public static IEnumerable SetDataGridInColumn_TestData() + { + yield return new object[] { null, null, null }; + + var dataGridWithoutListManager = new DataGrid(); + Assert.Null(dataGridWithoutListManager.ListManager); + yield return new object[] { null, dataGridWithoutListManager, null }; + + var dataGrid = new DataGrid + { + BindingContext = new BindingContext(), + DataSource = new List { new() { Value1 = 1 } } + }; + Assert.NotNull(dataGrid.ListManager); + yield return new object[] { null, dataGrid, null }; + yield return new object[] { string.Empty, dataGrid, null }; + yield return new object[] { "NoSuchProperty", dataGrid, null }; + yield return new object[] { nameof(DataClass.ListProperty), dataGrid, null }; + yield return new object[] { nameof(DataClass.Value1).ToLower(), dataGrid, null }; + yield return new object[] { nameof(DataClass.Value1), dataGrid, TypeDescriptor.GetProperties(typeof(DataClass)).Find(nameof(DataClass.Value1), ignoreCase: false) }; + } + + [Theory] + [MemberData(nameof(SetDataGridInColumn_TestData))] + public void SetDataGridInColumn_DataGridWithoutListManager_Nop(string headerText, DataGrid value, object expectedPropertyDescriptor) + { + var style = new SubDataGridColumnStyle + { + HeaderText = headerText + }; + style.SetDataGrid(value); + Assert.Equal(expectedPropertyDescriptor, style.PropertyDescriptor); + } + + [Fact] + public void DataGridColumnStyle_SetDataGridInColumn_HasPropertyDescriptor_Nop() + { + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(DataClass)).Find(nameof(DataClass.Value1), ignoreCase: false); + var style = new SubDataGridColumnStyle(descriptor) + { + HeaderText = nameof(DataClass.Value2) + }; + var dataGrid = new DataGrid + { + BindingContext = new BindingContext(), + DataSource = new List { new() { Value1 = 1 } } + }; + Assert.NotNull(dataGrid.ListManager); + style.SetDataGridInColumn(dataGrid); + Assert.Same(descriptor, style.PropertyDescriptor); + } + + public static IEnumerable UpdateUI_TestData() + { + yield return new object[] { null, -2, null }; + + var style = new SubDataGridColumnStyle(); + var context = new BindingContext(); + var dataSource = new List { new() { Value1 = 1 }, new() { Value1 = 2 }, new() { Value1 = 3 } }; + CurrencyManager source = Assert.IsType(context[dataSource]); + yield return new object[] { source, -1, string.Empty }; + yield return new object[] { source, 1, "displayText" }; + } + + [Theory] + [MemberData(nameof(UpdateUI_TestData))] + public void UpdateUI_Invoke_Nop(CurrencyManager source, int rowNum, string displayText) + { + var style = new SubDataGridColumnStyle(); + style.UpdateUI(source, rowNum, displayText); + } + + private class DataClass + { + public int Value1 { get; set; } + public int Value2 { get; set; } + + public IList ListProperty { get; set; } + } + + private class EditableDataClass : IEditableObject + { + public int BeginEditCallCount { get; set; } + + public void BeginEdit() => BeginEditCallCount++; + + public void CancelEdit() => throw new NotImplementedException(); + + public void EndEdit() { } + + public int Value { get; set; } + } + + private class ReadOnlyDataClass + { + public int Value1 { get; } + } + + private abstract class CustomDataGridColumnStyle : DataGridColumnStyle + { + protected CustomDataGridColumnStyle() + { + } + + protected CustomDataGridColumnStyle(PropertyDescriptor prop) : base(prop) + { + } + + protected CustomDataGridColumnStyle(PropertyDescriptor prop, bool isDefault) : base(prop, isDefault) + { + } + + protected internal override void Abort(int rowNum) + { + throw new NotImplementedException(); + } + + protected internal override bool Commit(CurrencyManager dataSource, int rowNum) + { + throw new NotImplementedException(); + } + + protected internal override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText, bool cellIsVisible) + { + throw new NotImplementedException(); + } + + protected internal override Size GetPreferredSize(Graphics g, object value) + { + throw new NotImplementedException(); + } + + protected internal override int GetMinimumHeight() + { + throw new NotImplementedException(); + } + + protected internal override int GetPreferredHeight(Graphics g, object value) + { + throw new NotImplementedException(); + } + + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum) + { + throw new NotImplementedException(); + } + + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) + { + throw new NotImplementedException(); + } + } + + private class SubDataGridColumnStyle : CustomDataGridColumnStyle + { + public SubDataGridColumnStyle() + { + } + + public SubDataGridColumnStyle(PropertyDescriptor prop) : base(prop) + { + } + + public SubDataGridColumnStyle(PropertyDescriptor prop, bool isDefault) : base(prop, isDefault) + { + } + + public new bool CanRaiseEvents => base.CanRaiseEvents; + + public new bool DesignMode => base.DesignMode; + + public new EventHandlerList Events => base.Events; + + public new int FontHeight => base.FontHeight; + + public new void BeginUpdate() => base.BeginUpdate(); + + public new void CheckValidDataSource(CurrencyManager value) => base.CheckValidDataSource(value); + + public new AccessibleObject CreateHeaderAccessibleObject() => base.CreateHeaderAccessibleObject(); + + public new void EndUpdate() => base.EndUpdate(); + + public new void Invalidate() => base.Invalidate(); + + public new void SetDataGrid(DataGrid value) => base.SetDataGrid(value); + + public new void SetDataGridInColumn(DataGrid value) => base.SetDataGridInColumn(value); + + public Action EditAction { get; set; } + + protected internal override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText, bool cellIsVisible) + { + EditAction(source, rowNum, bounds, readOnly, displayText, cellIsVisible); + } + + public Action PaintAction { get; set; } + + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) + { + PaintAction(g, bounds, source, rowNum, alignToRight); + } + } + + private class NullPropertyDescriptorDataGridColumnStyle : CustomDataGridColumnStyle + { + public NullPropertyDescriptorDataGridColumnStyle(int requiredCallCount) + { + RequiredCallCount = requiredCallCount; + } + + public NullPropertyDescriptorDataGridColumnStyle(PropertyDescriptor prop, int requiredCallCount) : base(prop) + { + RequiredCallCount = requiredCallCount; + } + + public int RequiredCallCount { get; set; } + + private int _callCount = 0; + + public override PropertyDescriptor PropertyDescriptor + { + get + { + if (_callCount < RequiredCallCount) + { + _callCount++; + return TypeDescriptor.GetProperties(typeof(DataClass)).Find(nameof(DataClass.Value1), ignoreCase: false); + } + + return null; + } + set { } + } + } + + private class InvalidateDataGridColumnStyle : CustomDataGridColumnStyle + { + public new void BeginUpdate() => base.BeginUpdate(); + + public new void EndUpdate() => base.EndUpdate(); + + public void CallInvalidate() => Invalidate(); + + public int InvalidateCallCount { get; set; } + + protected override void Invalidate() + { + InvalidateCallCount++; + base.Invalidate(); + } + } + + private class SetDataGridInColumnDataGridColumnStyle : CustomDataGridColumnStyle + { + public new void SetDataGrid(DataGrid value) => base.SetDataGrid(value); + + public Action SetDataGridInColumnAction { get; set; } + + protected override void SetDataGridInColumn(DataGrid value) + { + SetDataGridInColumnAction(value); + } + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/DataGridTableStyleTests.cs b/WTG.System.Windows.Forms.Tests/DataGridTableStyleTests.cs new file mode 100644 index 00000000000..96104fa9311 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/DataGridTableStyleTests.cs @@ -0,0 +1,4874 @@ + +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using WTG.System.Windows.Forms.Tests.Common; + +namespace WTG.System.Windows.Forms.Tests +{ + public class DataGridTableStyleTests + { + [Fact] + public void DataGridTableStyle_Ctor_Default() + { + var style = new SubDataGridTableStyle(); + Assert.True(style.AllowSorting); + Assert.Equal(SystemColors.Window, style.AlternatingBackColor); + Assert.Equal(SystemColors.Window, style.BackColor); + Assert.True(style.CanRaiseEvents); + Assert.True(style.ColumnHeadersVisible); + Assert.Null(style.Container); + Assert.Null(style.DataGrid); + Assert.False(style.DesignMode); + Assert.NotNull(style.Events); + Assert.Same(style.Events, style.Events); + Assert.Equal(SystemColors.WindowText, style.ForeColor); + Assert.Empty(style.GridColumnStyles); + Assert.Same(style.GridColumnStyles, style.GridColumnStyles); + Assert.Equal(SystemColors.Control, style.GridLineColor); + Assert.Equal(DataGridLineStyle.Solid, style.GridLineStyle); + Assert.Equal(SystemColors.Control, style.HeaderBackColor); + Assert.Equal(Control.DefaultFont, style.HeaderFont); + Assert.Equal(SystemColors.ControlText, style.HeaderForeColor); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + Assert.Empty(style.MappingName); + Assert.Equal(75, style.PreferredColumnWidth); + Assert.Equal(Control.DefaultFont.Height + 3, style.PreferredRowHeight); + Assert.False(style.ReadOnly); + Assert.True(style.RowHeadersVisible); + Assert.Equal(35, style.RowHeaderWidth); + Assert.Equal(SystemColors.ActiveCaption, style.SelectionBackColor); + Assert.Equal(SystemColors.ActiveCaptionText, style.SelectionForeColor); + Assert.Null(style.Site); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_Ctor_Bool(bool isDefaultTableStyle) + { + var style = new SubDataGridTableStyle(isDefaultTableStyle); + Assert.True(style.AllowSorting); + Assert.Equal(SystemColors.Window, style.AlternatingBackColor); + Assert.Equal(SystemColors.Window, style.BackColor); + Assert.True(style.CanRaiseEvents); + Assert.True(style.ColumnHeadersVisible); + Assert.Null(style.Container); + Assert.Null(style.DataGrid); + Assert.False(style.DesignMode); + Assert.NotNull(style.Events); + Assert.Same(style.Events, style.Events); + Assert.Equal(SystemColors.WindowText, style.ForeColor); + Assert.Empty(style.GridColumnStyles); + Assert.Same(style.GridColumnStyles, style.GridColumnStyles); + Assert.Equal(SystemColors.Control, style.GridLineColor); + Assert.Equal(DataGridLineStyle.Solid, style.GridLineStyle); + Assert.Equal(SystemColors.Control, style.HeaderBackColor); + Assert.Equal(Control.DefaultFont, style.HeaderFont); + Assert.Equal(SystemColors.ControlText, style.HeaderForeColor); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + Assert.Empty(style.MappingName); + Assert.Equal(75, style.PreferredColumnWidth); + Assert.Equal(Control.DefaultFont.Height + 3, style.PreferredRowHeight); + Assert.False(style.ReadOnly); + Assert.True(style.RowHeadersVisible); + Assert.Equal(35, style.RowHeaderWidth); + Assert.Equal(SystemColors.ActiveCaption, style.SelectionBackColor); + Assert.Equal(SystemColors.ActiveCaptionText, style.SelectionForeColor); + Assert.Null(style.Site); + } + + [Fact] + public void DataGridTableStyle_DefaultTableStyle_Get_ReturnsExpected() + { + DataGridTableStyle style = DataGridTableStyle.DefaultTableStyle; + Assert.True(style.AllowSorting); + Assert.Equal(SystemColors.Window, style.AlternatingBackColor); + Assert.Equal(SystemColors.Window, style.BackColor); + Assert.True(style.ColumnHeadersVisible); + Assert.Null(style.Container); + Assert.Null(style.DataGrid); + Assert.Equal(SystemColors.WindowText, style.ForeColor); + Assert.Empty(style.GridColumnStyles); + Assert.Same(style.GridColumnStyles, style.GridColumnStyles); + Assert.Equal(SystemColors.Control, style.GridLineColor); + Assert.Equal(DataGridLineStyle.Solid, style.GridLineStyle); + Assert.Equal(SystemColors.Control, style.HeaderBackColor); + Assert.Equal(Control.DefaultFont, style.HeaderFont); + Assert.Equal(SystemColors.ControlText, style.HeaderForeColor); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + Assert.Empty(style.MappingName); + Assert.Equal(75, style.PreferredColumnWidth); + Assert.Equal(Control.DefaultFont.Height + 3, style.PreferredRowHeight); + Assert.False(style.ReadOnly); + Assert.True(style.RowHeadersVisible); + Assert.Equal(35, style.RowHeaderWidth); + Assert.Equal(SystemColors.ActiveCaption, style.SelectionBackColor); + Assert.Equal(SystemColors.ActiveCaptionText, style.SelectionForeColor); + Assert.Null(style.Site); + Assert.Same(style, DataGridTableStyle.DefaultTableStyle); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_AllowSorting_Set_GetReturnsExpected(bool value) + { + var style = new DataGridTableStyle + { + AllowSorting = value + }; + Assert.Equal(value, style.AllowSorting); + + // Set same. + style.AllowSorting = value; + Assert.Equal(value, style.AllowSorting); + + // Set different + style.AllowSorting = !value; + Assert.Equal(!value, style.AllowSorting); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_AllowSorting_SetWithDataGrid_DoesNotCallInvalidate(bool value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.AllowSorting = value; + Assert.Equal(value, style.AllowSorting); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.AllowSorting = value; + Assert.Equal(value, style.AllowSorting); + Assert.Equal(0, invalidatedCallCount); + + // Set different + style.AllowSorting = !value; + Assert.Equal(!value, style.AllowSorting); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_AllowSorting_SetWithHandler_CallsAllowSortingChanged() + { + var style = new DataGridTableStyle + { + AllowSorting = true + }; + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.AllowSortingChanged += handler; + + // Set different. + style.AllowSorting = false; + Assert.False(style.AllowSorting); + Assert.Equal(1, callCount); + + // Set same. + style.AllowSorting = false; + Assert.False(style.AllowSorting); + Assert.Equal(1, callCount); + + // Set different. + style.AllowSorting = true; + Assert.True(style.AllowSorting); + Assert.Equal(2, callCount); + + // Remove handler. + style.AllowSortingChanged -= handler; + style.AllowSorting = false; + Assert.False(style.AllowSorting); + Assert.Equal(2, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetColorTheoryData))] + public void DataGridTableStyle_AlternatingBackColor_Set_GetReturnsExpected(Color value) + { + var style = new DataGridTableStyle + { + AlternatingBackColor = value + }; + Assert.Equal(value, style.AlternatingBackColor); + + // Set same. + style.AlternatingBackColor = value; + Assert.Equal(value, style.AlternatingBackColor); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetColorTheoryData))] + public void DataGridTableStyle_AlternatingBackColor_SetWithDataGrid_CallsInvalidate(Color value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.AlternatingBackColor = value; + Assert.Equal(value, style.AlternatingBackColor); + Assert.Equal(1, invalidatedCallCount); + + // Set same. + style.AlternatingBackColor = value; + Assert.Equal(value, style.AlternatingBackColor); + Assert.Equal(1, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_AlternatingBackColor_SetWithHandler_CallsAlternatingBackColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.AlternatingBackColorChanged += handler; + + // Set different. + style.AlternatingBackColor = Color.Red; + Assert.Equal(Color.Red, style.AlternatingBackColor); + Assert.Equal(1, callCount); + + // Set same. + style.AlternatingBackColor = Color.Red; + Assert.Equal(Color.Red, style.AlternatingBackColor); + Assert.Equal(1, callCount); + + // Set different. + style.AlternatingBackColor = Color.Blue; + Assert.Equal(Color.Blue, style.AlternatingBackColor); + Assert.Equal(2, callCount); + + // Remove handler. + style.AlternatingBackColorChanged -= handler; + style.AlternatingBackColor = Color.Red; + Assert.Equal(Color.Red, style.AlternatingBackColor); + Assert.Equal(2, callCount); + } + + public static IEnumerable InvalidColor_TestData() + { + yield return new object[] { Color.Empty }; + yield return new object[] { Color.FromArgb(254, 1, 2, 3) }; + } + + [Theory] + [MemberData(nameof(InvalidColor_TestData))] + public void DataGridTableStyle_AlternatingBackColor_SetInvalid_ThrowsArgumentException(Color value) + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.AlternatingBackColor = value); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetColorTheoryData))] + public void DataGridTableStyle_BackColor_Set_GetReturnsExpected(Color value) + { + var style = new DataGridTableStyle + { + BackColor = value + }; + Assert.Equal(value, style.BackColor); + + // Set same. + style.BackColor = value; + Assert.Equal(value, style.BackColor); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetColorTheoryData))] + public void DataGridTableStyle_BackColor_SetWithDataGrid_CallsInvalidate(Color value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.BackColor = value; + Assert.Equal(value, style.BackColor); + Assert.Equal(1, invalidatedCallCount); + + // Set same. + style.BackColor = value; + Assert.Equal(value, style.BackColor); + Assert.Equal(1, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_BackColor_SetWithHandler_CallsBackColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.BackColorChanged += handler; + + // Set different. + style.BackColor = Color.Red; + Assert.Equal(Color.Red, style.BackColor); + Assert.Equal(1, callCount); + + // Set same. + style.BackColor = Color.Red; + Assert.Equal(Color.Red, style.BackColor); + Assert.Equal(1, callCount); + + // Set different. + style.BackColor = Color.Blue; + Assert.Equal(Color.Blue, style.BackColor); + Assert.Equal(2, callCount); + + // Remove handler. + style.BackColorChanged -= handler; + style.BackColor = Color.Red; + Assert.Equal(Color.Red, style.BackColor); + Assert.Equal(2, callCount); + } + + [Theory] + [MemberData(nameof(InvalidColor_TestData))] + public void DataGridTableStyle_BackColor_SetInvalid_ThrowsArgumentException(Color value) + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.BackColor = value); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_ColumnHeadersVisible_Set_GetReturnsExpected(bool value) + { + var style = new DataGridTableStyle + { + ColumnHeadersVisible = value + }; + Assert.Equal(value, style.ColumnHeadersVisible); + + // Set same. + style.ColumnHeadersVisible = value; + Assert.Equal(value, style.ColumnHeadersVisible); + + // Set different + style.ColumnHeadersVisible = !value; + Assert.Equal(!value, style.ColumnHeadersVisible); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_ColumnHeadersVisible_SetDefaultTableStyle_GetReturnsExpected(bool value) + { + var style = new DataGridTableStyle(isDefaultTableStyle: true) + { + ColumnHeadersVisible = value + }; + Assert.Equal(value, style.ColumnHeadersVisible); + + // Set same. + style.ColumnHeadersVisible = value; + Assert.Equal(value, style.ColumnHeadersVisible); + + // Set different + style.ColumnHeadersVisible = !value; + Assert.Equal(!value, style.ColumnHeadersVisible); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_ColumnHeadersVisible_SetWithDataGrid_DoesNotCallInvalidate(bool value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.ColumnHeadersVisible = value; + Assert.Equal(value, style.ColumnHeadersVisible); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.ColumnHeadersVisible = value; + Assert.Equal(value, style.ColumnHeadersVisible); + Assert.Equal(0, invalidatedCallCount); + + // Set different + style.ColumnHeadersVisible = !value; + Assert.Equal(!value, style.ColumnHeadersVisible); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ColumnHeadersVisible_SetWithHandler_CallsColumnHeadersVisibleChanged() + { + var style = new DataGridTableStyle + { + ColumnHeadersVisible = true + }; + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.ColumnHeadersVisibleChanged += handler; + + // Set different. + style.ColumnHeadersVisible = false; + Assert.False(style.ColumnHeadersVisible); + Assert.Equal(1, callCount); + + // Set same. + style.ColumnHeadersVisible = false; + Assert.False(style.ColumnHeadersVisible); + Assert.Equal(1, callCount); + + // Set different. + style.ColumnHeadersVisible = true; + Assert.True(style.ColumnHeadersVisible); + Assert.Equal(2, callCount); + + // Remove handler. + style.ColumnHeadersVisibleChanged -= handler; + style.ColumnHeadersVisible = false; + Assert.False(style.ColumnHeadersVisible); + Assert.Equal(2, callCount); + } + + public static IEnumerable DataGrid_TestData() + { + yield return new object[] { null }; + yield return new object[] { new DataGrid() }; + } + + [Theory] + [MemberData(nameof(DataGrid_TestData))] + public void DataGridTableStyle_DataGrid_Set_GetReturnsExpected(DataGrid value) + { + var style = new DataGridTableStyle + { + DataGrid = value + }; + Assert.Same(value, style.DataGrid); + Assert.Same(value?.Font ?? Control.DefaultFont, style.HeaderFont); + + // Set same. + style.DataGrid = value; + Assert.Same(value, style.DataGrid); + Assert.Same(value?.Font ?? Control.DefaultFont, style.HeaderFont); + } + + [Theory] + [MemberData(nameof(DataGrid_TestData))] + public void DataGridTableStyle_DataGrid_SetDefaultTableStyle_GetReturnsExpected(DataGrid value) + { + var style = new DataGridTableStyle(isDefaultTableStyle: true) + { + DataGrid = value + }; + Assert.Same(value, style.DataGrid); + Assert.Same(value?.Font ?? Control.DefaultFont, style.HeaderFont); + + // Set same. + style.DataGrid = value; + Assert.Same(value, style.DataGrid); + Assert.Same(value?.Font ?? Control.DefaultFont, style.HeaderFont); + } + + [Fact] + public void DataGridTableStyle_DataGrid_SetWithGridColumnStyles_SetsDataGridOnGridColumnStyles() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle(); + var columnStyle = new SubDataGridColumnStyle(); + int callCount = 0; + columnStyle.SetDataGridInColumnAction = actualDataGrid => + { + Assert.Same(dataGrid, actualDataGrid); + callCount++; + }; + style.GridColumnStyles.Add(columnStyle); + + style.DataGrid = dataGrid; + Assert.Same(dataGrid, style.DataGrid); + Assert.Equal(1, callCount); + + // Set same. + style.DataGrid = dataGrid; + Assert.Same(dataGrid, style.DataGrid); + Assert.Equal(2, callCount); + + // Set null. + style.DataGrid = null; + Assert.Null(style.DataGrid); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_DataGrid_SetWithGridColumnStylesInitializing_DoesNotSetDataGridOnGridColumnStyles() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle(); + var columnStyle = new SubDataGridColumnStyle(); + int callCount = 0; + columnStyle.SetDataGridInColumnAction = actualDataGrid => + { + Assert.Same(dataGrid, actualDataGrid); + callCount++; + }; + style.GridColumnStyles.Add(columnStyle); + dataGrid.BeginInit(); + + style.DataGrid = dataGrid; + Assert.Same(dataGrid, style.DataGrid); + Assert.Equal(0, callCount); + + // Set same. + style.DataGrid = dataGrid; + Assert.Same(dataGrid, style.DataGrid); + Assert.Equal(0, callCount); + + // Set null. + style.DataGrid = null; + Assert.Null(style.DataGrid); + Assert.Equal(0, callCount); + } + + public static IEnumerable ForeColor_Set_TestData() + { + yield return new object[] { Color.FromArgb(254, 1, 2, 3) }; + yield return new object[] { Color.Red }; + } + + [Theory] + [MemberData(nameof(ForeColor_Set_TestData))] + public void DataGridTableStyle_ForeColor_Set_GetReturnsExpected(Color value) + { + var style = new DataGridTableStyle + { + ForeColor = value + }; + Assert.Equal(value, style.ForeColor); + + // Set same. + style.ForeColor = value; + Assert.Equal(value, style.ForeColor); + } + + [Theory] + [MemberData(nameof(ForeColor_Set_TestData))] + public void DataGridTableStyle_ForeColor_SetWithDataGrid_CallsInvalidate(Color value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.ForeColor = value; + Assert.Equal(value, style.ForeColor); + Assert.Equal(1, invalidatedCallCount); + + // Set same. + style.ForeColor = value; + Assert.Equal(value, style.ForeColor); + Assert.Equal(1, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ForeColor_SetWithHandler_CallsForeColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.ForeColorChanged += handler; + + // Set different. + style.ForeColor = Color.Red; + Assert.Equal(Color.Red, style.ForeColor); + Assert.Equal(1, callCount); + + // Set same. + style.ForeColor = Color.Red; + Assert.Equal(Color.Red, style.ForeColor); + Assert.Equal(1, callCount); + + // Set different. + style.ForeColor = Color.Blue; + Assert.Equal(Color.Blue, style.ForeColor); + Assert.Equal(2, callCount); + + // Remove handler. + style.ForeColorChanged -= handler; + style.ForeColor = Color.Red; + Assert.Equal(Color.Red, style.ForeColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ForeColor_SetEmpty_ThrowsArgumentException() + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.ForeColor = Color.Empty); + } + + public static IEnumerable GridLineColor_Set_TestData() + { + yield return new object[] { Color.FromArgb(254, 1, 2, 3) }; + yield return new object[] { Color.Red }; + } + + [Theory] + [MemberData(nameof(GridLineColor_Set_TestData))] + public void DataGridTableStyle_GridLineColor_Set_GetReturnsExpected(Color value) + { + var style = new DataGridTableStyle + { + GridLineColor = value + }; + Assert.Equal(value, style.GridLineColor); + + // Set same. + style.GridLineColor = value; + Assert.Equal(value, style.GridLineColor); + } + + [Theory] + [MemberData(nameof(GridLineColor_Set_TestData))] + public void DataGridTableStyle_GridLineColor_SetWithDataGrid_DoesNotCallInvalidate(Color value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.GridLineColor = value; + Assert.Equal(value, style.GridLineColor); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.GridLineColor = value; + Assert.Equal(value, style.GridLineColor); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_GridLineColor_SetWithHandler_CallsGridLineColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.GridLineColorChanged += handler; + + // Set different. + style.GridLineColor = Color.Red; + Assert.Equal(Color.Red, style.GridLineColor); + Assert.Equal(1, callCount); + + // Set same. + style.GridLineColor = Color.Red; + Assert.Equal(Color.Red, style.GridLineColor); + Assert.Equal(1, callCount); + + // Set different. + style.GridLineColor = Color.Blue; + Assert.Equal(Color.Blue, style.GridLineColor); + Assert.Equal(2, callCount); + + // Remove handler. + style.GridLineColorChanged -= handler; + style.GridLineColor = Color.Red; + Assert.Equal(Color.Red, style.GridLineColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_GridLineColor_SetEmpty_ThrowsArgumentException() + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.GridLineColor = Color.Empty); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEnumTypeTheoryData), typeof(DataGridLineStyle))] + public void DataGridTableStyle_GridLineStyle_Set_GetReturnsExpected(DataGridLineStyle value) + { + var style = new DataGridTableStyle + { + GridLineStyle = value + }; + Assert.Equal(value, style.GridLineStyle); + + // Set same. + style.GridLineStyle = value; + Assert.Equal(value, style.GridLineStyle); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEnumTypeTheoryData), typeof(DataGridLineStyle))] + public void DataGridTableStyle_GridLineStyle_SetWithDataGrid_DoesNotCallInvalidate(DataGridLineStyle value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.GridLineStyle = value; + Assert.Equal(value, style.GridLineStyle); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.GridLineStyle = value; + Assert.Equal(value, style.GridLineStyle); + Assert.Equal(0, invalidatedCallCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEnumTypeTheoryDataInvalid), typeof(DataGridLineStyle))] + public void DataGridTableStyle_GridLineStyle_SetInvalidValue_ThrowsInvalidEnumArgumentException(DataGridLineStyle value) + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.GridLineStyle = value); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetColorTheoryData))] + public void DataGridTableStyle_HeaderBackColor_Set_GetReturnsExpected(Color value) + { + var style = new DataGridTableStyle + { + HeaderBackColor = value + }; + Assert.Equal(value, style.HeaderBackColor); + + // Set same. + style.HeaderBackColor = value; + Assert.Equal(value, style.HeaderBackColor); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetColorTheoryData))] + public void DataGridTableStyle_HeaderBackColor_SetWithDataGrid_DoesNotCallInvalidate(Color value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.HeaderBackColor = value; + Assert.Equal(value, style.HeaderBackColor); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.HeaderBackColor = value; + Assert.Equal(value, style.HeaderBackColor); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_HeaderBackColor_SetWithHandler_CallsHeaderBackColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.HeaderBackColorChanged += handler; + + // Set different. + style.HeaderBackColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderBackColor); + Assert.Equal(1, callCount); + + // Set same. + style.HeaderBackColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderBackColor); + Assert.Equal(1, callCount); + + // Set different. + style.HeaderBackColor = Color.Blue; + Assert.Equal(Color.Blue, style.HeaderBackColor); + Assert.Equal(2, callCount); + + // Remove handler. + style.HeaderBackColorChanged -= handler; + style.HeaderBackColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderBackColor); + Assert.Equal(2, callCount); + } + + [Theory] + [MemberData(nameof(InvalidColor_TestData))] + public void DataGridTableStyle_HeaderBackColor_SetInvalid_ThrowsArgumentException(Color value) + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.HeaderBackColor = value); + } + + [Fact] + public void DataGridTableStyle_HeaderFont_Set_GetReturnsExpected() + { + var font1 = new Font(SystemFonts.MessageBoxFont.FontFamily, 10); + var font2 = new Font(SystemFonts.MessageBoxFont.FontFamily, 11); + var style = new DataGridTableStyle + { + HeaderFont = font1 + }; + Assert.Same(font1, style.HeaderFont); + + // Set same. + style.HeaderFont = font1; + Assert.Same(font1, style.HeaderFont); + + // Set null. + style.HeaderFont = null; + Assert.Equal(Control.DefaultFont, style.HeaderFont); + + // Set null again. + style.HeaderFont = null; + Assert.Equal(Control.DefaultFont, style.HeaderFont); + + // Set different. + style.HeaderFont = font1; + Assert.Same(font1, style.HeaderFont); + + // Set different. + style.HeaderFont = font2; + Assert.Same(font2, style.HeaderFont); + } + + [Fact] + public void DataGridTableStyle_HeaderFont_SetWithDataGrid_DoesNotCallInvalidate() + { + var font1 = new Font(SystemFonts.MessageBoxFont.FontFamily, 10); + var font2 = new Font(SystemFonts.MessageBoxFont.FontFamily, 11); + var dataGrid = new DataGrid + { + Font = SystemFonts.StatusFont + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.HeaderFont = font1; + Assert.Same(font1, style.HeaderFont); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.HeaderFont = font1; + Assert.Same(font1, style.HeaderFont); + Assert.Equal(0, invalidatedCallCount); + + // Set null. + style.HeaderFont = null; + Assert.Same(dataGrid.Font, style.HeaderFont); + Assert.Equal(0, invalidatedCallCount); + + // Set null again. + style.HeaderFont = null; + Assert.Same(dataGrid.Font, style.HeaderFont); + Assert.Equal(0, invalidatedCallCount); + + // Set different. + style.HeaderFont = font1; + Assert.Same(font1, style.HeaderFont); + Assert.Equal(0, invalidatedCallCount); + + // Set different. + style.HeaderFont = font2; + Assert.Same(font2, style.HeaderFont); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_HeaderFont_SetWithHandler_CallsHeaderFontChanged() + { + var font1 = new Font(SystemFonts.MessageBoxFont.FontFamily, 10); + var font2 = new Font(SystemFonts.MessageBoxFont.FontFamily, 11); + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.HeaderFontChanged += handler; + + // Set different. + style.HeaderFont = font1; + Assert.Same(font1, style.HeaderFont); + Assert.Equal(1, callCount); + + // Set same. + style.HeaderFont = font1; + Assert.Same(font1, style.HeaderFont); + Assert.Equal(1, callCount); + + // Set null. + style.HeaderFont = null; + Assert.Equal(Control.DefaultFont, style.HeaderFont); + Assert.Equal(2, callCount); + + // Set null again. + style.HeaderFont = null; + Assert.Equal(Control.DefaultFont, style.HeaderFont); + Assert.Equal(2, callCount); + + // Set different. + style.HeaderFont = font1; + Assert.Same(font1, style.HeaderFont); + Assert.Equal(3, callCount); + + // Set different. + style.HeaderFont = font2; + Assert.Same(font2, style.HeaderFont); + Assert.Equal(4, callCount); + + // Remove handler. + style.HeaderFontChanged -= handler; + style.HeaderFont = font1; + Assert.Same(font1, style.HeaderFont); + Assert.Equal(4, callCount); + } + + public static IEnumerable HeaderForeColor_Set_TestData() + { + yield return new object[] { Color.FromArgb(254, 1, 2, 3) }; + yield return new object[] { Color.Red }; + } + + [Theory] + [MemberData(nameof(HeaderForeColor_Set_TestData))] + public void DataGridTableStyle_HeaderForeColor_Set_GetReturnsExpected(Color value) + { + var style = new DataGridTableStyle + { + HeaderForeColor = value + }; + Assert.Equal(value, style.HeaderForeColor); + + // Set same. + style.HeaderForeColor = value; + Assert.Equal(value, style.HeaderForeColor); + } + + [Theory] + [MemberData(nameof(HeaderForeColor_Set_TestData))] + public void DataGridTableStyle_HeaderForeColor_SetWithDataGrid_DoesNotCallInvalidate(Color value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.HeaderForeColor = value; + Assert.Equal(value, style.HeaderForeColor); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.HeaderForeColor = value; + Assert.Equal(value, style.HeaderForeColor); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_HeaderForeColor_SetWithHandler_CallsHeaderForeColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.HeaderForeColorChanged += handler; + + // Set different. + style.HeaderForeColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderForeColor); + Assert.Equal(1, callCount); + + // Set same. + style.HeaderForeColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderForeColor); + Assert.Equal(1, callCount); + + // Set different. + style.HeaderForeColor = Color.Blue; + Assert.Equal(Color.Blue, style.HeaderForeColor); + Assert.Equal(2, callCount); + + // Remove handler. + style.HeaderForeColorChanged -= handler; + style.HeaderForeColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderForeColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_HeaderForeColor_SetEmpty_ThrowsArgumentException() + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.HeaderForeColor = Color.Empty); + } + + public static IEnumerable LinkColor_Set_TestData() + { + yield return new object[] { Color.FromArgb(254, 1, 2, 3) }; + yield return new object[] { Color.Red }; + } + + [Theory] + [MemberData(nameof(LinkColor_Set_TestData))] + public void DataGridTableStyle_LinkColor_Set_GetReturnsExpected(Color value) + { + var style = new DataGridTableStyle + { + LinkColor = value + }; + Assert.Equal(value, style.LinkColor); + Assert.Equal(value, style.LinkHoverColor); + + // Set same. + style.LinkColor = value; + Assert.Equal(value, style.LinkColor); + Assert.Equal(value, style.LinkHoverColor); + } + + [Theory] + [MemberData(nameof(LinkColor_Set_TestData))] + public void DataGridTableStyle_LinkColor_SetWithDataGrid_DoesNotCallInvalidate(Color value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.LinkColor = value; + Assert.Equal(value, style.LinkColor); + Assert.Equal(value, style.LinkHoverColor); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.LinkColor = value; + Assert.Equal(value, style.LinkColor); + Assert.Equal(value, style.LinkHoverColor); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_LinkColor_SetWithHandler_CallsLinkColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.LinkColorChanged += handler; + + // Set different. + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + Assert.Equal(1, callCount); + + // Set same. + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + Assert.Equal(1, callCount); + + // Set different. + style.LinkColor = Color.Blue; + Assert.Equal(Color.Blue, style.LinkColor); + Assert.Equal(Color.Blue, style.LinkHoverColor); + Assert.Equal(2, callCount); + + // Remove handler. + style.LinkColorChanged -= handler; + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_LinkColor_SetEmpty_ThrowsArgumentException() + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.LinkColor = Color.Empty); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetColorWithEmptyTheoryData))] + public void DataGridTableStyle_LinkHoverColor_Set_Nop(Color value) + { + var style = new DataGridTableStyle(); + style.LinkHoverColor = value; + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void DataGridTableStyle_MappingName_Set_GetReturnsExpected(string value, string expected) + { + var style = new DataGridTableStyle + { + MappingName = value + }; + Assert.Equal(expected, style.MappingName); + + // Set same. + style.MappingName = value; + Assert.Equal(expected, style.MappingName); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void DataGridTableStyle_MappingName_SetWithDataGridView_GetReturnsExpected(string value, string expected) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.MappingName = value; + Assert.Equal(expected, style.MappingName); + Assert.Equal(0, invalidatedCallCount); + + style.MappingName = value; + Assert.Equal(expected, style.MappingName); + Assert.Equal(0, invalidatedCallCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void DataGridTableStyle_MappingName_SetDefaultTableStyle_GetReturnsExpected(string value, string expected) + { + var style = new DataGridTableStyle(isDefaultTableStyle: true) + { + MappingName = value + }; + Assert.Equal(expected, style.MappingName); + + style.MappingName = value; + Assert.Equal(expected, style.MappingName); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + [InlineData("mappingname2", "mappingname2")] + public void DataGridTableStyle_MappingName_SetNonDuplicate_GetReturnsExpected(string value, string expected) + { + var dataGrid = new DataGrid(); + var style1 = new DataGridTableStyle + { + MappingName = "MappingName1" + }; + var style2 = new DataGridTableStyle + { + MappingName = "MappingName2" + }; + dataGrid.TableStyles.Add(style1); + dataGrid.TableStyles.Add(style2); + + style1.MappingName = value; + Assert.Equal(expected, style1.MappingName); + + // Set same. + style1.MappingName = value; + Assert.Equal(expected, style1.MappingName); + } + + [Fact] + public void DataGridTableStyle_MappingName_SetDuplicate_Throws() + { + var dataGrid = new DataGrid(); + var style1 = new DataGridTableStyle + { + MappingName = "MappingName1" + }; + var style2 = new DataGridTableStyle + { + MappingName = "MappingName2" + }; + dataGrid.TableStyles.Add(style1); + dataGrid.TableStyles.Add(style2); + + Assert.Throws("table", () => style1.MappingName = "MappingName2"); + Assert.Equal("MappingName1", style1.MappingName); + } + + [Fact] + public void DataGridTableStyle_MappingName_SetWithHandler_CallsMappingNameChanged() + { + var control = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(control, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + control.MappingNameChanged += handler; + + // Set different. + control.MappingName = "mappingName"; + Assert.Same("mappingName", control.MappingName); + Assert.Equal(1, callCount); + + // Set same. + control.MappingName = "mappingName"; + Assert.Same("mappingName", control.MappingName); + Assert.Equal(1, callCount); + + // Set empty. + control.MappingName = string.Empty; + Assert.Empty(control.MappingName); + Assert.Equal(2, callCount); + + // Set null. + control.MappingName = null; + Assert.Empty(control.MappingName); + Assert.Equal(2, callCount); + + // Remove handler. + control.MappingNameChanged -= handler; + control.MappingName = "mappingName"; + Assert.Same("mappingName", control.MappingName); + Assert.Equal(2, callCount); + } + + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(75)] + [InlineData(76)] + public void DataGridTableStyle_PreferredColumnWidth_Set_GetReturnsExpected(int value) + { + var style = new DataGridTableStyle + { + PreferredColumnWidth = value + }; + Assert.Equal(value, style.PreferredColumnWidth); + + // Set same. + style.PreferredColumnWidth = value; + Assert.Equal(value, style.PreferredColumnWidth); + } + + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(75)] + [InlineData(76)] + public void DataGridTableStyle_PreferredColumnWidth_SetWithDataGrid_DoesNotCallInvalidate(int value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.PreferredColumnWidth = value; + Assert.Equal(value, style.PreferredColumnWidth); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.PreferredColumnWidth = value; + Assert.Equal(value, style.PreferredColumnWidth); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_PreferredColumnWidth_SetWithHandler_CallsPreferredColumnWidthChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.PreferredColumnWidthChanged += handler; + + // Set different. + style.PreferredColumnWidth = 1; + Assert.Equal(1, style.PreferredColumnWidth); + Assert.Equal(1, callCount); + + // Set same. + style.PreferredColumnWidth = 1; + Assert.Equal(1, style.PreferredColumnWidth); + Assert.Equal(1, callCount); + + // Set different. + style.PreferredColumnWidth = 2; + Assert.Equal(2, style.PreferredColumnWidth); + Assert.Equal(2, callCount); + + // Remove handler. + style.PreferredColumnWidthChanged -= handler; + style.PreferredColumnWidth = 1; + Assert.Equal(1, style.PreferredColumnWidth); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_PreferredColumnWidth_SetNegative_ThrowsArgumentOutOfRangeException() + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.PreferredColumnWidth = -1); + } + + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(75)] + [InlineData(76)] + public void DataGridTableStyle_PreferredRowHeight_Set_GetReturnsExpected(int value) + { + var style = new DataGridTableStyle + { + PreferredRowHeight = value + }; + Assert.Equal(value, style.PreferredRowHeight); + + // Set same. + style.PreferredRowHeight = value; + Assert.Equal(value, style.PreferredRowHeight); + } + + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(75)] + [InlineData(76)] + public void DataGridTableStyle_PreferredRowHeight_SetWithDataGrid_DoesNotCallInvalidate(int value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.PreferredRowHeight = value; + Assert.Equal(value, style.PreferredRowHeight); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.PreferredRowHeight = value; + Assert.Equal(value, style.PreferredRowHeight); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_PreferredRowHeight_SetWithHandler_CallsPreferredRowHeightChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.PreferredRowHeightChanged += handler; + + // Set different. + style.PreferredRowHeight = 1; + Assert.Equal(1, style.PreferredRowHeight); + Assert.Equal(1, callCount); + + // Set same. + style.PreferredRowHeight = 1; + Assert.Equal(1, style.PreferredRowHeight); + Assert.Equal(1, callCount); + + // Set different. + style.PreferredRowHeight = 2; + Assert.Equal(2, style.PreferredRowHeight); + Assert.Equal(2, callCount); + + // Remove handler. + style.PreferredRowHeightChanged -= handler; + style.PreferredRowHeight = 1; + Assert.Equal(1, style.PreferredRowHeight); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_PreferredRowHeight_SetNegative_ThrowsArgumentOutOfRangeException() + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.PreferredRowHeight = -1); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_ReadOnly_Set_GetReturnsExpected(bool value) + { + var style = new DataGridTableStyle + { + ReadOnly = value + }; + Assert.Equal(value, style.ReadOnly); + + // Set same. + style.ReadOnly = value; + Assert.Equal(value, style.ReadOnly); + + // Set different + style.ReadOnly = !value; + Assert.Equal(!value, style.ReadOnly); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_ReadOnly_SetWithDataGrid_DoesNotCallInvalidate(bool value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.ReadOnly = value; + Assert.Equal(value, style.ReadOnly); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.ReadOnly = value; + Assert.Equal(value, style.ReadOnly); + Assert.Equal(0, invalidatedCallCount); + + // Set different + style.ReadOnly = !value; + Assert.Equal(!value, style.ReadOnly); + Assert.Equal(0, invalidatedCallCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_ReadOnly_SetDefaultTableStyle_GetReturnsExpected(bool value) + { + var style = new DataGridTableStyle(isDefaultTableStyle: true) + { + ReadOnly = value + }; + Assert.Equal(value, style.ReadOnly); + + // Set same. + style.ReadOnly = value; + Assert.Equal(value, style.ReadOnly); + + // Set different + style.ReadOnly = !value; + Assert.Equal(!value, style.ReadOnly); + } + + [Fact] + public void DataGridTableStyle_ReadOnly_SetWithHandler_CallsReadOnlyChanged() + { + var style = new DataGridTableStyle + { + ReadOnly = true + }; + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.ReadOnlyChanged += handler; + + // Set different. + style.ReadOnly = false; + Assert.False(style.ReadOnly); + Assert.Equal(1, callCount); + + // Set same. + style.ReadOnly = false; + Assert.False(style.ReadOnly); + Assert.Equal(1, callCount); + + // Set different. + style.ReadOnly = true; + Assert.True(style.ReadOnly); + Assert.Equal(2, callCount); + + // Remove handler. + style.ReadOnlyChanged -= handler; + style.ReadOnly = false; + Assert.False(style.ReadOnly); + Assert.Equal(2, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_RowHeadersVisible_Set_GetReturnsExpected(bool value) + { + var style = new DataGridTableStyle + { + RowHeadersVisible = value + }; + Assert.Equal(value, style.RowHeadersVisible); + + // Set same. + style.RowHeadersVisible = value; + Assert.Equal(value, style.RowHeadersVisible); + + // Set different + style.RowHeadersVisible = !value; + Assert.Equal(!value, style.RowHeadersVisible); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_RowHeadersVisible_SetWithDataGrid_DoesNotCallInvalidate(bool value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.RowHeadersVisible = value; + Assert.Equal(value, style.RowHeadersVisible); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.RowHeadersVisible = value; + Assert.Equal(value, style.RowHeadersVisible); + Assert.Equal(0, invalidatedCallCount); + + // Set different + style.RowHeadersVisible = !value; + Assert.Equal(!value, style.RowHeadersVisible); + Assert.Equal(0, invalidatedCallCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_RowHeadersVisible_SetDefaultTableStyle_GetReturnsExpected(bool value) + { + var style = new DataGridTableStyle(isDefaultTableStyle: true) + { + RowHeadersVisible = value + }; + Assert.Equal(value, style.RowHeadersVisible); + + // Set same. + style.RowHeadersVisible = value; + Assert.Equal(value, style.RowHeadersVisible); + + // Set different + style.RowHeadersVisible = !value; + Assert.Equal(!value, style.RowHeadersVisible); + } + + [Fact] + public void DataGridTableStyle_RowHeadersVisible_SetWithHandler_CallsRowHeadersVisibleChanged() + { + var style = new DataGridTableStyle + { + RowHeadersVisible = true + }; + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.RowHeadersVisibleChanged += handler; + + // Set different. + style.RowHeadersVisible = false; + Assert.False(style.RowHeadersVisible); + Assert.Equal(1, callCount); + + // Set same. + style.RowHeadersVisible = false; + Assert.False(style.RowHeadersVisible); + Assert.Equal(1, callCount); + + // Set different. + style.RowHeadersVisible = true; + Assert.True(style.RowHeadersVisible); + Assert.Equal(2, callCount); + + // Remove handler. + style.RowHeadersVisibleChanged -= handler; + style.RowHeadersVisible = false; + Assert.False(style.RowHeadersVisible); + Assert.Equal(2, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetIntTheoryData))] + public void DataGridTableStyle_RowHeaderWidth_Set_GetReturnsExpected(int value) + { + var style = new DataGridTableStyle + { + RowHeaderWidth = value + }; + Assert.Equal(value, style.RowHeaderWidth); + + // Set same. + style.RowHeaderWidth = value; + Assert.Equal(value, style.RowHeaderWidth); + } + + [Theory] + [InlineData(-1, 0)] + [InlineData(0, 0)] + [InlineData(1, 1)] + [InlineData(35, 35)] + [InlineData(36, 36)] + public void DataGridTableStyle_RowHeaderWidth_SetWithDataGrid_DoesNotCallInvalidate(int value, int expected) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.RowHeaderWidth = value; + Assert.Equal(expected, style.RowHeaderWidth); + Assert.Equal(0, invalidatedCallCount); + + // Set same. + style.RowHeaderWidth = value; + Assert.Equal(expected, style.RowHeaderWidth); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_RowHeaderWidth_SetWithHandler_CallsRowHeaderWidthChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.RowHeaderWidthChanged += handler; + + // Set different. + style.RowHeaderWidth = 1; + Assert.Equal(1, style.RowHeaderWidth); + Assert.Equal(1, callCount); + + // Set same. + style.RowHeaderWidth = 1; + Assert.Equal(1, style.RowHeaderWidth); + Assert.Equal(1, callCount); + + // Set different. + style.RowHeaderWidth = 2; + Assert.Equal(2, style.RowHeaderWidth); + Assert.Equal(2, callCount); + + // Remove handler. + style.RowHeaderWidthChanged -= handler; + style.RowHeaderWidth = 1; + Assert.Equal(1, style.RowHeaderWidth); + Assert.Equal(2, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetColorTheoryData))] + public void DataGridTableStyle_SelectionBackColor_Set_GetReturnsExpected(Color value) + { + var style = new DataGridTableStyle + { + SelectionBackColor = value + }; + Assert.Equal(value, style.SelectionBackColor); + + // Set same. + style.SelectionBackColor = value; + Assert.Equal(value, style.SelectionBackColor); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetColorTheoryData))] + public void DataGridTableStyle_SelectionBackColor_SetWithDataGrid_CallsInvalidate(Color value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.SelectionBackColor = value; + Assert.Equal(value, style.SelectionBackColor); + Assert.Equal(1, invalidatedCallCount); + + // Set same. + style.SelectionBackColor = value; + Assert.Equal(value, style.SelectionBackColor); + Assert.Equal(1, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_SelectionBackColor_SetWithHandler_CallsSelectionBackColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.SelectionBackColorChanged += handler; + + // Set different. + style.SelectionBackColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionBackColor); + Assert.Equal(1, callCount); + + // Set same. + style.SelectionBackColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionBackColor); + Assert.Equal(1, callCount); + + // Set different. + style.SelectionBackColor = Color.Blue; + Assert.Equal(Color.Blue, style.SelectionBackColor); + Assert.Equal(2, callCount); + + // Remove handler. + style.SelectionBackColorChanged -= handler; + style.SelectionBackColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionBackColor); + Assert.Equal(2, callCount); + } + + [Theory] + [MemberData(nameof(InvalidColor_TestData))] + public void DataGridTableStyle_SelectionBackColor_SetInvalid_ThrowsArgumentException(Color value) + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.SelectionBackColor = value); + } + + public static IEnumerable SelectionForeColor_Set_TestData() + { + yield return new object[] { Color.FromArgb(254, 1, 2, 3) }; + yield return new object[] { Color.Red }; + } + + [Theory] + [MemberData(nameof(SelectionForeColor_Set_TestData))] + public void DataGridTableStyle_SelectionForeColor_Set_GetReturnsExpected(Color value) + { + var style = new DataGridTableStyle + { + SelectionForeColor = value + }; + Assert.Equal(value, style.SelectionForeColor); + + // Set same. + style.SelectionForeColor = value; + Assert.Equal(value, style.SelectionForeColor); + } + + [Theory] + [MemberData(nameof(SelectionForeColor_Set_TestData))] + public void DataGridTableStyle_SelectionForeColor_SetWithDataGrid_CallsInvalidate(Color value) + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + style.SelectionForeColor = value; + Assert.Equal(value, style.SelectionForeColor); + Assert.Equal(1, invalidatedCallCount); + + // Set same. + style.SelectionForeColor = value; + Assert.Equal(value, style.SelectionForeColor); + Assert.Equal(1, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_SelectionForeColor_SetWithHandler_CallsSelectionForeColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.SelectionForeColorChanged += handler; + + // Set different. + style.SelectionForeColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionForeColor); + Assert.Equal(1, callCount); + + // Set same. + style.SelectionForeColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionForeColor); + Assert.Equal(1, callCount); + + // Set different. + style.SelectionForeColor = Color.Blue; + Assert.Equal(Color.Blue, style.SelectionForeColor); + Assert.Equal(2, callCount); + + // Remove handler. + style.SelectionForeColorChanged -= handler; + style.SelectionForeColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionForeColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_SelectionForeColor_SetEmpty_ThrowsArgumentException() + { + var style = new DataGridTableStyle(); + Assert.Throws("value", () => style.SelectionForeColor = Color.Empty); + } + + public static IEnumerable BeginEdit_WithDataSource_TestData() + { + yield return new object[] { 0, true, true, 0, 1, 0, 0, 5 }; + yield return new object[] { 1, true, true, 1, 2, 1, 0, 5 }; + yield return new object[] { -1, true, true, 0, 1, 0, 0, 5 }; + yield return new object[] { 2, true, true, 1, 2, 1, 0, 5 }; + + yield return new object[] { 0, false, true, 0, 1, 0, 0, 2 }; + yield return new object[] { 1, false, true, 1, 2, 1, 1, 3 }; + yield return new object[] { -1, false, true, 0, 1, 0, 0, 2 }; + yield return new object[] { 2, false, true, 1, 2, 1, 1, 3 }; + } + + [Theory] + [MemberData(nameof(BeginEdit_WithDataSource_TestData))] + public void DataGridTableStyle_BeginEdit_InvokeWithDataSource_ReturnsExpected(int rowNumber, bool commitResult1, bool commitResult2, int expectedRowNumber, int expectedEditCallCount, int expectedCommitCallCount, int expectedAbortCallCount, int expectedCommitCallCount2) + { + var dataSource = new DataClass[] + { + new() { Value1 = "Value1_1", Value2 = "Value2_1" }, + new() { Value1 = "Value1_2", Value2 = "Value2_2" } + }; + var bindingContext = new BindingContext(); + CurrencyManager currencyManager = (CurrencyManager)bindingContext[dataSource, null]; + + var style = new DataGridTableStyle + { + MappingName = "DataClass[]" + }; + + var gridColumn1 = new SubDataGridColumnStyle + { + MappingName = "Value1" + }; + int editCallCount1 = 0; + gridColumn1.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount1++; + }; + int commitCallCount1 = 0; + gridColumn1.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount1++; + return commitResult1; + }; + int abortCallCount1 = 0; + gridColumn1.AbortAction = (rowNum) => + { + Assert.Equal(expectedRowNumber, rowNum); + abortCallCount1++; + }; + style.GridColumnStyles.Add(gridColumn1); + + var gridColumn2 = new SubDataGridColumnStyle + { + MappingName = "Value2" + }; + int editCallCount2 = 0; + gridColumn2.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount2++; + }; + int commitCallCount2 = 0; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount2++; + return commitResult2; + }; + int abortCallCount2 = 0; + gridColumn2.AbortAction = (rowNum) => + { + Assert.Equal(expectedRowNumber, rowNum); + abortCallCount2++; + }; + style.GridColumnStyles.Add(gridColumn2); + + var dataGrid = new SubDataGrid + { + BindingContext = bindingContext + }; + dataGrid.TableStyles.Add(style); + dataGrid.SetDataBinding(dataSource, null); + + // Simulate layout on the DataGrid. + using (var image = new Bitmap(10, 10)) + using (Graphics graphics = Graphics.FromImage(image)) + { + dataGrid.OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, 1, 2))); + } + + // Edit cell. + Assert.True(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.Equal(expectedAbortCallCount, abortCallCount1); + Assert.Equal(0, abortCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // Edit same. + Assert.True(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount + 1, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount + 1, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // Edit another. + Assert.True(style.BeginEdit(gridColumn2, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 1), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount + 1, editCallCount1); + Assert.Equal(2, editCallCount2); + Assert.Equal(expectedCommitCallCount2, commitCallCount1); + Assert.Equal(1, commitCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // Edit invalid. + Assert.False(style.BeginEdit(new SubDataGridColumnStyle(), rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 1), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount + 1, editCallCount1); + Assert.Equal(2, editCallCount2); + Assert.Equal(expectedCommitCallCount2, commitCallCount1); + Assert.Equal(1, commitCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // Edit null. + Assert.False(style.BeginEdit(null, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 1), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount + 1, editCallCount1); + Assert.Equal(2, editCallCount2); + Assert.Equal(expectedCommitCallCount2, commitCallCount1); + Assert.Equal(1, commitCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + } + + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(-1)] + [InlineData(2)] + public void DataGridTableStyle_BeginEdit_InvokeWithEmptyDataSource_ReturnsExpected(int rowNumber) + { + var dataSource = new DataClass[0]; + var bindingContext = new BindingContext(); + CurrencyManager currencyManager = (CurrencyManager)bindingContext[dataSource, null]; + + var style = new DataGridTableStyle + { + MappingName = "DataClass[]" + }; + + var gridColumn1 = new SubDataGridColumnStyle + { + MappingName = "Value1" + }; + int editCallCount1 = 0; + gridColumn1.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + editCallCount1++; + }; + int commitCallCount1 = 0; + gridColumn1.CommitAction = (dataSource, rowNum) => + { + commitCallCount1++; + return true; + }; + style.GridColumnStyles.Add(gridColumn1); + + var gridColumn2 = new SubDataGridColumnStyle + { + MappingName = "Value2" + }; + int editCallCount2 = 0; + gridColumn2.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + editCallCount2++; + }; + int commitCallCount2 = 0; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + commitCallCount2++; + return true; + }; + style.GridColumnStyles.Add(gridColumn2); + + var dataGrid = new SubDataGrid + { + BindingContext = bindingContext + }; + dataGrid.TableStyles.Add(style); + dataGrid.SetDataBinding(dataSource, null); + + // Simulate layout on the DataGrid. + using (var image = new Bitmap(10, 10)) + using (Graphics graphics = Graphics.FromImage(image)) + { + dataGrid.OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, 1, 2))); + } + + // Edit cell. + Assert.True(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(0, 0), dataGrid.CurrentCell); + Assert.Equal(0, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(0, commitCallCount1); + Assert.Equal(0, commitCallCount2); + + // Edit same. + Assert.True(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(0, 0), dataGrid.CurrentCell); + Assert.Equal(0, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(0, commitCallCount1); + Assert.Equal(0, commitCallCount2); + + // Edit another. + Assert.True(style.BeginEdit(gridColumn2, rowNumber)); + Assert.Equal(new DataGridCell(0, 0), dataGrid.CurrentCell); + Assert.Equal(0, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(0, commitCallCount1); + Assert.Equal(0, commitCallCount2); + + // Edit invalid. + Assert.False(style.BeginEdit(new SubDataGridColumnStyle(), rowNumber)); + Assert.Equal(new DataGridCell(0, 0), dataGrid.CurrentCell); + Assert.Equal(0, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(0, commitCallCount1); + Assert.Equal(0, commitCallCount2); + + // Edit null. + Assert.False(style.BeginEdit(null, rowNumber)); + Assert.Equal(new DataGridCell(0, 0), dataGrid.CurrentCell); + Assert.Equal(0, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(0, commitCallCount1); + Assert.Equal(0, commitCallCount2); + } + + [Theory] + [InlineData(0, 0, 1, 0)] + [InlineData(1, 1, 2, 1)] + [InlineData(-1, 0, 1, 0)] + [InlineData(2, 1, 2, 1)] + public void DataGridTableStyle_BeginEdit_InvokeWithDataSource_ResetsSelection(int rowNumber, int expectedRowNumber, int expectedEditCallCount, int expectedCommitCallCount) + { + var dataSource = new DataClass[] + { + new() { Value1 = "Value1_1", Value2 = "Value2_1" }, + new() { Value1 = "Value1_2", Value2 = "Value2_2" } + }; + var bindingContext = new BindingContext(); + CurrencyManager currencyManager = (CurrencyManager)bindingContext[dataSource, null]; + + var style = new DataGridTableStyle + { + MappingName = "DataClass[]" + }; + + var gridColumn1 = new SubDataGridColumnStyle + { + MappingName = "Value1" + }; + int editCallCount1 = 0; + gridColumn1.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount1++; + }; + int commitCallCount1 = 0; + gridColumn1.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount1++; + return true; + }; + style.GridColumnStyles.Add(gridColumn1); + + var gridColumn2 = new SubDataGridColumnStyle + { + MappingName = "Value2" + }; + int editCallCount2 = 0; + gridColumn2.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount2++; + }; + int commitCallCount2 = 0; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount2++; + return true; + }; + style.GridColumnStyles.Add(gridColumn2); + + var dataGrid = new SubDataGrid + { + BindingContext = bindingContext + }; + dataGrid.TableStyles.Add(style); + dataGrid.SetDataBinding(dataSource, null); + + // Simulate layout on the DataGrid. + using (var image = new Bitmap(10, 10)) + using (Graphics graphics = Graphics.FromImage(image)) + { + dataGrid.OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, 1, 2))); + } + + dataGrid.Select(0); + Assert.True(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // Edit cell. + Assert.True(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + } + + [Theory] + [InlineData(0, 0, 1, 0)] + [InlineData(1, 1, 2, 1)] + [InlineData(-1, 0, 1, 0)] + [InlineData(2, 1, 2, 1)] + public void DataGridTableStyle_BeginEdit_InvokeWithDataSourceEditing_ReturnsFalse(int rowNumber, int expectedRowNumber, int expectedEditCallCount, int expectedCommitCallCount) + { + var dataSource = new DataClass[] + { + new() { Value1 = "Value1_1", Value2 = "Value2_1" }, + new() { Value1 = "Value1_2", Value2 = "Value2_2" } + }; + var bindingContext = new BindingContext(); + CurrencyManager currencyManager = (CurrencyManager)bindingContext[dataSource, null]; + + var style = new DataGridTableStyle + { + MappingName = "DataClass[]" + }; + + var gridColumn1 = new SubDataGridColumnStyle + { + MappingName = "Value1" + }; + int editCallCount1 = 0; + gridColumn1.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount1++; + }; + int commitCallCount1 = 0; + gridColumn1.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount1++; + return true; + }; + style.GridColumnStyles.Add(gridColumn1); + + var gridColumn2 = new SubDataGridColumnStyle + { + MappingName = "Value2" + }; + int editCallCount2 = 0; + gridColumn2.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount2++; + }; + int commitCallCount2 = 0; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount2++; + return true; + }; + style.GridColumnStyles.Add(gridColumn2); + + var dataGrid = new SubDataGrid + { + BindingContext = bindingContext + }; + dataGrid.TableStyles.Add(style); + dataGrid.SetDataBinding(dataSource, null); + + // Simulate layout on the DataGrid. + using (var image = new Bitmap(10, 10)) + using (Graphics graphics = Graphics.FromImage(image)) + { + dataGrid.OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, 1, 2))); + } + + // Edit cell. + Assert.True(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // Actual edit. + dataGrid.ColumnStartedEditing(Rectangle.Empty); + Assert.False(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + } + + public static IEnumerable BeginEdit_WithoutDataSource_TestData() + { + yield return new object[] { null, null, -1, null }; + yield return new object[] { null, null, 0, null }; + yield return new object[] { null, null, 1, null }; + yield return new object[] { null, new SubDataGridColumnStyle(), -1, null }; + yield return new object[] { null, new SubDataGridColumnStyle(), 0, null }; + yield return new object[] { null, new SubDataGridColumnStyle(), 1, null }; + + yield return new object[] { new DataGrid(), null, -1, new DataGridCell(0, 0) }; + yield return new object[] { new DataGrid(), null, 0, new DataGridCell(0, 0) }; + yield return new object[] { new DataGrid(), null, 1, new DataGridCell(0, 0) }; + yield return new object[] { new DataGrid(), new SubDataGridColumnStyle(), -1, new DataGridCell(0, 0) }; + yield return new object[] { new DataGrid(), new SubDataGridColumnStyle(), 0, new DataGridCell(0, 0) }; + yield return new object[] { new DataGrid(), new SubDataGridColumnStyle(), 1, new DataGridCell(0, 0) }; + } + + [Theory] + [MemberData(nameof(BeginEdit_WithoutDataSource_TestData))] + public void DataGridTableStyle_BeginEdit_InvokeWithoutDataSource_ReturnsFalse(DataGrid dataGrid, DataGridColumnStyle gridColumn, int rowNumber, DataGridCell? expectedCurrentCell) + { + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + Assert.False(style.BeginEdit(gridColumn, rowNumber)); + Assert.Equal(expectedCurrentCell, dataGrid?.CurrentCell); + } + + [Fact] + public void DataGridTableStyle_CreateGridColumn_InvokePropertyDescriptorBoolProperty_ReturnsExpected() + { + PropertyDescriptor prop = TypeDescriptor.GetProperties(typeof(ClassWithProperties))[nameof(ClassWithProperties.BoolProperty)]; + var style = new SubDataGridTableStyle(); + DataGridBoolColumn columnStyle = Assert.IsType(style.CreateGridColumn(prop)); + Assert.Same(prop, columnStyle.PropertyDescriptor); + Assert.Empty(columnStyle.MappingName); + } + + [Theory] + [InlineData(nameof(ClassWithProperties.SByteProperty), "G")] + [InlineData(nameof(ClassWithProperties.ShortProperty), "G")] + [InlineData(nameof(ClassWithProperties.IntProperty), "G")] + [InlineData(nameof(ClassWithProperties.LongProperty), "G")] + [InlineData(nameof(ClassWithProperties.ByteProperty), "G")] + [InlineData(nameof(ClassWithProperties.UShortProperty), "G")] + [InlineData(nameof(ClassWithProperties.UIntProperty), "G")] + [InlineData(nameof(ClassWithProperties.ULongProperty), "G")] + [InlineData(nameof(ClassWithProperties.CharProperty), "")] + [InlineData(nameof(ClassWithProperties.StringProperty), "")] + [InlineData(nameof(ClassWithProperties.DateTimeProperty), "d")] + [InlineData(nameof(ClassWithProperties.DecimalProperty), "G")] + [InlineData(nameof(ClassWithProperties.DoubleProperty), "G")] + [InlineData(nameof(ClassWithProperties.FloatProperty), "G")] + [InlineData(nameof(ClassWithProperties.ObjectProperty), "")] + public void DataGridTableStyle_CreateGridColumn_InvokePropertyDescriptorTextBoxProperty_ReturnsExpected(string propertyName, string expectedFormat) + { + PropertyDescriptor prop = TypeDescriptor.GetProperties(typeof(ClassWithProperties))[propertyName]; + var style = new SubDataGridTableStyle(); + DataGridTextBoxColumn columnStyle = Assert.IsType(style.CreateGridColumn(prop)); + Assert.Same(prop, columnStyle.PropertyDescriptor); + Assert.Equal(expectedFormat, columnStyle.Format); + Assert.Empty(columnStyle.MappingName); + } + + [Theory] + [InlineData(true, nameof(ClassWithProperties.BoolProperty))] + [InlineData(false, "")] + public void DataGridTableStyle_CreateGridColumn_InvokePropertyDescriptorBoolBoolProperty_ReturnsExpected(bool isDefault, string expectedMappingName) + { + PropertyDescriptor prop = TypeDescriptor.GetProperties(typeof(ClassWithProperties))[nameof(ClassWithProperties.BoolProperty)]; + var style = new SubDataGridTableStyle(); + DataGridBoolColumn columnStyle = Assert.IsType(style.CreateGridColumn(prop, isDefault)); + Assert.Same(prop, columnStyle.PropertyDescriptor); + Assert.Equal(expectedMappingName, columnStyle.MappingName); + } + + public static IEnumerable CreateGridColumn_TextBoxProperty_TestData() + { + yield return new object[] { nameof(ClassWithProperties.SByteProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.ShortProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.IntProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.LongProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.ByteProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.UShortProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.UIntProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.ULongProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.CharProperty), false, "", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.StringProperty), false, "", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.DateTimeProperty), false, "d", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.DecimalProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.DoubleProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.FloatProperty), false, "G", string.Empty }; + yield return new object[] { nameof(ClassWithProperties.ObjectProperty), false, "", string.Empty }; + + yield return new object[] { nameof(ClassWithProperties.SByteProperty), true, "G", nameof(ClassWithProperties.SByteProperty) }; + yield return new object[] { nameof(ClassWithProperties.ShortProperty), true, "G", nameof(ClassWithProperties.ShortProperty) }; + yield return new object[] { nameof(ClassWithProperties.IntProperty), true, "G", nameof(ClassWithProperties.IntProperty) }; + yield return new object[] { nameof(ClassWithProperties.LongProperty), true, "G", nameof(ClassWithProperties.LongProperty) }; + yield return new object[] { nameof(ClassWithProperties.ByteProperty), true, "G", nameof(ClassWithProperties.ByteProperty) }; + yield return new object[] { nameof(ClassWithProperties.UShortProperty), true, "G", nameof(ClassWithProperties.UShortProperty) }; + yield return new object[] { nameof(ClassWithProperties.UIntProperty), true, "G", nameof(ClassWithProperties.UIntProperty) }; + yield return new object[] { nameof(ClassWithProperties.ULongProperty), true, "G", nameof(ClassWithProperties.ULongProperty) }; + yield return new object[] { nameof(ClassWithProperties.CharProperty), true, "", nameof(ClassWithProperties.CharProperty) }; + yield return new object[] { nameof(ClassWithProperties.StringProperty), true, "", nameof(ClassWithProperties.StringProperty) }; + yield return new object[] { nameof(ClassWithProperties.DateTimeProperty), true, "d", nameof(ClassWithProperties.DateTimeProperty) }; + yield return new object[] { nameof(ClassWithProperties.DecimalProperty), true, "G", nameof(ClassWithProperties.DecimalProperty) }; + yield return new object[] { nameof(ClassWithProperties.DoubleProperty), true, "G", nameof(ClassWithProperties.DoubleProperty) }; + yield return new object[] { nameof(ClassWithProperties.FloatProperty), true, "G", nameof(ClassWithProperties.FloatProperty) }; + yield return new object[] { nameof(ClassWithProperties.ObjectProperty), true, "", nameof(ClassWithProperties.ObjectProperty) }; + } + + [Theory] + [MemberData(nameof(CreateGridColumn_TextBoxProperty_TestData))] + public void DataGridTableStyle_CreateGridColumn_InvokePropertyDescriptorBoolTextBoxProperty_ReturnsExpected(string propertyName, bool isDefault, string expectedFormat, string expectedMappingName) + { + PropertyDescriptor prop = TypeDescriptor.GetProperties(typeof(ClassWithProperties))[propertyName]; + var style = new SubDataGridTableStyle(); + DataGridTextBoxColumn columnStyle = Assert.IsType(style.CreateGridColumn(prop, isDefault)); + Assert.Same(prop, columnStyle.PropertyDescriptor); + Assert.Equal(expectedFormat, columnStyle.Format); + Assert.Equal(expectedMappingName, columnStyle.MappingName); + } + + [Fact] + public void DataGridTableStyle_CreateGridColumn_NullProp_ThrowsArgumentNullException() + { + var style = new SubDataGridTableStyle(); + Assert.Throws("prop", () => style.CreateGridColumn(null)); + Assert.Throws("prop", () => style.CreateGridColumn(null, isDefault: true)); + Assert.Throws("prop", () => style.CreateGridColumn(null, isDefault: false)); + } + + [Fact] + public void DataGridTableStyle_Dispose_InvokeWithEmptyGridColumnStyles_Nop() + { + var style = new DataGridTableStyle(); + style.Dispose(); + style.Dispose(); + } + + [Fact] + public void DataGridTableStyle_Dispose_InvokeWithNullGridColumnStyles_Nop() + { + var style = new NullGridColumnStylesDataGridTableStyle(); + style.Dispose(); + style.Dispose(); + } + + [Fact] + public void DataGridTableStyle_Dispose_Invoke_CallsDisposeOnChildren() + { + var columnStyle = new SubDataGridColumnStyle(); + int disposeCallCount = 0; + columnStyle.DisposeAction = (disposing) => + { + Assert.True(disposing); + disposeCallCount++; + }; + var style = new DataGridTableStyle(); + style.GridColumnStyles.Add(columnStyle); + + style.Dispose(); + Assert.Equal(1, disposeCallCount); + Assert.Same(columnStyle, Assert.Single(style.GridColumnStyles)); + + // Call again. + style.Dispose(); + Assert.Equal(2, disposeCallCount); + Assert.Same(columnStyle, Assert.Single(style.GridColumnStyles)); + + columnStyle.DisposeAction = null; + } + + [Fact] + public void DataGridTableStyle_Dispose_InvokeWithHandler_CallsDisposed() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.Disposed += handler; + + // Call with handler. + style.Dispose(); + Assert.Equal(1, callCount); + + // Call again. + style.Dispose(); + Assert.Equal(2, callCount); + + // Remove handler. + style.Disposed -= handler; + style.Dispose(); + Assert.Equal(2, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_Dispose_InvokeBoolWithEmptyGridColumnStyles_Nop(bool disposing) + { + var style = new SubDataGridTableStyle(); + style.Dispose(disposing); + style.Dispose(disposing); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void DataGridTableStyle_Dispose_InvokeBoolWithNullGridColumnStyles_Nop(bool disposing) + { + var style = new NullGridColumnStylesDataGridTableStyle(); + style.Dispose(disposing); + style.Dispose(disposing); + } + + [Theory] + [InlineData(true, 1)] + [InlineData(false, 0)] + public void DataGridTableStyle_Dispose_InvokeBool_CallsDisposeOnChildren(bool disposing, int expectedCallCount) + { + var columnStyle = new SubDataGridColumnStyle(); + int disposeCallCount = 0; + columnStyle.DisposeAction += (disposing) => + { + Assert.True(disposing); + disposeCallCount++; + }; + var style = new SubDataGridTableStyle(); + style.GridColumnStyles.Add(columnStyle); + + style.Dispose(disposing); + Assert.Equal(expectedCallCount, disposeCallCount); + Assert.Same(columnStyle, Assert.Single(style.GridColumnStyles)); + + // Call again. + style.Dispose(disposing); + Assert.Equal(expectedCallCount * 2, disposeCallCount); + Assert.Same(columnStyle, Assert.Single(style.GridColumnStyles)); + + columnStyle.DisposeAction = null; + } + + [Theory] + [InlineData(true, 1)] + [InlineData(false, 0)] + public void DataGridTableStyle_Dispose_InvokeBoolWithHandler_CallsDisposed(bool disposing, int expectedCallCount) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.Disposed += handler; + + // Call with handler. + style.Dispose(disposing); + Assert.Equal(expectedCallCount, callCount); + + // Call again. + style.Dispose(disposing); + Assert.Equal(expectedCallCount * 2, callCount); + + // Remove handler. + style.Disposed -= handler; + style.Dispose(disposing); + Assert.Equal(expectedCallCount * 2, callCount); + } + + public static IEnumerable EndEdit_DataSource_TestData() + { + foreach (bool commitResult in new bool[] { true, false }) + { + yield return new object[] { 0, true, 0, 1, 0, 1, 0, commitResult, true }; + yield return new object[] { 1, true, 1, 2, 1, 1, 1, commitResult, true }; + yield return new object[] { -1, true, 0, 1, 0, 1, 0, commitResult, true }; + yield return new object[] { 2, true, 1, 2, 1, 1, 1, commitResult, true }; + yield return new object[] { 0, false, 0, 1, 0, 0, 1, commitResult, commitResult }; + yield return new object[] { 1, false, 1, 2, 1, 0, 2, commitResult, commitResult }; + yield return new object[] { -1, false, 0, 1, 0, 0, 1, commitResult, commitResult }; + yield return new object[] { 2, false, 1, 2, 1, 0, 2, commitResult, commitResult }; + } + } + + [Theory] + [MemberData(nameof(EndEdit_DataSource_TestData))] + public void DataGridTableStyle_EndEdit_InvokeWithDataSourceAbort_ReturnsExpected(int rowNumber, bool shouldAbort, int expectedRowNumber, int expectedEditCallCount, int expectedCommitCallCount, int expectedAbortCallCount, int expectedCommitCallCount2, bool commitResult, bool expected) + { + var dataSource = new DataClass[] + { + new() { Value1 = "Value1_1", Value2 = "Value2_1" }, + new() { Value1 = "Value1_2", Value2 = "Value2_2" } + }; + var bindingContext = new BindingContext(); + CurrencyManager currencyManager = (CurrencyManager)bindingContext[dataSource, null]; + + var style = new DataGridTableStyle + { + MappingName = "DataClass[]" + }; + + var gridColumn1 = new SubDataGridColumnStyle + { + MappingName = "Value1" + }; + int editCallCount1 = 0; + gridColumn1.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount1++; + }; + int commitCallCount1 = 0; + gridColumn1.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount1++; + return true; + }; + int abortCallCount1 = 0; + gridColumn1.AbortAction = (rowNum) => + { + Assert.Equal(expectedRowNumber, rowNum); + abortCallCount1++; + }; + style.GridColumnStyles.Add(gridColumn1); + + var gridColumn2 = new SubDataGridColumnStyle + { + MappingName = "Value2" + }; + int editCallCount2 = 0; + gridColumn2.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount2++; + }; + int commitCallCount2 = 0; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount2++; + return true; + }; + int abortCallCount2 = 0; + gridColumn2.AbortAction = (rowNum) => + { + Assert.Equal(expectedRowNumber, rowNum); + abortCallCount2++; + }; + style.GridColumnStyles.Add(gridColumn2); + + var dataGrid = new SubDataGrid + { + BindingContext = bindingContext + }; + dataGrid.TableStyles.Add(style); + dataGrid.SetDataBinding(dataSource, null); + + // Simulate layout on the DataGrid. + using (var image = new Bitmap(10, 10)) + using (Graphics graphics = Graphics.FromImage(image)) + { + dataGrid.OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, 1, 2))); + } + + // Edit cell. + Assert.True(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.Equal(0, abortCallCount1); + Assert.Equal(0, abortCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // End edit. + gridColumn1.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount1++; + return commitResult; + }; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount2++; + return commitResult; + }; + dataGrid.ColumnStartedEditing(Rectangle.Empty); + Assert.Equal(expected, style.EndEdit(gridColumn1, rowNumber, shouldAbort)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount2, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.Equal(expectedAbortCallCount, abortCallCount1); + Assert.Equal(0, abortCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // End edit again. + Assert.False(style.EndEdit(gridColumn1, rowNumber, shouldAbort)); + } + + [Theory] + [MemberData(nameof(EndEdit_DataSource_TestData))] + public void DataGridTableStyle_EndEdit_InvokeWithDataSourceDifferentColumn_ReturnsExpected(int rowNumber, bool shouldAbort, int expectedRowNumber, int expectedEditCallCount, int expectedCommitCallCount, int expectedAbortCallCount, int expectedCommitCallCount2, bool commitResult, bool expected) + { + var dataSource = new DataClass[] + { + new() { Value1 = "Value1_1", Value2 = "Value2_1" }, + new() { Value1 = "Value1_2", Value2 = "Value2_2" } + }; + var bindingContext = new BindingContext(); + CurrencyManager currencyManager = (CurrencyManager)bindingContext[dataSource, null]; + + var style = new DataGridTableStyle + { + MappingName = "DataClass[]" + }; + + var gridColumn1 = new SubDataGridColumnStyle + { + MappingName = "Value1" + }; + int editCallCount1 = 0; + gridColumn1.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount1++; + }; + int commitCallCount1 = 0; + gridColumn1.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount1++; + return true; + }; + int abortCallCount1 = 0; + gridColumn1.AbortAction = (rowNum) => + { + Assert.Equal(expectedRowNumber, rowNum); + abortCallCount1++; + }; + style.GridColumnStyles.Add(gridColumn1); + + var gridColumn2 = new SubDataGridColumnStyle + { + MappingName = "Value2" + }; + int editCallCount2 = 0; + gridColumn2.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount2++; + }; + int commitCallCount2 = 0; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount2++; + return true; + }; + int abortCallCount2 = 0; + gridColumn2.AbortAction = (rowNum) => + { + Assert.Equal(expectedRowNumber, rowNum); + abortCallCount2++; + }; + style.GridColumnStyles.Add(gridColumn2); + + var dataGrid = new SubDataGrid + { + BindingContext = bindingContext + }; + dataGrid.TableStyles.Add(style); + dataGrid.SetDataBinding(dataSource, null); + + // Simulate layout on the DataGrid. + using (var image = new Bitmap(10, 10)) + using (Graphics graphics = Graphics.FromImage(image)) + { + dataGrid.OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, 1, 2))); + } + + // Edit cell. + Assert.True(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.Equal(0, abortCallCount1); + Assert.Equal(0, abortCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // End edit. + gridColumn1.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount1++; + return commitResult; + }; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount2++; + return commitResult; + }; + dataGrid.ColumnStartedEditing(Rectangle.Empty); + Assert.Equal(expected, style.EndEdit(gridColumn2, rowNumber, shouldAbort)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount2, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.Equal(expectedAbortCallCount, abortCallCount1); + Assert.Equal(0, abortCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // End edit again. + Assert.False(style.EndEdit(gridColumn2, rowNumber, shouldAbort)); + } + + public static IEnumerable EndEdit_DataSourceInvalidColumn_TestData() + { + foreach (object[] testData in EndEdit_DataSource_TestData()) + { + yield return testData.Prepend(null).ToArray(); + yield return testData.Prepend(new SubDataGridColumnStyle()).ToArray(); + } + } + + [Theory] + [MemberData(nameof(EndEdit_DataSourceInvalidColumn_TestData))] + public void DataGridTableStyle_EndEdit_InvokeWithDataSourceInvalidColumn_ReturnsExpected(DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort, int expectedRowNumber, int expectedEditCallCount, int expectedCommitCallCount, int expectedAbortCallCount, int expectedCommitCallCount2, bool commitResult, bool expected) + { + var dataSource = new DataClass[] + { + new() { Value1 = "Value1_1", Value2 = "Value2_1" }, + new() { Value1 = "Value1_2", Value2 = "Value2_2" } + }; + var bindingContext = new BindingContext(); + CurrencyManager currencyManager = (CurrencyManager)bindingContext[dataSource, null]; + + var style = new DataGridTableStyle + { + MappingName = "DataClass[]" + }; + + var gridColumn1 = new SubDataGridColumnStyle + { + MappingName = "Value1" + }; + int editCallCount1 = 0; + gridColumn1.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount1++; + }; + int commitCallCount1 = 0; + gridColumn1.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount1++; + return true; + }; + int abortCallCount1 = 0; + gridColumn1.AbortAction = (rowNum) => + { + Assert.Equal(expectedRowNumber, rowNum); + abortCallCount1++; + }; + style.GridColumnStyles.Add(gridColumn1); + + var gridColumn2 = new SubDataGridColumnStyle + { + MappingName = "Value2" + }; + int editCallCount2 = 0; + gridColumn2.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + Assert.Same(currencyManager, source); + Assert.Equal(expectedRowNumber, rowNum); + Assert.NotEqual(Rectangle.Empty, bounds); + Assert.False(readOnly); + Assert.Null(displayText); + Assert.True(cellIsVisible); + editCallCount2++; + }; + int commitCallCount2 = 0; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount2++; + return true; + }; + int abortCallCount2 = 0; + gridColumn2.AbortAction = (rowNum) => + { + Assert.Equal(expectedRowNumber, rowNum); + abortCallCount2++; + }; + style.GridColumnStyles.Add(gridColumn2); + + var dataGrid = new SubDataGrid + { + BindingContext = bindingContext + }; + dataGrid.TableStyles.Add(style); + dataGrid.SetDataBinding(dataSource, null); + + // Simulate layout on the DataGrid. + using (var image = new Bitmap(10, 10)) + using (Graphics graphics = Graphics.FromImage(image)) + { + dataGrid.OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, 1, 2))); + } + + // Edit cell. + Assert.True(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.Equal(0, abortCallCount1); + Assert.Equal(0, abortCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // End edit. + gridColumn1.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount1++; + return commitResult; + }; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + Assert.Same(currencyManager, dataSource); + Assert.Equal(expectedRowNumber, rowNum); + commitCallCount2++; + return commitResult; + }; + dataGrid.ColumnStartedEditing(Rectangle.Empty); + Assert.Equal(expected, style.EndEdit(gridColumn, rowNumber, shouldAbort)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount2, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.Equal(expectedAbortCallCount, abortCallCount1); + Assert.Equal(0, abortCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // End edit again. + Assert.False(style.EndEdit(gridColumn, rowNumber, shouldAbort)); + } + + [Theory] + [InlineData(0, true, 0, 1, 0)] + [InlineData(1, true, 1, 2, 1)] + [InlineData(-1, true, 0, 1, 0)] + [InlineData(2, true, 1, 2, 1)] + [InlineData(0, false, 0, 1, 0)] + [InlineData(1, false, 1, 2, 1)] + [InlineData(-1, false, 0, 1, 0)] + [InlineData(2, false, 1, 2, 1)] + public void DataGridTableStyle_EndEdit_InvokeWithDataSourceNotEditing_ReturnsFalse(int rowNumber, bool shouldAbort, int expectedRowNumber, int expectedEditCallCount, int expectedCommitCallCount) + { + var dataSource = new DataClass[] + { + new() { Value1 = "Value1_1", Value2 = "Value2_1" }, + new() { Value1 = "Value1_2", Value2 = "Value2_2" } + }; + var bindingContext = new BindingContext(); + CurrencyManager currencyManager = (CurrencyManager)bindingContext[dataSource, null]; + + var style = new DataGridTableStyle + { + MappingName = "DataClass[]" + }; + + var gridColumn1 = new SubDataGridColumnStyle + { + MappingName = "Value1" + }; + int editCallCount1 = 0; + gridColumn1.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + editCallCount1++; + }; + int commitCallCount1 = 0; + gridColumn1.CommitAction = (dataSource, rowNum) => + { + commitCallCount1++; + return true; + }; + style.GridColumnStyles.Add(gridColumn1); + + var gridColumn2 = new SubDataGridColumnStyle + { + MappingName = "Value2" + }; + int editCallCount2 = 0; + gridColumn2.EditAction = (source, rowNum, bounds, readOnly, displayText, cellIsVisible) => + { + editCallCount2++; + }; + int commitCallCount2 = 0; + gridColumn2.CommitAction = (dataSource, rowNum) => + { + commitCallCount2++; + return true; + }; + style.GridColumnStyles.Add(gridColumn2); + + var dataGrid = new SubDataGrid + { + BindingContext = bindingContext + }; + dataGrid.TableStyles.Add(style); + dataGrid.SetDataBinding(dataSource, null); + + // Simulate layout on the DataGrid. + using (var image = new Bitmap(10, 10)) + using (Graphics graphics = Graphics.FromImage(image)) + { + dataGrid.OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, 1, 2))); + } + + // Edit cell. + Assert.True(style.BeginEdit(gridColumn1, rowNumber)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + + // End edit. + Assert.False(style.EndEdit(gridColumn1, rowNumber, shouldAbort)); + Assert.Equal(new DataGridCell(expectedRowNumber, 0), dataGrid.CurrentCell); + Assert.Equal(expectedEditCallCount, editCallCount1); + Assert.Equal(0, editCallCount2); + Assert.Equal(expectedCommitCallCount, commitCallCount1); + Assert.Equal(0, commitCallCount2); + Assert.False(dataGrid.IsSelected(0)); + Assert.False(dataGrid.IsSelected(1)); + } + + public static IEnumerable EndEdit_TestData() + { + foreach (bool shouldAbort in new bool[] { true, false }) + { + yield return new object[] { null, null, -1, shouldAbort, null }; + yield return new object[] { null, null, 0, shouldAbort, null }; + yield return new object[] { null, null, 1, shouldAbort, null }; + yield return new object[] { null, new SubDataGridColumnStyle(), -1, shouldAbort, null }; + yield return new object[] { null, new SubDataGridColumnStyle(), 0, shouldAbort, null }; + yield return new object[] { null, new SubDataGridColumnStyle(), 1, shouldAbort, null }; + + yield return new object[] { new DataGrid(), null, -1, shouldAbort, new DataGridCell(0, 0) }; + yield return new object[] { new DataGrid(), null, 0, shouldAbort, new DataGridCell(0, 0) }; + yield return new object[] { new DataGrid(), null, 1, shouldAbort, new DataGridCell(0, 0) }; + yield return new object[] { new DataGrid(), new SubDataGridColumnStyle(), -1, shouldAbort, new DataGridCell(0, 0) }; + yield return new object[] { new DataGrid(), new SubDataGridColumnStyle(), 0, shouldAbort, new DataGridCell(0, 0) }; + yield return new object[] { new DataGrid(), new SubDataGridColumnStyle(), 1, shouldAbort, new DataGridCell(0, 0) }; + } + } + + [Theory] + [MemberData(nameof(EndEdit_TestData))] + public void DataGridTableStyle_EndEdit_InvokeWithoutDataSource_ReturnsFalse(DataGrid dataGrid, DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort, DataGridCell? expectedCurrentCell) + { + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + Assert.False(style.EndEdit(gridColumn, rowNumber, shouldAbort)); + Assert.Equal(expectedCurrentCell, dataGrid?.CurrentCell); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnAllowSortingChanged_Invoke_CallsAllowSortingChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.AllowSortingChanged += handler; + style.OnAllowSortingChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.AllowSortingChanged -= handler; + style.OnAllowSortingChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnAlternatingBackColorChanged_Invoke_CallsAlternatingBackColorChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.AlternatingBackColorChanged += handler; + style.OnAlternatingBackColorChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.AlternatingBackColorChanged -= handler; + style.OnAlternatingBackColorChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnBackColorChanged_Invoke_CallsBackColorChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.BackColorChanged += handler; + style.OnBackColorChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.BackColorChanged -= handler; + style.OnBackColorChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnColumnHeadersVisibleChanged_Invoke_CallsColumnHeadersVisibleChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.ColumnHeadersVisibleChanged += handler; + style.OnColumnHeadersVisibleChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.ColumnHeadersVisibleChanged -= handler; + style.OnColumnHeadersVisibleChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnForeColorChanged_Invoke_CallsForeColorChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.ForeColorChanged += handler; + style.OnForeColorChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.ForeColorChanged -= handler; + style.OnForeColorChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnGridLineColorChanged_Invoke_CallsGridLineColorChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.GridLineColorChanged += handler; + style.OnGridLineColorChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.GridLineColorChanged -= handler; + style.OnGridLineColorChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnGridLineStyleChanged_Invoke_CallsGridLineStyleChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.GridLineStyleChanged += handler; + style.OnGridLineStyleChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.GridLineStyleChanged -= handler; + style.OnGridLineStyleChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnHeaderBackColorChanged_Invoke_CallsHeaderBackColorChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.HeaderBackColorChanged += handler; + style.OnHeaderBackColorChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.HeaderBackColorChanged -= handler; + style.OnHeaderBackColorChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnHeaderFontChanged_Invoke_CallsHeaderFontChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.HeaderFontChanged += handler; + style.OnHeaderFontChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.HeaderFontChanged -= handler; + style.OnHeaderFontChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnHeaderForeColorChanged_Invoke_CallsHeaderForeColorChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.HeaderForeColorChanged += handler; + style.OnHeaderForeColorChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.HeaderForeColorChanged -= handler; + style.OnHeaderForeColorChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnLinkColorChanged_Invoke_CallsLineColorChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.LinkColorChanged += handler; + style.OnLinkColorChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.LinkColorChanged -= handler; + style.OnLinkColorChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnLinkHoverColorChanged_Invoke_CallsLinkHoverColorChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.LinkHoverColorChanged += handler; + style.OnLinkHoverColorChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.LinkHoverColorChanged -= handler; + style.OnLinkHoverColorChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnMappingNameChanged_Invoke_CallsMappingNameChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.MappingNameChanged += handler; + style.OnMappingNameChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.MappingNameChanged -= handler; + style.OnMappingNameChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnPreferredColumnWidthChanged_Invoke_CallsPreferredColumnWidthChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.PreferredColumnWidthChanged += handler; + style.OnPreferredColumnWidthChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.PreferredColumnWidthChanged -= handler; + style.OnPreferredColumnWidthChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnPreferredRowHeightChanged_Invoke_CallsPreferredRowHeightChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.PreferredRowHeightChanged += handler; + style.OnPreferredRowHeightChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.PreferredRowHeightChanged -= handler; + style.OnPreferredRowHeightChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnReadOnlyChanged_Invoke_CallsReadOnlyChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.ReadOnlyChanged += handler; + style.OnReadOnlyChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.ReadOnlyChanged -= handler; + style.OnReadOnlyChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnRowHeadersVisibleChanged_Invoke_CallsRowHeadersVisibleChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.RowHeadersVisibleChanged += handler; + style.OnRowHeadersVisibleChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.RowHeadersVisibleChanged -= handler; + style.OnRowHeadersVisibleChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnRowHeaderWidthChanged_Invoke_CallsRowHeaderWidthChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.RowHeaderWidthChanged += handler; + style.OnRowHeaderWidthChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.RowHeaderWidthChanged -= handler; + style.OnRowHeaderWidthChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnSelectionBackColorChanged_Invoke_CallsSelectionBackColorChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.SelectionBackColorChanged += handler; + style.OnSelectionBackColorChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.SelectionBackColorChanged -= handler; + style.OnSelectionBackColorChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEventArgsTheoryData))] + public void DataGridTableStyle_OnSelectionForeColorChanged_Invoke_CallsSelectionForeColorChanged(EventArgs eventArgs) + { + var style = new SubDataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(style, sender); + Assert.Same(eventArgs, e); + callCount++; + }; + + // Call with handler. + style.SelectionForeColorChanged += handler; + style.OnSelectionForeColorChanged(eventArgs); + Assert.Equal(1, callCount); + + // Remove handler. + style.SelectionForeColorChanged -= handler; + style.OnSelectionForeColorChanged(eventArgs); + Assert.Equal(1, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetAlternatingBackColor_Invoke_GetReturnsExpected() + { + var style = new DataGridTableStyle(); + + // Reset default. + style.ResetAlternatingBackColor(); + Assert.Equal(SystemColors.Window, style.AlternatingBackColor); + + // Reset custom. + style.AlternatingBackColor = Color.Red; + Assert.Equal(Color.Red, style.AlternatingBackColor); + style.ResetAlternatingBackColor(); + Assert.Equal(SystemColors.Window, style.AlternatingBackColor); + } + + [Fact] + public void DataGridTableStyle_ResetAlternatingBackColor_InvokeWithDataGrid_CallsInvalidate() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + style.ResetAlternatingBackColor(); + Assert.Equal(SystemColors.Window, style.AlternatingBackColor); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.AlternatingBackColor = Color.Red; + Assert.Equal(Color.Red, style.AlternatingBackColor); + Assert.Equal(1, invalidatedCallCount); + style.ResetAlternatingBackColor(); + Assert.Equal(SystemColors.Window, style.AlternatingBackColor); + Assert.Equal(3, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetAlternatingBackColor_InvokeWithHandler_CallsAlternatingBackColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.AlternatingBackColorChanged += handler; + + // Reset default. + style.ResetAlternatingBackColor(); + Assert.Equal(SystemColors.Window, style.AlternatingBackColor); + Assert.Equal(0, callCount); + + // Reset custom. + style.AlternatingBackColor = Color.Red; + Assert.Equal(Color.Red, style.AlternatingBackColor); + Assert.Equal(1, callCount); + style.ResetAlternatingBackColor(); + Assert.Equal(SystemColors.Window, style.AlternatingBackColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetBackColor_Invoke_GetReturnsExpected() + { + var style = new DataGridTableStyle(); + + // Reset default. + style.ResetBackColor(); + Assert.Equal(SystemColors.Window, style.BackColor); + + // Reset custom. + style.BackColor = Color.Red; + Assert.Equal(Color.Red, style.BackColor); + style.ResetBackColor(); + Assert.Equal(SystemColors.Window, style.BackColor); + } + + [Fact] + public void DataGridTableStyle_ResetBackColor_InvokeWithDataGrid_CallsInvalidate() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + style.ResetBackColor(); + Assert.Equal(SystemColors.Window, style.BackColor); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.BackColor = Color.Red; + Assert.Equal(Color.Red, style.BackColor); + Assert.Equal(1, invalidatedCallCount); + style.ResetBackColor(); + Assert.Equal(SystemColors.Window, style.BackColor); + Assert.Equal(2, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetBackColor_InvokeWithHandler_CallsBackColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.BackColorChanged += handler; + + // Reset default. + style.ResetBackColor(); + Assert.Equal(SystemColors.Window, style.BackColor); + Assert.Equal(0, callCount); + + // Reset custom. + style.BackColor = Color.Red; + Assert.Equal(Color.Red, style.BackColor); + Assert.Equal(1, callCount); + style.ResetBackColor(); + Assert.Equal(SystemColors.Window, style.BackColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetForeColor_Invoke_GetReturnsExpected() + { + var style = new DataGridTableStyle(); + + // Reset default. + style.ResetForeColor(); + Assert.Equal(SystemColors.WindowText, style.ForeColor); + + // Reset custom. + style.ForeColor = Color.Red; + Assert.Equal(Color.Red, style.ForeColor); + style.ResetForeColor(); + Assert.Equal(SystemColors.WindowText, style.ForeColor); + } + + [Fact] + public void DataGridTableStyle_ResetForeColor_InvokeWithDataGrid_CallsInvalidate() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + style.ResetForeColor(); + Assert.Equal(SystemColors.WindowText, style.ForeColor); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.ForeColor = Color.Red; + Assert.Equal(Color.Red, style.ForeColor); + Assert.Equal(1, invalidatedCallCount); + style.ResetForeColor(); + Assert.Equal(SystemColors.WindowText, style.ForeColor); + Assert.Equal(2, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetForeColor_InvokeWithHandler_CallsForeColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.ForeColorChanged += handler; + + // Reset default. + style.ResetForeColor(); + Assert.Equal(SystemColors.WindowText, style.ForeColor); + Assert.Equal(0, callCount); + + // Reset custom. + style.ForeColor = Color.Red; + Assert.Equal(Color.Red, style.ForeColor); + Assert.Equal(1, callCount); + style.ResetForeColor(); + Assert.Equal(SystemColors.WindowText, style.ForeColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetHeaderBackColor_Invoke_GetReturnsExpected() + { + var style = new DataGridTableStyle(); + + // Reset default. + style.ResetHeaderBackColor(); + Assert.Equal(SystemColors.Control, style.HeaderBackColor); + + // Reset custom. + style.HeaderBackColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderBackColor); + style.ResetHeaderBackColor(); + Assert.Equal(SystemColors.Control, style.HeaderBackColor); + } + + [Fact] + public void DataGridTableStyle_ResetHeaderBackColor_InvokeWithDataGrid_DoesNotCallInvalidate() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + style.ResetHeaderBackColor(); + Assert.Equal(SystemColors.Control, style.HeaderBackColor); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.HeaderBackColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderBackColor); + Assert.Equal(0, invalidatedCallCount); + style.ResetHeaderBackColor(); + Assert.Equal(SystemColors.Control, style.HeaderBackColor); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetHeaderBackColor_InvokeWithHandler_CallsHeaderBackColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.HeaderBackColorChanged += handler; + + // Reset default. + style.ResetHeaderBackColor(); + Assert.Equal(SystemColors.Control, style.HeaderBackColor); + Assert.Equal(0, callCount); + + // Reset custom. + style.HeaderBackColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderBackColor); + Assert.Equal(1, callCount); + style.ResetHeaderBackColor(); + Assert.Equal(SystemColors.Control, style.HeaderBackColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetHeaderFont_Invoke_GetReturnsExpected() + { + var style = new DataGridTableStyle(); + var font = new Font(SystemFonts.MessageBoxFont.FontFamily, 10); + + // Reset default. + style.ResetHeaderFont(); + Assert.Equal(Control.DefaultFont, style.HeaderFont); + + // Reset custom. + style.HeaderFont = font; + Assert.Same(font, style.HeaderFont); + style.ResetHeaderFont(); + Assert.Equal(Control.DefaultFont, style.HeaderFont); + } + + [Fact] + public void DataGridTableStyle_ResetHeaderFont_InvokeWithDataGrid_DoesNotCallInvalidate() + { + var font1 = new Font(SystemFonts.MessageBoxFont.FontFamily, 10); + var font2 = new Font(SystemFonts.MessageBoxFont.FontFamily, 11); + var dataGrid = new DataGrid + { + Font = font1 + }; + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + style.ResetHeaderFont(); + Assert.Same(font1, style.HeaderFont); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.HeaderFont = font2; + Assert.Same(font2, style.HeaderFont); + Assert.Equal(0, invalidatedCallCount); + style.ResetHeaderFont(); + Assert.Same(font1, style.HeaderFont); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetHeaderFont_InvokeWithHandler_CallsHeaderFontChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.HeaderFontChanged += handler; + var font = new Font(SystemFonts.MessageBoxFont.FontFamily, 10); + + // Reset default. + style.ResetHeaderFont(); + Assert.Equal(Control.DefaultFont, style.HeaderFont); + Assert.Equal(0, callCount); + + // Reset custom. + style.HeaderFont = font; + Assert.Same(font, style.HeaderFont); + Assert.Equal(1, callCount); + style.ResetHeaderFont(); + Assert.Equal(Control.DefaultFont, style.HeaderFont); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetHeaderForeColor_Invoke_GetReturnsExpected() + { + var style = new DataGridTableStyle(); + + // Reset default. + style.ResetHeaderForeColor(); + Assert.Equal(SystemColors.ControlText, style.HeaderForeColor); + + // Reset custom. + style.HeaderForeColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderForeColor); + style.ResetHeaderForeColor(); + Assert.Equal(SystemColors.ControlText, style.HeaderForeColor); + } + + [Fact] + public void DataGridTableStyle_ResetHeaderForeColor_InvokeWithDataGrid_DoesNotCallInvalidate() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + style.ResetHeaderForeColor(); + Assert.Equal(SystemColors.ControlText, style.HeaderForeColor); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.HeaderForeColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderForeColor); + Assert.Equal(0, invalidatedCallCount); + style.ResetHeaderForeColor(); + Assert.Equal(SystemColors.ControlText, style.HeaderForeColor); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetHeaderForeColor_InvokeWithHandler_CallsHeaderForeColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.HeaderForeColorChanged += handler; + + // Reset default. + style.ResetHeaderForeColor(); + Assert.Equal(SystemColors.ControlText, style.HeaderForeColor); + Assert.Equal(0, callCount); + + // Reset custom. + style.HeaderForeColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderForeColor); + Assert.Equal(1, callCount); + style.ResetHeaderForeColor(); + Assert.Equal(SystemColors.ControlText, style.HeaderForeColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetLinkColor_Invoke_GetReturnsExpected() + { + var style = new DataGridTableStyle(); + + // Reset default. + style.ResetLinkColor(); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + + // Reset custom. + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + style.ResetLinkColor(); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + } + + [Fact] + public void DataGridTableStyle_ResetLinkColor_InvokeWithDataGrid_DoesNotCallInvalidate() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + style.ResetLinkColor(); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + Assert.Equal(0, invalidatedCallCount); + style.ResetLinkColor(); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetLinkColor_InvokeWithHandler_CallsLinkColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.LinkColorChanged += handler; + + // Reset default. + style.ResetLinkColor(); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + Assert.Equal(0, callCount); + + // Reset custom. + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(1, callCount); + style.ResetLinkColor(); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetLinkHoverColor_Invoke_Nop() + { + var style = new DataGridTableStyle(); + + // Reset default. + style.ResetLinkHoverColor(); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + + // Reset custom. + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + style.ResetLinkHoverColor(); + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + } + + [Fact] + public void DataGridTableStyle_ResetLinkHoverColor_InvokeWithDataGrid_Nop() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + style.ResetLinkHoverColor(); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + Assert.Equal(0, invalidatedCallCount); + style.ResetLinkHoverColor(); + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetLinkHoverColor_InvokeWithHandler_DoesNotCallLinkColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.LinkColorChanged += handler; + + // Reset default. + style.ResetLinkHoverColor(); + Assert.Equal(SystemColors.HotTrack, style.LinkColor); + Assert.Equal(SystemColors.HotTrack, style.LinkHoverColor); + Assert.Equal(0, callCount); + + // Reset custom. + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + Assert.Equal(1, callCount); + style.ResetLinkHoverColor(); + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + Assert.Equal(1, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetPreferredRowHeight_Invoke_GetReturnsExpected() + { + var style = new DataGridTableStyle(); + PropertyDescriptor property = TypeDescriptor.GetProperties(typeof(DataGridTableStyle))[nameof(DataGridTableStyle.PreferredRowHeight)]; + + // Reset default. + Assert.False(property.CanResetValue(style)); + property.ResetValue(style); + Assert.Equal(Control.DefaultFont.Height + 3, style.PreferredRowHeight); + + // Reset custom. + style.PreferredRowHeight = 1; + Assert.Equal(1, style.PreferredRowHeight); + Assert.True(property.CanResetValue(style)); + property.ResetValue(style); + Assert.Equal(Control.DefaultFont.Height + 3, style.PreferredRowHeight); + } + + [Fact] + public void DataGridTableStyle_ResetPreferredRowHeight_InvokeWithDataGrid_DoesNotCallInvalidate() + { + var dataGrid = new DataGrid(); + PropertyDescriptor property = TypeDescriptor.GetProperties(typeof(DataGridTableStyle))[nameof(DataGridTableStyle.PreferredRowHeight)]; + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + Assert.False(property.CanResetValue(style)); + property.ResetValue(style); + Assert.Equal(Control.DefaultFont.Height + 3, style.PreferredRowHeight); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.PreferredRowHeight = 1; + Assert.Equal(1, style.PreferredRowHeight); + Assert.Equal(0, invalidatedCallCount); + Assert.True(property.CanResetValue(style)); + property.ResetValue(style); + Assert.Equal(Control.DefaultFont.Height + 3, style.PreferredRowHeight); + Assert.Equal(0, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetPreferredRowHeight_InvokeWithHandler_CallsPreferredRowHeightChanged() + { + var style = new DataGridTableStyle(); + PropertyDescriptor property = TypeDescriptor.GetProperties(typeof(DataGridTableStyle))[nameof(DataGridTableStyle.PreferredRowHeight)]; + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.PreferredRowHeightChanged += handler; + + // Reset default. + Assert.False(property.CanResetValue(style)); + property.ResetValue(style); + Assert.Equal(Control.DefaultFont.Height + 3, style.PreferredRowHeight); + Assert.Equal(0, callCount); + + // Reset custom. + style.PreferredRowHeight = 1; + Assert.Equal(1, style.PreferredRowHeight); + Assert.Equal(1, callCount); + Assert.True(property.CanResetValue(style)); + property.ResetValue(style); + Assert.Equal(Control.DefaultFont.Height + 3, style.PreferredRowHeight); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetSelectionBackColor_Invoke_GetReturnsExpected() + { + var style = new DataGridTableStyle(); + + // Reset default. + style.ResetSelectionBackColor(); + Assert.Equal(SystemColors.ActiveCaption, style.SelectionBackColor); + + // Reset custom. + style.SelectionBackColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionBackColor); + style.ResetSelectionBackColor(); + Assert.Equal(SystemColors.ActiveCaption, style.SelectionBackColor); + } + + [Fact] + public void DataGridTableStyle_ResetSelectionBackColor_InvokeWithDataGrid_CallsInvalidate() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + style.ResetSelectionBackColor(); + Assert.Equal(SystemColors.ActiveCaption, style.SelectionBackColor); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.SelectionBackColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionBackColor); + Assert.Equal(1, invalidatedCallCount); + style.ResetSelectionBackColor(); + Assert.Equal(SystemColors.ActiveCaption, style.SelectionBackColor); + Assert.Equal(2, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetSelectionBackColor_InvokeWithHandler_CallsSelectionBackColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.SelectionBackColorChanged += handler; + + // Reset default. + style.ResetSelectionBackColor(); + Assert.Equal(SystemColors.ActiveCaption, style.SelectionBackColor); + Assert.Equal(0, callCount); + + // Reset custom. + style.SelectionBackColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionBackColor); + Assert.Equal(1, callCount); + style.ResetSelectionBackColor(); + Assert.Equal(SystemColors.ActiveCaption, style.SelectionBackColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ResetSelectionForeColor_Invoke_GetReturnsExpected() + { + var style = new DataGridTableStyle(); + + // Reset default. + style.ResetSelectionForeColor(); + Assert.Equal(SystemColors.ActiveCaptionText, style.SelectionForeColor); + + // Reset custom. + style.SelectionForeColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionForeColor); + style.ResetSelectionForeColor(); + Assert.Equal(SystemColors.ActiveCaptionText, style.SelectionForeColor); + } + + [Fact] + public void DataGridTableStyle_ResetSelectionForeColor_InvokeWithDataGrid_CallsInvalidate() + { + var dataGrid = new DataGrid(); + var style = new DataGridTableStyle + { + DataGrid = dataGrid + }; + int invalidatedCallCount = 0; + dataGrid.Invalidated += (sender, e) => invalidatedCallCount++; + Assert.NotEqual(IntPtr.Zero, dataGrid.Handle); + + // Reset default. + style.ResetSelectionForeColor(); + Assert.Equal(SystemColors.ActiveCaptionText, style.SelectionForeColor); + Assert.Equal(0, invalidatedCallCount); + + // Reset custom. + style.SelectionForeColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionForeColor); + Assert.Equal(1, invalidatedCallCount); + style.ResetSelectionForeColor(); + Assert.Equal(SystemColors.ActiveCaptionText, style.SelectionForeColor); + Assert.Equal(2, invalidatedCallCount); + } + + [Fact] + public void DataGridTableStyle_ResetSelectionForeColor_InvokeWithHandler_CallsSelectionForeColorChanged() + { + var style = new DataGridTableStyle(); + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Same(sender, sender); + Assert.Same(EventArgs.Empty, e); + callCount++; + }; + style.SelectionForeColorChanged += handler; + + // Reset default. + style.ResetSelectionForeColor(); + Assert.Equal(SystemColors.ActiveCaptionText, style.SelectionForeColor); + Assert.Equal(0, callCount); + + // Reset custom. + style.SelectionForeColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionForeColor); + Assert.Equal(1, callCount); + style.ResetSelectionForeColor(); + Assert.Equal(SystemColors.ActiveCaptionText, style.SelectionForeColor); + Assert.Equal(2, callCount); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeAlternatingBackColor_Invoke_ReturnsExpected() + { + var style = new SubDataGridTableStyle(); + Assert.False(style.ShouldSerializeAlternatingBackColor()); + + style.AlternatingBackColor = Color.Red; + Assert.Equal(Color.Red, style.AlternatingBackColor); + Assert.True(style.ShouldSerializeAlternatingBackColor()); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeBackColor_Invoke_ReturnsExpected() + { + var style = new SubDataGridTableStyle(); + Assert.False(style.ShouldSerializeBackColor()); + + style.BackColor = Color.Red; + Assert.Equal(Color.Red, style.BackColor); + Assert.True(style.ShouldSerializeBackColor()); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeForeColor_Invoke_ReturnsExpected() + { + var style = new SubDataGridTableStyle(); + Assert.False(style.ShouldSerializeForeColor()); + + style.ForeColor = Color.Red; + Assert.Equal(Color.Red, style.ForeColor); + Assert.True(style.ShouldSerializeForeColor()); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeGridLineColor_Invoke_ReturnsExpected() + { + var style = new SubDataGridTableStyle(); + Assert.False(style.ShouldSerializeGridLineColor()); + + style.GridLineColor = Color.Red; + Assert.Equal(Color.Red, style.GridLineColor); + Assert.True(style.ShouldSerializeGridLineColor()); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeHeaderBackColor_Invoke_ReturnsExpected() + { + var style = new SubDataGridTableStyle(); + Assert.False(style.ShouldSerializeHeaderBackColor()); + + style.HeaderBackColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderBackColor); + Assert.True(style.ShouldSerializeHeaderBackColor()); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeHeaderFont_Invoke_ReturnsExpected() + { + var style = new DataGridTableStyle(); + var font = new Font(SystemFonts.MessageBoxFont.FontFamily, 10); + PropertyDescriptor property = TypeDescriptor.GetProperties(typeof(DataGridTableStyle))[nameof(DataGridTableStyle.HeaderFont)]; + Assert.False(property.ShouldSerializeValue(style)); + + style.HeaderFont = font; + Assert.Same(font, style.HeaderFont); + Assert.True(property.ShouldSerializeValue(style)); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeHeaderForeColor_Invoke_ReturnsExpected() + { + var style = new SubDataGridTableStyle(); + Assert.True(style.ShouldSerializeHeaderForeColor()); + + style.HeaderForeColor = Color.Red; + Assert.Equal(Color.Red, style.HeaderForeColor); + Assert.True(style.ShouldSerializeHeaderForeColor()); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeLinkColor_Invoke_ReturnsExpected() + { + var style = new SubDataGridTableStyle(); + Assert.False(style.ShouldSerializeLinkColor()); + + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + Assert.True(style.ShouldSerializeLinkColor()); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeLinkHoverColor_Invoke_ReturnsFalse() + { + var style = new SubDataGridTableStyle(); + Assert.False(style.ShouldSerializeLinkHoverColor()); + + style.LinkColor = Color.Red; + Assert.Equal(Color.Red, style.LinkColor); + Assert.Equal(Color.Red, style.LinkHoverColor); + Assert.False(style.ShouldSerializeLinkHoverColor()); + } + + [Fact] + public void DataGridTableStyle_ShouldShouldSerializePreferredRowHeight_Invoke_ReturnsExpected() + { + var style = new SubDataGridTableStyle(); + Assert.False(style.ShouldSerializePreferredRowHeight()); + + style.PreferredRowHeight = 1; + Assert.Equal(1, style.PreferredRowHeight); + Assert.True(style.ShouldSerializePreferredRowHeight()); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeSelectionBackColor_Invoke_ReturnsExpected() + { + var style = new SubDataGridTableStyle(); + Assert.False(style.ShouldSerializeSelectionBackColor()); + + style.SelectionBackColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionBackColor); + Assert.True(style.ShouldSerializeSelectionBackColor()); + } + + [Fact] + public void DataGridTableStyle_ShouldSerializeSelectionForeColor_Invoke_ReturnsExpected() + { + var style = new SubDataGridTableStyle(); + Assert.False(style.ShouldSerializeSelectionForeColor()); + + style.SelectionForeColor = Color.Red; + Assert.Equal(Color.Red, style.SelectionForeColor); + Assert.True(style.ShouldSerializeSelectionForeColor()); + } + + private class SubDataGridTableStyle : DataGridTableStyle + { + public SubDataGridTableStyle() : base() + { + } + + public SubDataGridTableStyle(bool isDefaultTableStyle) : base(isDefaultTableStyle) + { + } + + public SubDataGridTableStyle(CurrencyManager listManager) : base(listManager) + { + } + + public new bool CanRaiseEvents => base.CanRaiseEvents; + + public new bool DesignMode => base.DesignMode; + + public new EventHandlerList Events => base.Events; + + public new DataGridColumnStyle CreateGridColumn(PropertyDescriptor prop) => base.CreateGridColumn(prop); + + public new DataGridColumnStyle CreateGridColumn(PropertyDescriptor prop, bool isDefault) => base.CreateGridColumn(prop, isDefault); + + public new void Dispose(bool disposing) => base.Dispose(disposing); + + public new void OnAllowSortingChanged(EventArgs e) => base.OnAllowSortingChanged(e); + + public new void OnAlternatingBackColorChanged(EventArgs e) => base.OnAlternatingBackColorChanged(e); + + public new void OnBackColorChanged(EventArgs e) => base.OnBackColorChanged(e); + + public new void OnColumnHeadersVisibleChanged(EventArgs e) => base.OnColumnHeadersVisibleChanged(e); + + public new void OnForeColorChanged(EventArgs e) => base.OnForeColorChanged(e); + + public new void OnGridLineColorChanged(EventArgs e) => base.OnGridLineColorChanged(e); + + public new void OnGridLineStyleChanged(EventArgs e) => base.OnGridLineStyleChanged(e); + + public new void OnHeaderBackColorChanged(EventArgs e) => base.OnHeaderBackColorChanged(e); + + public new void OnHeaderFontChanged(EventArgs e) => base.OnHeaderFontChanged(e); + + public new void OnHeaderForeColorChanged(EventArgs e) => base.OnHeaderForeColorChanged(e); + + public new void OnLinkColorChanged(EventArgs e) => base.OnLinkColorChanged(e); + + public new void OnLinkHoverColorChanged(EventArgs e) => base.OnLinkHoverColorChanged(e); + + public new void OnMappingNameChanged(EventArgs e) => base.OnMappingNameChanged(e); + + public new void OnPreferredColumnWidthChanged(EventArgs e) => base.OnPreferredColumnWidthChanged(e); + + public new void OnPreferredRowHeightChanged(EventArgs e) => base.OnPreferredRowHeightChanged(e); + + public new void OnReadOnlyChanged(EventArgs e) => base.OnReadOnlyChanged(e); + + public new void OnRowHeadersVisibleChanged(EventArgs e) => base.OnRowHeadersVisibleChanged(e); + + public new void OnRowHeaderWidthChanged(EventArgs e) => base.OnRowHeaderWidthChanged(e); + + public new void OnSelectionBackColorChanged(EventArgs e) => base.OnSelectionBackColorChanged(e); + + public new void OnSelectionForeColorChanged(EventArgs e) => base.OnSelectionForeColorChanged(e); + + public new bool ShouldSerializeAlternatingBackColor() => base.ShouldSerializeAlternatingBackColor(); + + public new bool ShouldSerializeBackColor() => base.ShouldSerializeBackColor(); + + public new bool ShouldSerializeForeColor() => base.ShouldSerializeForeColor(); + + public new bool ShouldSerializeGridLineColor() => base.ShouldSerializeGridLineColor(); + + public new bool ShouldSerializeHeaderBackColor() => base.ShouldSerializeHeaderBackColor(); + + public new bool ShouldSerializeHeaderForeColor() => base.ShouldSerializeHeaderForeColor(); + + public new bool ShouldSerializeLinkColor() => base.ShouldSerializeLinkColor(); + + public new bool ShouldSerializeLinkHoverColor() => base.ShouldSerializeLinkHoverColor(); + + public new bool ShouldSerializePreferredRowHeight() => base.ShouldSerializePreferredRowHeight(); + + public new bool ShouldSerializeSelectionBackColor() => base.ShouldSerializeSelectionBackColor(); + + public new bool ShouldSerializeSelectionForeColor() => base.ShouldSerializeSelectionForeColor(); + } + + private class SubDataGridColumnStyle : DataGridColumnStyle + { + public Action AbortAction { get; set; } + + protected internal override void Abort(int rowNum) + { + AbortAction(rowNum); + } + + public Func CommitAction { get; set; } + + protected internal override bool Commit(CurrencyManager dataSource, int rowNum) + { + return CommitAction(dataSource, rowNum); + } + + public Action EditAction { get; set; } + + protected internal override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText, bool cellIsVisible) + { + EditAction(source, rowNum, bounds, readOnly, displayText, cellIsVisible); + } + + protected internal override Size GetPreferredSize(Graphics g, object value) + { + throw new NotImplementedException(); + } + + protected internal override int GetMinimumHeight() + { + throw new NotImplementedException(); + } + + protected internal override int GetPreferredHeight(Graphics g, object value) + { + throw new NotImplementedException(); + } + + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum) + { + throw new NotImplementedException(); + } + + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) + { + throw new NotImplementedException(); + } + + public Action SetDataGridInColumnAction { get; set; } + + protected override void SetDataGridInColumn(DataGrid value) + { + if (SetDataGridInColumnAction == null) + { + base.SetDataGridInColumn(value); + } + else + { + SetDataGridInColumnAction(value); + } + } + + public Action DisposeAction { get; set; } + + protected override void Dispose(bool disposing) + { + DisposeAction?.Invoke(disposing); + } + } + + private class NullGridColumnStylesDataGridTableStyle : DataGridTableStyle + { + public override GridColumnStylesCollection GridColumnStyles => null; + + public new void Dispose(bool disposing) => base.Dispose(disposing); + } + + private class SubDataGrid : DataGrid + { + public new void ColumnStartedEditing(Rectangle bounds) => base.ColumnStartedEditing(bounds); + + public new void OnPaint(PaintEventArgs pe) => base.OnPaint(pe); + } + + private class DataClass + { + public string Value1 { get; set; } + + public string Value2 { get; set; } + } + + + private class ClassWithProperties + { + public bool BoolProperty { get; set; } + + public string StringProperty { get; set; } + + public DateTime DateTimeProperty { get; set; } + + public sbyte SByteProperty { get; set; } + + public short ShortProperty { get; set; } + + public int IntProperty { get; set; } + + public long LongProperty { get; set; } + + public byte ByteProperty { get; set; } + + public ushort UShortProperty { get; set; } + + public uint UIntProperty { get; set; } + + public ulong ULongProperty { get; set; } + + public char CharProperty { get; set; } + + public decimal DecimalProperty { get; set; } + + public double DoubleProperty { get; set; } + + public float FloatProperty { get; set; } + + public object ObjectProperty { get; set; } + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/DataGridTests.cs b/WTG.System.Windows.Forms.Tests/DataGridTests.cs new file mode 100644 index 00000000000..57d9ed3e1c6 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/DataGridTests.cs @@ -0,0 +1,140 @@ +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.Tests +{ + public class DataGridTests + { + [Fact] + public void DataGrid_Ctor_Default() + { + var dataGrid = new SubDataGrid(); + Assert.True(dataGrid.AllowNavigation); + Assert.True(dataGrid.AllowSorting); + Assert.Equal(SystemColors.Window, dataGrid.AlternatingBackColor); + Assert.Equal(SystemColors.Window, dataGrid.BackColor); + Assert.Equal(SystemColors.AppWorkspace, dataGrid.BackgroundColor); + Assert.Null(dataGrid.BackgroundImage); + Assert.Equal(ImageLayout.Tile, dataGrid.BackgroundImageLayout); + Assert.Equal(BorderStyle.Fixed3D, dataGrid.BorderStyle); + Assert.Equal(new Rectangle(0, 0, 130, 80), dataGrid.Bounds); + Assert.Equal(80, dataGrid.Bottom); + Assert.Equal(SystemColors.ActiveCaption, dataGrid.CaptionBackColor); + Assert.Equal(Control.DefaultFont.Name, dataGrid.CaptionFont.Name); + Assert.Equal(FontStyle.Bold, dataGrid.CaptionFont.Style); + Assert.Equal(SystemColors.ActiveCaptionText, dataGrid.CaptionForeColor); + Assert.Empty(dataGrid.CaptionText); + Assert.True(dataGrid.CaptionVisible); + Assert.Equal(new Rectangle(0, 0, 130, 80), dataGrid.ClientRectangle); + Assert.Equal(new Size(130, 80), dataGrid.ClientSize); + Assert.True(dataGrid.ColumnHeadersVisible); + Assert.Equal(0, dataGrid.CurrentCell.RowNumber); + Assert.Equal(0, dataGrid.CurrentCell.ColumnNumber); + Assert.Equal(-1, dataGrid.CurrentRowIndex); + Assert.Same(Cursors.Default, dataGrid.Cursor); + Assert.Empty(dataGrid.DataMember); + Assert.Null(dataGrid.DataSource); + Assert.Equal(new Rectangle(0, 0, 130, 80), dataGrid.DisplayRectangle); + Assert.Equal(Size.Empty, dataGrid.DefaultMaximumSize); + Assert.Equal(Size.Empty, dataGrid.DefaultMinimumSize); + Assert.Equal(Padding.Empty, dataGrid.DefaultPadding); + Assert.Equal(new Size(130, 80), dataGrid.DefaultSize); + Assert.Equal(0, dataGrid.FirstVisibleColumn); + Assert.False(dataGrid.FlatMode); + Assert.Equal(SystemColors.WindowText, dataGrid.ForeColor); + Assert.Equal(SystemColors.Control, dataGrid.GridLineColor); + Assert.Equal(DataGridLineStyle.Solid, dataGrid.GridLineStyle); + Assert.Equal(SystemColors.Control, dataGrid.HeaderBackColor); + Assert.Equal(Control.DefaultFont, dataGrid.HeaderFont); + Assert.Equal(SystemColors.ControlText, dataGrid.HeaderForeColor); + Assert.Equal(SystemColors.ControlText, dataGrid.HeaderForeColor); + Assert.Equal(80, dataGrid.Height); + Assert.NotNull(dataGrid.HorizScrollBar); + Assert.Same(dataGrid.HorizScrollBar, dataGrid.HorizScrollBar); + Assert.Equal(0, dataGrid.Left); + Assert.Equal(SystemColors.HotTrack, dataGrid.LinkColor); + Assert.Equal(SystemColors.HotTrack, dataGrid.LinkHoverColor); + Assert.Null(dataGrid.ListManager); + Assert.Equal(Point.Empty, dataGrid.Location); + Assert.Equal(new Padding(3, 3, 3, 3), dataGrid.Margin); + Assert.Equal(Size.Empty, dataGrid.MaximumSize); + Assert.Equal(Size.Empty, dataGrid.MinimumSize); + Assert.Equal(Padding.Empty, dataGrid.Padding); + Assert.Equal(SystemColors.Control, dataGrid.ParentRowsBackColor); + Assert.Equal(SystemColors.WindowText, dataGrid.ParentRowsForeColor); + Assert.Equal(DataGridParentRowsLabelStyle.Both, dataGrid.ParentRowsLabelStyle); + Assert.True(dataGrid.ParentRowsVisible); + Assert.Equal(75, dataGrid.PreferredColumnWidth); + Assert.Equal(Control.DefaultFont.Height + 3, dataGrid.PreferredRowHeight); + Assert.Equal(new Size(130, 80), dataGrid.PreferredSize); + Assert.False(dataGrid.ReadOnly); + Assert.True(dataGrid.RowHeadersVisible); + Assert.Equal(35, dataGrid.RowHeaderWidth); + Assert.Equal(SystemColors.ActiveCaption, dataGrid.SelectionBackColor); + Assert.Equal(SystemColors.ActiveCaptionText, dataGrid.SelectionForeColor); + Assert.Null(dataGrid.Site); + Assert.Equal(new Size(130, 80), dataGrid.Size); + Assert.Empty(dataGrid.TableStyles); + Assert.Same(dataGrid.TableStyles, dataGrid.TableStyles); + Assert.Empty(dataGrid.Text); + Assert.Equal(0, dataGrid.Top); + Assert.NotNull(dataGrid.VertScrollBar); + Assert.Same(dataGrid.VertScrollBar, dataGrid.VertScrollBar); + Assert.Equal(0, dataGrid.VisibleColumnCount); + Assert.Equal(0, dataGrid.VisibleRowCount); + Assert.Equal(130, dataGrid.Width); + } + + [Fact] + public void DataGrid_ColumnStartedEditing_ValidControl_Success() + { + var dataGrid = new DataGrid(); + var control = new Control(); + dataGrid.ColumnStartedEditing(control); + } + + [Fact] + public void DataGrid_ColumnStartedEditing_NullControl_Nop() + { + var dataGrid = new DataGrid(); + dataGrid.ColumnStartedEditing(null); + } + + private class SubDataGridTableStyle : DataGridTableStyle + { + public SubDataGridTableStyle() : base() + { + } + + public SubDataGridTableStyle(bool isDefaultTableStyle) : base(isDefaultTableStyle) + { + } + + public SubDataGridTableStyle(CurrencyManager listManager) : base(listManager) + { + } + + public new bool CanRaiseEvents => base.CanRaiseEvents; + + public new bool DesignMode => base.DesignMode; + + public new EventHandlerList Events => base.Events; + } + + private class SubDataGrid : DataGrid + { + public new Size DefaultMaximumSize => base.DefaultMaximumSize; + + public new Size DefaultMinimumSize => base.DefaultMinimumSize; + + public new Padding DefaultPadding => base.DefaultPadding; + + public new Size DefaultSize => base.DefaultSize; + + public new ScrollBar HorizScrollBar => base.HorizScrollBar; + + public new ScrollBar VertScrollBar => base.VertScrollBar; + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/GlobalUsings.cs b/WTG.System.Windows.Forms.Tests/GlobalUsings.cs new file mode 100644 index 00000000000..8c927eb747a --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/WTG.System.Windows.Forms.Tests/GridColumnStylesCollectionTests.cs b/WTG.System.Windows.Forms.Tests/GridColumnStylesCollectionTests.cs new file mode 100644 index 00000000000..e7b518b9243 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/GridColumnStylesCollectionTests.cs @@ -0,0 +1,63 @@ + +using System.Drawing; +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.Tests +{ + public class GridColumnStylesCollectionTests + { + [Fact] + public void GridColumnStylesCollection_Add_DataGridColumnStyle_Success() + { + var tableStyle = new DataGridTableStyle(); + GridColumnStylesCollection collection = tableStyle.GridColumnStyles; + var style = new SubDataGridColumnStyle(); + Assert.Equal(0, collection.Add(style)); + Assert.Same(style, Assert.Single(collection)); + Assert.Same(tableStyle, style.DataGridTableStyle); + } + + private class SubDataGridColumnStyle : DataGridColumnStyle + { + protected internal override void Abort(int rowNum) + { + throw new NotImplementedException(); + } + + protected internal override bool Commit(CurrencyManager dataSource, int rowNum) + { + throw new NotImplementedException(); + } + + protected internal override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText, bool cellIsVisible) + { + throw new NotImplementedException(); + } + + protected internal override Size GetPreferredSize(Graphics g, object value) + { + throw new NotImplementedException(); + } + + protected internal override int GetMinimumHeight() + { + throw new NotImplementedException(); + } + + protected internal override int GetPreferredHeight(Graphics g, object value) + { + throw new NotImplementedException(); + } + + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum) + { + throw new NotImplementedException(); + } + + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) + { + throw new NotImplementedException(); + } + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/GridTableStylesCollectionTests.cs b/WTG.System.Windows.Forms.Tests/GridTableStylesCollectionTests.cs new file mode 100644 index 00000000000..de68d18014d --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/GridTableStylesCollectionTests.cs @@ -0,0 +1,19 @@ + +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.Tests +{ + public class GridTableStylesCollectionTests + { + [Fact] + public void GridTableStylesCollection_Add_DataGridTableStyle_Success() + { + var dataGrid = new DataGrid(); + GridTableStylesCollection collection = dataGrid.TableStyles; + var style = new DataGridTableStyle(); + Assert.Equal(0, collection.Add(style)); + Assert.Same(style, Assert.Single(collection)); + Assert.Same(dataGrid, style.DataGrid); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/GridTablesFactoryTests.cs b/WTG.System.Windows.Forms.Tests/GridTablesFactoryTests.cs new file mode 100644 index 00000000000..a61ce1ded12 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/GridTablesFactoryTests.cs @@ -0,0 +1,23 @@ +using System.Windows.Forms; +using WTG.System.Windows.Forms.System.Windows.Forms; + +namespace WTG.System.Windows.Forms.Tests +{ + public class GridTablesFactoryTests + { + public static IEnumerable CreateGridTables_TestData() + { + yield return new object[] { null, null, null, null, new DataGridTableStyle[] { null } }; + var style = new DataGridTableStyle(); + yield return new object[] { style, new(), string.Empty, new BindingContext(), new DataGridTableStyle[] { style } }; + yield return new object[] { style, new(), "dataMember", new BindingContext(), new DataGridTableStyle[] { style } }; + } + + [Theory] + [MemberData(nameof(CreateGridTables_TestData))] + public void GridTablesFactory_CreateGridTables_Invoke_ReturnsExpected(DataGridTableStyle gridTable, object dataSource, string dataMember, BindingContext bindingManager, DataGridTableStyle[] expected) + { + Assert.Equal(expected, GridTablesFactory.CreateGridTables(gridTable, dataSource, dataMember, bindingManager)); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/MainMenuTestsTests.cs b/WTG.System.Windows.Forms.Tests/MainMenuTestsTests.cs new file mode 100644 index 00000000000..516bdb182e5 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/MainMenuTestsTests.cs @@ -0,0 +1,233 @@ +using System.ComponentModel; +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.Tests +{ + public class MainMenuTestsTests + { + [Fact] + public void MainMenu_Ctor_Default() + { + var menu = new MainMenu(); + Assert.Empty(menu.MenuItems); + Assert.False(menu.IsParent); + Assert.Equal(RightToLeft.Inherit, menu.RightToLeft); + Assert.Null(menu.GetForm()); + Assert.Empty(menu.Name); + Assert.Null(menu.Site); + Assert.Null(menu.Container); + Assert.Null(menu.Tag); + } + + [Fact] + public void MainMenu_Ctor_IContainer() + { + var container = new Container(); + var menu = new MainMenu(container); + Assert.Empty(menu.MenuItems); + Assert.False(menu.IsParent); + Assert.Equal(RightToLeft.Inherit, menu.RightToLeft); + Assert.Null(menu.GetForm()); + Assert.Empty(menu.Name); + Assert.NotNull(menu.Site); + Assert.Equal(container, menu.Container); + Assert.Null(menu.Tag); + } + + [Fact] + public void MainMenu_Ctor_NullContainer_ThrowsArgumentNullException() + { + Assert.Throws("container", () => new MainMenu((IContainer)null)); + } + + public static IEnumerable Ctor_MenuItemArray_TestData() + { + yield return new object[] { null, false }; + yield return new object[] { Array.Empty(), false }; + yield return new object[] { new MenuItem[] { new() }, true }; + } + + [Theory] + [MemberData(nameof(Ctor_MenuItemArray_TestData))] + public void MainMenu_Ctor_MenuItemArray(MenuItem[] items, bool expectedIsParent) + { + var menu = new MainMenu(items); + Assert.Equal(items ?? Array.Empty(), menu.MenuItems.Cast()); + for (int i = 0; i < (items?.Length ?? 0); i++) + { + Assert.Equal(i, menu.MenuItems[i].Index); + Assert.Equal(menu, menu.MenuItems[i].Parent); + } + + Assert.Equal(expectedIsParent, menu.IsParent); + Assert.Equal(RightToLeft.Inherit, menu.RightToLeft); + Assert.Null(menu.GetForm()); + Assert.Empty(menu.Name); + Assert.Null(menu.Site); + Assert.Null(menu.Container); + Assert.Null(menu.Tag); + } + + [Fact] + public void MainMenu_Ctor_NullItemInMenuItemArray_ThrowsArgumentNullException() + { + Assert.Throws("item", () => new MainMenu(new MenuItem[] { null })); + } + + [Fact] + public void MainMenu_GetForm_AddedToForm_ReturnsExpected() + { + var form = new Form + { + Menu = new MainMenu() + }; + + MainMenu menu = form.Menu; + Assert.Equal(form, menu.GetForm()); + } + + [Theory] + [MemberData(nameof(CommonTestHelper.GetEnumTypeTheoryData), typeof(RightToLeft), MemberType = typeof(CommonTestHelper))] + public void MainMenu_RightToLeft_SetWithoutForm_GetReturnsExpected(RightToLeft value) + { + var menu = new MainMenu + { + RightToLeft = value + }; + Assert.Equal(value, menu.RightToLeft); + } + + [Theory] + [InlineData(RightToLeft.Yes, RightToLeft.Yes)] + [InlineData(RightToLeft.No, RightToLeft.No)] + [InlineData(RightToLeft.Inherit, RightToLeft.Yes)] + public void MainMenu_RightToLeft_SetWithSourceControl_GetReturnsExpected(RightToLeft value, RightToLeft expectedValue) + { + var form = new Form + { + Menu = new MainMenu(), + RightToLeft = RightToLeft.Yes + }; + MainMenu menu = form.Menu; + + menu.RightToLeft = value; + Assert.Equal(expectedValue, menu.RightToLeft); + } + + [Fact] + public void MainMenu_RightToLeft_SetCreated_GetReturnsExpected() + { + using (var menu = new MainMenu(new MenuItem[] { new("text") })) + { + Assert.NotEqual(IntPtr.Zero, menu.Handle); + menu.RightToLeft = RightToLeft.Yes; + menu.RightToLeft = RightToLeft.No; + Assert.Equal(RightToLeft.No, menu.RightToLeft); + } + } + + [Theory] + [MemberData(nameof(CommonTestHelper.GetEnumTypeTheoryDataInvalid), typeof(RightToLeft), MemberType = typeof(CommonTestHelper))] + public void MainMenu_RightToLeft_SetInvalid_ThrowsInvalidEnumArgumentException(RightToLeft value) + { + var menu = new MainMenu(); + Assert.Throws("RightToLeft", () => menu.RightToLeft = value); + } + + [Fact] + public void MainMenu_OnCollapse_Invoke_Success() + { + var menu = new MainMenu(); + + // No handler. + menu.OnCollapse(null); + + // Handler. + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(menu, sender); + callCount++; + }; + + menu.Collapse += handler; + menu.OnCollapse(null); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menu.Collapse -= handler; + menu.OnCollapse(null); + Assert.Equal(1, callCount); + } + + public static IEnumerable CloneMenu_TestData() + { + yield return new object[] { Array.Empty() }; + yield return new object[] { new MenuItem[] { new("text") } }; + } + + [Theory] + [MemberData(nameof(CloneMenu_TestData))] + public void MainMenu_CloneMenu_Invoke_Success(MenuItem[] items) + { + var source = new MainMenu(items) + { + RightToLeft = RightToLeft.No + }; + MainMenu menu = source.CloneMenu(); + Assert.NotSame(source, menu); + Assert.Equal(items.Select(m => m.Name), menu.MenuItems.Cast().Select(m => m.Name)); + Assert.Equal(source.IsParent, menu.IsParent); + Assert.Equal(RightToLeft.Inherit, menu.RightToLeft); + Assert.Null(menu.GetForm()); + Assert.Empty(menu.Name); + Assert.Null(menu.Site); + Assert.Null(menu.Container); + Assert.Null(menu.Tag); + } + + [Fact] + public void MainMenu_CreateMenuHandle_Invoke_ReturnsExpected() + { + var menu = new SubMainMenu(); + Assert.NotEqual(IntPtr.Zero, menu.CreateMenuHandle()); + } + + [Fact] + public void MainMenu_Dispose_HasForm_Success() + { + var form = new Form + { + Menu = new MainMenu() + }; + + MainMenu menu = form.Menu; + menu.Dispose(); + Assert.Null(menu.GetForm()); + Assert.Null(form.Menu); + } + + [Fact] + public void MainMenu_Dispose_HasOwnerForm_Success() + { + var parentForm = new Form { IsMdiContainer = true }; + var form = new Form + { + Menu = new MainMenu(), + MdiParent = parentForm + }; + + MainMenu menu = form.MergedMenu; + menu.Dispose(); + Assert.Null(menu.GetForm()); + Assert.Null(form.Menu); + } + + private class SubMainMenu : MainMenu + { + public new IntPtr CreateMenuHandle() => base.CreateMenuHandle(); + + public new void OnCollapse(EventArgs e) => base.OnCollapse(e); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/MenuItemCollectionTests.cs b/WTG.System.Windows.Forms.Tests/MenuItemCollectionTests.cs new file mode 100644 index 00000000000..2d868289460 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/MenuItemCollectionTests.cs @@ -0,0 +1,753 @@ +using System.Collections; +using System.Windows.Forms; +using WTG.System.Windows.Forms.Tests.Common; + +namespace WTG.System.Windows.Forms.Tests +{ + public class MenuItemCollectionTests + { + [Fact] + public void MenuItemCollection_Ctor_Menu() + { + var menu = new SubMenu(new MenuItem[] { new MenuItem() }); + var collection = new Menu.MenuItemCollection(menu); + Assert.Single(collection); + } + + [Fact] + public void MenuItemCollection_IList_Properties_ReturnsExpected() + { + var menu = new SubMenu(Array.Empty()); + IList collection = new Menu.MenuItemCollection(menu); + Assert.False(collection.IsFixedSize); + Assert.False(collection.IsReadOnly); + Assert.False(collection.IsSynchronized); + Assert.Same(collection, collection.SyncRoot); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void MenuItemCollection_Add_String_Success(string caption, string expectedText) + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + MenuItem menuItem = collection.Add(caption); + Assert.Same(menuItem, Assert.Single(collection)); + Assert.Equal(expectedText, menuItem.Text); + Assert.Empty(menuItem.MenuItems); + Assert.Equal(menu, menuItem.Parent); + Assert.Equal(0, menuItem.Index); + } + + public static IEnumerable Add_StringEventHandler_TestData() + { + EventHandler onClick = (sender, e) => { }; + yield return new object[] { null, null, string.Empty }; + yield return new object[] { string.Empty, onClick, string.Empty }; + yield return new object[] { "caption", onClick, "caption" }; + } + + [Theory] + [MemberData(nameof(Add_StringEventHandler_TestData))] + public void MenuItemCollection_Add_StringEventHandler_Success(string caption, EventHandler onClick, string expectedText) + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + MenuItem menuItem = collection.Add(caption, onClick); + Assert.Same(menuItem, Assert.Single(collection)); + Assert.Same(expectedText, menuItem.Text); + Assert.Empty(menuItem.MenuItems); + Assert.Equal(menu, menuItem.Parent); + Assert.Equal(0, menuItem.Index); + } + + public static IEnumerable Add_StringMenuItemArray_TestData() + { + yield return new object[] { null, null, string.Empty }; + yield return new object[] { string.Empty, Array.Empty(), string.Empty }; + yield return new object[] { "caption", new MenuItem[] { new MenuItem() }, "caption" }; + } + + [Theory] + [MemberData(nameof(Add_StringMenuItemArray_TestData))] + public void MenuItemCollection_Add_StringMenuItemArray_Success(string caption, MenuItem[] items, string expectedText) + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + MenuItem menuItem = collection.Add(caption, items); + Assert.Same(menuItem, Assert.Single(collection)); + Assert.Same(expectedText, menuItem.Text); + Assert.Equal(items ?? Array.Empty(), menuItem.MenuItems.Cast()); + Assert.Equal(menu, menuItem.Parent); + Assert.Equal(0, menuItem.Index); + } + + [Fact] + public void MenuItemCollection_Add_MenuItem_Success() + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + + var menuItem1 = new MenuItem("text1"); + Assert.Equal(0, collection.Add(menuItem1)); + Assert.Same(menuItem1, Assert.Single(collection)); + Assert.Equal(menu, menuItem1.Parent); + Assert.Equal(0, menuItem1.Index); + + var menuItem2 = new MenuItem("text2"); + Assert.Equal(1, collection.Add(menuItem2)); + Assert.Equal(2, collection.Count); + Assert.Same(menuItem1, collection[0]); + Assert.Same(menuItem2, collection[1]); + Assert.Equal(menu, menuItem1.Parent); + Assert.Equal(0, menuItem1.Index); + Assert.Equal(menu, menuItem2.Parent); + Assert.Equal(1, menuItem2.Index); + } + + [Fact] + public void MenuItemCollection_Add_IndexMenuItem_Success() + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + + var menuItem1 = new MenuItem("text1"); + Assert.Equal(0, collection.Add(0, menuItem1)); + Assert.Same(menuItem1, Assert.Single(collection)); + Assert.Equal(menu, menuItem1.Parent); + Assert.Equal(0, menuItem1.Index); + + var menuItem2 = new MenuItem("text1"); + Assert.Equal(0, collection.Add(0, menuItem2)); + Assert.Equal(2, collection.Count); + Assert.Same(menuItem2, collection[0]); + Assert.Same(menuItem1, collection[1]); + Assert.Equal(menu, menuItem1.Parent); + Assert.Equal(1, menuItem1.Index); + Assert.Equal(menu, menuItem2.Parent); + Assert.Equal(0, menuItem2.Index); + } + + [Fact] + public void MenuItemCollection_Add_SelfMenuItem_Nop() + { + var menuItem = new MenuItem("text", Array.Empty()); + var collection = new Menu.MenuItemCollection(menuItem); + Assert.Empty(collection); + } + + [Fact] + public void MenuItemCollection_Add_AlreadyInSameCollection_Success() + { + var menuItem1 = new MenuItem(); + var menuItem2 = new MenuItem(); + var parent = new MenuItem("text", Array.Empty()); + var collection = new Menu.MenuItemCollection(parent) + { + menuItem1, + menuItem2 + }; + + Assert.Equal(0, collection.Add(0, menuItem2)); + Assert.Equal(2, collection.Count); + Assert.Same(menuItem2, collection[0]); + Assert.Same(menuItem1, collection[1]); + Assert.Equal(parent, menuItem1.Parent); + Assert.Equal(1, menuItem1.Index); + Assert.Equal(parent, menuItem2.Parent); + Assert.Equal(0, menuItem2.Index); + + Assert.Equal(1, collection.Add(2, menuItem2)); + Assert.Equal(2, collection.Count); + Assert.Same(menuItem1, collection[0]); + Assert.Same(menuItem2, collection[1]); + Assert.Equal(parent, menuItem1.Parent); + Assert.Equal(0, menuItem1.Index); + Assert.Equal(parent, menuItem2.Parent); + Assert.Equal(1, menuItem2.Index); + } + + [Fact] + public void MenuItemCollection_Add_AlreadyInDifferentCollection_Success() + { + var oldParent = new MenuItem("text", Array.Empty()); + var oldCollection = new Menu.MenuItemCollection(oldParent); + var newParent = new MenuItem("text", Array.Empty()); + var newCollection = new Menu.MenuItemCollection(newParent); + + var menuItem = new MenuItem(); + oldCollection.Add(menuItem); + + Assert.Equal(0, newCollection.Add(menuItem)); + Assert.Empty(oldCollection); + Assert.Same(menuItem, Assert.Single(newCollection)); + Assert.Equal(newParent, menuItem.Parent); + Assert.Equal(0, menuItem.Index); + } + + [Fact] + public void MenuItemCollection_Add_MenuItemToCreatedMenu_Success() + { + using (var menu = new SubMenu(Array.Empty())) + { + Assert.NotEqual(IntPtr.Zero, menu.Handle); + + var collection = new Menu.MenuItemCollection(menu); + + var menuItem1 = new MenuItem("text1"); + Assert.Equal(0, collection.Add(menuItem1)); + Assert.Same(menuItem1, Assert.Single(collection)); + Assert.Equal(menu, menuItem1.Parent); + Assert.Equal(0, menuItem1.Index); + + var menuItem2 = new MenuItem("text2"); + Assert.Equal(1, collection.Add(menuItem2)); + Assert.Equal(2, collection.Count); + Assert.Same(menuItem1, collection[0]); + Assert.Same(menuItem2, collection[1]); + Assert.Equal(menu, menuItem1.Parent); + Assert.Equal(0, menuItem1.Index); + Assert.Equal(menu, menuItem2.Parent); + Assert.Equal(1, menuItem2.Index); + } + } + + [Fact] + public void MenuItemCollection_Add_CreatedMenuItemToMenu_Success() + { + var menuItem = new MenuItem("text1"); + using (var otherMenu = new SubMenu(new MenuItem[] { menuItem })) + { + Assert.NotEqual(IntPtr.Zero, otherMenu.Handle); + + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + + Assert.Equal(0, collection.Add(menuItem)); + Assert.Same(menuItem, Assert.Single(collection)); + Assert.Equal(menu, menuItem.Parent); + Assert.Equal(0, menuItem.Index); + } + } + + [Fact] + public void MenuItemCollection_Add_NullMenuItem_ThrowsArgumentNullException() + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + Assert.Throws("item", () => collection.Add((MenuItem)null)); + Assert.Throws("item", () => collection.Add(0, null)); + } + + [Fact] + public void MenuItemCollection_Add_SelfWithParent_ThrowsArgumentException() + { + var menuItem = new MenuItem("text", Array.Empty()); + var parent = new MenuItem("parent", new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menuItem); + Assert.Throws("item", () => collection.Add(menuItem)); + } + + [Fact] + public void MenuItemCollection_Add_ParentWithGrandparent_ThrowsArgumentException() + { + var menuItem = new MenuItem(); + var parent = new MenuItem("parent", new MenuItem[] { menuItem }); + var grandparent = new MenuItem("grandparent", new MenuItem[] { parent }); + + var oldCollection = new Menu.MenuItemCollection(menuItem); + Assert.Throws("item", () => oldCollection.Add(parent)); + } + + [Theory] + [InlineData(-1)] + [InlineData(1)] + public void MenuItemCollection_Add_InvalidIndex_ThrowsArgumentOutOfRangeException(int index) + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + Assert.Throws("index", () => collection.Add(index, new MenuItem())); + } + + [Theory] + [InlineData(-1)] + [InlineData(2)] + public void MenuItemCollection_Add_AlreadyInCollection_InvalidIndex_ThrowsArgumentOutOfRangeException(int index) + { + var menuItem = new MenuItem(); + var parent = new MenuItem("text", Array.Empty()); + var collection = new Menu.MenuItemCollection(parent) + { + menuItem + }; + Assert.Throws("index", () => collection.Add(index, menuItem)); + } + + [Fact] + public void MenuItemCollection_Add_IListMenuItem_Success() + { + var menu = new SubMenu(Array.Empty()); + IList collection = new Menu.MenuItemCollection(menu); + + var menuItem1 = new MenuItem("text1"); + Assert.Equal(0, collection.Add(menuItem1)); + Assert.Same(menuItem1, Assert.Single(collection)); + Assert.Equal(menu, menuItem1.Parent); + Assert.Equal(0, menuItem1.Index); + + var menuItem2 = new MenuItem("text2"); + Assert.Equal(1, collection.Add(menuItem2)); + Assert.Equal(2, collection.Count); + Assert.Same(menuItem1, collection[0]); + Assert.Same(menuItem2, collection[1]); + Assert.Equal(menu, menuItem1.Parent); + Assert.Equal(0, menuItem1.Index); + Assert.Equal(menu, menuItem2.Parent); + Assert.Equal(1, menuItem2.Index); + } + + [Theory] + [InlineData("value")] + [InlineData(null)] + public void MenuItemCollection_Add_IListNotMenuItem_ThrowsArgumentException(object value) + { + var menu = new SubMenu(Array.Empty()); + IList collection = new Menu.MenuItemCollection(menu); + Assert.Throws("value", () => collection.Add(value)); + } + + public static IEnumerable AddRange_TestData() + { + yield return new object[] { Array.Empty() }; + yield return new object[] { new MenuItem[] { new MenuItem(), new MenuItem() } }; + } + + [Theory] + [MemberData(nameof(AddRange_TestData))] + public void MenuItemCollection_AddRange_Invoke_Success(MenuItem[] items) + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + collection.AddRange(items); + Assert.Equal(items.Length, collection.Count); + Assert.Equal(items, collection.Cast()); + } + + [Fact] + public void MenuItemCollection_AddRange_NullItems_ThrowsArgumentNullException() + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + Assert.Throws("items", () => collection.AddRange(null)); + } + + [Fact] + public void MenuItemCollection_AddRange_NullValueInItems_ThrowsArgumentNullException() + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + Assert.Throws("item", () => collection.AddRange(new MenuItem[] { null })); + } + + [Fact] + public void MenuItemCollection_Clear_InvokeOnMenu_Success() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menu); + collection.Clear(); + Assert.Empty(collection); + Assert.Null(menuItem.Parent); + Assert.Equal(-1, menuItem.Index); + + collection.Clear(); + Assert.Empty(collection); + } + + [Fact] + public void MenuItemCollection_Clear_InvokeOnMenuItem_Success() + { + var menuItem = new MenuItem(); + var menu = new MenuItem("text", new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menu); + collection.Clear(); + Assert.Empty(collection); + Assert.Null(menuItem.Parent); + Assert.Equal(-1, menuItem.Index); + + collection.Clear(); + Assert.Empty(collection); + } + + [Fact] + public void MenuItemCollection_CopyTo_NotEmpty_Success() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu) + { + menuItem + }; + var array = new object[] { 1, 2, 3 }; + collection.CopyTo(array, 1); + Assert.Equal(new object[] { 1, menuItem, 3 }, array); + } + + [Fact] + public void MenuItemCollection_CopyTo_Empty_Nop() + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + var array = new object[] { 1, 2, 3 }; + collection.CopyTo(array, 1); + Assert.Equal(new object[] { 1, 2, 3 }, array); + } + + public static IEnumerable Contains_TestData() + { + var menuItem = new MenuItem(); + yield return new object[] { new SubMenu(new MenuItem[] { menuItem }), menuItem, true }; + yield return new object[] { new SubMenu(new MenuItem[] { new MenuItem() }), new MenuItem(), false }; + yield return new object[] { new SubMenu(new MenuItem[] { new MenuItem() }), null, false }; + } + + [Theory] + [MemberData(nameof(Contains_TestData))] + public void MenuItemCollection_Contains_Invoke_ReturnsExpected(Menu menu, MenuItem value, bool expected) + { + var collection = new Menu.MenuItemCollection(menu); + Assert.Equal(expected, collection.Contains(value)); + } + + [Theory] + [MemberData(nameof(Contains_TestData))] + public void MenuItemCollection_Contains_IListInvoke_ReturnsExpected(Menu menu, MenuItem value, bool expected) + { + IList collection = new Menu.MenuItemCollection(menu); + Assert.Equal(expected, collection.Contains(value)); + } + + [Fact] + public void MenuItemCollection_Contains_IListNotMenuItem_ReturnsMinusOne() + { + var menu = new SubMenu(Array.Empty()); + IList collection = new Menu.MenuItemCollection(menu); + Assert.False(collection.Contains("value")); + } + + [Theory] + [InlineData(null, false)] + [InlineData("", false)] + [InlineData("name", true)] + [InlineData("NAME", true)] + [InlineData("noSuchName", false)] + public void MenuItemCollection_ContainsKey_Invoke_ReturnsExpected(string key, bool expected) + { + var menu = new SubMenu(new MenuItem[] { new MenuItem { Name = "name" } }); + var collection = new Menu.MenuItemCollection(menu); + Assert.Equal(expected, collection.ContainsKey(key)); + } + + public static IEnumerable Find_TestData() + { + yield return new object[] { new MenuItem[] { new MenuItem() }, "noSuchKey", false, Array.Empty() }; + yield return new object[] { new MenuItem[] { new MenuItem() }, "noSuchKey", true, Array.Empty() }; + + foreach (bool searchAllChildren in new bool[] { true, false }) + { + var menuItem1 = new MenuItem { Name = "name" }; + var menuItem2 = new MenuItem { Name = "NAME" }; + var menuItem3 = new MenuItem { Name = "otherName" }; + var menuItem4 = new MenuItem { Name = "name" }; + yield return new object[] { new MenuItem[] { menuItem1, menuItem2, menuItem3 }, "name", searchAllChildren, new MenuItem[] { menuItem1, menuItem2 } }; + } + + yield return new object[] { new MenuItem[] { new MenuItem { Name = "name" } }, "noSuchName", true, Array.Empty() }; + yield return new object[] { new MenuItem[] { new MenuItem { Name = "name" } }, "noSuchName", false, Array.Empty() }; + yield return new object[] { new MenuItem[] { new MenuItem("text", new MenuItem[] { new MenuItem { Name = "name2" } }) { Name = "name" }, }, "noSuchName", true, Array.Empty() }; + yield return new object[] { new MenuItem[] { new MenuItem("text", new MenuItem[] { new MenuItem { Name = "name2" } }) { Name = "name" }, }, "noSuchName", false, Array.Empty() }; + + var menuItemChild = new MenuItem { Name = "name" }; + yield return new object[] { new MenuItem[] { new MenuItem("text", new MenuItem[] { menuItemChild }) }, "name", true, new MenuItem[] { menuItemChild } }; + yield return new object[] { new MenuItem[] { new MenuItem("text", new MenuItem[] { new MenuItem { Name = "name" } }) }, "name", false, Array.Empty() }; + } + + [Theory] + [MemberData(nameof(Find_TestData))] + public void MenuItemCollection_Find_Invoke_ReturnsExpected(MenuItem[] items, string key, bool searchAllChildren, MenuItem[] expected) + { + var menu = new SubMenu(items); + var collection = new Menu.MenuItemCollection(menu); + Assert.Equal(expected, collection.Find(key, searchAllChildren)); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void MenuItemCollection_Find_NullOrEmptyKey_ThrowsArgumentNullException(string key) + { + var menu = new SubMenu(Array.Empty()); + var collection = new Menu.MenuItemCollection(menu); + Assert.Throws("key", () => collection.Find(key, searchAllChildren: false)); + } + + public static IEnumerable IndexOf_TestData() + { + var menuItem = new MenuItem(); + yield return new object[] { new SubMenu(new MenuItem[] { menuItem }), menuItem, 0 }; + yield return new object[] { new SubMenu(new MenuItem[] { new MenuItem() }), new MenuItem(), -1 }; + yield return new object[] { new SubMenu(new MenuItem[] { new MenuItem() }), null, -1 }; + } + + [Theory] + [MemberData(nameof(IndexOf_TestData))] + public void MenuItemCollection_IndexOf_Invoke_ReturnsExpected(Menu menu, MenuItem value, int expected) + { + var collection = new Menu.MenuItemCollection(menu); + Assert.Equal(expected, collection.IndexOf(value)); + } + + [Theory] + [MemberData(nameof(IndexOf_TestData))] + public void MenuItemCollection_IndexOf_IListInvoke_ReturnsExpected(Menu menu, MenuItem value, int expected) + { + IList collection = new Menu.MenuItemCollection(menu); + Assert.Equal(expected, collection.IndexOf(value)); + } + + [Fact] + public void MenuItemCollection_IndexOf_IListNotMenuItem_ReturnsMinusOne() + { + var menu = new SubMenu(Array.Empty()); + IList collection = new Menu.MenuItemCollection(menu); + Assert.Equal(-1, collection.IndexOf("value")); + } + + [Theory] + [InlineData(null, -1)] + [InlineData("", -1)] + [InlineData("name", 0)] + [InlineData("NAME", 0)] + [InlineData("noSuchName", -1)] + public void MenuItemCollection_IndexOfKey_Invoke_ReturnsExpected(string key, int expected) + { + var menu = new SubMenu(new MenuItem[] { new MenuItem { Name = "name" } }); + var collection = new Menu.MenuItemCollection(menu); + Assert.Equal(expected, collection.IndexOfKey(key)); + + // Call again to validate caching behaviour. + Assert.Equal(expected, collection.IndexOfKey(key)); + Assert.Equal(-1, collection.IndexOfKey("noSuchKey")); + } + + [Fact] + public void MenuItemCollection_Insert_IListInvoke_Success() + { + var menu = new SubMenu(Array.Empty()); + IList collection = new Menu.MenuItemCollection(menu); + + var menuItem1 = new MenuItem("text1"); + collection.Insert(0, menuItem1); + Assert.Same(menuItem1, Assert.Single(collection)); + Assert.Equal(menu, menuItem1.Parent); + Assert.Equal(0, menuItem1.Index); + + var menuItem2 = new MenuItem("text1"); + collection.Insert(0, menuItem2); + Assert.Equal(2, collection.Count); + Assert.Same(menuItem2, collection[0]); + Assert.Same(menuItem1, collection[1]); + Assert.Equal(menu, menuItem1.Parent); + Assert.Equal(1, menuItem1.Index); + Assert.Equal(menu, menuItem2.Parent); + Assert.Equal(0, menuItem2.Index); + } + + [Theory] + [InlineData("value")] + [InlineData(null)] + public void MenuItemCollection_Insert_IListNotMenuItem_ThrowsArgumentException(object value) + { + var menu = new SubMenu(Array.Empty()); + IList collection = new Menu.MenuItemCollection(menu); + Assert.Throws("value", () => collection.Insert(0, value)); + } + + [Fact] + public void MenuItemCollection_Item_GetValidIndex_ReturnsExpected() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menu); + Assert.Equal(menuItem, collection[0]); + } + + [Theory] + [InlineData(-1)] + [InlineData(1)] + public void MenuItemCollection_Item_GetInvalidIndex_ThrowsArgumentOutOfRangeException(int index) + { + var menu = new SubMenu(new MenuItem[] { new MenuItem() }); + var collection = new Menu.MenuItemCollection(menu); + Assert.Throws("index", () => collection[index]); + } + + [Fact] + public void MenuItemCollection_Item_IListGetValidIndex_ReturnsExpected() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + IList collection = new Menu.MenuItemCollection(menu); + Assert.Equal(menuItem, collection[0]); + } + + [Theory] + [InlineData(-1)] + [InlineData(1)] + public void MenuItemCollection_Item_IListGetInvalidIndex_ThrowsArgumentOutOfRangeException(int index) + { + var menu = new SubMenu(new MenuItem[] { new MenuItem() }); + IList collection = new Menu.MenuItemCollection(menu); + Assert.Throws("index", () => collection[index]); + } + + [Theory] + [InlineData(-1)] + [InlineData(0)] + [InlineData(1)] + public void MenuItemCollection_Item_IListSet_ThrowsNotSupportedException(int index) + { + var menu = new SubMenu(new MenuItem[] { new MenuItem() }); + IList collection = new Menu.MenuItemCollection(menu); + Assert.Throws(() => collection[index] = new MenuItem()); + } + + [Theory] + [InlineData(null, false)] + [InlineData("", false)] + [InlineData("name", true)] + [InlineData("NAME", true)] + [InlineData("noSuchName", false)] + public void MenuItemCollection_Item_GetKey_ReturnsExpected(string key, bool expected) + { + var menuItem = new MenuItem { Name = "name" }; + var menu = new SubMenu(new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menu); + Assert.Equal(expected ? menuItem : null, collection[key]); + } + + [Fact] + public void MenuItemCollection_Remove_MenuItem_Success() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menu); + collection.Remove(menuItem); + Assert.Empty(collection); + Assert.Null(menuItem.Parent); + Assert.Equal(-1, menuItem.Index); + } + + [Fact] + public void MenuItemCollection_Remove_DifferentOwnerMenuMenuItem_Nop() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menu); + + var otherMenuItem = new MenuItem(); + var otherMenu = new SubMenu(new MenuItem[] { otherMenuItem }); + collection.Remove(otherMenuItem); + Assert.Equal(menuItem, Assert.Single(collection)); + } + + [Fact] + public void MenuItemCollection_Remove_NoMenuMenuItem_Nop() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menu); + collection.Remove(new MenuItem()); + Assert.Equal(menuItem, Assert.Single(collection)); + } + + [Fact] + public void MenuItemCollection_Remove_IListMenuItem_Success() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + IList collection = new Menu.MenuItemCollection(menu); + collection.Remove(menuItem); + Assert.Empty(collection); + Assert.Null(menuItem.Parent); + Assert.Equal(-1, menuItem.Index); + } + + [Theory] + [InlineData("value")] + [InlineData(null)] + public void MenuItemCollection_Remove_IListNotMenuItem_Nop(object value) + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + IList collection = new Menu.MenuItemCollection(menu); + collection.Remove(value); + Assert.Equal(menuItem, Assert.Single(collection)); + } + + [Fact] + public void MenuItemCollection_RemoveAt_Invoke_Success() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menu); + collection.RemoveAt(0); + + Assert.Empty(collection); + Assert.Null(menuItem.Parent); + Assert.Equal(-1, menuItem.Index); + } + + [Theory] + [InlineData(-1)] + [InlineData(1)] + public void MenuItemCollection_RemoveAt_InvalidIndex_ThrowsArgumentOutOfRangeException(int index) + { + var menu = new SubMenu(new MenuItem[] { new MenuItem() }); + var collection = new Menu.MenuItemCollection(menu); + Assert.Throws("index", () => collection.RemoveAt(index)); + } + + [Theory] + [InlineData("name")] + [InlineData("NAME")] + public void MenuItemCollection_RemoveByKey_KeyExists_Success(string key) + { + var menuItem = new MenuItem { Name = "name" }; + var menu = new SubMenu(new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menu); + collection.RemoveByKey(key); + Assert.Empty(collection); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("noSuchName")] + public void MenuItemCollection_RemoveByKey_NoSuchKey_Nop(string key) + { + var menuItem = new MenuItem { Name = "name" }; + var menu = new SubMenu(new MenuItem[] { menuItem }); + var collection = new Menu.MenuItemCollection(menu); + collection.RemoveByKey(key); + Assert.Equal(menuItem, Assert.Single(collection)); + } + + private class SubMenu : Menu + { + public SubMenu(params MenuItem[] items) : base(items) + { + } + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/MenuItemTests.cs b/WTG.System.Windows.Forms.Tests/MenuItemTests.cs new file mode 100644 index 00000000000..e28ef88f1ff --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/MenuItemTests.cs @@ -0,0 +1,1827 @@ +using System.ComponentModel; +using System.Windows.Forms; +using Moq; +using WTG.System.Windows.Forms.Tests.Common; + +namespace WTG.System.Windows.Forms.Tests +{ + public class MenuItemTests + { + [Fact] + public void MenuItem_Ctor_Default() + { + var menuItem = new MenuItem(); + Assert.False(menuItem.BarBreak); + Assert.False(menuItem.Break); + Assert.False(menuItem.Checked); + Assert.False(menuItem.DefaultItem); + Assert.True(menuItem.Enabled); + Assert.Equal(-1, menuItem.Index); + Assert.False(menuItem.IsParent); + Assert.False(menuItem.MdiList); + Assert.Empty(menuItem.MenuItems); + Assert.Equal(0, menuItem.MergeOrder); + Assert.Equal(MenuMerge.Add, menuItem.MergeType); + Assert.Equal('\0', menuItem.Mnemonic); + Assert.False(menuItem.OwnerDraw); + Assert.Null(menuItem.Parent); + Assert.False(menuItem.RadioCheck); + Assert.True(menuItem.ShowShortcut); + Assert.Equal(Shortcut.None, menuItem.Shortcut); + Assert.True(menuItem.Visible); + Assert.Empty(menuItem.Name); + Assert.Null(menuItem.Site); + Assert.Null(menuItem.Container); + Assert.Null(menuItem.Tag); + Assert.Empty(menuItem.Text); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void MenuItem_Ctor_String(string text, string expectedText) + { + var menuItem = new MenuItem(text); + Assert.False(menuItem.BarBreak); + Assert.False(menuItem.Break); + Assert.False(menuItem.Checked); + Assert.False(menuItem.DefaultItem); + Assert.True(menuItem.Enabled); + Assert.Equal(-1, menuItem.Index); + Assert.False(menuItem.IsParent); + Assert.False(menuItem.MdiList); + Assert.Empty(menuItem.MenuItems); + Assert.Equal(0, menuItem.MergeOrder); + Assert.Equal(MenuMerge.Add, menuItem.MergeType); + Assert.Equal('\0', menuItem.Mnemonic); + Assert.False(menuItem.OwnerDraw); + Assert.Null(menuItem.Parent); + Assert.False(menuItem.RadioCheck); + Assert.True(menuItem.ShowShortcut); + Assert.Equal(Shortcut.None, menuItem.Shortcut); + Assert.True(menuItem.Visible); + Assert.Empty(menuItem.Name); + Assert.Null(menuItem.Site); + Assert.Null(menuItem.Container); + Assert.Null(menuItem.Tag); + Assert.Equal(expectedText, menuItem.Text); + } + + public static IEnumerable Ctor_String_EventHandler_TestData() + { + EventHandler onClick = (sender, e) => { }; + yield return new object[] { null, null, string.Empty }; + yield return new object[] { string.Empty, onClick, string.Empty }; + yield return new object[] { "text", onClick, "text" }; + } + + [Theory] + [MemberData(nameof(Ctor_String_EventHandler_TestData))] + public void MenuItem_Ctor_String_EventHandler(string text, EventHandler onClick, string expectedText) + { + var menuItem = new MenuItem(text, onClick); + Assert.False(menuItem.BarBreak); + Assert.False(menuItem.Break); + Assert.False(menuItem.Checked); + Assert.False(menuItem.DefaultItem); + Assert.True(menuItem.Enabled); + Assert.Equal(-1, menuItem.Index); + Assert.False(menuItem.IsParent); + Assert.False(menuItem.MdiList); + Assert.Empty(menuItem.MenuItems); + Assert.Equal(0, menuItem.MergeOrder); + Assert.Equal(MenuMerge.Add, menuItem.MergeType); + Assert.Equal('\0', menuItem.Mnemonic); + Assert.False(menuItem.OwnerDraw); + Assert.Null(menuItem.Parent); + Assert.False(menuItem.RadioCheck); + Assert.True(menuItem.ShowShortcut); + Assert.Equal(Shortcut.None, menuItem.Shortcut); + Assert.True(menuItem.Visible); + Assert.Empty(menuItem.Name); + Assert.Null(menuItem.Site); + Assert.Null(menuItem.Container); + Assert.Null(menuItem.Tag); + Assert.Same(expectedText, menuItem.Text); + } + + [Fact] + public void MenuItem_Ctor_String_EventHandler_OnClick() + { + SubMenuItem menuItem = null; + int callCount = 0; + EventHandler onClick = (sender, e) => + { + Assert.Same(menuItem, sender); + callCount++; + }; + menuItem = new SubMenuItem("text", onClick); + menuItem.OnClick(null); + Assert.Equal(1, callCount); + } + + public static IEnumerable Ctor_String_EventHandler_Shortcut_TestData() + { + EventHandler onClick = (sender, e) => { }; + yield return new object[] { null, null, Shortcut.None, string.Empty }; + yield return new object[] { string.Empty, onClick, (Shortcut)(Shortcut.None - 1), string.Empty }; + yield return new object[] { "text", onClick, Shortcut.CtrlA, "text" }; + } + + [Theory] + [MemberData(nameof(Ctor_String_EventHandler_Shortcut_TestData))] + public void MenuItem_Ctor_String_EventHandler_Shortcut(string text, EventHandler onClick, Shortcut shortcut, string expectedText) + { + var menuItem = new MenuItem(text, onClick, shortcut); + Assert.False(menuItem.BarBreak); + Assert.False(menuItem.Break); + Assert.False(menuItem.Checked); + Assert.False(menuItem.DefaultItem); + Assert.True(menuItem.Enabled); + Assert.Equal(-1, menuItem.Index); + Assert.False(menuItem.IsParent); + Assert.False(menuItem.MdiList); + Assert.Empty(menuItem.MenuItems); + Assert.Equal(0, menuItem.MergeOrder); + Assert.Equal(MenuMerge.Add, menuItem.MergeType); + Assert.Equal('\0', menuItem.Mnemonic); + Assert.False(menuItem.OwnerDraw); + Assert.Null(menuItem.Parent); + Assert.False(menuItem.RadioCheck); + Assert.True(menuItem.ShowShortcut); + Assert.Equal(shortcut, menuItem.Shortcut); + Assert.True(menuItem.Visible); + Assert.Empty(menuItem.Name); + Assert.Null(menuItem.Site); + Assert.Null(menuItem.Container); + Assert.Null(menuItem.Tag); + Assert.Same(expectedText, menuItem.Text); + } + + [Fact] + public void MenuItem_Ctor_String_EventHandler_Shortcut_OnClick() + { + SubMenuItem menuItem = null; + int callCount = 0; + EventHandler onClick = (sender, e) => + { + Assert.Same(menuItem, sender); + callCount++; + }; + menuItem = new SubMenuItem("text", onClick, Shortcut.None); + menuItem.OnClick(null); + Assert.Equal(1, callCount); + } + + public static IEnumerable Ctor_String_MenuItemArray_TestData() + { + yield return new object[] { null, null, false, string.Empty }; + yield return new object[] { string.Empty, Array.Empty(), false, string.Empty }; + yield return new object[] { "text", new MenuItem[] { new MenuItem() }, true, "text" }; + } + + [Theory] + [MemberData(nameof(Ctor_String_MenuItemArray_TestData))] + public void MenuItem_Ctor_String_MenuItemArray(string text, MenuItem[] items, bool expectedIsParent, string expectedText) + { + var menuItem = new MenuItem(text, items); + Assert.False(menuItem.BarBreak); + Assert.False(menuItem.Break); + Assert.False(menuItem.Checked); + Assert.False(menuItem.DefaultItem); + Assert.True(menuItem.Enabled); + Assert.Equal(-1, menuItem.Index); + Assert.Equal(expectedIsParent, menuItem.IsParent); + Assert.False(menuItem.MdiList); + Assert.Equal(items ?? Array.Empty(), menuItem.MenuItems.Cast()); + Assert.Equal(0, menuItem.MergeOrder); + Assert.Equal(MenuMerge.Add, menuItem.MergeType); + Assert.Equal('\0', menuItem.Mnemonic); + Assert.False(menuItem.OwnerDraw); + Assert.Null(menuItem.Parent); + Assert.False(menuItem.RadioCheck); + Assert.True(menuItem.ShowShortcut); + Assert.Equal(Shortcut.None, menuItem.Shortcut); + Assert.True(menuItem.Visible); + Assert.Empty(menuItem.Name); + Assert.Null(menuItem.Site); + Assert.Null(menuItem.Container); + Assert.Null(menuItem.Tag); + Assert.Same(expectedText, menuItem.Text); + } + + public static IEnumerable Ctor_MergeType_Int_Shortcut_String_EventHandler_EventHandler_EventHandler_MenuItemArray_TestData() + { + EventHandler onClick = (sender, e) => { }; + EventHandler onPopup = (sender, e) => { }; + EventHandler onSelect = (sender, e) => { }; + + yield return new object[] { (MenuMerge)(MenuMerge.Add - 1), -1, (Shortcut)(Shortcut.None - 1), null, null, null, null, null, false, string.Empty }; + yield return new object[] { MenuMerge.Add, 0, Shortcut.None, string.Empty, onClick, onPopup, onSelect, Array.Empty(), false, string.Empty }; + yield return new object[] { MenuMerge.MergeItems, 1, Shortcut.CtrlA, "text", onClick, onPopup, onSelect, new MenuItem[] { new MenuItem() }, true, "text" }; + } + + [Theory] + [MemberData(nameof(Ctor_MergeType_Int_Shortcut_String_EventHandler_EventHandler_EventHandler_MenuItemArray_TestData))] + public void MenuItem_Ctor_MenuMerge_Int_Shortcut_String_EventHandler_EventHandler_EventHandler_MenuItemArray(MenuMerge mergeType, int mergeOrder, Shortcut shortcut, string text, EventHandler onClick, EventHandler onPopup, EventHandler onSelect, MenuItem[] items, bool expectedIsParent, string expectedText) + { + var menuItem = new MenuItem(mergeType, mergeOrder, shortcut, text, onClick, onPopup, onSelect, items); + Assert.False(menuItem.BarBreak); + Assert.False(menuItem.Break); + Assert.False(menuItem.Checked); + Assert.False(menuItem.DefaultItem); + Assert.True(menuItem.Enabled); + Assert.Equal(-1, menuItem.Index); + Assert.Equal(expectedIsParent, menuItem.IsParent); + Assert.False(menuItem.MdiList); + Assert.Equal(items ?? Array.Empty(), menuItem.MenuItems.Cast()); + Assert.Equal(mergeOrder, menuItem.MergeOrder); + Assert.Equal(mergeType, menuItem.MergeType); + Assert.Equal('\0', menuItem.Mnemonic); + Assert.False(menuItem.OwnerDraw); + Assert.Null(menuItem.Parent); + Assert.False(menuItem.RadioCheck); + Assert.True(menuItem.ShowShortcut); + Assert.Equal(shortcut, menuItem.Shortcut); + Assert.True(menuItem.Visible); + Assert.Empty(menuItem.Name); + Assert.Null(menuItem.Site); + Assert.Null(menuItem.Container); + Assert.Null(menuItem.Tag); + Assert.Same(expectedText, menuItem.Text); + } + + [Fact] + public void MenuItem_Ctor_MenuMerge_Int_Shortcut_String_EventHandler_EventHandler_EventHandler_MenuItemArray_OnClick() + { + SubMenuItem menuItem = null; + int callCount = 0; + EventHandler onClick = (sender, e) => + { + Assert.Same(menuItem, sender); + callCount++; + }; + menuItem = new SubMenuItem(MenuMerge.Add, 0, Shortcut.None, string.Empty, onClick, null, null, Array.Empty()); + menuItem.OnClick(null); + Assert.Equal(1, callCount); + } + + [Fact] + public void MenuItem_Ctor_MenuMerge_Int_Shortcut_String_EventHandler_EventHandler_EventHandler_MenuItemArray_OnPopup() + { + SubMenuItem menuItem = null; + int callCount = 0; + EventHandler onPopup = (sender, e) => + { + Assert.Same(menuItem, sender); + callCount++; + }; + menuItem = new SubMenuItem(MenuMerge.Add, 0, Shortcut.None, string.Empty, null, onPopup, null, Array.Empty()); + menuItem.OnPopup(null); + Assert.Equal(1, callCount); + } + + [Fact] + public void MenuItem_Ctor_MenuMerge_Int_Shortcut_String_EventHandler_EventHandler_EventHandler_MenuItemArray_OnSelect() + { + SubMenuItem menuItem = null; + int callCount = 0; + EventHandler onSelect = (sender, e) => + { + Assert.Same(menuItem, sender); + callCount++; + }; + menuItem = new SubMenuItem(MenuMerge.Add, 0, Shortcut.None, string.Empty, null, null, onSelect, Array.Empty()); + menuItem.OnSelect(null); + Assert.Equal(1, callCount); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_BarBreak_Set_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem + { + BarBreak = value + }; + Assert.Equal(value, menuItem.BarBreak); + } + + [Fact] + public void MenuItem_BarBreak_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.BarBreak); + Assert.Throws(() => menuItem.BarBreak = true); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_Break_Set_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem + { + Break = value + }; + Assert.Equal(value, menuItem.Break); + } + + [Fact] + public void MenuItem_Break_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.Break); + Assert.Throws(() => menuItem.Break = true); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_Checked_Set_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem + { + Checked = value + }; + Assert.Equal(value, menuItem.Checked); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_Checked_SetWithParent_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + menuItem.Checked = value; + Assert.Equal(value, menuItem.Checked); + } + + [Fact] + public void MenuItem_Checked_SetWithMainMenuParent_ThrowsArgumentException() + { + var menuItem = new MenuItem(); + var menu = new MainMenu(new MenuItem[] { menuItem }); + Assert.Throws("value", () => menuItem.Checked = true); + Assert.False(menuItem.Checked); + + menuItem.Checked = false; + Assert.False(menuItem.Checked); + } + + [Fact] + public void MenuItem_Checked_SetWithChildren_ThrowsArgumentException() + { + var menuItem = new MenuItem("text", new MenuItem[] { new MenuItem() }); + Assert.Throws("value", () => menuItem.Checked = true); + Assert.False(menuItem.Checked); + + menuItem.Checked = false; + Assert.False(menuItem.Checked); + } + + [Fact] + public void MenuItem_Checked_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.Checked); + Assert.Throws(() => menuItem.Checked = true); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_DefaultItem_Set_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem + { + DefaultItem = value + }; + Assert.Equal(value, menuItem.DefaultItem); + } + + [Fact] + public void MenuItem_DefaultItem_SetWithParent_GetReturnsExpected() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + menuItem.DefaultItem = true; + Assert.True(menuItem.DefaultItem); + + // Set same. + menuItem.DefaultItem = true; + Assert.True(menuItem.DefaultItem); + + menuItem.DefaultItem = false; + Assert.False(menuItem.DefaultItem); + + // Set same. + menuItem.DefaultItem = false; + Assert.False(menuItem.DefaultItem); + } + + [Fact] + public void MenuItem_DefaultItem_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.DefaultItem); + Assert.Throws(() => menuItem.DefaultItem = true); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_Enabled_Set_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem + { + Enabled = value + }; + Assert.Equal(value, menuItem.Enabled); + } + + [Fact] + public void MenuItem_Enabled_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.Enabled); + Assert.Throws(() => menuItem.Enabled = true); + } + + [Theory] + [InlineData(0)] + [InlineData(1)] + public void MenuItem_Index_SetWithParent_GetReturnsExpected(int value) + { + var menuItem1 = new MenuItem(); + var menuItem2 = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem1, menuItem2 }); + menuItem1.Index = value; + Assert.Equal(value, menuItem1.Index); + if (value == 0) + { + Assert.Equal(new MenuItem[] { menuItem1, menuItem2 }, menu.MenuItems.Cast()); + } + else + { + Assert.Equal(new MenuItem[] { menuItem2, menuItem1 }, menu.MenuItems.Cast()); + } + } + + [Theory] + [InlineData(-1)] + [InlineData(1)] + public void MenuItem_Index_SetInvalid_ThrowsArgumentOutOfRangeException(int value) + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + Assert.Throws("value", () => menuItem.Index = value); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetIntTheoryData))] + public void MenuItem_Index_SetWithoutParent_Nop(int value) + { + var menuItem = new MenuItem + { + Index = value + }; + Assert.Equal(-1, menuItem.Index); + } + + public static IEnumerable IsParent_TestData() + { + yield return new object[] { new MenuItem { MdiList = true }, new SubMenu(), true }; + yield return new object[] { new MenuItem { MdiList = true }, null, false }; + yield return new object[] { new MenuItem { MdiList = false }, new SubMenu(), false }; + yield return new object[] { new MenuItem { MdiList = false }, new MenuItem(), false }; + yield return new object[] { new MenuItem { MdiList = false }, null, false }; + + foreach (bool mdiList in new bool[] { true, false }) + { + yield return new object[] { new MenuItem { MdiList = mdiList }, new MenuItem(), false }; + yield return new object[] { new MenuItem { MdiList = mdiList }, null, false }; + yield return new object[] { new MenuItem("text", new MenuItem[] { new MenuItem() }) { MdiList = mdiList }, null, true }; + } + + var disposedItem = new MenuItem("text", Array.Empty()); + disposedItem.Dispose(); + yield return new object[] { disposedItem, new SubMenu(), false }; + + yield return new object[] { new MenuItem { MdiList = true }, new MainMenu(), true }; + + var nonMdiForm = new Form { Menu = new MainMenu() }; + yield return new object[] { new MenuItem { MdiList = true }, nonMdiForm.Menu, true }; + + var formWithNoMdiChildren = new Form { Menu = new MainMenu() }; + formWithNoMdiChildren.Controls.Add(new MdiClient()); + yield return new object[] { new MenuItem { MdiList = true }, formWithNoMdiChildren.Menu, true }; + + var formWithMdiChildren = new Form { Menu = new MainMenu() }; + var client = new MdiClient(); + formWithMdiChildren.Controls.Add(client); + client.Controls.Add(new Form { MdiParent = formWithMdiChildren }); + yield return new object[] { new MenuItem { MdiList = true }, formWithMdiChildren.Menu, true }; + } + + [Theory] + [MemberData(nameof(IsParent_TestData))] + public void MenuItem_IsParent_HasParent_ReturnsExpected(MenuItem menuItem, Menu parent, bool expected) + { + parent?.MenuItems.Add(menuItem); + Assert.Equal(expected, menuItem.IsParent); + } + + [Fact] + public void MenuItem_IsParent_MdiSeparator_ReturnsFalse() + { + var parentForm = new Form { Menu = new MainMenu() }; + var parentFormClient = new MdiClient(); + parentForm.Controls.Add(parentFormClient); + parentFormClient.Controls.Add(new Form { MdiParent = parentForm }); + var menuItem = new SubMenuItem("text", new MenuItem[] { new MenuItem() }) { MdiList = true }; + var parentMenuItem = new MenuItem("parent", new MenuItem[] { menuItem }); + parentForm.Menu.MenuItems.Add(parentMenuItem); + + // Has a normal child and a MDI item. + menuItem.OnPopup(null); + Assert.True(menuItem.IsParent); + + // Has only MDI items. + menuItem.MenuItems.RemoveAt(0); + Assert.Equal("-", Assert.Single(menuItem.MenuItems.Cast()).Text); + Assert.True(menuItem.IsParent); + + // Parent form does not have MDI forms. + parentForm.IsMdiContainer = false; + Assert.Equal("-", Assert.Single(menuItem.MenuItems.Cast()).Text); + Assert.False(menuItem.IsParent); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_MdiList_Set_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem + { + MdiList = value + }; + Assert.Equal(value, menuItem.MdiList); + } + + [Fact] + public void MenuItem_MdiList_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.MdiList); + Assert.Throws(() => menuItem.MdiList = true); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetIntTheoryData))] + public void MenuItem_MergeOrder_Set_GetReturnsExpected(int value) + { + var menuItem = new MenuItem + { + MergeOrder = value + }; + Assert.Equal(value, menuItem.MergeOrder); + } + + [Fact] + public void MenuItem_MergeOrder_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.MergeOrder); + Assert.Throws(() => menuItem.MergeOrder = 1); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEnumTypeTheoryData), typeof(MenuMerge))] + public void MenuItem_MergeType_Set_GetReturnsExpected(MenuMerge value) + { + var menuItem = new MenuItem + { + MergeType = value + }; + Assert.Equal(value, menuItem.MergeType); + } + + [Fact] + public void MenuItem_MergeType_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.MergeType); + Assert.Throws(() => menuItem.MergeType = MenuMerge.Add); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetEnumTypeTheoryDataInvalid), typeof(MenuMerge))] + public void MenuItem_MergeType_SetInvalid_ThrowsInvalidEnumArgumentException(MenuMerge value) + { + var menuItem = new MenuItem(); + Assert.Throws("value", () => menuItem.MergeType = value); + } + + [Theory] + [InlineData("", '\0')] + [InlineData("text", '\0')] + [InlineData("&&abc", '\0')] + [InlineData("&abc", 'A')] + [InlineData("&", '\0')] + [InlineData("&&", '\0')] + public void MenuItem_Mnemonic_Get_ReturnsExpected(string text, char expected) + { + var menuItem = new MenuItem(text); + Assert.Equal(expected, menuItem.Mnemonic); + } + + [Fact] + public void MenuItem_Mneumonic_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.Mnemonic); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_OwnerDraw_Set_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem + { + OwnerDraw = value + }; + Assert.Equal(value, menuItem.OwnerDraw); + } + + [Fact] + public void MenuItem_OwnerDraw_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.OwnerDraw); + Assert.Throws(() => menuItem.OwnerDraw = true); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_RadioCheck_Set_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem + { + RadioCheck = value + }; + Assert.Equal(value, menuItem.RadioCheck); + } + + [Fact] + public void MenuItem_RadioCheck_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.RadioCheck); + Assert.Throws(() => menuItem.RadioCheck = true); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_ShowShortcut_Set_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem + { + ShowShortcut = value + }; + Assert.Equal(value, menuItem.ShowShortcut); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_ShowShortcut_SetCreated_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem(); + using (var menu = new SubMenu(new MenuItem[] { menuItem })) + { + menuItem.ShowShortcut = value; + Assert.Equal(value, menuItem.ShowShortcut); + } + } + + [Fact] + public void MenuItem_ShowShortcut_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.ShowShortcut); + Assert.Throws(() => menuItem.ShowShortcut = true); + } + + [Theory] + [InlineData(Shortcut.None)] + [InlineData(Shortcut.Ctrl0)] + public void MenuItem_Shortcut_Set_GetReturnsExpected(Shortcut value) + { + var menuItem = new MenuItem + { + Shortcut = value + }; + Assert.Equal(value, menuItem.Shortcut); + } + + [Theory] + [InlineData(Shortcut.None)] + [InlineData(Shortcut.Ctrl0)] + public void MenuItem_Shortcut_SetCreated_GetReturnsExpected(Shortcut value) + { + var menuItem = new MenuItem(); + using (var menu = new SubMenu(new MenuItem[] { menuItem })) + { + menuItem.Shortcut = value; + Assert.Equal(value, menuItem.Shortcut); + } + } + + [Theory] + [InlineData((Shortcut)(Shortcut.None - 1))] + public void MenuItem_Shortcut_SetInvalid_ThrowsInvalidEnumArgumentException(Shortcut value) + { + var menuItem = new MenuItem(); + Assert.Throws("value", () => menuItem.Shortcut = value); + } + + [Fact] + public void MenuItem_Shortcut_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.Shortcut); + Assert.Throws(() => menuItem.Shortcut = Shortcut.None); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void MenuItem_Text_Set_GetReturnsExpected(string value, string expected) + { + var menuItem = new MenuItem + { + Text = value + }; + Assert.Equal(expected, menuItem.Text); + + // Set same. + menuItem.Text = value; + Assert.Equal(expected, menuItem.Text); + } + + [Fact] + public void MenuItem_Text_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.Text); + Assert.Throws(() => menuItem.Text = string.Empty); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_Visible_Set_GetReturnsExpected(bool value) + { + var menuItem = new MenuItem + { + Visible = value + }; + Assert.Equal(value, menuItem.Visible); + + // Set same. + menuItem.Visible = value; + Assert.Equal(value, menuItem.Visible); + + // Set different. + menuItem.Visible = !value; + Assert.Equal(!value, menuItem.Visible); + } + + [Fact] + public void MenuItem_Visible_SetWithMainMenuParent_GetReturnsExpected() + { + var menuItem = new MenuItem(); + var menu = new MainMenu(new MenuItem[] { menuItem }); + menuItem.Visible = false; + Assert.False(menuItem.Visible); + + menuItem.Visible = true; + Assert.True(menuItem.Visible); + } + + [Fact] + public void MenuItem_Visible_SetWithHandle_GetReturnsExpected() + { + var menuItem = new MenuItem(); + using (var menu = new SubMenu(new MenuItem[] { menuItem })) + { + Assert.NotEqual(IntPtr.Zero, menu.Handle); + menuItem.Visible = false; + Assert.False(menuItem.Visible); + + menuItem.Visible = true; + Assert.True(menuItem.Visible); + } + } + + [Fact] + public void MenuItem_Visible_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.Visible); + Assert.Throws(() => menuItem.Visible = true); + } + + [Fact] + public void MenuItem_MenuID_Get_ReturnsExpected() + { + var menuItem = new SubMenuItem(); + Assert.NotEqual(0, menuItem.MenuID); + } + + [Fact] + public void MenuItem_MenuID_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.MenuID); + } + + [Fact] + public void MenuItem_OnClick_Invoke_Success() + { + var menuItem = new SubMenuItem(); + + // No handler. + menuItem.OnClick(null); + + // Handler. + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(menuItem, sender); + callCount++; + }; + + menuItem.Click += handler; + menuItem.OnClick(null); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menuItem.Click -= handler; + menuItem.OnClick(null); + Assert.Equal(1, callCount); + } + + [Fact] + public void MenuItem_OnClick_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.OnClick(null)); + } + + [Fact] + public void MenuItem_Click_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + EventHandler handler = (sender, e) => { }; + Assert.Throws(() => menuItem.Click += handler); + Assert.Throws(() => menuItem.Click -= handler); + } + + [Fact] + public void MenuItem_OnDrawItem_Invoke_Success() + { + var menuItem = new SubMenuItem(); + + // No handler. + menuItem.OnDrawItem(null); + + // Handler. + int callCount = 0; + DrawItemEventHandler handler = (sender, e) => + { + Assert.Equal(menuItem, sender); + callCount++; + }; + + menuItem.DrawItem += handler; + menuItem.OnDrawItem(null); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menuItem.DrawItem -= handler; + menuItem.OnDrawItem(null); + Assert.Equal(1, callCount); + } + + [Fact] + public void MenuItem_OnDrawItem_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.OnDrawItem(null)); + } + + [Fact] + public void MenuItem_DrawItem_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + DrawItemEventHandler handler = (sender, e) => { }; + Assert.Throws(() => menuItem.DrawItem += handler); + Assert.Throws(() => menuItem.DrawItem -= handler); + } + + [Fact] + public void MenuItem_OnInitMenuPopup_Invoke_Success() + { + var menuItem = new SubMenuItem(); + + // No handler. + menuItem.OnInitMenuPopup(null); + + // Handler. + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(menuItem, sender); + callCount++; + }; + + menuItem.Popup += handler; + menuItem.OnInitMenuPopup(null); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menuItem.Popup -= handler; + menuItem.OnInitMenuPopup(null); + Assert.Equal(1, callCount); + } + + [Fact] + public void MenuItem_OnInitMenuPopup_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.OnInitMenuPopup(null)); + } + + [Fact] + public void MenuItem_OnMeasureItem_Invoke_Success() + { + var menuItem = new SubMenuItem(); + + // No handler. + menuItem.OnMeasureItem(null); + + // Handler. + int callCount = 0; + MeasureItemEventHandler handler = (sender, e) => + { + Assert.Equal(menuItem, sender); + callCount++; + }; + + menuItem.MeasureItem += handler; + menuItem.OnMeasureItem(null); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menuItem.MeasureItem -= handler; + menuItem.OnMeasureItem(null); + Assert.Equal(1, callCount); + } + + [Fact] + public void MenuItem_OnMeasureItem_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.OnMeasureItem(null)); + } + + [Fact] + public void MenuItem_MeasureItem_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + MeasureItemEventHandler handler = (sender, e) => { }; + Assert.Throws(() => menuItem.MeasureItem += handler); + Assert.Throws(() => menuItem.MeasureItem -= handler); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_OnPopup_Invoke_Success(bool mdiList) + { + var menuItem = new SubMenuItem + { + MdiList = mdiList + }; + + // No handler. + menuItem.OnPopup(null); + + // Handler. + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(menuItem, sender); + callCount++; + }; + + menuItem.Popup += handler; + menuItem.OnPopup(null); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menuItem.Popup -= handler; + menuItem.OnPopup(null); + Assert.Equal(1, callCount); + } + + [Fact] + public void MenuItem_OnPopup_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.OnPopup(null)); + } + + [Fact] + public void MenuItem_Popup_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + EventHandler handler = (sender, e) => { }; + Assert.Throws(() => menuItem.Popup += handler); + Assert.Throws(() => menuItem.Popup -= handler); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetBoolTheoryData))] + public void MenuItem_OnPopup_InvokeWithChildren_Success(bool mdiList) + { + var menuItem = new SubMenuItem("text", new MenuItem[] { new MenuItem("text") { MdiList = mdiList } }); + + // No handler. + menuItem.OnPopup(null); + + // Handler. + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(menuItem, sender); + callCount++; + }; + + menuItem.Popup += handler; + menuItem.OnPopup(null); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menuItem.Popup -= handler; + menuItem.OnPopup(null); + Assert.Equal(1, callCount); + } + + [Fact] + public void MenuItem_OnPopup_MdiChildrenWithoutParent_DoesNotAddSeparator() + { + var menuItem = new SubMenuItem("text", new MenuItem[] { new MenuItem("child") }) { MdiList = true }; + + menuItem.OnPopup(null); + Assert.Equal(new string[] { "child" }, menuItem.MenuItems.Cast().Select(m => m.Text)); + + // Calling OnPopup again should not add duplicate items. + menuItem.OnPopup(null); + Assert.Equal(new string[] { "child" }, menuItem.MenuItems.Cast().Select(m => m.Text)); + } + + public static IEnumerable OnPopup_MdiChildren_TestData() + { + var formWithNoMdiChildren = new Form { Menu = new MainMenu() }; + formWithNoMdiChildren.Controls.Add(new MdiClient()); + yield return new object[] { new SubMenuItem("text", new MenuItem[] { new MenuItem("child") }) { MdiList = true }, new MainMenu(), new string[] { "child" } }; + yield return new object[] { new SubMenuItem("text") { MdiList = true }, formWithNoMdiChildren.Menu, Array.Empty() }; + + var formWithNoVisibleMdiChildren = new Form { Menu = new MainMenu() }; + var formWithNoVisibleMdiChildrenClient = new MdiClient(); + formWithNoVisibleMdiChildren.Controls.Add(formWithNoVisibleMdiChildrenClient); + formWithNoVisibleMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithNoVisibleMdiChildren }); + yield return new object[] { new SubMenuItem("text", new MenuItem[] { new MenuItem("child") }) { MdiList = true }, formWithNoVisibleMdiChildren.Menu, new string[] { "child", "-" } }; + yield return new object[] { new SubMenuItem("text"), formWithNoVisibleMdiChildren.Menu, Array.Empty() }; + + var formWithMdiChildren = new Form { Menu = new MainMenu(), Visible = true }; + var formWithMdiChildrenClient = new MdiClient(); + formWithMdiChildren.Controls.Add(formWithMdiChildrenClient); + formWithMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithMdiChildren, Visible = true, Text = "Form" }); + yield return new object[] { new SubMenuItem("text", new MenuItem[] { new MenuItem("child") }) { MdiList = true }, formWithMdiChildren.Menu, new string[] { "child", "-", "&1 Form", "&2 Form" } }; + + var formWithManyMdiChildren = new Form { Menu = new MainMenu(), Visible = true }; + var formWithManyMdiChildrenClient = new MdiClient(); + formWithManyMdiChildren.Controls.Add(formWithManyMdiChildrenClient); + formWithManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithManyMdiChildren, Visible = true, Text = "Form1" }); + formWithManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithManyMdiChildren, Visible = true, Text = "Form2" }); + formWithManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithManyMdiChildren, Visible = true, Text = "Form3" }); + formWithManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithManyMdiChildren, Visible = true, Text = "Form4" }); + formWithManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithManyMdiChildren, Visible = true, Text = "Form5" }); + formWithManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithManyMdiChildren, Visible = true, Text = "Form6" }); + formWithManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithManyMdiChildren, Visible = true, Text = "Form7" }); + formWithManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithManyMdiChildren, Visible = true, Text = "Form8" }); + formWithManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithManyMdiChildren, Visible = true, Text = "Form9" }); + formWithManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithManyMdiChildren, Visible = true, Text = "Form10" }); + yield return new object[] { new SubMenuItem("text", new MenuItem[] { new MenuItem("child") }) { MdiList = true }, formWithManyMdiChildren.Menu, new string[] { "child", "-", "&1 Form1", "&2 Form1", "&3 Form2", "&4 Form2", "&5 Form3", "&6 Form3", "&7 Form4", "&8 Form4", "&9 Form10", "&10 Form10", "&More Windows..." } }; + + var formWithActiveMdiChildren = new SubForm { Menu = new MainMenu(), Visible = true }; + var formWithActiveMdiChildrenClient = new MdiClient(); + formWithActiveMdiChildren.Controls.Add(formWithActiveMdiChildrenClient); + var activeForm1 = new Form { MdiParent = formWithActiveMdiChildren, Visible = true, Text = "Form2" }; + formWithActiveMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveMdiChildren, Visible = true, Text = "Form1" }); + formWithActiveMdiChildrenClient.Controls.Add(activeForm1); + formWithActiveMdiChildren.ActivateMdiChild(activeForm1); + yield return new object[] { new SubMenuItem("text", new MenuItem[] { new MenuItem("child") }) { MdiList = true }, formWithActiveMdiChildren.Menu, new string[] { "child", "-", "&1 Form2", "&2 Form1", "&3 Form1", "&4 Form2" } }; + + var formWithActiveManyMdiChildren = new SubForm { Menu = new MainMenu(), Visible = true }; + var formWithActiveManyMdiChildrenClient = new MdiClient(); + formWithActiveManyMdiChildren.Controls.Add(formWithActiveManyMdiChildrenClient); + var activeForm2 = new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form11" }; + formWithActiveManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form1" }); + formWithActiveManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form2" }); + formWithActiveManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form3" }); + formWithActiveManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form4" }); + formWithActiveManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form5" }); + formWithActiveManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form6" }); + formWithActiveManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form7" }); + formWithActiveManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form8" }); + formWithActiveManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form9" }); + formWithActiveManyMdiChildrenClient.Controls.Add(new Form { MdiParent = formWithActiveManyMdiChildren, Visible = true, Text = "Form10" }); + formWithActiveManyMdiChildrenClient.Controls.Add(activeForm2); + formWithActiveManyMdiChildren.ActivateMdiChild(activeForm2); + yield return new object[] { new SubMenuItem("text", new MenuItem[] { new MenuItem("child") }) { MdiList = true }, formWithActiveManyMdiChildren.Menu, new string[] { "child", "-", "&1 Form11", "&2 Form1", "&3 Form1", "&4 Form2", "&5 Form2", "&6 Form3", "&7 Form3", "&8 Form4", "&9 Form4", "&10 Form11", "&More Windows..." } }; + } + + [Theory] + [MemberData(nameof(OnPopup_MdiChildren_TestData))] + public void MenuItem_OnPopup_MdiChildren_AddsSeparator(SubMenuItem menuItem, Menu parent, string[] expectedItems) + { + try + { + parent.MenuItems.Add(menuItem); + + menuItem.OnPopup(null); + Assert.Equal(expectedItems, menuItem.MenuItems.Cast().Select(m => m.Text)); + + // Calling OnPopup again should not add duplicate items. + menuItem.OnPopup(null); + Assert.Equal(expectedItems, menuItem.MenuItems.Cast().Select(m => m.Text)); + } + catch + { + string expected = "Expected: " + string.Join(", ", expectedItems.Select(i => "\"" + i + "\"")); + string actual = "Actual: " + string.Join(", ", menuItem.MenuItems.Cast().Select(m => m.Text).Select(i => "\"" + i + "\"")); + throw new Exception(expected + Environment.NewLine + actual); + } + } + + [Fact] + public void MenuItem_PerformClick_MdiSeparator_Nop() + { + var parentForm = new Form { Menu = new MainMenu() }; + var parentFormClient = new MdiClient(); + parentForm.Controls.Add(parentFormClient); + parentFormClient.Controls.Add(new Form { MdiParent = parentForm }); + var menuItem = new SubMenuItem("text", new MenuItem[] { new MenuItem() }) { MdiList = true }; + parentForm.Menu.MenuItems.Add(menuItem); + menuItem.OnPopup(null); + + MenuItem separator = menuItem.MenuItems[1]; + Assert.Equal("-", separator.Text); + separator.PerformClick(); + } + + [Fact] + public void MenuItem_OnSelect_Invoke_Success() + { + var menuItem = new SubMenuItem(); + + // No handler. + menuItem.OnSelect(null); + + // Handler. + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(menuItem, sender); + callCount++; + }; + + menuItem.Select += handler; + menuItem.OnSelect(null); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menuItem.Select -= handler; + menuItem.OnSelect(null); + Assert.Equal(1, callCount); + } + + [Fact] + public void MenuItem_OnSelect_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.OnSelect(null)); + } + + [Fact] + public void MenuItem_Select_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new SubMenuItem(); + menuItem.Dispose(); + EventHandler handler = (sender, e) => { }; + Assert.Throws(() => menuItem.Select += handler); + Assert.Throws(() => menuItem.Select -= handler); + } + + [Fact] + public void MenuItem_PerformClick_Invoke_Success() + { + var menuItem = new SubMenuItem(); + + // No handler. + menuItem.PerformClick(); + + // Handler. + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(EventArgs.Empty, e); + Assert.Equal(menuItem, sender); + callCount++; + }; + + menuItem.Click += handler; + menuItem.PerformClick(); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menuItem.Click -= handler; + menuItem.PerformClick(); + Assert.Equal(1, callCount); + } + + [Fact] + public void MenuItem_PerformSelect_Invoke_Success() + { + var menuItem = new SubMenuItem(); + + // No handler. + menuItem.PerformSelect(); + + // Handler. + int callCount = 0; + EventHandler handler = (sender, e) => + { + Assert.Equal(EventArgs.Empty, e); + Assert.Equal(menuItem, sender); + callCount++; + }; + + menuItem.Select += handler; + menuItem.PerformSelect(); + Assert.Equal(1, callCount); + + // Should not call if the handler is removed. + menuItem.Select -= handler; + menuItem.PerformSelect(); + Assert.Equal(1, callCount); + } + + public static IEnumerable CloneMenu_TestData() + { + yield return new object[] { Array.Empty() }; + yield return new object[] { new MenuItem[] { new MenuItem("text") } }; + } + + [Theory] + [MemberData(nameof(CloneMenu_TestData))] + public void MenuItem_CloneMenu_InvokeNew_Success(MenuItem[] items) + { + var source = new MenuItem("text", items) + { + BarBreak = true, + Break = true, + Checked = items.Length == 0, + Enabled = false, + MdiList = true, + MergeOrder = -1, + MergeType = MenuMerge.Remove, + Name = "name", + OwnerDraw = true, + RadioCheck = true, + ShowShortcut = false, + Shortcut = Shortcut.CtrlA, + Site = Mock.Of(), + Tag = "tag", + Visible = false + }; + var menu = new SubMenu(new MenuItem[] { new MenuItem("parent", new MenuItem[] { source }) }); + MenuItem menuItem = source.CloneMenu(); + Assert.NotSame(source, menuItem); + + Assert.Equal(source.BarBreak, menuItem.BarBreak); + Assert.Equal(source.Break, menuItem.Break); + Assert.Equal(source.Checked, menuItem.Checked); + Assert.Equal(source.DefaultItem, menuItem.DefaultItem); + Assert.Equal(source.Enabled, menuItem.Enabled); + Assert.Equal(-1, menuItem.Index); + Assert.Equal(source.IsParent, menuItem.IsParent); + Assert.Equal(source.MdiList, menuItem.MdiList); + MenuTests.AssertEqualMenuItems(items, menuItem.MenuItems.Cast().ToArray()); + for (int i = 0; i < items.Length; i++) + { + Assert.Equal(i, menuItem.MenuItems[i].Index); + Assert.Equal(menuItem, menuItem.MenuItems[i].Parent); + } + Assert.Equal(source.MergeOrder, menuItem.MergeOrder); + Assert.Equal(source.MergeType, menuItem.MergeType); + Assert.Equal(source.Mnemonic, menuItem.Mnemonic); + Assert.Equal(source.OwnerDraw, menuItem.OwnerDraw); + Assert.Null(menuItem.Parent); + Assert.Equal(source.RadioCheck, menuItem.RadioCheck); + Assert.Equal(source.ShowShortcut, menuItem.ShowShortcut); + Assert.Equal(source.Shortcut, menuItem.Shortcut); + Assert.Equal(source.Visible, menuItem.Visible); + Assert.Empty(menuItem.Name); + Assert.Null(menuItem.Site); + Assert.Null(menuItem.Container); + Assert.Null(menuItem.Tag); + Assert.Equal(source.Text, menuItem.Text); + } + + [Theory] + [MemberData(nameof(CloneMenu_TestData))] + public void MenuItem_CloneMenu_InvokeExisting_Success(MenuItem[] items) + { + var source = new MenuItem("text", items) + { + BarBreak = true, + Break = true, + Checked = items.Length == 0, + Enabled = false, + MdiList = true, + MergeOrder = -1, + MergeType = MenuMerge.Remove, + OwnerDraw = true, + Site = Mock.Of(), + Tag = "tag" + }; + var menu = new SubMenu(new MenuItem[] { new MenuItem("parent", new MenuItem[] { source }) }); + var menuItem = new SubMenuItem(); + menuItem.CloneMenu(source); + + Assert.False(menuItem.BarBreak); + Assert.False(menuItem.Break); + Assert.False(menuItem.Checked); + Assert.False(menuItem.DefaultItem); + Assert.True(menuItem.Enabled); + Assert.Equal(-1, menuItem.Index); + Assert.Equal(source.IsParent, menuItem.IsParent); + Assert.False(menuItem.MdiList); + MenuTests.AssertEqualMenuItems(items, menuItem.MenuItems.Cast().ToArray()); + for (int i = 0; i < items.Length; i++) + { + Assert.Equal(i, menuItem.MenuItems[i].Index); + Assert.Equal(menuItem, menuItem.MenuItems[i].Parent); + } + Assert.Equal(0, menuItem.MergeOrder); + Assert.Equal(MenuMerge.Add, menuItem.MergeType); + Assert.Equal('\0', menuItem.Mnemonic); + Assert.False(menuItem.OwnerDraw); + Assert.Null(menuItem.Parent); + Assert.False(menuItem.RadioCheck); + Assert.True(menuItem.ShowShortcut); + Assert.Equal(Shortcut.None, menuItem.Shortcut); + Assert.True(menuItem.Visible); + Assert.Empty(menuItem.Name); + Assert.Null(menuItem.Site); + Assert.Null(menuItem.Container); + Assert.Null(menuItem.Tag); + Assert.Empty(menuItem.Text); + } + + [Fact] + public void MenuItem_CloneMenu_NullMenuSource_ThrowsArgumentNullException() + { + var menu = new SubMenuItem("text"); + Assert.Throws("menuSrc", () => menu.CloneMenu(null)); + } + + [Theory] + [MemberData(nameof(CloneMenu_TestData))] + public void MenuItem_MergeMenu_InvokeNew_Success(MenuItem[] items) + { + var source = new MenuItem("text", items) + { + BarBreak = true, + Break = true, + Checked = items.Length == 0, + Enabled = false, + MdiList = true, + MergeOrder = -1, + MergeType = MenuMerge.Remove, + Name = "name", + OwnerDraw = true, + RadioCheck = true, + ShowShortcut = false, + Shortcut = Shortcut.CtrlA, + Site = Mock.Of(), + Tag = "tag", + Visible = false + }; + var menu = new SubMenu(new MenuItem[] { new MenuItem("parent", new MenuItem[] { source }) }); + MenuItem menuItem = source.MergeMenu(); + Assert.NotSame(source, menuItem); + + Assert.Equal(source.BarBreak, menuItem.BarBreak); + Assert.Equal(source.Break, menuItem.Break); + Assert.Equal(source.Checked, menuItem.Checked); + Assert.Equal(source.DefaultItem, menuItem.DefaultItem); + Assert.Equal(source.Enabled, menuItem.Enabled); + Assert.Equal(-1, menuItem.Index); + Assert.Equal(source.IsParent, menuItem.IsParent); + Assert.Equal(source.MdiList, menuItem.MdiList); + MenuTests.AssertEqualMenuItems(items, menuItem.MenuItems.Cast().ToArray()); + for (int i = 0; i < items.Length; i++) + { + Assert.Equal(i, menuItem.MenuItems[i].Index); + Assert.Equal(menuItem, menuItem.MenuItems[i].Parent); + } + Assert.Equal(source.MergeOrder, menuItem.MergeOrder); + Assert.Equal(source.MergeType, menuItem.MergeType); + Assert.Equal(source.Mnemonic, menuItem.Mnemonic); + Assert.Equal(source.OwnerDraw, menuItem.OwnerDraw); + Assert.Null(menuItem.Parent); + Assert.Equal(source.RadioCheck, menuItem.RadioCheck); + Assert.Equal(source.ShowShortcut, menuItem.ShowShortcut); + Assert.Equal(source.Shortcut, menuItem.Shortcut); + Assert.Equal(source.Visible, menuItem.Visible); + Assert.Empty(menuItem.Name); + Assert.Null(menuItem.Site); + Assert.Null(menuItem.Container); + Assert.Null(menuItem.Tag); + Assert.Equal(source.Text, menuItem.Text); + } + + [Theory] + [MemberData(nameof(CloneMenu_TestData))] + public void MenuItem_MergeMenu_InvokeExisting_Success(MenuItem[] items) + { + var source = new MenuItem("text", items) + { + BarBreak = true, + Break = true, + Checked = items.Length == 0, + Enabled = false, + MdiList = true, + MergeOrder = -1, + MergeType = MenuMerge.Remove, + Name = "name", + OwnerDraw = true, + RadioCheck = true, + ShowShortcut = false, + Shortcut = Shortcut.CtrlA, + Site = Mock.Of(), + Tag = "tag", + Visible = false + }; + var menu = new SubMenu(new MenuItem[] { new MenuItem("parent", new MenuItem[] { source }) }); + var menuItem = new MenuItem(); + menuItem.MergeMenu(source); + + Assert.Equal(source.BarBreak, menuItem.BarBreak); + Assert.Equal(source.Break, menuItem.Break); + Assert.Equal(source.Checked, menuItem.Checked); + Assert.Equal(source.DefaultItem, menuItem.DefaultItem); + Assert.Equal(source.Enabled, menuItem.Enabled); + Assert.Equal(-1, menuItem.Index); + Assert.Equal(source.IsParent, menuItem.IsParent); + Assert.Equal(source.MdiList, menuItem.MdiList); + MenuTests.AssertEqualMenuItems(items, menuItem.MenuItems.Cast().ToArray()); + for (int i = 0; i < items.Length; i++) + { + Assert.Equal(i, menuItem.MenuItems[i].Index); + Assert.Equal(menuItem, menuItem.MenuItems[i].Parent); + } + Assert.Equal(source.MergeOrder, menuItem.MergeOrder); + Assert.Equal(source.MergeType, menuItem.MergeType); + Assert.Equal(source.Mnemonic, menuItem.Mnemonic); + Assert.Equal(source.OwnerDraw, menuItem.OwnerDraw); + Assert.Null(menuItem.Parent); + Assert.Equal(source.RadioCheck, menuItem.RadioCheck); + Assert.Equal(source.ShowShortcut, menuItem.ShowShortcut); + Assert.Equal(source.Shortcut, menuItem.Shortcut); + Assert.Equal(source.Visible, menuItem.Visible); + Assert.Empty(menuItem.Name); + Assert.Null(menuItem.Site); + Assert.Null(menuItem.Container); + Assert.Null(menuItem.Tag); + Assert.Equal(source.Text, menuItem.Text); + } + + [Fact] + public void MenuItem_MergeMenu_OnClick_Success() + { + var source = new SubMenuItem(); + + int sourceCallCount = 0; + source.Click += (sender, e) => + { + sourceCallCount++; + Assert.Equal(source, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + SubMenuItem destination = Assert.IsType(source.MergeMenu()); + int destinationCallCount = 0; + destination.Click += (sender, e) => + { + destinationCallCount++; + Assert.Equal(source, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + destination.OnClick(EventArgs.Empty); + Assert.Equal(1, sourceCallCount); + Assert.Equal(1, destinationCallCount); + + source.OnClick(EventArgs.Empty); + Assert.Equal(2, sourceCallCount); + Assert.Equal(2, destinationCallCount); + } + + [Fact] + public void MenuItem_MergeMenu_OnDrawItem_Success() + { + var source = new SubMenuItem(); + + int sourceCallCount = 0; + source.DrawItem += (sender, e) => + { + sourceCallCount++; + Assert.Equal(source, sender); + Assert.Null(e); + }; + + SubMenuItem destination = Assert.IsType(source.MergeMenu()); + int destinationCallCount = 0; + destination.DrawItem += (sender, e) => + { + destinationCallCount++; + Assert.Equal(source, sender); + Assert.Null(e); + }; + + destination.OnDrawItem(null); + Assert.Equal(1, sourceCallCount); + Assert.Equal(1, destinationCallCount); + + source.OnDrawItem(null); + Assert.Equal(2, sourceCallCount); + Assert.Equal(2, destinationCallCount); + } + + [Fact] + public void MenuItem_MergeMenu_OnMeasureItem_Success() + { + var source = new SubMenuItem(); + + int sourceCallCount = 0; + source.MeasureItem += (sender, e) => + { + sourceCallCount++; + Assert.Equal(source, sender); + Assert.Null(e); + }; + + SubMenuItem destination = Assert.IsType(source.MergeMenu()); + int destinationCallCount = 0; + destination.MeasureItem += (sender, e) => + { + destinationCallCount++; + Assert.Equal(source, sender); + Assert.Null(e); + }; + + destination.OnMeasureItem(null); + Assert.Equal(1, sourceCallCount); + Assert.Equal(1, destinationCallCount); + + source.OnMeasureItem(null); + Assert.Equal(2, sourceCallCount); + Assert.Equal(2, destinationCallCount); + } + + [Fact] + public void MenuItem_MergeMenu_OnPopup_Success() + { + var source = new SubMenuItem(); + + int sourceCallCount = 0; + source.Popup += (sender, e) => + { + sourceCallCount++; + Assert.Equal(source, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + SubMenuItem destination = Assert.IsType(source.MergeMenu()); + int destinationCallCount = 0; + destination.Popup += (sender, e) => + { + destinationCallCount++; + Assert.Equal(source, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + destination.OnPopup(EventArgs.Empty); + Assert.Equal(1, sourceCallCount); + Assert.Equal(1, destinationCallCount); + + source.OnPopup(EventArgs.Empty); + Assert.Equal(2, sourceCallCount); + Assert.Equal(2, destinationCallCount); + } + + [Fact] + public void MenuItem_MergeMenu_OnSelect_Success() + { + var source = new SubMenuItem(); + + int sourceCallCount = 0; + source.Select += (sender, e) => + { + sourceCallCount++; + Assert.Equal(source, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + SubMenuItem destination = Assert.IsType(source.MergeMenu()); + int destinationCallCount = 0; + destination.Select += (sender, e) => + { + destinationCallCount++; + Assert.Equal(source, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + destination.OnSelect(EventArgs.Empty); + Assert.Equal(1, sourceCallCount); + Assert.Equal(1, destinationCallCount); + + source.OnSelect(EventArgs.Empty); + Assert.Equal(2, sourceCallCount); + Assert.Equal(2, destinationCallCount); + } + + [Fact] + public void MenuItem_MergeMenu_NullMenuSource_ThrowsArgumentNullException() + { + var menu = new MenuItem("text"); + Assert.Throws("menuSrc", () => menu.MergeMenu(null)); + } + + [Fact] + public void MenuItem_MergeMenu_Disposed_ThrowsObjectDisposedException() + { + var menuItem = new MenuItem(); + menuItem.Dispose(); + Assert.Throws(() => menuItem.MergeMenu()); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringWithNullTheoryData))] + public void MenuItem_ToString_Invoke_ReturnsExpected(string text) + { + var menuItem = new MenuItem + { + Text = text + }; + Assert.Equal("System.Windows.Forms.MenuItem, Items.Count: 0, Text: " + text, menuItem.ToString()); + } + + [Fact] + public void MenuItem_Dispose_NoParentOrChildren_Success() + { + var menuItem = new MenuItem("text", Array.Empty()); + menuItem.Dispose(); + menuItem.Dispose(); + } + + [Fact] + public void MenuItem_Dispose_NoParent_Success() + { + var childMenuItem = new MenuItem(); + var menuItem = new MenuItem("text", new MenuItem[] { childMenuItem }); + menuItem.Dispose(); + Assert.Null(childMenuItem.Parent); + Assert.Empty(menuItem.MenuItems); + + menuItem.Dispose(); + Assert.Empty(menuItem.MenuItems); + } + + [Fact] + public void MenuItem_Dispose_HasParent_Success() + { + var childMenuItem = new MenuItem(); + var menuItem = new MenuItem("text", new MenuItem[] { childMenuItem }); + childMenuItem.Dispose(); + Assert.Null(childMenuItem.Parent); + Assert.Empty(menuItem.MenuItems); + + childMenuItem.Dispose(); + Assert.Empty(menuItem.MenuItems); + } + + [Fact] + public void MenuItem_Dispose_HasMenuId_Success() + { + var menuItem = new SubMenuItem(); + Assert.NotEqual(0, menuItem.MenuID); + + menuItem.Dispose(); + Assert.Throws(() => menuItem.MenuID); + + menuItem.Dispose(); + Assert.Throws(() => menuItem.MenuID); + } + + public class SubMenuItem : MenuItem + { + public SubMenuItem() + { + } + + public SubMenuItem(string text) : base(text) + { + } + + public SubMenuItem(string text, EventHandler onClick) : base(text, onClick) + { + } + + public SubMenuItem(string text, MenuItem[] items) : base(text, items) + { + } + + public SubMenuItem(string text, EventHandler onClick, Shortcut shortcut) : base(text, onClick, shortcut) + { + } + + public SubMenuItem(MenuMerge mergeType, int mergeOrder, Shortcut shortcut, string text, EventHandler onClick, EventHandler onPopup, EventHandler onSelect, MenuItem[] items) : base(mergeType, mergeOrder, shortcut, text, onClick, onPopup, onSelect, items) + { + } + + public new int MenuID => base.MenuID; + + public new void OnClick(EventArgs e) => base.OnClick(e); + + public new void OnDrawItem(DrawItemEventArgs e) => base.OnDrawItem(e); + + public new void OnInitMenuPopup(EventArgs e) => base.OnInitMenuPopup(e); + + public new void OnMeasureItem(MeasureItemEventArgs e) => base.OnMeasureItem(e); + + public new void OnPopup(EventArgs e) => base.OnPopup(e); + + public new void OnSelect(EventArgs e) => base.OnSelect(e); + + public new void CloneMenu(Menu menuSrc) => base.CloneMenu(menuSrc); + } + + private class SubMenu : Menu + { + public SubMenu(params MenuItem[] items) : base(items) + { + } + } + + private class SubForm : Form + { + public new void ActivateMdiChild(Form form) => base.ActivateMdiChild(form); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/MenuTests.cs b/WTG.System.Windows.Forms.Tests/MenuTests.cs new file mode 100644 index 00000000000..8f0e703ac68 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/MenuTests.cs @@ -0,0 +1,741 @@ +using System.ComponentModel; +using System.Windows.Forms; +using Moq; +using WTG.System.Windows.Forms.Tests.Common; + +namespace WTG.System.Windows.Forms.Tests +{ + public class MenuTests + { + public static IEnumerable Ctor_MenuItemArray_TestData() + { + yield return new object[] { null, false }; + yield return new object[] { Array.Empty(), false }; + yield return new object[] { new MenuItem[] { new MenuItem() }, true }; + } + + [Theory] + [MemberData(nameof(Ctor_MenuItemArray_TestData))] + public void Menu_Ctor_MenuItemArray(MenuItem[] items, bool expectedIsParent) + { + var menu = new SubMenu(items); + Assert.Equal(items ?? Array.Empty(), menu.MenuItems.Cast()); + for (int i = 0; i < (items?.Length ?? 0); i++) + { + Assert.Equal(i, menu.MenuItems[i].Index); + Assert.Equal(menu, menu.MenuItems[i].Parent); + } + Assert.Equal(expectedIsParent, menu.IsParent); + Assert.Empty(menu.Name); + Assert.Null(menu.Site); + Assert.Null(menu.Container); + Assert.Null(menu.Tag); + } + + [Fact] + public void Menu_Ctor_NullItemInMenuItemArray_ThrowsArgumentNullException() + { + Assert.Throws("item", () => new SubMenu(new MenuItem[] { null })); + } + + [Fact] + public void Menu_FindHandle_Get_ReturnsExpected() + { + Assert.Equal(0, Menu.FindHandle); + } + + [Fact] + public void Menu_FindShortcut_Get_ReturnsExpected() + { + Assert.Equal(1, Menu.FindShortcut); + } + + public static IEnumerable HandleMenuItems_TestData() + { + yield return new object[] { Array.Empty() }; + yield return new object[] + { + new MenuItem[] + { + // Not visible. + new MenuItem { Visible = false }, + + // Has state. + new MenuItem { BarBreak = true, Break = true, Checked = true, DefaultItem = true, Enabled = false }, + + // Has shortcut. + new MenuItem { Shortcut = Shortcut.CtrlA }, + + // Has no shortcut. + new MenuItem { ShowShortcut = false, Shortcut = Shortcut.CtrlA }, + + // Has owner draw. + new MenuItem("text") { OwnerDraw = true }, + + // Has children. + new MenuItem("text", new MenuItem[] { new MenuItem("child") }), + } + }; + } + + [Theory] + [MemberData(nameof(HandleMenuItems_TestData))] + public void Menu_Handle_Get_ReturnsExpected(MenuItem[] items) + { + using (var menu = new SubMenu(items)) + { + Assert.NotEqual(IntPtr.Zero, menu.Handle); + Assert.Equal(menu.Handle, menu.Handle); + } + } + + [Fact] + public void Menu_Handle_GetWithDashTextInNormalMenu_ReturnsExpected() + { + var menuItem = new MenuItem("-"); + using (var menu = new SubMenu(new MenuItem[] { menuItem })) + { + Assert.NotEqual(IntPtr.Zero, menu.Handle); + Assert.Equal(menu.Handle, menu.Handle); + + // Does not affect the text. + Assert.Equal("-", menuItem.Text); + } + } + + [Fact] + public void Menu_Handle_GetWithDashTextInMainMenu_ReturnsExpected() + { + var menuItem = new MenuItem("-"); + using (var menu = new MainMenu(new MenuItem[] { menuItem })) + { + Assert.NotEqual(IntPtr.Zero, menu.Handle); + Assert.Equal(menu.Handle, menu.Handle); + + // Sets the separator to a space. + Assert.Equal(" ", menuItem.Text); + } + } + + [Fact] + public void Menu_Handle_GetWithRightToLeftItem_ReturnsExpected() + { + using (var menu = new ContextMenu(new MenuItem[] { new MenuItem("text") })) + { + menu.RightToLeft = RightToLeft.Yes; + Assert.NotEqual(IntPtr.Zero, menu.Handle); + Assert.Equal(menu.Handle, menu.Handle); + } + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void Menu_Name_GetWithSite_ReturnsExpected(string name, string expected) + { + var menu = new SubMenu(Array.Empty()) + { + Site = Mock.Of(s => s.Name == name) + }; + Assert.Equal(expected, menu.Name); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void Menu_Name_SetWithoutSite_GetReturnsExpected(string value, string expected) + { + var menu = new SubMenu(Array.Empty()) + { + Name = value + }; + Assert.Equal(expected, menu.Name); + + // Set same. + menu.Name = value; + Assert.Equal(expected, menu.Name); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringNormalizedTheoryData))] + public void Menu_Name_SetWithSite_GetReturnsExpected(string value, string expected) + { + var menu = new SubMenu(Array.Empty()) + { + Site = Mock.Of(), + Name = value + }; + Assert.Equal(expected, menu.Name); + Assert.Equal(value?.Length == 0 ? null : value, menu.Site.Name); + } + + public static IEnumerable MdiListItem_TestData() + { + var listItem1 = new MenuItem { MdiList = true }; + var listItem2 = new MenuItem { MdiList = true }; + + yield return new object[] { Array.Empty(), null }; + yield return new object[] { new MenuItem[] { listItem1 }, listItem1 }; + yield return new object[] { new MenuItem[] { new MenuItem() }, null }; + yield return new object[] { new MenuItem[] { new MenuItem("parent", new MenuItem[] { listItem2 }) }, listItem2 }; + yield return new object[] { new MenuItem[] { new MenuItem("parent", new MenuItem[] { new MenuItem() }) }, null }; + } + + [Theory] + [MemberData(nameof(MdiListItem_TestData))] + public void Menu_MdiListItem_Get_ReturnsExpected(MenuItem[] items, MenuItem expected) + { + var menu = new SubMenu(items); + Assert.Equal(expected, menu.MdiListItem); + } + + [Theory] + [CommonMemberData(nameof(CommonTestHelper.GetStringWithNullTheoryData))] + public void Menu_Tag_Set_GetReturnsExpected(object value) + { + var menu = new SubMenu(Array.Empty()) + { + Tag = value + }; + Assert.Same(value, menu.Tag); + + // Set same. + menu.Tag = value; + Assert.Same(value, menu.Tag); + } + + public static IEnumerable FindMenuItem_TestData() + { + yield return new object[] { Array.Empty(), MenuItem.FindHandle, IntPtr.Zero, null }; + yield return new object[] { Array.Empty(), MenuItem.FindShortcut, IntPtr.Zero, null }; + yield return new object[] { Array.Empty(), 2, IntPtr.Zero, null }; + + var menuItem1 = new MenuItem(); + var menuItem2 = new MenuItem(); + yield return new object[] { new MenuItem[] { menuItem1 }, MenuItem.FindHandle, IntPtr.Zero, menuItem1 }; + yield return new object[] { new MenuItem[] { new MenuItem() }, MenuItem.FindHandle, (IntPtr)1, null }; + yield return new object[] { new MenuItem[] { menuItem2 }, MenuItem.FindShortcut, IntPtr.Zero, menuItem2 }; + yield return new object[] { new MenuItem[] { new MenuItem() }, MenuItem.FindShortcut, (IntPtr)1, null }; + yield return new object[] { new MenuItem[] { new MenuItem() }, 2, IntPtr.Zero, null }; + + var shortcutItem1 = new MenuItem + { + Shortcut = Shortcut.CtrlA + }; + yield return new object[] { new MenuItem[] { shortcutItem1 }, MenuItem.FindShortcut, (IntPtr)0x20041, shortcutItem1 }; + yield return new object[] { new MenuItem[] { new MenuItem { Shortcut = Shortcut.CtrlA } }, MenuItem.FindShortcut, (IntPtr)0x20042, null }; + + var parent = new MenuItem("parent", new MenuItem[] { new MenuItem() }); + var shortcutItem2 = new MenuItem + { + Shortcut = Shortcut.CtrlA + }; + yield return new object[] { new MenuItem[] { parent }, MenuItem.FindHandle, IntPtr.Zero, parent }; + yield return new object[] { new MenuItem[] { new MenuItem("parent", new MenuItem[] { new MenuItem() }) }, MenuItem.FindHandle, (IntPtr)1, null }; + yield return new object[] { new MenuItem[] { new MenuItem("parent", new MenuItem[] { new MenuItem() }) }, MenuItem.FindHandle, (IntPtr)1, null }; + yield return new object[] { new MenuItem[] { new MenuItem("parent", new MenuItem[] { shortcutItem2 }) }, MenuItem.FindShortcut, (IntPtr)0x20041, shortcutItem2 }; + yield return new object[] { new MenuItem[] { new MenuItem("parent", new MenuItem[] { new MenuItem() { Shortcut = Shortcut.CtrlA } }) }, MenuItem.FindShortcut, (IntPtr)0x20042, null }; + } + + [Theory] + [MemberData(nameof(FindMenuItem_TestData))] + public void Menu_FindMenuItem_Invoke_ReturnsExpected(MenuItem[] items, int type, IntPtr value, MenuItem expected) + { + var menu = new SubMenu(items); + Assert.Equal(expected, menu.FindMenuItem(type, value)); + } + + public static IEnumerable ProcessCmdKey_TestData() + { + yield return new object[] { new MenuItem { Shortcut = Shortcut.CtrlA }, true, 1, 0 }; + yield return new object[] { new MenuItem { Shortcut = Shortcut.CtrlA, Enabled = false }, false, 0, 0 }; + yield return new object[] { new MenuItem("text", new MenuItem[] { new MenuItem() }) { Shortcut = Shortcut.CtrlA }, true, 0, 1 }; + yield return new object[] { new MenuItem("text", new MenuItem[] { new MenuItem() }) { Shortcut = Shortcut.CtrlA, Enabled = false }, false, 0, 0 }; + } + + [Theory] + [MemberData(nameof(ProcessCmdKey_TestData))] + public void Menu_ProcessCmdKey_HasItemWithShoutcutKey_ReturnsExpected(MenuItem menuItem, bool expectedResult, int expectedOnClickCallCount, int expectedOnPopupCallCount) + { + int onClickCallCount = 0; + menuItem.Click += (sender, e) => + { + onClickCallCount++; + Assert.Same(menuItem, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + int onPopupCallCount = 0; + menuItem.Popup += (sender, e) => + { + onPopupCallCount++; + Assert.Same(menuItem, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + var menu = new SubMenu(new MenuItem[] { menuItem }); + var message = new Message(); + Assert.Equal(expectedResult, menu.ProcessCmdKey(ref message, Keys.Control | Keys.A)); + Assert.Equal(expectedOnClickCallCount, onClickCallCount); + Assert.Equal(expectedOnPopupCallCount, onPopupCallCount); + } + + public static IEnumerable ProcessCmdKey_MenuItemParent_TestData() + { + var enabledParentChild = new MenuItem { Shortcut = Shortcut.CtrlA }; + var enabledParent = new MenuItem("text", new MenuItem[] { enabledParentChild }); + yield return new object[] { enabledParent, enabledParentChild, true, 1, 0, 0, 1 }; + + var enabledParentChildWithItems = new MenuItem("text", new MenuItem[] { new MenuItem() }) { Shortcut = Shortcut.CtrlA }; + var enabledParentWithItems = new MenuItem("text", new MenuItem[] { enabledParentChildWithItems }); + yield return new object[] { enabledParentWithItems, enabledParentChildWithItems, true, 0, 1, 0, 1 }; + + var disabledParentChild = new MenuItem { Shortcut = Shortcut.CtrlA }; + var disabledParent = new MenuItem("text", new MenuItem[] { disabledParentChild }) { Enabled = false }; + yield return new object[] { disabledParent, disabledParentChild, false, 0, 0, 0, 0 }; + } + + [Theory] + [MemberData(nameof(ProcessCmdKey_MenuItemParent_TestData))] + public void Menu_ProcessCmdKey_MenuItemParent_ReturnsExpected(MenuItem parent, MenuItem child, bool expectedResult, int expectedChildOnClickCallCount, int expectedChildOnPopupCallCount, int expectedParentOnClickCallCount, int expectedParentOnPopupCallCount) + { + int childOnClickCallCount = 0; + child.Click += (sender, e) => + { + childOnClickCallCount++; + Assert.Same(child, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + int childOnPopupCallCount = 0; + child.Popup += (sender, e) => + { + childOnPopupCallCount++; + Assert.Same(child, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + int parentOnClickCallCount = 0; + parent.Click += (sender, e) => + { + parentOnClickCallCount++; + Assert.Same(parent, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + int parentOnPopupCallCount = 0; + parent.Popup += (sender, e) => + { + parentOnPopupCallCount++; + Assert.Same(parent, sender); + Assert.Equal(EventArgs.Empty, e); + }; + + var message = new Message(); + Assert.Equal(expectedResult, parent.ProcessCmdKey(ref message, Keys.Control | Keys.A)); + Assert.Equal(expectedChildOnClickCallCount, childOnClickCallCount); + Assert.Equal(expectedChildOnPopupCallCount, childOnPopupCallCount); + Assert.Equal(expectedParentOnClickCallCount, parentOnClickCallCount); + Assert.Equal(expectedParentOnPopupCallCount, parentOnPopupCallCount); + } + + [Fact] + public void Menu_ProcessCmdKey_ParentMenuItemPopupHandlerRemovesChild_ReturnsFalse() + { + var child = new MenuItem { Shortcut = Shortcut.CtrlA }; + var parent = new MenuItem("text", new MenuItem[] { child }); + var message = new Message(); + + parent.Popup += (sender, e) => + { + parent.MenuItems.Remove(child); + }; + + Assert.False(parent.ProcessCmdKey(ref message, Keys.Control | Keys.A)); + } + + [Fact] + public void Menu_ProcessCmdKey_NoSuchShortcutKey_ReturnsFalse() + { + var menu = new SubMenu(new MenuItem[] { new MenuItem() }); + var message = new Message(); + Assert.False(menu.ProcessCmdKey(ref message, Keys.Control | Keys.A)); + } + + [Fact] + public void Menu_Dispose_NoChildren_Success() + { + var menu = new SubMenu(Array.Empty()); + menu.Dispose(); + menu.Dispose(); + } + + [Fact] + public void Menu_Dispose_WithChildren_Success() + { + var menuItem = new MenuItem(); + var menu = new SubMenu(new MenuItem[] { menuItem }); + menu.Dispose(); + Assert.Null(menuItem.Parent); + Assert.Empty(menu.MenuItems); + + menu.Dispose(); + Assert.Empty(menu.MenuItems); + } + + [Fact] + public void Menu_Dispose_ItemHasSite_Success() + { + var menuItem = new MenuItem + { + Site = Mock.Of() + }; + var menu = new SubMenu(new MenuItem[] { menuItem }); + menu.Dispose(); + Assert.Null(menuItem.Parent); + Assert.Empty(menu.MenuItems); + + menu.Dispose(); + Assert.Empty(menu.MenuItems); + } + + [Fact] + public void Menu_Dispose_ItemHasSiteWithContainer_Success() + { + var container = new Container(); + var menuItem = new MenuItem + { + Site = Mock.Of(s => s.Container == container) + }; + container.Add(menuItem); + var menu = new SubMenu(new MenuItem[] { menuItem }); + menu.Dispose(); + Assert.Empty(container.Components); + Assert.Null(menuItem.Parent); + Assert.Empty(menu.MenuItems); + + menu.Dispose(); + Assert.Empty(menu.MenuItems); + } + + public static IEnumerable FindMergePosition_TestData() + { + yield return new object[] { Array.Empty(), -1, 0 }; + yield return new object[] { new MenuItem[] { new MenuItem { MergeOrder = 10 }, new MenuItem { MergeOrder = 12 }, new MenuItem(), new MenuItem(), new MenuItem() }, 12, 5 }; + yield return new object[] { new MenuItem[] { new MenuItem { MergeOrder = 10 }, new MenuItem { MergeOrder = 12 }, new MenuItem(), new MenuItem(), new MenuItem() }, 11, 5 }; + yield return new object[] { new MenuItem[] { new MenuItem { MergeOrder = 10 }, new MenuItem { MergeOrder = 12 }, new MenuItem(), new MenuItem(), new MenuItem() }, -1, 0 }; + yield return new object[] { new MenuItem[] { new MenuItem { MergeOrder = 10 }, new MenuItem(), new MenuItem(), new MenuItem { MergeOrder = 12 }, new MenuItem() }, 0, 5 }; + yield return new object[] { new MenuItem[] { new MenuItem { MergeOrder = 10 }, new MenuItem(), new MenuItem(), new MenuItem { MergeOrder = 12 }, new MenuItem() }, 5, 5 }; + yield return new object[] { new MenuItem[] { new MenuItem() }, 0, 1 }; + } + + [Theory] + [MemberData(nameof(FindMergePosition_TestData))] + public void Menu_FindMergePosition_Invoke_ReturnsExpected(MenuItem[] items, int mergeOrder, int expected) + { + var menu = new SubMenu(items); + Assert.Equal(expected, menu.FindMergePosition(mergeOrder)); + } + + public static IEnumerable GetContextMenu_TestData() + { + yield return new object[] { new SubMenu(Array.Empty()), null }; + yield return new object[] { new MenuItem(), null }; + + var menuItem1 = new MenuItem(); + var menu1 = new ContextMenu(new MenuItem[] { menuItem1 }); + yield return new object[] { menu1, menu1 }; + yield return new object[] { menuItem1, menu1 }; + + var menuItem2 = new MenuItem(); + var menu2 = new SubMenu(new MenuItem[] { menuItem2 }); + yield return new object[] { menu2, null }; + yield return new object[] { menuItem2, null }; + } + + [Theory] + [MemberData(nameof(GetContextMenu_TestData))] + public void Menu_GetContextMenu_Invoke_ReturnsExpected(Menu menu, ContextMenu expected) + { + Assert.Equal(expected, menu.GetContextMenu()); + } + + public static IEnumerable GetMainMenu_TestData() + { + yield return new object[] { new SubMenu(Array.Empty()), null }; + yield return new object[] { new MenuItem(), null }; + + var menuItem1 = new MenuItem(); + var menu1 = new MainMenu(new MenuItem[] { menuItem1 }); + yield return new object[] { menu1, menu1 }; + yield return new object[] { menuItem1, menu1 }; + + var menuItem2 = new MenuItem(); + var menu2 = new SubMenu(new MenuItem[] { menuItem2 }); + yield return new object[] { menu2, null }; + yield return new object[] { menuItem2, null }; + } + + [Theory] + [MemberData(nameof(GetMainMenu_TestData))] + public void Menu_GetMainMenu_Invoke_ReturnsExpected(Menu menu, MainMenu expected) + { + Assert.Equal(expected, menu.GetMainMenu()); + } + + public static IEnumerable MergeMenu_TestData() + { + { + var menu1 = new MenuItem("1"); + var menu2 = new MenuItem("2"); + yield return new object[] + { + new MenuItem[] { menu1 }, + new MenuItem[] { menu2 }, + new MenuItem[] { menu1, menu2 } + }; + } + { + var menu1 = new MenuItem("1"); + var menu2 = new MenuItem("2") { MergeType = MenuMerge.MergeItems }; + yield return new object[] + { + new MenuItem[] { menu1 }, + new MenuItem[] { menu2 }, + new MenuItem[] { menu1, menu2 } + }; + } + { + var menu1 = new MenuItem("1"); + var menu2 = new MenuItem("2"); + var menu3 = new MenuItem("3") { MergeType = MenuMerge.Replace }; + yield return new object[] + { + new MenuItem[] { menu1, menu2 }, + new MenuItem[] { menu3 }, + new MenuItem[] { menu1, menu2, menu3 } + }; + } + { + var menu1 = new MenuItem("1"); + var menu2 = new MenuItem("2") { MergeType = MenuMerge.Remove }; + yield return new object[] + { + new MenuItem[] { menu1 }, + new MenuItem[] { menu2 }, + new MenuItem[] { menu1 } + }; + } + { + var menu1 = new MenuItem("1") { MergeOrder = 1 }; + var menu2 = new MenuItem("2"); + yield return new object[] + { + new MenuItem[] { menu1 }, + new MenuItem[] { menu2 }, + new MenuItem[] { menu2, menu1 } + }; + } + { + var menu1 = new MenuItem("1") { MergeOrder = -1 }; + var menu2 = new MenuItem("2"); + yield return new object[] + { + new MenuItem[] { menu1 }, + new MenuItem[] { menu2 }, + new MenuItem[] { menu1, menu2 } + }; + } + { + var menu1 = new MenuItem("1") { MergeOrder = 1 }; + var menu2 = new MenuItem("2") { MergeOrder = 1 }; + var menu3 = new MenuItem("3") { MergeOrder = 2 }; + var menu4 = new MenuItem("4") { MergeOrder = 2 }; + var menu5 = new MenuItem("5") { MergeOrder = 3 }; + var menu6 = new MenuItem("6") { MergeOrder = 0 }; + yield return new object[] + { + new MenuItem[] { menu1, menu2, menu3 }, + new MenuItem[] { menu4, menu5, menu6 }, + new MenuItem[] { menu6, menu1, menu2, menu3, menu4, menu5 } + }; + } + { + var menu1 = new MenuItem("1") { MergeOrder = 1, MergeType = MenuMerge.Replace }; + var menu2 = new MenuItem("2") { MergeOrder = 1, MergeType = MenuMerge.Replace }; + var menu3 = new MenuItem("3") { MergeOrder = 2, MergeType = MenuMerge.Replace }; + var menu4 = new MenuItem("4") { MergeOrder = 2, MergeType = MenuMerge.Replace }; + var menu5 = new MenuItem("5") { MergeOrder = 3, MergeType = MenuMerge.Replace }; + var menu6 = new MenuItem("6") { MergeOrder = 0, MergeType = MenuMerge.Replace }; + yield return new object[] + { + new MenuItem[] { menu1, menu2, menu3 }, + new MenuItem[] { menu4, menu5, menu6 }, + new MenuItem[] { menu6, menu1, menu3, menu4, menu5 } + }; + } + { + var menu1 = new MenuItem("1") { MergeOrder = 1, MergeType = MenuMerge.Remove }; + var menu2 = new MenuItem("2") { MergeOrder = 1, MergeType = MenuMerge.Remove }; + var menu3 = new MenuItem("3") { MergeOrder = 2, MergeType = MenuMerge.Remove }; + var menu4 = new MenuItem("4") { MergeOrder = 2, MergeType = MenuMerge.Remove }; + var menu5 = new MenuItem("5") { MergeOrder = 3, MergeType = MenuMerge.Remove }; + var menu6 = new MenuItem("6") { MergeOrder = 0, MergeType = MenuMerge.Remove }; + yield return new object[] + { + new MenuItem[] { menu1, menu2, menu3 }, + new MenuItem[] { menu4, menu5, menu6 }, + new MenuItem[] { menu1, menu2, menu3 } + }; + } + { + var menu1 = new MenuItem("1") { MergeOrder = 1, MergeType = MenuMerge.MergeItems }; + var menu2 = new MenuItem("2") { MergeOrder = 1, MergeType = MenuMerge.MergeItems }; + var menu3 = new MenuItem("3") { MergeOrder = 2, MergeType = MenuMerge.MergeItems }; + var menu4 = new MenuItem("4") { MergeOrder = 2, MergeType = MenuMerge.MergeItems }; + var menu5 = new MenuItem("5") { MergeOrder = 3, MergeType = MenuMerge.MergeItems }; + var menu6 = new MenuItem("6") { MergeOrder = 0, MergeType = MenuMerge.MergeItems }; + yield return new object[] + { + new MenuItem[] { menu1, menu2, menu3 }, + new MenuItem[] { menu4, menu5, menu6 }, + new MenuItem[] { menu6, menu1, menu2, menu4, menu5 } + }; + } + { + var menu1 = new MenuItem("1"); + var menu2 = new MenuItem("2"); + yield return new object[] + { + new MenuItem[] { menu1, menu2 }, + null, + new MenuItem[] { menu1, menu2 } + }; + } + { + var menu1 = new MenuItem("1"); + var menu2 = new MenuItem("2"); + yield return new object[] + { + null, + new MenuItem[] { menu1, menu2 }, + new MenuItem[] { menu1, menu2 } + }; + } + { + yield return new object[] + { + null, + null, + Array.Empty() + }; + } + } + + [Theory] + [MemberData(nameof(MergeMenu_TestData))] + public void Menu_MergeMenu_Invoke_ReturnsExpected(MenuItem[] destinationItems, MenuItem[] sourceItems, MenuItem[] expectedItems) + { + var menu = new SubMenu(destinationItems); + var menuSrc = new SubMenu(sourceItems); + menu.MergeMenu(menuSrc); + AssertEqualMenuItems(expectedItems, menu.MenuItems.Cast().ToArray()); + } + + [Fact] + public void Menu_MergeMenu_SameSourceAndDestination_ThrowsArgumentException() + { + var menu = new SubMenu(Array.Empty()); + Assert.Throws("menuSrc", () => menu.MergeMenu(menu)); + } + + [Fact] + public void Menu_MergeMenu_NullSource_ThrowsArgumentNullException() + { + var menu = new SubMenu(Array.Empty()); + Assert.Throws("menuSrc", () => menu.MergeMenu(null)); + } + + public static IEnumerable CloneMenu_TestData() + { + yield return new object[] { Array.Empty() }; + yield return new object[] { new MenuItem[] { new MenuItem("text") } }; + } + + [Theory] + [MemberData(nameof(CloneMenu_TestData))] + public void Menu_CloneMenu_Invoke_Success(MenuItem[] items) + { + var menu = new SubMenu(new MenuItem[] { new MenuItem() }); + menu.CloneMenu(new SubMenu(items)); + AssertEqualMenuItems(items, menu.MenuItems.Cast().ToArray()); + for (int i = 0; i < items.Length; i++) + { + Assert.Equal(i, menu.MenuItems[i].Index); + Assert.Equal(menu, menu.MenuItems[i].Parent); + } + } + + [Fact] + public void Menu_CloneMenu_NullMenuSource_ThrowsArgumentNullException() + { + var menu = new SubMenu(Array.Empty()); + Assert.Throws("menuSrc", () => menu.CloneMenu(null)); + } + + [Fact] + public void Menu_CreateMenuHandle_Invoke_ReturnsExpected() + { + var menu = new SubMenu(Array.Empty()); + Assert.NotEqual(IntPtr.Zero, menu.CreateMenuHandle()); + } + + [Fact] + public void Menu_ToString_Invoke_ReturnsExpected() + { + var menu = new SubMenu(new MenuItem[] { new MenuItem() }); + Assert.Equal("WTG.System.Windows.Forms.Tests.MenuTests+SubMenu, Items.Count: 1", menu.ToString()); + } + + internal static void AssertEqualMenuItems(MenuItem[] expected, MenuItem[] actual) + { + Assert.Equal(expected.Length, actual.Length); + try + { + Assert.Equal(expected.Select(m => m.Text), actual.Cast().Select(m => m.Text)); + } + catch (ObjectDisposedException) + { + } + for (int i = 0; i < expected.Length; i++) + { + AssertEqualMenuItem(expected[i], actual[i]); + } + } + + internal static void AssertEqualMenuItem(MenuItem expected, MenuItem actual) + { + try + { + Assert.Equal(expected.Name, actual.Name); + } + catch (ObjectDisposedException) + { + } + AssertEqualMenuItems(expected.MenuItems.Cast().ToArray(), actual.MenuItems.Cast().ToArray()); + } + + private class SubMenu : Menu + { + public SubMenu(MenuItem[] items) : base(items) + { + } + + public new IntPtr CreateMenuHandle() => base.CreateMenuHandle(); + + public new int FindMergePosition(int mergeOrder) => base.FindMergePosition(mergeOrder); + + public new void CloneMenu(Menu menuSrc) => base.CloneMenu(menuSrc); + + public new bool ProcessCmdKey(ref Message msg, Keys keyData) => base.ProcessCmdKey(ref msg, keyData); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/StatusBarDrawItemEventArgsTests.cs b/WTG.System.Windows.Forms.Tests/StatusBarDrawItemEventArgsTests.cs new file mode 100644 index 00000000000..36d2b65c4c1 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/StatusBarDrawItemEventArgsTests.cs @@ -0,0 +1,64 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.Tests +{ + public class StatusBarDrawItemEventArgsTests + { + public static IEnumerable Ctor_Graphics_Font_Rectangle_Int_DrawItemState_StatusBarPanel_TestData() + { + yield return new object[] { null, Rectangle.Empty, -2, (DrawItemState)(DrawItemState.None - 1), null, SystemColors.HighlightText, SystemColors.Highlight }; + yield return new object[] { SystemFonts.DefaultFont, new Rectangle(1, 2, 3, 4), -1, DrawItemState.None, new StatusBarPanel(), SystemColors.WindowText, SystemColors.Window }; + yield return new object[] { SystemFonts.DefaultFont, new Rectangle(-1, 2, -3, -4), 0, DrawItemState.Selected, new StatusBarPanel(), SystemColors.HighlightText, SystemColors.Highlight }; + yield return new object[] { SystemFonts.DefaultFont, new Rectangle(1, 2, 3, 4), 1, DrawItemState.Focus, new StatusBarPanel(), SystemColors.WindowText, SystemColors.Window }; + yield return new object[] { SystemFonts.DefaultFont, new Rectangle(1, 2, 3, 4), 1, DrawItemState.Focus | DrawItemState.NoFocusRect, new StatusBarPanel(), SystemColors.WindowText, SystemColors.Window }; + } + + [Theory] + [MemberData(nameof(Ctor_Graphics_Font_Rectangle_Int_DrawItemState_StatusBarPanel_TestData))] + public void StatusBarDrawItemEventArgs_Ctor_Graphics_Font_Rectangle_Int_DrawItemState_StatusBarPanel(Font font, Rectangle rect, int index, DrawItemState state, StatusBarPanel panel, Color expectedForeColor, Color expectedBackColor) + { + using (var image = new Bitmap(10, 10)) + using (Graphics graphics = Graphics.FromImage(image)) + { + var e = new StatusBarDrawItemEventArgs(graphics, font, rect, index, state, panel); + Assert.Same(graphics, e.Graphics); + Assert.Same(font, e.Font); + Assert.Equal(rect, e.Bounds); + Assert.Equal(index, e.Index); + Assert.Equal(state, e.State); + Assert.Same(panel, e.Panel); + Assert.Equal(expectedForeColor, e.ForeColor); + Assert.Equal(expectedBackColor, e.BackColor); + } + } + + public static IEnumerable Ctor_Graphics_Font_Rectangle_Int_DrawItemState_StatusBarPanel_Color_Color_TestData() + { + yield return new object[] { null, Rectangle.Empty, -2, (DrawItemState)(DrawItemState.None - 1), null, Color.Empty, Color.Empty, SystemColors.HighlightText, SystemColors.Highlight }; + yield return new object[] { SystemFonts.DefaultFont, new Rectangle(1, 2, 3, 4), -1, DrawItemState.None, new StatusBarPanel(), Color.Red, Color.Blue, Color.Red, Color.Blue }; + yield return new object[] { SystemFonts.DefaultFont, new Rectangle(-1, 2, -3, -4), 0, DrawItemState.Selected, new StatusBarPanel(), Color.Red, Color.Blue, SystemColors.HighlightText, SystemColors.Highlight }; + yield return new object[] { SystemFonts.DefaultFont, new Rectangle(1, 2, 3, 4), 1, DrawItemState.Focus, new StatusBarPanel(), Color.Red, Color.Blue, Color.Red, Color.Blue }; + yield return new object[] { SystemFonts.DefaultFont, new Rectangle(1, 2, 3, 4), 1, DrawItemState.Focus | DrawItemState.NoFocusRect, new StatusBarPanel(), Color.Red, Color.Blue, Color.Red, Color.Blue }; + } + + [Theory] + [MemberData(nameof(Ctor_Graphics_Font_Rectangle_Int_DrawItemState_StatusBarPanel_Color_Color_TestData))] + public void StatusBarDrawItemEventArgs_Ctor_Graphics_Font_Rectangle_Int_DrawItemState_StatusBarPanel_Color_Color(Font font, Rectangle rect, int index, DrawItemState state, StatusBarPanel panel, Color foreColor, Color backColor, Color expectedForeColor, Color expectedBackColor) + { + using (var image = new Bitmap(10, 10)) + using (Graphics graphics = Graphics.FromImage(image)) + { + var e = new StatusBarDrawItemEventArgs(graphics, font, rect, index, state, panel, foreColor, backColor); + Assert.Same(graphics, e.Graphics); + Assert.Same(font, e.Font); + Assert.Equal(rect, e.Bounds); + Assert.Equal(index, e.Index); + Assert.Equal(state, e.State); + Assert.Same(panel, e.Panel); + Assert.Equal(expectedForeColor, e.ForeColor); + Assert.Equal(expectedBackColor, e.BackColor); + } + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/StatusBarPanelClickEventArgsTests.cs b/WTG.System.Windows.Forms.Tests/StatusBarPanelClickEventArgsTests.cs new file mode 100644 index 00000000000..91780370e87 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/StatusBarPanelClickEventArgsTests.cs @@ -0,0 +1,29 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.Tests +{ + public class StatusBarPanelClickEventArgsTests + { + public static IEnumerable Ctor_StatusBarPanel_MouseButtons_Int_Int_Int_Int_TestData() + { + yield return new object[] { null, MouseButtons.Left, 1, 2, 3 }; + yield return new object[] { new StatusBarPanel(), (MouseButtons)1, 0, 0, 0 }; + yield return new object[] { new StatusBarPanel(), (MouseButtons)3, -1, -1, -1 }; + } + + [Theory] + [MemberData(nameof(Ctor_StatusBarPanel_MouseButtons_Int_Int_Int_Int_TestData))] + public void Ctor_StatusBarPanel_MouseButtons_Int_Int_Int_Int(StatusBarPanel statusBarPanel, MouseButtons button, int clicks, int x, int y) + { + var e = new StatusBarPanelClickEventArgs(statusBarPanel, button, clicks, x, y); + Assert.Equal(statusBarPanel, e.StatusBarPanel); + Assert.Equal(button, e.Button); + Assert.Equal(clicks, e.Clicks); + Assert.Equal(x, e.X); + Assert.Equal(y, e.Y); + Assert.Equal(0, e.Delta); + Assert.Equal(new Point(x, y), e.Location); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/System/Windows/Forms/ErrorProviderTests.cs b/WTG.System.Windows.Forms.Tests/System/Windows/Forms/ErrorProviderTests.cs new file mode 100644 index 00000000000..20ad08bf227 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/System/Windows/Forms/ErrorProviderTests.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + + +using System.ComponentModel; +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.System.Windows.Forms +{ + public class ErrorProviderTests + { + public static IEnumerable CanExtend_TestData() + { + yield return new object[] { null, false }; + yield return new object[] { new(), false }; + yield return new object[] { new Component(), false }; + yield return new object[] { new ToolBar(), false }; + yield return new object[] { new Form(), false }; + yield return new object[] { new Control(), true }; + } + + [Theory] + [MemberData(nameof(CanExtend_TestData))] + public void ErrorProvider_CanExtend_Invoke_ReturnsExpected(object extendee, bool expected) + { + var provider = new ErrorProvider(); + Assert.Equal(expected, provider.CanExtend(extendee)); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/System/Windows/Forms/ToolBarButtonClickEventArgsTests.cs b/WTG.System.Windows.Forms.Tests/System/Windows/Forms/ToolBarButtonClickEventArgsTests.cs new file mode 100644 index 00000000000..e9dc4ac9785 --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/System/Windows/Forms/ToolBarButtonClickEventArgsTests.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms.Tests +{ + public class ToolBarButtonClickEventArgsTests + { + public static IEnumerable ToolBarButton_TestData() + { + yield return new object[] { null }; + yield return new object[] { new ToolBarButton() }; + } + + [Theory] + [MemberData(nameof(ToolBarButton_TestData))] + public void Ctor_ToolBarButton(ToolBarButton button) + { + var e = new ToolBarButtonClickEventArgs(button); + Assert.Equal(button, e.Button); + } + + [Theory] + [MemberData(nameof(ToolBarButton_TestData))] + public void Button_Set_GetReturnsExpected(ToolBarButton value) + { + var e = new ToolBarButtonClickEventArgs(new ToolBarButton()) + { + Button = value + }; + Assert.Equal(value, e.Button); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/VisualStyles/VisualStyleElementTests.cs b/WTG.System.Windows.Forms.Tests/VisualStyles/VisualStyleElementTests.cs new file mode 100644 index 00000000000..0884387723d --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/VisualStyles/VisualStyleElementTests.cs @@ -0,0 +1,658 @@ +using System.Windows.Forms.VisualStyles; + +namespace WTG.System.Windows.Forms.Tests.VisualStyles +{ + public class VisualStyleElementTests + { + public static IEnumerable CreateElement_TestData() + { + yield return new object[] { string.Empty, 0, 0 }; + yield return new object[] { "className", -1, -2 }; + } + + [Theory] + [MemberData(nameof(CreateElement_TestData))] + public void VisualStyleElement_CreateElement_Invoke_ReturnsExpected(string className, int part, int state) + { + VisualStyleElement element = VisualStyleElement.CreateElement(className, part, state); + Assert.Same(className, element.ClassName); + Assert.Equal(part, element.Part); + Assert.Equal(state, element.State); + } + + [Fact] + public void VisualStyleElement_CreateElement_NullClassName_ThrowsArgumentNullException() + { + Assert.Throws("className", () => VisualStyleElement.CreateElement(null, 1, 2)); + } + + public static IEnumerable KnownElements_TestData() + { + // Identity function to avoid constant casting + Func I(Func factory) => factory; + + yield return new object[] { I(() => VisualStyleElement.Button.PushButton.Normal), "BUTTON", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.Button.PushButton.Hot), "BUTTON", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.Button.PushButton.Pressed), "BUTTON", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.Button.PushButton.Disabled), "BUTTON", 1, 4 }; + yield return new object[] { I(() => VisualStyleElement.Button.PushButton.Default), "BUTTON", 1, 5 }; + + yield return new object[] { I(() => VisualStyleElement.Button.RadioButton.UncheckedNormal), "BUTTON", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.Button.RadioButton.UncheckedHot), "BUTTON", 2, 2 }; + yield return new object[] { I(() => VisualStyleElement.Button.RadioButton.UncheckedPressed), "BUTTON", 2, 3 }; + yield return new object[] { I(() => VisualStyleElement.Button.RadioButton.UncheckedDisabled), "BUTTON", 2, 4 }; + yield return new object[] { I(() => VisualStyleElement.Button.RadioButton.CheckedNormal), "BUTTON", 2, 5 }; + yield return new object[] { I(() => VisualStyleElement.Button.RadioButton.CheckedHot), "BUTTON", 2, 6 }; + yield return new object[] { I(() => VisualStyleElement.Button.RadioButton.CheckedPressed), "BUTTON", 2, 7 }; + yield return new object[] { I(() => VisualStyleElement.Button.RadioButton.CheckedDisabled), "BUTTON", 2, 8 }; + + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.UncheckedNormal), "BUTTON", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.UncheckedHot), "BUTTON", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.UncheckedPressed), "BUTTON", 3, 3 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.UncheckedDisabled), "BUTTON", 3, 4 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.CheckedNormal), "BUTTON", 3, 5 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.CheckedHot), "BUTTON", 3, 6 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.CheckedPressed), "BUTTON", 3, 7 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.CheckedDisabled), "BUTTON", 3, 8 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.MixedNormal), "BUTTON", 3, 9 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.MixedHot), "BUTTON", 3, 10 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.MixedPressed), "BUTTON", 3, 11 }; + yield return new object[] { I(() => VisualStyleElement.Button.CheckBox.MixedDisabled), "BUTTON", 3, 12 }; + + yield return new object[] { I(() => VisualStyleElement.Button.GroupBox.Normal), "BUTTON", 4, 1 }; + yield return new object[] { I(() => VisualStyleElement.Button.GroupBox.Disabled), "BUTTON", 4, 2 }; + + yield return new object[] { I(() => VisualStyleElement.Button.UserButton.Normal), "BUTTON", 5, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ComboBox.DropDownButton.Normal), "COMBOBOX", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.ComboBox.DropDownButton.Hot), "COMBOBOX", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.ComboBox.DropDownButton.Pressed), "COMBOBOX", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.ComboBox.DropDownButton.Disabled), "COMBOBOX", 1, 4 }; + + yield return new object[] { I(() => VisualStyleElement.ComboBox.Border.Normal), "COMBOBOX", 4, 3 }; + + yield return new object[] { I(() => VisualStyleElement.ComboBox.ReadOnlyButton.Normal), "COMBOBOX", 5, 2 }; + + yield return new object[] { I(() => VisualStyleElement.ComboBox.DropDownButtonRight.Normal), "COMBOBOX", 6, 1 }; + + yield return new object[] { I(() => VisualStyleElement.ComboBox.DropDownButtonLeft.Normal), "COMBOBOX", 7, 2 }; + + yield return new object[] { I(() => VisualStyleElement.Page.Up.Normal), "PAGE", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.Page.Up.Hot), "PAGE", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.Page.Up.Pressed), "PAGE", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.Page.Up.Disabled), "PAGE", 1, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Page.Down.Normal), "PAGE", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.Page.Down.Hot), "PAGE", 2, 2 }; + yield return new object[] { I(() => VisualStyleElement.Page.Down.Pressed), "PAGE", 2, 3 }; + yield return new object[] { I(() => VisualStyleElement.Page.Down.Disabled), "PAGE", 2, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Page.UpHorizontal.Normal), "PAGE", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.Page.UpHorizontal.Hot), "PAGE", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.Page.UpHorizontal.Pressed), "PAGE", 3, 3 }; + yield return new object[] { I(() => VisualStyleElement.Page.UpHorizontal.Disabled), "PAGE", 3, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Page.DownHorizontal.Normal), "PAGE", 4, 1 }; + yield return new object[] { I(() => VisualStyleElement.Page.DownHorizontal.Hot), "PAGE", 4, 2 }; + yield return new object[] { I(() => VisualStyleElement.Page.DownHorizontal.Pressed), "PAGE", 4, 3 }; + yield return new object[] { I(() => VisualStyleElement.Page.DownHorizontal.Disabled), "PAGE", 4, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Spin.Up.Normal), "SPIN", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.Spin.Up.Hot), "SPIN", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.Spin.Up.Pressed), "SPIN", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.Spin.Up.Disabled), "SPIN", 1, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Spin.Down.Normal), "SPIN", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.Spin.Down.Hot), "SPIN", 2, 2 }; + yield return new object[] { I(() => VisualStyleElement.Spin.Down.Pressed), "SPIN", 2, 3 }; + yield return new object[] { I(() => VisualStyleElement.Spin.Down.Disabled), "SPIN", 2, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Spin.UpHorizontal.Normal), "SPIN", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.Spin.UpHorizontal.Hot), "SPIN", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.Spin.UpHorizontal.Pressed), "SPIN", 3, 3 }; + yield return new object[] { I(() => VisualStyleElement.Spin.UpHorizontal.Disabled), "SPIN", 3, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Spin.DownHorizontal.Normal), "SPIN", 4, 1 }; + yield return new object[] { I(() => VisualStyleElement.Spin.DownHorizontal.Hot), "SPIN", 4, 2 }; + yield return new object[] { I(() => VisualStyleElement.Spin.DownHorizontal.Pressed), "SPIN", 4, 3 }; + yield return new object[] { I(() => VisualStyleElement.Spin.DownHorizontal.Disabled), "SPIN", 4, 4 }; + + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.UpNormal), "SCROLLBAR", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.UpHot), "SCROLLBAR", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.UpPressed), "SCROLLBAR", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.UpDisabled), "SCROLLBAR", 1, 4 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.DownNormal), "SCROLLBAR", 1, 5 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.DownHot), "SCROLLBAR", 1, 6 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.DownPressed), "SCROLLBAR", 1, 7 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.DownDisabled), "SCROLLBAR", 1, 8 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.LeftNormal), "SCROLLBAR", 1, 9 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.LeftHot), "SCROLLBAR", 1, 10 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.LeftPressed), "SCROLLBAR", 1, 11 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.LeftDisabled), "SCROLLBAR", 1, 12 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.RightNormal), "SCROLLBAR", 1, 13 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.RightHot), "SCROLLBAR", 1, 14 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.RightPressed), "SCROLLBAR", 1, 15 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ArrowButton.RightDisabled), "SCROLLBAR", 1, 16 }; + + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ThumbButtonHorizontal.Normal), "SCROLLBAR", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ThumbButtonHorizontal.Hot), "SCROLLBAR", 2, 2 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ThumbButtonHorizontal.Pressed), "SCROLLBAR", 2, 3 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ThumbButtonHorizontal.Disabled), "SCROLLBAR", 2, 4 }; + + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ThumbButtonVertical.Normal), "SCROLLBAR", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ThumbButtonVertical.Hot), "SCROLLBAR", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ThumbButtonVertical.Pressed), "SCROLLBAR", 3, 3 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.ThumbButtonVertical.Disabled), "SCROLLBAR", 3, 4 }; + + yield return new object[] { I(() => VisualStyleElement.ScrollBar.RightTrackHorizontal.Normal), "SCROLLBAR", 4, 1 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.RightTrackHorizontal.Hot), "SCROLLBAR", 4, 2 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.RightTrackHorizontal.Pressed), "SCROLLBAR", 4, 3 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.RightTrackHorizontal.Disabled), "SCROLLBAR", 4, 4 }; + + yield return new object[] { I(() => VisualStyleElement.ScrollBar.LeftTrackHorizontal.Normal), "SCROLLBAR", 5, 1 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.LeftTrackHorizontal.Hot), "SCROLLBAR", 5, 2 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.LeftTrackHorizontal.Pressed), "SCROLLBAR", 5, 3 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.LeftTrackHorizontal.Disabled), "SCROLLBAR", 5, 4 }; + + yield return new object[] { I(() => VisualStyleElement.ScrollBar.LowerTrackVertical.Normal), "SCROLLBAR", 6, 1 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.LowerTrackVertical.Hot), "SCROLLBAR", 6, 2 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.LowerTrackVertical.Pressed), "SCROLLBAR", 6, 3 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.LowerTrackVertical.Disabled), "SCROLLBAR", 6, 4 }; + + yield return new object[] { I(() => VisualStyleElement.ScrollBar.UpperTrackVertical.Normal), "SCROLLBAR", 7, 1 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.UpperTrackVertical.Hot), "SCROLLBAR", 7, 2 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.UpperTrackVertical.Pressed), "SCROLLBAR", 7, 3 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.UpperTrackVertical.Disabled), "SCROLLBAR", 7, 4 }; + + yield return new object[] { I(() => VisualStyleElement.ScrollBar.GripperHorizontal.Normal), "SCROLLBAR", 8, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ScrollBar.GripperVertical.Normal), "SCROLLBAR", 9, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ScrollBar.SizeBox.RightAlign), "SCROLLBAR", 10, 1 }; + yield return new object[] { I(() => VisualStyleElement.ScrollBar.SizeBox.LeftAlign), "SCROLLBAR", 10, 2 }; + + yield return new object[] { I(() => VisualStyleElement.Tab.TabItem.Normal), "TAB", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TabItem.Hot), "TAB", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TabItem.Pressed), "TAB", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TabItem.Disabled), "TAB", 1, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Tab.TabItemLeftEdge.Normal), "TAB", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TabItemLeftEdge.Hot), "TAB", 2, 2 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TabItemLeftEdge.Pressed), "TAB", 2, 3 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TabItemLeftEdge.Disabled), "TAB", 2, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Tab.TabItemRightEdge.Normal), "TAB", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TabItemRightEdge.Hot), "TAB", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TabItemRightEdge.Pressed), "TAB", 3, 3 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TabItemRightEdge.Disabled), "TAB", 3, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Tab.TabItemBothEdges.Normal), "TAB", 4, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItem.Normal), "TAB", 5, 1 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItem.Hot), "TAB", 5, 2 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItem.Pressed), "TAB", 5, 3 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItem.Disabled), "TAB", 5, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItemLeftEdge.Normal), "TAB", 6, 1 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItemLeftEdge.Hot), "TAB", 6, 2 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItemLeftEdge.Pressed), "TAB", 6, 3 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItemLeftEdge.Disabled), "TAB", 6, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItemRightEdge.Normal), "TAB", 7, 1 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItemRightEdge.Hot), "TAB", 7, 2 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItemRightEdge.Pressed), "TAB", 7, 3 }; + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItemRightEdge.Disabled), "TAB", 7, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Tab.TopTabItemBothEdges.Normal), "TAB", 8, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Tab.Pane.Normal), "TAB", 9, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Tab.Body.Normal), "TAB", 10, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.HeaderBackground.Normal), "EXPLORERBAR", 1, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.HeaderClose.Normal), "EXPLORERBAR", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.HeaderClose.Hot), "EXPLORERBAR", 2, 2 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.HeaderClose.Pressed), "EXPLORERBAR", 2, 3 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.HeaderPin.Normal), "EXPLORERBAR", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.HeaderPin.Hot), "EXPLORERBAR", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.HeaderPin.Pressed), "EXPLORERBAR", 3, 3 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.HeaderPin.SelectedNormal), "EXPLORERBAR", 3, 4 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.HeaderPin.SelectedHot), "EXPLORERBAR", 3, 5 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.HeaderPin.SelectedPressed), "EXPLORERBAR", 3, 6 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.IEBarMenu.Normal), "EXPLORERBAR", 4, 1 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.IEBarMenu.Hot), "EXPLORERBAR", 4, 2 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.IEBarMenu.Pressed), "EXPLORERBAR", 4, 3 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.NormalGroupBackground.Normal), "EXPLORERBAR", 5, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.NormalGroupCollapse.Normal), "EXPLORERBAR", 6, 1 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.NormalGroupCollapse.Hot), "EXPLORERBAR", 6, 2 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.NormalGroupCollapse.Pressed), "EXPLORERBAR", 6, 3 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.NormalGroupExpand.Normal), "EXPLORERBAR", 7, 1 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.NormalGroupExpand.Hot), "EXPLORERBAR", 7, 2 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.NormalGroupExpand.Pressed), "EXPLORERBAR", 7, 3 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.NormalGroupHead.Normal), "EXPLORERBAR", 8, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.SpecialGroupBackground.Normal), "EXPLORERBAR", 9, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.SpecialGroupCollapse.Normal), "EXPLORERBAR", 10, 1 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.SpecialGroupCollapse.Hot), "EXPLORERBAR", 10, 2 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.SpecialGroupCollapse.Pressed), "EXPLORERBAR", 10, 3 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.SpecialGroupExpand.Normal), "EXPLORERBAR", 11, 1 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.SpecialGroupExpand.Hot), "EXPLORERBAR", 11, 2 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.SpecialGroupExpand.Pressed), "EXPLORERBAR", 11, 3 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerBar.SpecialGroupHead.Normal), "EXPLORERBAR", 12, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Header.Item.Normal), "HEADER", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.Header.Item.Hot), "HEADER", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.Header.Item.Pressed), "HEADER", 1, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Header.ItemLeft.Normal), "HEADER", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.Header.ItemLeft.Hot), "HEADER", 2, 2 }; + yield return new object[] { I(() => VisualStyleElement.Header.ItemLeft.Pressed), "HEADER", 2, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Header.ItemRight.Normal), "HEADER", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.Header.ItemRight.Hot), "HEADER", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.Header.ItemRight.Pressed), "HEADER", 3, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Header.SortArrow.SortedUp), "HEADER", 4, 1 }; + yield return new object[] { I(() => VisualStyleElement.Header.SortArrow.SortedDown), "HEADER", 4, 2 }; + + yield return new object[] { I(() => VisualStyleElement.ListView.Item.Normal), "LISTVIEW", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.ListView.Item.Hot), "LISTVIEW", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.ListView.Item.Selected), "LISTVIEW", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.ListView.Item.Disabled), "LISTVIEW", 1, 4 }; + yield return new object[] { I(() => VisualStyleElement.ListView.Item.SelectedNotFocus), "LISTVIEW", 1, 5 }; + + yield return new object[] { I(() => VisualStyleElement.ListView.Group.Normal), "LISTVIEW", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ListView.Detail.Normal), "LISTVIEW", 3, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ListView.SortedDetail.Normal), "LISTVIEW", 4, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ListView.EmptyText.Normal), "LISTVIEW", 5, 0 }; + + yield return new object[] { I(() => VisualStyleElement.MenuBand.NewApplicationButton.Normal), "MENUBAND", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.MenuBand.NewApplicationButton.Hot), "MENUBAND", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.MenuBand.NewApplicationButton.Pressed), "MENUBAND", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.MenuBand.NewApplicationButton.Disabled), "MENUBAND", 1, 4 }; + yield return new object[] { I(() => VisualStyleElement.MenuBand.NewApplicationButton.Checked), "MENUBAND", 1, 5 }; + yield return new object[] { I(() => VisualStyleElement.MenuBand.NewApplicationButton.HotChecked), "MENUBAND", 1, 6 }; + + yield return new object[] { I(() => VisualStyleElement.MenuBand.Separator.Normal), "MENUBAND", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Menu.Item.Normal), "MENU", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.Menu.Item.Selected), "MENU", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.Menu.Item.Demoted), "MENU", 1, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Menu.DropDown.Normal), "MENU", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Menu.BarItem.Normal), "MENU", 3, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Menu.BarDropDown.Normal), "MENU", 4, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Menu.Chevron.Normal), "MENU", 5, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Menu.Separator.Normal), "MENU", 6, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ProgressBar.Bar.Normal), "PROGRESS", 1, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ProgressBar.BarVertical.Normal), "PROGRESS", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ProgressBar.Chunk.Normal), "PROGRESS", 3, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ProgressBar.ChunkVertical.Normal), "PROGRESS", 4, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Rebar.Gripper.Normal), "REBAR", 1, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Rebar.GripperVertical.Normal), "REBAR", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Rebar.Band.Normal), "REBAR", 3, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Rebar.Chevron.Normal), "REBAR", 4, 1 }; + yield return new object[] { I(() => VisualStyleElement.Rebar.Chevron.Hot), "REBAR", 4, 2 }; + yield return new object[] { I(() => VisualStyleElement.Rebar.Chevron.Pressed), "REBAR", 4, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Rebar.ChevronVertical.Normal), "REBAR", 5, 1 }; + yield return new object[] { I(() => VisualStyleElement.Rebar.ChevronVertical.Hot), "REBAR", 5, 2 }; + yield return new object[] { I(() => VisualStyleElement.Rebar.ChevronVertical.Pressed), "REBAR", 5, 3 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.UserPane.Normal), "STARTPANEL", 1, 0 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.MorePrograms.Normal), "STARTPANEL", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.MoreProgramsArrow.Normal), "STARTPANEL", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.StartPanel.MoreProgramsArrow.Hot), "STARTPANEL", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.StartPanel.MoreProgramsArrow.Pressed), "STARTPANEL", 3, 3 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.ProgList.Normal), "STARTPANEL", 4, 0 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.ProgListSeparator.Normal), "STARTPANEL", 5, 0 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.PlaceList.Normal), "STARTPANEL", 6, 0 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.PlaceListSeparator.Normal), "STARTPANEL", 7, 0 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.LogOff.Normal), "STARTPANEL", 8, 0 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.LogOffButtons.Normal), "STARTPANEL", 9, 1 }; + yield return new object[] { I(() => VisualStyleElement.StartPanel.LogOffButtons.Hot), "STARTPANEL", 9, 2 }; + yield return new object[] { I(() => VisualStyleElement.StartPanel.LogOffButtons.Pressed), "STARTPANEL", 9, 3 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.UserPicture.Normal), "STARTPANEL", 10, 0 }; + + yield return new object[] { I(() => VisualStyleElement.StartPanel.Preview.Normal), "STARTPANEL", 11, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Status.Bar.Normal), "STATUS", 0, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Status.Pane.Normal), "STATUS", 1, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Status.GripperPane.Normal), "STATUS", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Status.Gripper.Normal), "STATUS", 3, 0 }; + + yield return new object[] { I(() => VisualStyleElement.TaskBand.GroupCount.Normal), "TASKBAND", 1, 0 }; + + yield return new object[] { I(() => VisualStyleElement.TaskBand.FlashButton.Normal), "TASKBAND", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.TaskBand.FlashButtonGroupMenu.Normal), "TASKBAND", 3, 0 }; + + yield return new object[] { I(() => VisualStyleElement.TaskbarClock.Time.Normal), "CLOCK", 1, 1 }; + + yield return new object[] { I(() => VisualStyleElement.Taskbar.BackgroundBottom.Normal), "TASKBAR", 1, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Taskbar.BackgroundRight.Normal), "TASKBAR", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Taskbar.BackgroundTop.Normal), "TASKBAR", 3, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Taskbar.BackgroundLeft.Normal), "TASKBAR", 4, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Taskbar.SizingBarBottom.Normal), "TASKBAR", 5, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Taskbar.SizingBarRight.Normal), "TASKBAR", 6, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Taskbar.SizingBarTop.Normal), "TASKBAR", 7, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Taskbar.SizingBarLeft.Normal), "TASKBAR", 8, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ToolBar.Bar.Normal), "TOOLBAR", 0, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ToolBar.Bar.Normal), "TOOLBAR", 0, 0 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.Button.Normal), "TOOLBAR", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.Button.Hot), "TOOLBAR", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.Button.Pressed), "TOOLBAR", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.Button.Disabled), "TOOLBAR", 1, 4 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.Button.Checked), "TOOLBAR", 1, 5 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.Button.HotChecked), "TOOLBAR", 1, 6 }; + + yield return new object[] { I(() => VisualStyleElement.ToolBar.DropDownButton.Normal), "TOOLBAR", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.DropDownButton.Hot), "TOOLBAR", 2, 2 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.DropDownButton.Pressed), "TOOLBAR", 2, 3 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.DropDownButton.Disabled), "TOOLBAR", 2, 4 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.DropDownButton.Checked), "TOOLBAR", 2, 5 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.DropDownButton.HotChecked), "TOOLBAR", 2, 6 }; + + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButton.Normal), "TOOLBAR", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButton.Hot), "TOOLBAR", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButton.Pressed), "TOOLBAR", 3, 3 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButton.Disabled), "TOOLBAR", 3, 4 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButton.Checked), "TOOLBAR", 3, 5 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButton.HotChecked), "TOOLBAR", 3, 6 }; + + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButtonDropDown.Normal), "TOOLBAR", 4, 1 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButtonDropDown.Hot), "TOOLBAR", 4, 2 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButtonDropDown.Pressed), "TOOLBAR", 4, 3 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButtonDropDown.Disabled), "TOOLBAR", 4, 4 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButtonDropDown.Checked), "TOOLBAR", 4, 5 }; + yield return new object[] { I(() => VisualStyleElement.ToolBar.SplitButtonDropDown.HotChecked), "TOOLBAR", 4, 6 }; + + yield return new object[] { I(() => VisualStyleElement.ToolBar.SeparatorHorizontal.Normal), "TOOLBAR", 5, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ToolBar.SeparatorVertical.Normal), "TOOLBAR", 6, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ToolTip.Standard.Normal), "TOOLTIP", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.ToolTip.Standard.Link), "TOOLTIP", 1, 2 }; + + yield return new object[] { I(() => VisualStyleElement.ToolTip.StandardTitle.Normal), "TOOLTIP", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ToolTip.Balloon.Normal), "TOOLTIP", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.ToolTip.Balloon.Link), "TOOLTIP", 3, 2 }; + + yield return new object[] { I(() => VisualStyleElement.ToolTip.BalloonTitle.Normal), "TOOLTIP", 4, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ToolTip.Close.Normal), "TOOLTIP", 5, 1 }; + yield return new object[] { I(() => VisualStyleElement.ToolTip.Close.Hot), "TOOLTIP", 5, 2 }; + yield return new object[] { I(() => VisualStyleElement.ToolTip.Close.Pressed), "TOOLTIP", 5, 3 }; + + yield return new object[] { I(() => VisualStyleElement.TrackBar.Track.Normal), "TRACKBAR", 1, 1 }; + + yield return new object[] { I(() => VisualStyleElement.TrackBar.TrackVertical.Normal), "TRACKBAR", 2, 1 }; + + yield return new object[] { I(() => VisualStyleElement.TrackBar.Thumb.Normal), "TRACKBAR", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.Thumb.Hot), "TRACKBAR", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.Thumb.Pressed), "TRACKBAR", 3, 3 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.Thumb.Focused), "TRACKBAR", 3, 4 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.Thumb.Disabled), "TRACKBAR", 3, 5 }; + + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbBottom.Normal), "TRACKBAR", 4, 1 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbBottom.Hot), "TRACKBAR", 4, 2 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbBottom.Pressed), "TRACKBAR", 4, 3 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbBottom.Focused), "TRACKBAR", 4, 4 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbBottom.Disabled), "TRACKBAR", 4, 5 }; + + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbTop.Normal), "TRACKBAR", 5, 1 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbTop.Hot), "TRACKBAR", 5, 2 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbTop.Pressed), "TRACKBAR", 5, 3 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbTop.Focused), "TRACKBAR", 5, 4 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbTop.Disabled), "TRACKBAR", 5, 5 }; + + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbVertical.Normal), "TRACKBAR", 6, 1 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbVertical.Hot), "TRACKBAR", 6, 2 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbVertical.Pressed), "TRACKBAR", 6, 3 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbVertical.Focused), "TRACKBAR", 6, 4 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbVertical.Disabled), "TRACKBAR", 6, 5 }; + + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbLeft.Normal), "TRACKBAR", 7, 1 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbLeft.Hot), "TRACKBAR", 7, 2 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbLeft.Pressed), "TRACKBAR", 7, 3 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbLeft.Focused), "TRACKBAR", 7, 4 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbLeft.Disabled), "TRACKBAR", 7, 5 }; + + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbRight.Normal), "TRACKBAR", 8, 1 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbRight.Hot), "TRACKBAR", 8, 2 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbRight.Pressed), "TRACKBAR", 8, 3 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbRight.Focused), "TRACKBAR", 8, 4 }; + yield return new object[] { I(() => VisualStyleElement.TrackBar.ThumbRight.Disabled), "TRACKBAR", 8, 5 }; + + yield return new object[] { I(() => VisualStyleElement.TrackBar.Ticks.Normal), "TRACKBAR", 9, 1 }; + + yield return new object[] { I(() => VisualStyleElement.TrackBar.TicksVertical.Normal), "TRACKBAR", 10, 1 }; + + yield return new object[] { I(() => VisualStyleElement.TreeView.Item.Normal), "TREEVIEW", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.TreeView.Item.Hot), "TREEVIEW", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.TreeView.Item.Selected), "TREEVIEW", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.TreeView.Item.Disabled), "TREEVIEW", 1, 4 }; + yield return new object[] { I(() => VisualStyleElement.TreeView.Item.SelectedNotFocus), "TREEVIEW", 1, 5 }; + + yield return new object[] { I(() => VisualStyleElement.TreeView.Glyph.Closed), "TREEVIEW", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.TreeView.Glyph.Opened), "TREEVIEW", 2, 2 }; + + yield return new object[] { I(() => VisualStyleElement.TreeView.Branch.Normal), "TREEVIEW", 3, 0 }; + + yield return new object[] { I(() => VisualStyleElement.ExplorerTreeView.Glyph.Closed), "Explorer::TreeView", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.ExplorerTreeView.Glyph.Opened), "Explorer::TreeView", 2, 2 }; + + yield return new object[] { I(() => VisualStyleElement.TextBox.TextEdit.Normal), "EDIT", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.TextBox.TextEdit.Hot), "EDIT", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.TextBox.TextEdit.Selected), "EDIT", 1, 3 }; + yield return new object[] { I(() => VisualStyleElement.TextBox.TextEdit.Disabled), "EDIT", 1, 4 }; + yield return new object[] { I(() => VisualStyleElement.TextBox.TextEdit.Focused), "EDIT", 1, 5 }; + yield return new object[] { I(() => VisualStyleElement.TextBox.TextEdit.ReadOnly), "EDIT", 1, 6 }; + yield return new object[] { I(() => VisualStyleElement.TextBox.TextEdit.Assist), "EDIT", 1, 7 }; + + yield return new object[] { I(() => VisualStyleElement.TextBox.Caret.Normal), "EDIT", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.TrayNotify.Background.Normal), "TRAYNOTIFY", 1, 0 }; + + yield return new object[] { I(() => VisualStyleElement.TrayNotify.AnimateBackground.Normal), "TRAYNOTIFY", 2, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Window.Caption.Active), "WINDOW", 1, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.Caption.Inactive), "WINDOW", 1, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.Caption.Disabled), "WINDOW", 1, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallCaption.Active), "WINDOW", 2, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallCaption.Inactive), "WINDOW", 2, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallCaption.Disabled), "WINDOW", 2, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Window.MinCaption.Active), "WINDOW", 3, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.MinCaption.Inactive), "WINDOW", 3, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.MinCaption.Disabled), "WINDOW", 3, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallMinCaption.Active), "WINDOW", 4, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallMinCaption.Inactive), "WINDOW", 4, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallMinCaption.Disabled), "WINDOW", 4, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Window.MaxCaption.Active), "WINDOW", 5, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.MaxCaption.Inactive), "WINDOW", 5, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.MaxCaption.Disabled), "WINDOW", 5, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallMaxCaption.Active), "WINDOW", 6, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallMaxCaption.Inactive), "WINDOW", 6, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallMaxCaption.Disabled), "WINDOW", 6, 3 }; + + yield return new object[] { I(() => VisualStyleElement.Window.FrameLeft.Active), "WINDOW", 7, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.FrameLeft.Inactive), "WINDOW", 7, 2 }; + + yield return new object[] { I(() => VisualStyleElement.Window.FrameRight.Active), "WINDOW", 8, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.FrameRight.Inactive), "WINDOW", 8, 2 }; + + yield return new object[] { I(() => VisualStyleElement.Window.FrameBottom.Active), "WINDOW", 9, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.FrameBottom.Inactive), "WINDOW", 9, 2 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallFrameLeft.Active), "WINDOW", 10, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallFrameLeft.Inactive), "WINDOW", 10, 2 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallFrameRight.Active), "WINDOW", 11, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallFrameRight.Inactive), "WINDOW", 11, 2 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallFrameBottom.Active), "WINDOW", 12, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallFrameBottom.Inactive), "WINDOW", 12, 2 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SysButton.Normal), "WINDOW", 13, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.SysButton.Hot), "WINDOW", 13, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.SysButton.Pressed), "WINDOW", 13, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.SysButton.Disabled), "WINDOW", 13, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.MdiSysButton.Normal), "WINDOW", 14, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiSysButton.Hot), "WINDOW", 14, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiSysButton.Pressed), "WINDOW", 14, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiSysButton.Disabled), "WINDOW", 14, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.MinButton.Normal), "WINDOW", 15, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.MinButton.Hot), "WINDOW", 15, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.MinButton.Pressed), "WINDOW", 15, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.MinButton.Disabled), "WINDOW", 15, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.MdiMinButton.Normal), "WINDOW", 16, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiMinButton.Hot), "WINDOW", 16, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiMinButton.Pressed), "WINDOW", 16, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiMinButton.Disabled), "WINDOW", 16, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.MaxButton.Normal), "WINDOW", 17, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.MaxButton.Hot), "WINDOW", 17, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.MaxButton.Pressed), "WINDOW", 17, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.MaxButton.Disabled), "WINDOW", 17, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.CloseButton.Normal), "WINDOW", 18, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.CloseButton.Hot), "WINDOW", 18, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.CloseButton.Pressed), "WINDOW", 18, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.CloseButton.Disabled), "WINDOW", 18, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallCloseButton.Normal), "WINDOW", 19, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallCloseButton.Hot), "WINDOW", 19, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallCloseButton.Pressed), "WINDOW", 19, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.SmallCloseButton.Disabled), "WINDOW", 19, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.MdiCloseButton.Normal), "WINDOW", 20, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiCloseButton.Hot), "WINDOW", 20, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiCloseButton.Pressed), "WINDOW", 20, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiCloseButton.Disabled), "WINDOW", 20, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.RestoreButton.Normal), "WINDOW", 21, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.RestoreButton.Hot), "WINDOW", 21, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.RestoreButton.Pressed), "WINDOW", 21, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.RestoreButton.Disabled), "WINDOW", 21, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.MdiRestoreButton.Normal), "WINDOW", 22, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiRestoreButton.Hot), "WINDOW", 22, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiRestoreButton.Pressed), "WINDOW", 22, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiRestoreButton.Disabled), "WINDOW", 22, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.HelpButton.Normal), "WINDOW", 23, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.HelpButton.Hot), "WINDOW", 23, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.HelpButton.Pressed), "WINDOW", 23, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.HelpButton.Disabled), "WINDOW", 23, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.MdiHelpButton.Normal), "WINDOW", 24, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiHelpButton.Hot), "WINDOW", 24, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiHelpButton.Pressed), "WINDOW", 24, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.MdiHelpButton.Disabled), "WINDOW", 24, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.HorizontalScroll.Normal), "WINDOW", 25, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.HorizontalScroll.Hot), "WINDOW", 25, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.HorizontalScroll.Pressed), "WINDOW", 25, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.HorizontalScroll.Disabled), "WINDOW", 25, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.HorizontalThumb.Normal), "WINDOW", 26, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.HorizontalThumb.Hot), "WINDOW", 26, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.HorizontalThumb.Pressed), "WINDOW", 26, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.HorizontalThumb.Disabled), "WINDOW", 26, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.VerticalScroll.Normal), "WINDOW", 27, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.VerticalScroll.Hot), "WINDOW", 27, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.VerticalScroll.Pressed), "WINDOW", 27, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.VerticalScroll.Disabled), "WINDOW", 27, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.VerticalThumb.Normal), "WINDOW", 28, 1 }; + yield return new object[] { I(() => VisualStyleElement.Window.VerticalThumb.Hot), "WINDOW", 28, 2 }; + yield return new object[] { I(() => VisualStyleElement.Window.VerticalThumb.Pressed), "WINDOW", 28, 3 }; + yield return new object[] { I(() => VisualStyleElement.Window.VerticalThumb.Disabled), "WINDOW", 28, 4 }; + + yield return new object[] { I(() => VisualStyleElement.Window.Dialog.Normal), "WINDOW", 29, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Window.CaptionSizingTemplate.Normal), "WINDOW", 30, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallCaptionSizingTemplate.Normal), "WINDOW", 31, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Window.FrameLeftSizingTemplate.Normal), "WINDOW", 32, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallFrameLeftSizingTemplate.Normal), "WINDOW", 33, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Window.FrameRightSizingTemplate.Normal), "WINDOW", 34, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallFrameRightSizingTemplate.Normal), "WINDOW", 35, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Window.FrameBottomSizingTemplate.Normal), "WINDOW", 36, 0 }; + + yield return new object[] { I(() => VisualStyleElement.Window.SmallFrameBottomSizingTemplate.Normal), "WINDOW", 37, 0 }; + } + + [Theory] + [MemberData(nameof(KnownElements_TestData))] + public void VisualStyleElement_KnownElements_Get_ReturnsExpected(Func elementFactory, string expectedClassName, int expectedPart, int expectedState) + { + VisualStyleElement element = elementFactory(); + Assert.Same(expectedClassName, element.ClassName); + Assert.Equal(expectedPart, element.Part); + Assert.Equal(expectedState, element.State); + Assert.Same(element, elementFactory()); + } + } +} diff --git a/WTG.System.Windows.Forms.Tests/WTG.System.Windows.Forms.Tests.csproj b/WTG.System.Windows.Forms.Tests/WTG.System.Windows.Forms.Tests.csproj new file mode 100644 index 00000000000..4ec0d76dcbe --- /dev/null +++ b/WTG.System.Windows.Forms.Tests/WTG.System.Windows.Forms.Tests.csproj @@ -0,0 +1,28 @@ + + + + net8.0 + enable + enable + + false + true + + + CS8625;CS8603;CS8600;CS8602;CS8604;CS8618;CS1591;CS8601;CS8619;CA1805;SA1507;SA1517;CSIsNull001;CA1825;IDE0090;SA1513 + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/Winforms.sln b/Winforms.sln index 6dd1b54eeaf..2b5a8c2dad1 100644 --- a/Winforms.sln +++ b/Winforms.sln @@ -2,165 +2,44 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31808.319 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinformsControlsTest", "src\System.Windows.Forms\tests\IntegrationTests\WinformsControlsTest\WinformsControlsTest.csproj", "{657472B8-FDA3-49DF-B8BE-0246046A4348}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms", "src\System.Windows.Forms\src\System.Windows.Forms.csproj", "{0D23A41B-2626-4703-9E4A-87C07F69B0B2}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Tests", "src\System.Windows.Forms\tests\UnitTests\System.Windows.Forms.Tests.csproj", "{AB38E262-F206-4820-8F29-23C5F72A4A16}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Design.Tests", "src\System.Windows.Forms.Design\tests\UnitTests\System.Windows.Forms.Design.Tests.csproj", "{F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Design", "src\System.Windows.Forms.Design\src\System.Windows.Forms.Design.csproj", "{61D06BBD-B0CF-4CE1-9139-1CC4B82F0F9B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Drawing.Design.Facade", "src\System.Drawing.Design\src\System.Drawing.Design.Facade.csproj", "{A2B1148A-1747-47BD-8048-416C2C2AF14C}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Design.Facade", "src\System.Design\src\System.Design.Facade.csproj", "{9BEC2806-D8E0-443B-8B58-9D344E0C2D24}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Private.Winforms", "pkg\Microsoft.Private.Winforms\Microsoft.Private.Winforms.csproj", "{F133342A-3040-4005-A2F0-7685AA7CB82D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Dotnet.Winforms.ProjectTemplates", "pkg\Microsoft.Dotnet.WinForms.ProjectTemplates\Microsoft.Dotnet.Winforms.ProjectTemplates.csproj", "{36A5139E-3E9C-42BD-95EE-818153A487DB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pkg", "pkg", "{989F376E-AE19-43B0-A3E6-96A7E22B4E80}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DF68A171-D27B-4E6A-8A7E-63A651622355}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "facade", "facade", "{434C00C3-E498-4BA7-9764-9F0FC8CFE457}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unit", "unit", "{583F1292-AE8D-4511-B8D8-A81FE4642DDC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "integration", "integration", "{680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.IntegrationTests", "src\System.Windows.Forms\tests\IntegrationTests\System.Windows.Forms.IntegrationTests\System.Windows.Forms.IntegrationTests.csproj", "{238195CE-7CCE-4469-ACD8-EA00E88D947A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Drawing.Facade", "src\System.Drawing\src\System.Drawing.Facade.csproj", "{F1B0790A-1A40-4487-A607-36D21D827E44}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Accessibility", "src\Accessibility\src\Accessibility.ilproj", "{351D8601-6E21-45E8-B3B9-847C4540BD4E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Accessibility-version", "src\Accessibility\ver\Accessibility-version.csproj", "{6103E743-057D-41C6-946C-23A751A08748}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Accessibility", "Accessibility", "{088DD24C-DF6B-45F3-A8BC-592580A4B2A9}" - ProjectSection(SolutionItems) = preProject - src\Accessibility\readme.md = src\Accessibility\readme.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.IntegrationTests.Common", "src\System.Windows.Forms\tests\IntegrationTests\System.Windows.Forms.IntegrationTests.Common\System.Windows.Forms.IntegrationTests.Common.csproj", "{48979B4E-EAEC-4B41-BB49-44CA230BECAB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{462AD69A-9395-4E98-882D-569CDE562559}" - ProjectSection(SolutionItems) = preProject - azure-pipelines.yml = azure-pipelines.yml - eng\common\templates\job\build.yml = eng\common\templates\job\build.yml - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "documentation", "documentation", "{C029199F-7D5C-417C-AA52-913A214E3285}" - ProjectSection(SolutionItems) = preProject - docs\building.md = docs\building.md - CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md - CONTRIBUTING.md = CONTRIBUTING.md - docs\debugging.md = docs\debugging.md - docs\developer-guide.md = docs\developer-guide.md - docs\getting-started.md = docs\getting-started.md - docs\issue-guide.md = docs\issue-guide.md - docs\porting-guidelines.md = docs\porting-guidelines.md - README.md = README.md - docs\roadmap.md = docs\roadmap.md - docs\testing.md = docs\testing.md - THIRD-PARTY-NOTICES.TXT = THIRD-PARTY-NOTICES.TXT - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Accessibility", "Accessibility", "{D390F7D2-1E11-4DEE-B7F1-4FD0681A81F0}" -EndProject -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Microsoft.VisualBasic.Forms", "src\Microsoft.VisualBasic.Forms\src\Microsoft.VisualBasic.Forms.vbproj", "{55E34830-B375-41FF-AFCA-F53B80A4D152}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualBasic.Tests", "src\Microsoft.VisualBasic\tests\UnitTests\Microsoft.VisualBasic.Tests.csproj", "{D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualBasic.Facade", "src\Microsoft.VisualBasic\src\Microsoft.VisualBasic.Facade.csproj", "{A756D568-AC89-4577-A9B2-E147784AB728}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualBasic.IntegrationTests", "src\Microsoft.VisualBasic\tests\IntegrationTests\Microsoft.VisualBasic.IntegrationTests\Microsoft.VisualBasic.IntegrationTests.csproj", "{1C6F6ADA-97B1-4EB9-934D-0071BB618729}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisualBasicRuntimeTest", "src\Microsoft.VisualBasic\tests\IntegrationTests\VisualBasicRuntimeTest\VisualBasicRuntimeTest.csproj", "{EC7608D1-1857-432E-930F-0F89B98979FB}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Primitives", "src\System.Windows.Forms.Primitives\src\System.Windows.Forms.Primitives.csproj", "{90B27178-F535-43F7-886E-0AB75203F246}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Primitives.Tests", "src\System.Windows.Forms.Primitives\tests\UnitTests\System.Windows.Forms.Primitives.Tests.csproj", "{9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4AA2764C-B013-40B5-9E5B-9459EF976C8B}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig .gitattributes = .gitattributes .gitignore = .gitignore + Build.xml = Build.xml + DeploymentSetup.ps1 = DeploymentSetup.ps1 Directory.Build.props = Directory.Build.props Directory.Build.targets = Directory.Build.targets + ..\..\..\wtg\CargoWise\Dev\EDI-Release-private.snk = ..\..\..\wtg\CargoWise\Dev\EDI-Release-private.snk global.json = global.json NuGet.Config = NuGet.Config + README.md = README.md start-vs.cmd = start-vs.cmd eng\Versions.props = eng\Versions.props EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Design.Editors.Facade3x", "src\System.Windows.Forms.Design.Editors\src\System.Windows.Forms.Design.Editors.Facade3x.csproj", "{E0681991-228A-420E-85D5-A9E796F0AAE0}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Primitives.TestUtilities", "src\System.Windows.Forms.Primitives\tests\TestUtilities\System.Windows.Forms.Primitives.TestUtilities.csproj", "{73B0857A-966B-4E7D-8A83-FECFE0281AB9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.TestUtilities", "src\System.Windows.Forms\tests\TestUtilities\System.Windows.Forms.TestUtilities.csproj", "{86418F0B-39DC-4B5A-8145-6D607E6150AC}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Interop.Tests", "src\System.Windows.Forms\tests\InteropTests\System.Windows.Forms.Interop.Tests.csproj", "{C272DA06-B98D-4BB7-B1C4-ECF58F54B224}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.PrivateSourceGenerators", "src\System.Windows.Forms.PrivateSourceGenerators\src\System.Windows.Forms.PrivateSourceGenerators.csproj", "{3BB220A9-7BC9-4D45-9DC7-B5A1D659B478}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.PrivateSourceGenerators.Tests", "src\System.Windows.Forms.PrivateSourceGenerators\tests\UnitTests\System.Windows.Forms.PrivateSourceGenerators.Tests.csproj", "{1976540D-65A6-45D7-95D2-13106DE6D5BB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Primitives.TestUtilities.Tests", "src\System.Windows.Forms.Primitives\tests\TestUtilities.Tests\System.Windows.Forms.Primitives.TestUtilities.Tests.csproj", "{6EE57002-9965-46E7-A48B-B449969738BB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "interop", "interop", "{A31B1F6F-4880-45DE-9845-EE3EF67C2FCC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DesignSurface", "DesignSurface", "{43E46506-7DF8-4E7A-A579-996CA43041EB}" - ProjectSection(SolutionItems) = preProject - src\System.Windows.Forms\tests\IntegrationTests\DesignSurface\.editorconfig = src\System.Windows.Forms\tests\IntegrationTests\DesignSurface\.editorconfig - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DemoConsole", "src\System.Windows.Forms\tests\IntegrationTests\DesignSurface\DemoConsole\DemoConsole.csproj", "{93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesignSurfaceExt", "src\System.Windows.Forms\tests\IntegrationTests\DesignSurface\DesignSurfaceExt\DesignSurfaceExt.csproj", "{E96C74BA-9F74-4289-BF72-45CAD472D3D2}" -EndProject -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Microsoft.VisualBasic.Forms.Tests", "src\Microsoft.VisualBasic.Forms\tests\UnitTests\Microsoft.VisualBasic.Forms.Tests.vbproj", "{FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Common.TestUtilities", "src\Common\tests\TestUtilities\System.Windows.Forms.Common.TestUtilities.csproj", "{05FD23CE-60AE-44A8-8DD6-1688F04BE385}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Analyzers", "src\System.Windows.Forms.Analyzers\src\System.Windows.Forms.Analyzers.csproj", "{3596BDE6-B211-4BE7-810D-DC7A4315E296}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Analyzers.Tests", "src\System.Windows.Forms.Analyzers\tests\UnitTests\System.Windows.Forms.Analyzers.Tests.csproj", "{E742382E-5D34-481D-A3FC-7B6B9C5033E2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Analyzers", "Analyzers", "{E4C6C5F5-46E9-4C63-9628-26752B4D9C11}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Analyzers", "Analyzers", "{D3AD0BF9-F5E2-4913-9AE3-9C4998F95EA1}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Analyzers.CSharp", "src\System.Windows.Forms.Analyzers.CSharp\src\System.Windows.Forms.Analyzers.CSharp.csproj", "{5025D7FF-EB6D-4250-B9C5-887ADFBBD952}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Analyzers.CSharp.Tests", "src\System.Windows.Forms.Analyzers.CSharp\tests\UnitTests\System.Windows.Forms.Analyzers.CSharp.Tests.csproj", "{714EC82C-D4E0-4E14-9C34-4F270774D384}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NativeHost", "src\System.Windows.Forms\tests\IntegrationTests\NativeHost\NativeHost.vcxproj", "{B68FD1FC-EA37-40F2-BBBD-77577A0A1815}" - ProjectSection(ProjectDependencies) = postProject - {3129970B-A4EB-46AC-B163-18A5557B11BD} = {3129970B-A4EB-46AC-B163-18A5557B11BD} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeHost.ManagedControl", "src\System.Windows.Forms\tests\IntegrationTests\NativeHost.ManagedControl\NativeHost.ManagedControl.csproj", "{3129970B-A4EB-46AC-B163-18A5557B11BD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.UI.IntegrationTests", "src\System.Windows.Forms\tests\IntegrationTests\UIIntegrationTests\System.Windows.Forms.UI.IntegrationTests.csproj", "{5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Accessibility_Core_App", "src\System.Windows.Forms\tests\AccessibilityTests\Accessibility_Core_App.csproj", "{317E131C-EA24-47A4-96EE-5A66DED10501}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AxHosts", "src\System.Windows.Forms\tests\AxHosts\AxHosts.csproj", "{93651A99-C9EB-4F83-8A66-DF9D21574550}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildAssist", "BuildAssist", "{B3CE7FA8-21C5-4CE8-970E-8210D1D89251}" -EndProject -Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "BuildAssist", "src\BuildAssist\BuildAssist.msbuildproj", "{20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Drawing.Common", "src\System.Drawing.Common\src\System.Drawing.Common.csproj", "{90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Demo", "Demo\Demo.csproj", "{313D5215-7E76-4864-AEBF-0C15819D0B34}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Drawing.Common.Tests", "src\System.Drawing.Common\tests\System.Drawing.Common.Tests.csproj", "{7650F24E-7132-42CF-ADCE-830C8DB26EE5}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D34EBBF2-C22B-4424-A275-0DC4E316AB21}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScratchProject", "src\System.Windows.Forms\tests\IntegrationTests\ScratchProject\ScratchProject.csproj", "{194D9B0B-421B-4485-B67E-B5A448388D39}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Tests", "Tests\System.Windows.Forms.Tests\System.Windows.Forms.Tests.csproj", "{EAF018D1-D51E-4F67-BC7F-6F7F5702C411}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -174,22 +53,6 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Debug|Any CPU.Build.0 = Debug|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Debug|arm64.ActiveCfg = Debug|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Debug|arm64.Build.0 = Debug|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Debug|x64.ActiveCfg = Debug|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Debug|x64.Build.0 = Debug|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Debug|x86.ActiveCfg = Debug|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Debug|x86.Build.0 = Debug|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Release|Any CPU.ActiveCfg = Release|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Release|Any CPU.Build.0 = Release|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Release|arm64.ActiveCfg = Release|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Release|arm64.Build.0 = Release|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Release|x64.ActiveCfg = Release|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Release|x64.Build.0 = Release|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Release|x86.ActiveCfg = Release|Any CPU - {657472B8-FDA3-49DF-B8BE-0246046A4348}.Release|x86.Build.0 = Release|Any CPU {0D23A41B-2626-4703-9E4A-87C07F69B0B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0D23A41B-2626-4703-9E4A-87C07F69B0B2}.Debug|Any CPU.Build.0 = Debug|Any CPU {0D23A41B-2626-4703-9E4A-87C07F69B0B2}.Debug|arm64.ActiveCfg = Debug|Any CPU @@ -206,38 +69,6 @@ Global {0D23A41B-2626-4703-9E4A-87C07F69B0B2}.Release|x64.Build.0 = Release|Any CPU {0D23A41B-2626-4703-9E4A-87C07F69B0B2}.Release|x86.ActiveCfg = Release|Any CPU {0D23A41B-2626-4703-9E4A-87C07F69B0B2}.Release|x86.Build.0 = Release|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Debug|arm64.ActiveCfg = Debug|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Debug|arm64.Build.0 = Debug|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Debug|x64.ActiveCfg = Debug|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Debug|x64.Build.0 = Debug|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Debug|x86.ActiveCfg = Debug|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Debug|x86.Build.0 = Debug|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Release|Any CPU.Build.0 = Release|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Release|arm64.ActiveCfg = Release|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Release|arm64.Build.0 = Release|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Release|x64.ActiveCfg = Release|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Release|x64.Build.0 = Release|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Release|x86.ActiveCfg = Release|Any CPU - {AB38E262-F206-4820-8F29-23C5F72A4A16}.Release|x86.Build.0 = Release|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Debug|arm64.ActiveCfg = Debug|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Debug|arm64.Build.0 = Debug|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Debug|x64.ActiveCfg = Debug|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Debug|x64.Build.0 = Debug|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Debug|x86.ActiveCfg = Debug|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Debug|x86.Build.0 = Debug|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Release|Any CPU.Build.0 = Release|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Release|arm64.ActiveCfg = Release|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Release|arm64.Build.0 = Release|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Release|x64.ActiveCfg = Release|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Release|x64.Build.0 = Release|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Release|x86.ActiveCfg = Release|Any CPU - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}.Release|x86.Build.0 = Release|Any CPU {61D06BBD-B0CF-4CE1-9139-1CC4B82F0F9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {61D06BBD-B0CF-4CE1-9139-1CC4B82F0F9B}.Debug|Any CPU.Build.0 = Debug|Any CPU {61D06BBD-B0CF-4CE1-9139-1CC4B82F0F9B}.Debug|arm64.ActiveCfg = Debug|Any CPU @@ -254,22 +85,6 @@ Global {61D06BBD-B0CF-4CE1-9139-1CC4B82F0F9B}.Release|x64.Build.0 = Release|Any CPU {61D06BBD-B0CF-4CE1-9139-1CC4B82F0F9B}.Release|x86.ActiveCfg = Release|Any CPU {61D06BBD-B0CF-4CE1-9139-1CC4B82F0F9B}.Release|x86.Build.0 = Release|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Debug|arm64.ActiveCfg = Debug|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Debug|arm64.Build.0 = Debug|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Debug|x64.ActiveCfg = Debug|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Debug|x64.Build.0 = Debug|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Debug|x86.ActiveCfg = Debug|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Debug|x86.Build.0 = Debug|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Release|Any CPU.Build.0 = Release|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Release|arm64.ActiveCfg = Release|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Release|arm64.Build.0 = Release|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Release|x64.ActiveCfg = Release|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Release|x64.Build.0 = Release|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Release|x86.ActiveCfg = Release|Any CPU - {A2B1148A-1747-47BD-8048-416C2C2AF14C}.Release|x86.Build.0 = Release|Any CPU {9BEC2806-D8E0-443B-8B58-9D344E0C2D24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9BEC2806-D8E0-443B-8B58-9D344E0C2D24}.Debug|Any CPU.Build.0 = Debug|Any CPU {9BEC2806-D8E0-443B-8B58-9D344E0C2D24}.Debug|arm64.ActiveCfg = Debug|Any CPU @@ -286,198 +101,6 @@ Global {9BEC2806-D8E0-443B-8B58-9D344E0C2D24}.Release|x64.Build.0 = Release|Any CPU {9BEC2806-D8E0-443B-8B58-9D344E0C2D24}.Release|x86.ActiveCfg = Release|Any CPU {9BEC2806-D8E0-443B-8B58-9D344E0C2D24}.Release|x86.Build.0 = Release|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Debug|arm64.ActiveCfg = Debug|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Debug|arm64.Build.0 = Debug|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Debug|x64.ActiveCfg = Debug|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Debug|x64.Build.0 = Debug|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Debug|x86.ActiveCfg = Debug|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Debug|x86.Build.0 = Debug|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Release|Any CPU.Build.0 = Release|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Release|arm64.ActiveCfg = Release|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Release|arm64.Build.0 = Release|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Release|x64.ActiveCfg = Release|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Release|x64.Build.0 = Release|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Release|x86.ActiveCfg = Release|Any CPU - {F133342A-3040-4005-A2F0-7685AA7CB82D}.Release|x86.Build.0 = Release|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Debug|arm64.ActiveCfg = Debug|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Debug|arm64.Build.0 = Debug|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Debug|x64.ActiveCfg = Debug|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Debug|x64.Build.0 = Debug|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Debug|x86.ActiveCfg = Debug|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Debug|x86.Build.0 = Debug|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Release|Any CPU.Build.0 = Release|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Release|arm64.ActiveCfg = Release|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Release|arm64.Build.0 = Release|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Release|x64.ActiveCfg = Release|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Release|x64.Build.0 = Release|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Release|x86.ActiveCfg = Release|Any CPU - {36A5139E-3E9C-42BD-95EE-818153A487DB}.Release|x86.Build.0 = Release|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Debug|arm64.ActiveCfg = Debug|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Debug|arm64.Build.0 = Debug|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Debug|x64.ActiveCfg = Debug|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Debug|x64.Build.0 = Debug|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Debug|x86.ActiveCfg = Debug|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Debug|x86.Build.0 = Debug|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Release|Any CPU.Build.0 = Release|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Release|arm64.ActiveCfg = Release|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Release|arm64.Build.0 = Release|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Release|x64.ActiveCfg = Release|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Release|x64.Build.0 = Release|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Release|x86.ActiveCfg = Release|Any CPU - {238195CE-7CCE-4469-ACD8-EA00E88D947A}.Release|x86.Build.0 = Release|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Debug|arm64.ActiveCfg = Debug|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Debug|arm64.Build.0 = Debug|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Debug|x64.ActiveCfg = Debug|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Debug|x64.Build.0 = Debug|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Debug|x86.ActiveCfg = Debug|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Debug|x86.Build.0 = Debug|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Release|Any CPU.Build.0 = Release|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Release|arm64.ActiveCfg = Release|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Release|arm64.Build.0 = Release|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Release|x64.ActiveCfg = Release|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Release|x64.Build.0 = Release|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Release|x86.ActiveCfg = Release|Any CPU - {F1B0790A-1A40-4487-A607-36D21D827E44}.Release|x86.Build.0 = Release|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Debug|arm64.ActiveCfg = Debug|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Debug|arm64.Build.0 = Debug|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Debug|x64.ActiveCfg = Debug|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Debug|x64.Build.0 = Debug|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Debug|x86.ActiveCfg = Debug|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Debug|x86.Build.0 = Debug|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Release|Any CPU.Build.0 = Release|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Release|arm64.ActiveCfg = Release|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Release|arm64.Build.0 = Release|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Release|x64.ActiveCfg = Release|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Release|x64.Build.0 = Release|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Release|x86.ActiveCfg = Release|Any CPU - {351D8601-6E21-45E8-B3B9-847C4540BD4E}.Release|x86.Build.0 = Release|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Debug|arm64.ActiveCfg = Debug|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Debug|arm64.Build.0 = Debug|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Debug|x64.ActiveCfg = Debug|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Debug|x64.Build.0 = Debug|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Debug|x86.ActiveCfg = Debug|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Debug|x86.Build.0 = Debug|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Release|Any CPU.Build.0 = Release|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Release|arm64.ActiveCfg = Release|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Release|arm64.Build.0 = Release|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Release|x64.ActiveCfg = Release|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Release|x64.Build.0 = Release|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Release|x86.ActiveCfg = Release|Any CPU - {6103E743-057D-41C6-946C-23A751A08748}.Release|x86.Build.0 = Release|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Debug|arm64.ActiveCfg = Debug|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Debug|arm64.Build.0 = Debug|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Debug|x64.ActiveCfg = Debug|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Debug|x64.Build.0 = Debug|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Debug|x86.ActiveCfg = Debug|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Debug|x86.Build.0 = Debug|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Release|Any CPU.Build.0 = Release|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Release|arm64.ActiveCfg = Release|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Release|arm64.Build.0 = Release|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Release|x64.ActiveCfg = Release|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Release|x64.Build.0 = Release|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Release|x86.ActiveCfg = Release|Any CPU - {48979B4E-EAEC-4B41-BB49-44CA230BECAB}.Release|x86.Build.0 = Release|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Debug|arm64.ActiveCfg = Debug|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Debug|arm64.Build.0 = Debug|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Debug|x64.ActiveCfg = Debug|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Debug|x64.Build.0 = Debug|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Debug|x86.ActiveCfg = Debug|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Debug|x86.Build.0 = Debug|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Release|Any CPU.Build.0 = Release|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Release|arm64.ActiveCfg = Release|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Release|arm64.Build.0 = Release|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Release|x64.ActiveCfg = Release|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Release|x64.Build.0 = Release|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Release|x86.ActiveCfg = Release|Any CPU - {55E34830-B375-41FF-AFCA-F53B80A4D152}.Release|x86.Build.0 = Release|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Debug|arm64.ActiveCfg = Debug|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Debug|arm64.Build.0 = Debug|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Debug|x64.ActiveCfg = Debug|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Debug|x64.Build.0 = Debug|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Debug|x86.ActiveCfg = Debug|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Debug|x86.Build.0 = Debug|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Release|Any CPU.Build.0 = Release|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Release|arm64.ActiveCfg = Release|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Release|arm64.Build.0 = Release|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Release|x64.ActiveCfg = Release|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Release|x64.Build.0 = Release|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Release|x86.ActiveCfg = Release|Any CPU - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938}.Release|x86.Build.0 = Release|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Debug|arm64.ActiveCfg = Debug|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Debug|arm64.Build.0 = Debug|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Debug|x64.ActiveCfg = Debug|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Debug|x64.Build.0 = Debug|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Debug|x86.ActiveCfg = Debug|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Debug|x86.Build.0 = Debug|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Release|Any CPU.Build.0 = Release|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Release|arm64.ActiveCfg = Release|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Release|arm64.Build.0 = Release|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Release|x64.ActiveCfg = Release|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Release|x64.Build.0 = Release|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Release|x86.ActiveCfg = Release|Any CPU - {A756D568-AC89-4577-A9B2-E147784AB728}.Release|x86.Build.0 = Release|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Debug|arm64.ActiveCfg = Debug|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Debug|arm64.Build.0 = Debug|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Debug|x64.ActiveCfg = Debug|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Debug|x64.Build.0 = Debug|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Debug|x86.ActiveCfg = Debug|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Debug|x86.Build.0 = Debug|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Release|Any CPU.Build.0 = Release|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Release|arm64.ActiveCfg = Release|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Release|arm64.Build.0 = Release|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Release|x64.ActiveCfg = Release|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Release|x64.Build.0 = Release|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Release|x86.ActiveCfg = Release|Any CPU - {1C6F6ADA-97B1-4EB9-934D-0071BB618729}.Release|x86.Build.0 = Release|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Debug|arm64.ActiveCfg = Debug|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Debug|arm64.Build.0 = Debug|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Debug|x64.ActiveCfg = Debug|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Debug|x64.Build.0 = Debug|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Debug|x86.ActiveCfg = Debug|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Debug|x86.Build.0 = Debug|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Release|Any CPU.Build.0 = Release|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Release|arm64.ActiveCfg = Release|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Release|arm64.Build.0 = Release|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Release|x64.ActiveCfg = Release|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Release|x64.Build.0 = Release|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Release|x86.ActiveCfg = Release|Any CPU - {EC7608D1-1857-432E-930F-0F89B98979FB}.Release|x86.Build.0 = Release|Any CPU {90B27178-F535-43F7-886E-0AB75203F246}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {90B27178-F535-43F7-886E-0AB75203F246}.Debug|Any CPU.Build.0 = Debug|Any CPU {90B27178-F535-43F7-886E-0AB75203F246}.Debug|arm64.ActiveCfg = Debug|Any CPU @@ -494,22 +117,6 @@ Global {90B27178-F535-43F7-886E-0AB75203F246}.Release|x64.Build.0 = Release|Any CPU {90B27178-F535-43F7-886E-0AB75203F246}.Release|x86.ActiveCfg = Release|Any CPU {90B27178-F535-43F7-886E-0AB75203F246}.Release|x86.Build.0 = Release|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Debug|arm64.ActiveCfg = Debug|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Debug|arm64.Build.0 = Debug|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Debug|x64.ActiveCfg = Debug|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Debug|x64.Build.0 = Debug|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Debug|x86.ActiveCfg = Debug|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Debug|x86.Build.0 = Debug|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Release|Any CPU.Build.0 = Release|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Release|arm64.ActiveCfg = Release|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Release|arm64.Build.0 = Release|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Release|x64.ActiveCfg = Release|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Release|x64.Build.0 = Release|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Release|x86.ActiveCfg = Release|Any CPU - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900}.Release|x86.Build.0 = Release|Any CPU {E0681991-228A-420E-85D5-A9E796F0AAE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E0681991-228A-420E-85D5-A9E796F0AAE0}.Debug|Any CPU.Build.0 = Debug|Any CPU {E0681991-228A-420E-85D5-A9E796F0AAE0}.Debug|arm64.ActiveCfg = Debug|Any CPU @@ -526,54 +133,6 @@ Global {E0681991-228A-420E-85D5-A9E796F0AAE0}.Release|x64.Build.0 = Release|Any CPU {E0681991-228A-420E-85D5-A9E796F0AAE0}.Release|x86.ActiveCfg = Release|Any CPU {E0681991-228A-420E-85D5-A9E796F0AAE0}.Release|x86.Build.0 = Release|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Debug|arm64.ActiveCfg = Debug|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Debug|arm64.Build.0 = Debug|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Debug|x64.ActiveCfg = Debug|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Debug|x64.Build.0 = Debug|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Debug|x86.ActiveCfg = Debug|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Debug|x86.Build.0 = Debug|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Release|Any CPU.Build.0 = Release|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Release|arm64.ActiveCfg = Release|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Release|arm64.Build.0 = Release|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Release|x64.ActiveCfg = Release|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Release|x64.Build.0 = Release|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Release|x86.ActiveCfg = Release|Any CPU - {73B0857A-966B-4E7D-8A83-FECFE0281AB9}.Release|x86.Build.0 = Release|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Debug|arm64.ActiveCfg = Debug|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Debug|arm64.Build.0 = Debug|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Debug|x64.ActiveCfg = Debug|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Debug|x64.Build.0 = Debug|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Debug|x86.ActiveCfg = Debug|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Debug|x86.Build.0 = Debug|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Release|Any CPU.Build.0 = Release|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Release|arm64.ActiveCfg = Release|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Release|arm64.Build.0 = Release|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Release|x64.ActiveCfg = Release|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Release|x64.Build.0 = Release|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Release|x86.ActiveCfg = Release|Any CPU - {86418F0B-39DC-4B5A-8145-6D607E6150AC}.Release|x86.Build.0 = Release|Any CPU - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Debug|Any CPU.ActiveCfg = Debug|x86 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Debug|Any CPU.Build.0 = Debug|x86 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Debug|arm64.ActiveCfg = Debug|x64 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Debug|arm64.Build.0 = Debug|x64 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Debug|x64.ActiveCfg = Debug|x64 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Debug|x64.Build.0 = Debug|x64 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Debug|x86.ActiveCfg = Debug|x86 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Debug|x86.Build.0 = Debug|x86 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Release|Any CPU.ActiveCfg = Release|x86 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Release|Any CPU.Build.0 = Release|x86 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Release|arm64.ActiveCfg = Release|x64 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Release|arm64.Build.0 = Release|x64 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Release|x64.ActiveCfg = Release|x64 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Release|x64.Build.0 = Release|x64 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Release|x86.ActiveCfg = Release|x86 - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224}.Release|x86.Build.0 = Release|x86 {3BB220A9-7BC9-4D45-9DC7-B5A1D659B478}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3BB220A9-7BC9-4D45-9DC7-B5A1D659B478}.Debug|Any CPU.Build.0 = Debug|Any CPU {3BB220A9-7BC9-4D45-9DC7-B5A1D659B478}.Debug|arm64.ActiveCfg = Debug|Any CPU @@ -590,361 +149,51 @@ Global {3BB220A9-7BC9-4D45-9DC7-B5A1D659B478}.Release|x64.Build.0 = Release|Any CPU {3BB220A9-7BC9-4D45-9DC7-B5A1D659B478}.Release|x86.ActiveCfg = Release|Any CPU {3BB220A9-7BC9-4D45-9DC7-B5A1D659B478}.Release|x86.Build.0 = Release|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Debug|arm64.ActiveCfg = Debug|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Debug|arm64.Build.0 = Debug|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Debug|x64.ActiveCfg = Debug|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Debug|x64.Build.0 = Debug|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Debug|x86.ActiveCfg = Debug|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Debug|x86.Build.0 = Debug|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Release|Any CPU.Build.0 = Release|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Release|arm64.ActiveCfg = Release|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Release|arm64.Build.0 = Release|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Release|x64.ActiveCfg = Release|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Release|x64.Build.0 = Release|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Release|x86.ActiveCfg = Release|Any CPU - {1976540D-65A6-45D7-95D2-13106DE6D5BB}.Release|x86.Build.0 = Release|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Debug|arm64.ActiveCfg = Debug|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Debug|arm64.Build.0 = Debug|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Debug|x64.ActiveCfg = Debug|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Debug|x64.Build.0 = Debug|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Debug|x86.ActiveCfg = Debug|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Debug|x86.Build.0 = Debug|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Release|Any CPU.Build.0 = Release|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Release|arm64.ActiveCfg = Release|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Release|arm64.Build.0 = Release|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Release|x64.ActiveCfg = Release|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Release|x64.Build.0 = Release|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Release|x86.ActiveCfg = Release|Any CPU - {6EE57002-9965-46E7-A48B-B449969738BB}.Release|x86.Build.0 = Release|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Debug|arm64.ActiveCfg = Debug|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Debug|arm64.Build.0 = Debug|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Debug|x64.ActiveCfg = Debug|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Debug|x64.Build.0 = Debug|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Debug|x86.ActiveCfg = Debug|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Debug|x86.Build.0 = Debug|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Release|Any CPU.Build.0 = Release|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Release|arm64.ActiveCfg = Release|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Release|arm64.Build.0 = Release|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Release|x64.ActiveCfg = Release|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Release|x64.Build.0 = Release|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Release|x86.ActiveCfg = Release|Any CPU - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4}.Release|x86.Build.0 = Release|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Debug|arm64.ActiveCfg = Debug|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Debug|arm64.Build.0 = Debug|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Debug|x64.ActiveCfg = Debug|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Debug|x64.Build.0 = Debug|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Debug|x86.ActiveCfg = Debug|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Debug|x86.Build.0 = Debug|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Release|Any CPU.Build.0 = Release|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Release|arm64.ActiveCfg = Release|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Release|arm64.Build.0 = Release|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Release|x64.ActiveCfg = Release|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Release|x64.Build.0 = Release|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Release|x86.ActiveCfg = Release|Any CPU - {E96C74BA-9F74-4289-BF72-45CAD472D3D2}.Release|x86.Build.0 = Release|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Debug|arm64.ActiveCfg = Debug|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Debug|arm64.Build.0 = Debug|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Debug|x64.ActiveCfg = Debug|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Debug|x64.Build.0 = Debug|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Debug|x86.ActiveCfg = Debug|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Debug|x86.Build.0 = Debug|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Release|Any CPU.Build.0 = Release|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Release|arm64.ActiveCfg = Release|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Release|arm64.Build.0 = Release|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Release|x64.ActiveCfg = Release|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Release|x64.Build.0 = Release|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Release|x86.ActiveCfg = Release|Any CPU - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D}.Release|x86.Build.0 = Release|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Debug|Any CPU.Build.0 = Debug|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Debug|arm64.ActiveCfg = Debug|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Debug|arm64.Build.0 = Debug|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Debug|x64.ActiveCfg = Debug|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Debug|x64.Build.0 = Debug|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Debug|x86.ActiveCfg = Debug|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Debug|x86.Build.0 = Debug|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Release|Any CPU.ActiveCfg = Release|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Release|Any CPU.Build.0 = Release|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Release|arm64.ActiveCfg = Release|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Release|arm64.Build.0 = Release|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Release|x64.ActiveCfg = Release|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Release|x64.Build.0 = Release|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Release|x86.ActiveCfg = Release|Any CPU - {05FD23CE-60AE-44A8-8DD6-1688F04BE385}.Release|x86.Build.0 = Release|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Debug|arm64.ActiveCfg = Debug|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Debug|arm64.Build.0 = Debug|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Debug|x64.ActiveCfg = Debug|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Debug|x64.Build.0 = Debug|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Debug|x86.ActiveCfg = Debug|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Debug|x86.Build.0 = Debug|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Release|Any CPU.Build.0 = Release|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Release|arm64.ActiveCfg = Release|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Release|arm64.Build.0 = Release|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Release|x64.ActiveCfg = Release|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Release|x64.Build.0 = Release|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Release|x86.ActiveCfg = Release|Any CPU - {3596BDE6-B211-4BE7-810D-DC7A4315E296}.Release|x86.Build.0 = Release|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Debug|arm64.ActiveCfg = Debug|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Debug|arm64.Build.0 = Debug|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Debug|x64.ActiveCfg = Debug|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Debug|x64.Build.0 = Debug|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Debug|x86.ActiveCfg = Debug|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Debug|x86.Build.0 = Debug|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Release|Any CPU.Build.0 = Release|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Release|arm64.ActiveCfg = Release|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Release|arm64.Build.0 = Release|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Release|x64.ActiveCfg = Release|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Release|x64.Build.0 = Release|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Release|x86.ActiveCfg = Release|Any CPU - {E742382E-5D34-481D-A3FC-7B6B9C5033E2}.Release|x86.Build.0 = Release|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Debug|arm64.ActiveCfg = Debug|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Debug|arm64.Build.0 = Debug|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Debug|x64.ActiveCfg = Debug|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Debug|x64.Build.0 = Debug|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Debug|x86.ActiveCfg = Debug|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Debug|x86.Build.0 = Debug|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Release|Any CPU.Build.0 = Release|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Release|arm64.ActiveCfg = Release|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Release|arm64.Build.0 = Release|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Release|x64.ActiveCfg = Release|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Release|x64.Build.0 = Release|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Release|x86.ActiveCfg = Release|Any CPU - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952}.Release|x86.Build.0 = Release|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Debug|Any CPU.Build.0 = Debug|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Debug|arm64.ActiveCfg = Debug|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Debug|arm64.Build.0 = Debug|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Debug|x64.ActiveCfg = Debug|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Debug|x64.Build.0 = Debug|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Debug|x86.ActiveCfg = Debug|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Debug|x86.Build.0 = Debug|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Release|Any CPU.ActiveCfg = Release|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Release|Any CPU.Build.0 = Release|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Release|arm64.ActiveCfg = Release|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Release|arm64.Build.0 = Release|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Release|x64.ActiveCfg = Release|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Release|x64.Build.0 = Release|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Release|x86.ActiveCfg = Release|Any CPU - {714EC82C-D4E0-4E14-9C34-4F270774D384}.Release|x86.Build.0 = Release|Any CPU - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Debug|Any CPU.ActiveCfg = Debug|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Debug|Any CPU.Build.0 = Debug|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Debug|arm64.ActiveCfg = Debug|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Debug|arm64.Build.0 = Debug|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Debug|x64.ActiveCfg = Debug|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Debug|x64.Build.0 = Debug|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Debug|x86.ActiveCfg = Debug|Win32 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Debug|x86.Build.0 = Debug|Win32 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Release|Any CPU.ActiveCfg = Release|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Release|Any CPU.Build.0 = Release|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Release|arm64.ActiveCfg = Release|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Release|arm64.Build.0 = Release|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Release|x64.ActiveCfg = Release|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Release|x64.Build.0 = Release|x64 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Release|x86.ActiveCfg = Release|Win32 - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815}.Release|x86.Build.0 = Release|Win32 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|Any CPU.ActiveCfg = Debug|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|Any CPU.Build.0 = Debug|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|arm64.ActiveCfg = Debug|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|arm64.Build.0 = Debug|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|x64.ActiveCfg = Debug|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|x64.Build.0 = Debug|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|x86.ActiveCfg = Debug|x86 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|x86.Build.0 = Debug|x86 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Release|Any CPU.ActiveCfg = Release|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Release|Any CPU.Build.0 = Release|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Release|arm64.ActiveCfg = Release|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Release|arm64.Build.0 = Release|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Release|x64.ActiveCfg = Release|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Release|x64.Build.0 = Release|x64 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Release|x86.ActiveCfg = Release|x86 - {3129970B-A4EB-46AC-B163-18A5557B11BD}.Release|x86.Build.0 = Release|x86 - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Debug|arm64.ActiveCfg = Debug|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Debug|arm64.Build.0 = Debug|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Debug|x64.ActiveCfg = Debug|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Debug|x64.Build.0 = Debug|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Debug|x86.ActiveCfg = Debug|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Debug|x86.Build.0 = Debug|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Release|Any CPU.Build.0 = Release|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Release|arm64.ActiveCfg = Release|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Release|arm64.Build.0 = Release|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Release|x64.ActiveCfg = Release|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Release|x64.Build.0 = Release|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Release|x86.ActiveCfg = Release|Any CPU - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6}.Release|x86.Build.0 = Release|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Debug|Any CPU.Build.0 = Debug|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Debug|arm64.ActiveCfg = Debug|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Debug|arm64.Build.0 = Debug|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Debug|x64.ActiveCfg = Debug|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Debug|x64.Build.0 = Debug|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Debug|x86.ActiveCfg = Debug|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Debug|x86.Build.0 = Debug|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Release|Any CPU.ActiveCfg = Release|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Release|Any CPU.Build.0 = Release|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Release|arm64.ActiveCfg = Release|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Release|arm64.Build.0 = Release|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Release|x64.ActiveCfg = Release|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Release|x64.Build.0 = Release|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Release|x86.ActiveCfg = Release|Any CPU - {317E131C-EA24-47A4-96EE-5A66DED10501}.Release|x86.Build.0 = Release|Any CPU - {93651A99-C9EB-4F83-8A66-DF9D21574550}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {93651A99-C9EB-4F83-8A66-DF9D21574550}.Debug|arm64.ActiveCfg = Debug|Any CPU - {93651A99-C9EB-4F83-8A66-DF9D21574550}.Debug|x64.ActiveCfg = Debug|Any CPU - {93651A99-C9EB-4F83-8A66-DF9D21574550}.Debug|x86.ActiveCfg = Debug|Any CPU - {93651A99-C9EB-4F83-8A66-DF9D21574550}.Release|Any CPU.ActiveCfg = Release|Any CPU - {93651A99-C9EB-4F83-8A66-DF9D21574550}.Release|arm64.ActiveCfg = Release|Any CPU - {93651A99-C9EB-4F83-8A66-DF9D21574550}.Release|x64.ActiveCfg = Release|Any CPU - {93651A99-C9EB-4F83-8A66-DF9D21574550}.Release|x86.ActiveCfg = Release|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Debug|arm64.ActiveCfg = Debug|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Debug|arm64.Build.0 = Debug|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Debug|x64.ActiveCfg = Debug|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Debug|x64.Build.0 = Debug|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Debug|x86.ActiveCfg = Debug|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Debug|x86.Build.0 = Debug|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Release|Any CPU.Build.0 = Release|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Release|arm64.ActiveCfg = Release|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Release|arm64.Build.0 = Release|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Release|x64.ActiveCfg = Release|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Release|x64.Build.0 = Release|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Release|x86.ActiveCfg = Release|Any CPU - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8}.Release|x86.Build.0 = Release|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Debug|arm64.ActiveCfg = Debug|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Debug|arm64.Build.0 = Debug|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Debug|x64.ActiveCfg = Debug|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Debug|x64.Build.0 = Debug|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Debug|x86.ActiveCfg = Debug|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Debug|x86.Build.0 = Debug|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Release|Any CPU.Build.0 = Release|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Release|arm64.ActiveCfg = Release|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Release|arm64.Build.0 = Release|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Release|x64.ActiveCfg = Release|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Release|x64.Build.0 = Release|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Release|x86.ActiveCfg = Release|Any CPU - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D}.Release|x86.Build.0 = Release|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Debug|arm64.ActiveCfg = Debug|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Debug|arm64.Build.0 = Debug|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Debug|x64.ActiveCfg = Debug|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Debug|x64.Build.0 = Debug|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Debug|x86.ActiveCfg = Debug|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Debug|x86.Build.0 = Debug|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Release|Any CPU.Build.0 = Release|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Release|arm64.ActiveCfg = Release|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Release|arm64.Build.0 = Release|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Release|x64.ActiveCfg = Release|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Release|x64.Build.0 = Release|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Release|x86.ActiveCfg = Release|Any CPU - {7650F24E-7132-42CF-ADCE-830C8DB26EE5}.Release|x86.Build.0 = Release|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Debug|Any CPU.Build.0 = Debug|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Debug|arm64.ActiveCfg = Debug|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Debug|arm64.Build.0 = Debug|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Debug|x64.ActiveCfg = Debug|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Debug|x64.Build.0 = Debug|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Debug|x86.ActiveCfg = Debug|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Debug|x86.Build.0 = Debug|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Release|Any CPU.ActiveCfg = Release|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Release|Any CPU.Build.0 = Release|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Release|arm64.ActiveCfg = Release|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Release|arm64.Build.0 = Release|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Release|x64.ActiveCfg = Release|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Release|x64.Build.0 = Release|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Release|x86.ActiveCfg = Release|Any CPU - {194D9B0B-421B-4485-B67E-B5A448388D39}.Release|x86.Build.0 = Release|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Debug|Any CPU.Build.0 = Debug|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Debug|arm64.ActiveCfg = Debug|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Debug|arm64.Build.0 = Debug|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Debug|x64.ActiveCfg = Debug|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Debug|x64.Build.0 = Debug|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Debug|x86.ActiveCfg = Debug|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Debug|x86.Build.0 = Debug|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Release|Any CPU.ActiveCfg = Release|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Release|Any CPU.Build.0 = Release|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Release|arm64.ActiveCfg = Release|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Release|arm64.Build.0 = Release|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Release|x64.ActiveCfg = Release|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Release|x64.Build.0 = Release|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Release|x86.ActiveCfg = Release|Any CPU + {313D5215-7E76-4864-AEBF-0C15819D0B34}.Release|x86.Build.0 = Release|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Debug|arm64.ActiveCfg = Debug|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Debug|arm64.Build.0 = Debug|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Debug|x64.ActiveCfg = Debug|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Debug|x64.Build.0 = Debug|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Debug|x86.ActiveCfg = Debug|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Debug|x86.Build.0 = Debug|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Release|Any CPU.Build.0 = Release|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Release|arm64.ActiveCfg = Release|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Release|arm64.Build.0 = Release|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Release|x64.ActiveCfg = Release|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Release|x64.Build.0 = Release|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Release|x86.ActiveCfg = Release|Any CPU + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {657472B8-FDA3-49DF-B8BE-0246046A4348} = {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A} {0D23A41B-2626-4703-9E4A-87C07F69B0B2} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} - {AB38E262-F206-4820-8F29-23C5F72A4A16} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC} - {F977CA8C-FBF9-4D82-80BA-FE5B2F33486E} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC} {61D06BBD-B0CF-4CE1-9139-1CC4B82F0F9B} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} - {A2B1148A-1747-47BD-8048-416C2C2AF14C} = {434C00C3-E498-4BA7-9764-9F0FC8CFE457} {9BEC2806-D8E0-443B-8B58-9D344E0C2D24} = {434C00C3-E498-4BA7-9764-9F0FC8CFE457} - {F133342A-3040-4005-A2F0-7685AA7CB82D} = {989F376E-AE19-43B0-A3E6-96A7E22B4E80} - {36A5139E-3E9C-42BD-95EE-818153A487DB} = {989F376E-AE19-43B0-A3E6-96A7E22B4E80} - {583F1292-AE8D-4511-B8D8-A81FE4642DDC} = {DF68A171-D27B-4E6A-8A7E-63A651622355} - {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A} = {DF68A171-D27B-4E6A-8A7E-63A651622355} - {238195CE-7CCE-4469-ACD8-EA00E88D947A} = {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A} - {F1B0790A-1A40-4487-A607-36D21D827E44} = {434C00C3-E498-4BA7-9764-9F0FC8CFE457} - {351D8601-6E21-45E8-B3B9-847C4540BD4E} = {088DD24C-DF6B-45F3-A8BC-592580A4B2A9} - {6103E743-057D-41C6-946C-23A751A08748} = {088DD24C-DF6B-45F3-A8BC-592580A4B2A9} - {088DD24C-DF6B-45F3-A8BC-592580A4B2A9} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} - {48979B4E-EAEC-4B41-BB49-44CA230BECAB} = {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A} - {462AD69A-9395-4E98-882D-569CDE562559} = {4AA2764C-B013-40B5-9E5B-9459EF976C8B} - {D390F7D2-1E11-4DEE-B7F1-4FD0681A81F0} = {DF68A171-D27B-4E6A-8A7E-63A651622355} - {55E34830-B375-41FF-AFCA-F53B80A4D152} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} - {D8598EC8-D64B-4BE7-A4DC-5D5CED6A3938} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC} - {A756D568-AC89-4577-A9B2-E147784AB728} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} - {1C6F6ADA-97B1-4EB9-934D-0071BB618729} = {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A} - {EC7608D1-1857-432E-930F-0F89B98979FB} = {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A} {90B27178-F535-43F7-886E-0AB75203F246} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} - {9BFDE7F2-C8F3-40D6-9A16-8DCD1A37E900} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC} {E0681991-228A-420E-85D5-A9E796F0AAE0} = {434C00C3-E498-4BA7-9764-9F0FC8CFE457} - {73B0857A-966B-4E7D-8A83-FECFE0281AB9} = {DF68A171-D27B-4E6A-8A7E-63A651622355} - {86418F0B-39DC-4B5A-8145-6D607E6150AC} = {DF68A171-D27B-4E6A-8A7E-63A651622355} - {C272DA06-B98D-4BB7-B1C4-ECF58F54B224} = {A31B1F6F-4880-45DE-9845-EE3EF67C2FCC} {3BB220A9-7BC9-4D45-9DC7-B5A1D659B478} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} - {1976540D-65A6-45D7-95D2-13106DE6D5BB} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC} - {6EE57002-9965-46E7-A48B-B449969738BB} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC} - {A31B1F6F-4880-45DE-9845-EE3EF67C2FCC} = {DF68A171-D27B-4E6A-8A7E-63A651622355} - {43E46506-7DF8-4E7A-A579-996CA43041EB} = {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A} - {93310A19-DDCA-4BCD-AEDE-5C5D788DAFB4} = {43E46506-7DF8-4E7A-A579-996CA43041EB} - {E96C74BA-9F74-4289-BF72-45CAD472D3D2} = {43E46506-7DF8-4E7A-A579-996CA43041EB} - {FC75CB54-D8D0-4B41-9A4D-9F862F34A02D} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC} - {05FD23CE-60AE-44A8-8DD6-1688F04BE385} = {DF68A171-D27B-4E6A-8A7E-63A651622355} - {3596BDE6-B211-4BE7-810D-DC7A4315E296} = {E4C6C5F5-46E9-4C63-9628-26752B4D9C11} - {E742382E-5D34-481D-A3FC-7B6B9C5033E2} = {D3AD0BF9-F5E2-4913-9AE3-9C4998F95EA1} - {E4C6C5F5-46E9-4C63-9628-26752B4D9C11} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} - {D3AD0BF9-F5E2-4913-9AE3-9C4998F95EA1} = {DF68A171-D27B-4E6A-8A7E-63A651622355} - {5025D7FF-EB6D-4250-B9C5-887ADFBBD952} = {E4C6C5F5-46E9-4C63-9628-26752B4D9C11} - {714EC82C-D4E0-4E14-9C34-4F270774D384} = {D3AD0BF9-F5E2-4913-9AE3-9C4998F95EA1} - {B68FD1FC-EA37-40F2-BBBD-77577A0A1815} = {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A} - {3129970B-A4EB-46AC-B163-18A5557B11BD} = {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A} - {5A6AFB8C-0EFE-4466-BD77-0F4159151AE6} = {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A} - {317E131C-EA24-47A4-96EE-5A66DED10501} = {D390F7D2-1E11-4DEE-B7F1-4FD0681A81F0} - {93651A99-C9EB-4F83-8A66-DF9D21574550} = {DF68A171-D27B-4E6A-8A7E-63A651622355} - {B3CE7FA8-21C5-4CE8-970E-8210D1D89251} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} - {20E7C5E8-CD56-4A1C-9CB2-B7169FD7A5B8} = {B3CE7FA8-21C5-4CE8-970E-8210D1D89251} - {90CC3A84-1087-48A0-8FDC-3A0F6D4D3B4D} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} - {7650F24E-7132-42CF-ADCE-830C8DB26EE5} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC} + {313D5215-7E76-4864-AEBF-0C15819D0B34} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7} + {EAF018D1-D51E-4F67-BC7F-6F7F5702C411} = {D34EBBF2-C22B-4424-A275-0DC4E316AB21} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7B1B0433-F612-4E5A-BE7E-FCF5B9F6E136} diff --git a/azure-pipelines-PR.yml b/azure-pipelines-PR.yml new file mode 100644 index 00000000000..1a0d40d5408 --- /dev/null +++ b/azure-pipelines-PR.yml @@ -0,0 +1,196 @@ +# Parameters ARE available in template expressions, and parameters can have default values, +# so they can be used to control yaml flow. + +# trigger ci builds for completed checkins into main and any release branches +trigger: + branches: + include: + - main + - release/* + - internal/release/* + - internal/experimental/* + paths: + include: + - '*' + exclude: + - .github/* + - docs/* + - CODE-OF-CONDUCT.md + - CONTRIBUTING.md + - LICENSE.TXT + - PATENTS.TXT + - README.md + - SECURITY.md + - THIRD-PARTY-NOTICES.TXT + +# trigger ci builds on pull requests into main and any release branches +pr: + autoCancel: true + branches: + include: + - main + - vnext + - release/* + - internal/release/* + - internal/experimental/* + - feature/win32 + - feature/9.0 + paths: + include: + - '*' + exclude: + - .github/* + - docs/* + - CODE-OF-CONDUCT.md + - CONTRIBUTING.md + - LICENSE.TXT + - PATENTS.TXT + - README.md + - SECURITY.md + - THIRD-PARTY-NOTICES.TXT + +variables: + - name: TeamName + value: DotNetCore + # clean the local repo on the build agents + - name: Build.Repository.Clean + value: true + - ${{ if or(startswith(variables['Build.SourceBranch'], 'refs/heads/release/'), startswith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'), eq(variables['Build.Reason'], 'Manual')) }}: + - name: PostBuildSign + value: false + - ${{ else }}: + - name: PostBuildSign + value: true + - name: EnableLoc + value: ${{ contains(variables['Build.SourceBranch'], 'main') }} + - name: NativeToolsOnMachine + value: true + - name: isPublic + value: ${{ eq(variables['System.TeamProject'], 'public') }} + - name: isPR + value: ${{ eq(variables['Build.Reason'], 'PullRequest')}} + + # used for post-build phases, internal builds only + - ${{ if and(ne(variables['isPublic'], 'true'), ne(variables['isPR'], 'true')) }}: + - group: DotNet-Winforms-SDLValidation-Params + - ${{ if ne(variables['System.TeamProject'], 'internal') }}: + - name: _InternalRuntimeDownloadArgs + value: '' + - ${{ if eq(variables['System.TeamProject'], 'internal') }}: + - group: DotNetBuilds storage account read tokens + - group: AzureDevOps-Artifact-Feeds-Pats + - name: _InternalRuntimeDownloadArgs + value: /p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal + /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) + + # Produce test-signed build for PR and Public builds + - ${{ if or(eq(variables['isPublic'], 'true'), eq(variables['isPR'], 'true')) }}: + # needed for darc (dependency flow) publishing + - name: _PublishArgs + value: '' + - name: _OfficialBuildIdArgs + value: '' + # needed for signing + - name: _SignType + value: test + - name: _SignArgs + value: '' + - name: _Sign + value: false + + # Set up non-PR build from internal project + - ${{ if and(ne(variables['isPublic'], 'true'), ne(variables['isPR'], 'true')) }}: + # needed for darc (dependency flow) publishing + - name: _PublishArgs + value: >- + /p:DotNetPublishUsingPipelines=true + - name: _OfficialBuildIdArgs + value: /p:OfficialBuildId=$(BUILD.BUILDNUMBER) + # needed for signing + - name: _SignType + value: real + - name: _SignArgs + value: /p:DotNetSignType=$(_SignType) /p:TeamName=$(_TeamName) /p:Sign=$(_Sign) + - name: _Sign + value: true + + +stages: + +- stage: Build + jobs: + + # Windows x64 + - template: /eng/pipelines/build-PR.yml + parameters: + name: Windows_x64 + targetArchitecture: x64 + skipTests: $(SkipTests) + + # Windows x86 + - template: /eng/pipelines/build-PR.yml + parameters: + name: Windows_x86 + targetArchitecture: x86 + skipTests: $(SkipTests) + + # Windows arm64 + - template: /eng/pipelines/build-PR.yml + parameters: + name: Windows_arm64 + targetArchitecture: arm64 + skipTests: $(SkipTests) + + +- ${{ if and(eq(variables['EnableLoc'], 'true'), ne(variables['isPublic'], 'true'), ne(variables['isPR'], 'true')) }}: + - stage: OneLocBuild + displayName: Publish localizable content to OneLocBuild + jobs: + - template: /eng/common/templates/job/onelocbuild.yml + parameters: + MirrorRepo: winforms + UseCheckedInLocProjectJson: true + LclSource: lclFilesfromPackage + LclPackageId: 'LCL-JUNO-PROD-WINFORMS' + + +- ${{ if and(ne(variables['isPublic'], 'true'), ne(variables['isPR'], 'true')) }}: + - stage: PublishAssetRegistry + displayName: Publish to Build Asset Registry + dependsOn: Build + variables: + - template: /eng/common/templates/variables/pool-providers.yml + jobs: + # Publish to Build Asset Registry in order to generate the ReleaseConfigs artifact. + - template: /eng/common/templates/job/publish-build-assets.yml + parameters: + publishUsingPipelines: true + pool: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals windows.vs2022preview.amd64 + + +# Copied from the arcade repo and modified for winforms +- ${{ if and(ne(variables['isPublic'], 'true'), ne(variables['isPR'], 'true')) }}: + - template: /eng/common/templates/post-build/post-build.yml + parameters: + validateDependsOn: PublishAssetRegistry + publishingInfraVersion: 3 + enableSymbolValidation: false + enableSigningValidation: false + enableNugetValidation: false + enableSourceLinkValidation: false + # these param values come from the DotNet-Winforms-SDLValidation-Params azdo variable group + SDLValidationParameters: + enable: false + params: ' -SourceToolsList $(_TsaSourceToolsList) + -TsaInstanceURL $(_TsaInstanceURL) + -TsaProjectName $(_TsaProjectName) + -TsaNotificationEmail $(_TsaNotificationEmail) + -TsaCodebaseAdmin $(_TsaCodebaseAdmin) + -TsaBugAreaPath $(_TsaBugAreaPath) + -TsaIterationPath $(_TsaIterationPath) + -TsaRepositoryName $(_TsaRepositoryName) + -TsaCodebaseName $(_TsaCodebaseName) + -TsaOnboard $(_TsaOnboard) + -TsaPublish $(_TsaPublish)' diff --git a/docs/accessibility/accessible-role-controltype.md b/docs/accessibility/accessible-role-controltype.md deleted file mode 100644 index a1e26b8fb2a..00000000000 --- a/docs/accessibility/accessible-role-controltype.md +++ /dev/null @@ -1,227 +0,0 @@ -# Consistency of AccessibleRole and "ControlType" for accessible objects - -This document describes a behavior and relations of `AccessibleRole` property of -[controls](https://docs.microsoft.com/dotnet/api/system.windows.forms.control.accessiblerole) and -[ToolStrip items](https://docs.microsoft.com/dotnet/api/system.windows.forms.toolstripitem.accessiblerole) - and `"ControlType"` accessibility property. - -* [Overview](#Overview) -* [AccessibleRole-"ControlType" mapping](#AccessibleRole-"ControlType"-mapping) -* [Default "ControlType" values](#Default-"ControlType"-values) -* [Exceptional cases and additional info](#Exceptional-cases-and-additional-info) - - -# Overview - -All accessible objects have `"ControlType"` (a part of modern [UIA](https://docs.microsoft.com/dotnet/framework/ui-automation/ui-automation-overview)) and "[LegacyIAccessible](https://docs.microsoft.com/windows/win32/winauto/uiauto-implementinglegacyiaccessible)`.Role"` -(further `"Role"` - a part of outdated [MSAA](https://docs.microsoft.com/windows/win32/winauto/microsoft-active-accessibility)) accessibility properties. - -![inspect-accessibility-properties][inspect-accessibility-properties] - -Accessibility tools ([Inspect](https://docs.microsoft.com/windows/win32/winauto/inspect-objects), -[Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1), - etc.) request [Role](https://docs.microsoft.com/dotnet/api/system.windows.forms.accessibleobject.role) property of accessible objects to -get `"Role"` accessibility property value. `Role` property value of -[ControlAccessibleObject](https://docs.microsoft.com/dotnet/api/system.windows.forms.control.controlaccessibleobject), -[ToolStripItemAccessibleObject](https://docs.microsoft.com/dotnet/api/system.windows.forms.toolstripitem.toolstripitemaccessibleobject), -and their descendants can be set by the developer using public `AccessibleRole` property. - -![accessibleobject-role-implementation][accessibleobject-role-implementation] - - -Accessibility tools call internal `GetPropertyValue` method with `ControlTypePropertyId` -argument to get `"ControlType"` value. - -![accessibleobject-getpropertyvalue-implementation][accessibleobject-getpropertyvalue-implementation] - - -**.NET Framework 4.7.2** implements the following `AccessibleRole` property and -`"ControlType"` accessibility property relations: -when `Control`'s or `ToolStripItem`'s `AccessibleRole` property is set to a non-default -value by the developer, the native accessibility proxy implementation would -set `"ControlType"` property to a matching value.
-**.NET Framework 4.8**, **.NET Core 3.0** and **3.1**, **.NET 5.0** lost -this behavior for all controls that implement **UIA providers** because -they provide custom implementation of UIA properties and no longer rely -on UIA proxy to match roles to control types. **.NET 6.0** restores the **.NET Framework 4.7.2** behavior. - - -# AccessibleRole-"ControlType" mapping - -When a developer changes `AccessibleRole` property value of a control -or a `ToolStrip` item (for example: `control.AccessibleRole = AccessibleRole.List;`), `"ControlType"` accessibility -property value of the corresponding accessible object will -be changed according to the following list (except some cases described below): - -| AccessibleRole | ControlType | -| ------------- | ------------- | -|Alert|Pane| -|Animation|Pane| -|Application|Window| -|Border|Pane| -|ButtonDropDown|SplitButton| -|ButtonDropDownGrid|Button| -|ButtonMenu|MenuItem| -|Caret|Pane| -|Cell|DataItem| -|Character|Pane| -|Chart|Pane| -|CheckButton|CheckBox| -|Client|Pane| -|Clock|Button| -|Column|Pane| -|ColumnHeader|Header| -|ComboBox|ComboBox| -|Cursor|Pane| -|Default|Pane| -|Diagram|Pane| -|Dial|Pane| -|Dialog|Pane| -|Document|Document| -|DropList|Pane| -|Equation|Pane| -|Graphic|Image| -|Grip|Thumb| -|Grouping|Group| -|HelpBalloon|Pane| -|HotkeyField|Pane| -|Indicator|Thumb| -|IpAddress|Pane| -|Link|Hyperlink| -|List|List| -|ListItem|ListItem| -|MenuBar|MenuBar| -|MenuItem|MenuItem| -|MenuPopup|Menu| -|None|Pane| -|Outline|Tree| -|OutlineButton|Pane| -|OutlineItem|TreeItem| -|PageTab|TabItem| -|PageTabList|Tab| -|Pane|Pane| -|ProgressBar|ProgressBar| -|PropertyPage|Pane| -|PushButton|Button| -|RadioButton|RadioButton| -|Row|Pane| -|RowHeader|Header| -|ScrollBar|ScrollBar| -|Separator|Separator| -|Slider|Slider| -|Sound|Pane| -|SpinButton|Spinner| -|SplitButton|SplitButton| -|StaticText|Text| -|StatusBar|StatusBar| -|Table|Table| -|Text|Edit| -|TitleBar|TitleBar| -|ToolBar|ToolBar| -|ToolTip|ToolTip| -|WhiteSpace|Pane| -|Window|Window| - - -# Default "ControlType" values - -Here is the list of common controls and `ToolStrip` items with -their accessible objects `"ControlType"` accessibility property values -by default - when `AccessibleRole` property value of these controls -and `ToolStrip` items is not set: -```cs -Control control = new Control(); -// control.AccessibleRole = AccessibleRole.List; - Role is not set -``` -or equals [AccessibleRole](https://docs.microsoft.com/dotnet/api/system.windows.forms.accessiblerole)`.Default`: -```cs -Control control = new Control(); -control.AccessibleRole = AccessibleRole.Default; // Role is set to the default value -``` - -| Control or item | Default ControlType | -| ------------- | ------------- | -|Button|Button | -|CheckBox |CheckBox | -|CheckedListBox |List | -|ComboBox |ComboBox | -|ContextMenuStrip
└ ToolStripMenuItem
└┴ ToolStripMenuItem
└┴ ToolStripComboBox
└┴ ToolStripTextBox
└┴ ToolStripSeparator
└ ToolStripComboBox
└ ToolStripTextBox
└ ToolStripSeparator|Menu
MenuItem
Pane
ComboBox
Edit
Separator
ComboBox
Edit
Separator| -|DataGridView
└ DataGridViewEditingPanel |Table
Pane| -|DateTimePicker |ComboBox| -|DomainUpDown
└ UpDownButtons
└ UpDownEdit|Spinner
Spinner
Edit| -|FlowLayoutPanel|Pane| -|Form|Window| -|GroupBox|Group| -|HScrollBar|ScrollBar| -|Label|Text| -|LinkLabel|Text| -|ListBox|List| -|ListView|List| -|MenuStrip
└ ToolStripMenuItem
└┴ ToolStripMenuItem
└┴ ToolStripComboBox
└┴ ToolStripTextBox
└┴ ToolStripSeparator
└ ToolStripComboBox
└ ToolStripTextBox|MenuBar
MenuItem
MenuItem
ComboBox
Edit
Separator
ComboBox
Edit| -|MaskedTextBox|Edit| -|MonthCalendar|Calendar/Table| -|NumericUpDown
└ UpDownButtons
└ UpDownEdit|Spinner
Spinner
Edit| -|PictureBox|Pane| -|ProgressBar|ProgressBar| -|PropertyGrid|Pane| -|RadioButton|RadioButton| -|RichTextBox|Document| -|ScrollBar|ScrollBar| -|SplitContainer|Pane| -|Splitter|Pane| -|StatusStrip
└ ToolStripStatusLabel
└ ToolStripProgressBar
└ ToolStripSplitButton
└ ToolStripDropDownButton
└┴ ToolStripMenuItem
└┴ ToolStripComboBox
└┴ ToolStripTextBox
└┴ ToolStripSeparator|StatusBar
Text/Link
ProgressBar
Button
Button
MenuItem
ComboBox
Edit
Separator| -|TabControl|Tab| -|TableLayoutPanel|Pane| -|TabPage|Pane| -|TextBox|Edit| -|TextBoxBase|Edit| -|ToolStrip
└ ToolStripItem
└ ToolStripComboBox
└ ToolStripDropDown
└ ToolStripNumericUpDown
└ ToolStripOverflow
└ ToolStripProgressBar
└ ToolStripTextBox
└ ToolStripButton
└ ToolStripLabel
└ ToolStripSplitButton
└ ToolStripDropDownButton
└ ToolStripSeparator
└ ToolStripOverflowButton
|ToolBar
Button
ComboBox
Menu
Spinner
Menu
ProgressBar
Edit
Button
Text/Link
Button
Button
Separator
MenuItem| -|TrackBar|Slider| -|TreeView|Tree| -|VScrollBar|ScrollBar| -|TrackBar|Slider| -|TreeView|Tree| -|VScrollBar|ScrollBar| - -# Exceptional cases and additional info -- Here is the list of controls and `ToolStrip` items that didn't change -their accessible objects `"ControlType"` values depending on `Role` in **.NET Framework 4.7.2** -but in **in .NET 6.0** they can do it correctly: - 1. **`ListView`** - `"ControlType"` was always `List` - 2. **`ToolStripMenuItem`** - `"ControlType"` was always `Menu item` - 3. **`ToolStripSplitButton`** - `"ControlType"` was always `Button` - 4. **`ToolStripDropDownButton`** - `"ControlType"` was always `Button` - -- **`RichTextBox`**: at this moment, we don't provide a managed accessible object for it. -It doesn't support setting a custom `AccessibleRole` and -changing `"ControlType"` respectively (in **.NET Framework 4.7.2** too). -It always has `"Role"` as `Document` and `"ControlType"` as `Document`. -- **`TreeView`**: at this moment, we don't provide a managed accessible object for it. -It doesn't support setting a custom `AccessibleRole` and -changing `"ControlType"` respectively (in **.NET Framework 4.7.2** too). -It always has `"Role"` value as `Outline` and `"ControlType"` value as `Tree`. -- **`DateTimePicker`**: its accessible object has non-standard -`"LocalizedControlType"` accessibility property value by default. -But it changes if to change `AccessibleRole` property value of the control. -- **`Form`**: default `"Role"` value is `Client` but default `"ControlType"` value -is `Window`. This is an exception and does not correspond to the list above. -In the rest, `Form` with a custom `AccessibleRole` value works as expected. -- **`MonthCalendar`**: if `AccessibleName` property value is null or empty -default `"ControlType"` of its accessible object is `Calendar`, -if `AccessibleName` is a some text - default `"ControlType"` is `Table`. -- **`ToolStripLabel`**: if `IsLink` property value equals `false` -its accessible object default `"ControlType"` value is `Text`, -and `"ControlType"` is `Hyperlink` if `IsLink` is `true`. -- **`ToolStripStatusLabel`**: if `IsLink` property value equals `false` -its accessible object default `"ControlType"` value is `Text`, -and `"ControlType"` is `Hyperlink` if `IsLink` is `true`. -- **`ToolStripNumericUpDown`**: this item is used in [PrintPreviewDialog](https://docs.microsoft.com/dotnet/api/system.windows.forms.printpreviewdialog) control. -- **`ToolStripOverflowButton`**: needs to use [ToolStrip.OverflowButton](https://docs.microsoft.com/dotnet/api/system.windows.forms.toolstrip.overflowbutton) -property to get this item and set a custom `AccessibleRole` value. -- **`DataGridViewEditingPanel`**: default `"Role"` is `Client`. -Needs to use [DataGridView.EditingPanel](https://docs.microsoft.com/dotnet/api/system.windows.forms.datagridview.editingpanel) to get the control and set -a custom value for its `AccessibleRole`. - -[inspect-accessibility-properties]: ../images/inspect-accessibility-properties.png -[accessibleobject-role-implementation]: ../images/accessibleobject-role-implementation.png -[accessibleobject-getpropertyvalue-implementation]: ../images/accessibleobject-getpropertyvalue-implementation.png \ No newline at end of file diff --git a/docs/accessibility/listview-expected-behavior.md b/docs/accessibility/listview-expected-behavior.md deleted file mode 100644 index c7cf81c52bb..00000000000 --- a/docs/accessibility/listview-expected-behavior.md +++ /dev/null @@ -1,655 +0,0 @@ -# ListView accessibility objects expected behavior - -This document describes the expected behavior of [ListView](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview) , [ListView](https://docs.microsoft.com/dotnet/api/system.windows.forms.listviewgroup), [ListViewSubItem](https://docs.microsoft.com/dotnet/api/system.windows.forms.listviewitem.listviewsubitem) accessibility objects when using Inspect. - - -- [Overview](#Overview) -- [ListView](#ListView) - - [Accessibility tree for ListView](##Accessibility-tree-for-ListView) -- [ListViewGroup](#ListViewGroup) - - [Accessibility tree for a ListView with displayed ListViewGroups](##Accessibility-tree-for-a-ListView-with-displayed-ListViewGroups) - - [Accessibility tree for a ListView with disabled visual styles](##Accessibility-tree-for-a-ListView-with-disabled-visual-styles) - - [Accessibility tree for a ListView with disabled ListViewGroups](##Accessibility-tree-for-a-ListView-with-disabled-ListViewGroups) - - [Accessibility tree for a ListView in virtual mode](##Accessibility-tree-for-a-ListView-in-virtual-mode) - - [Accessibility tree for a ListView without ListViewGroups](##Accessibility-tree-for-a-ListView-without-ListViewGroups) -- [ListViewSubItem](#ListViewSubItem) - - [Accessibility tree for a ListViewItem](##Accessibility-tree-for-a-ListViewItem) - - [Accessibility tree for a ListViewItem (Details view)](##Accessibility-tree-for-a-ListViewItem-(Details-view)) - - [Accessibility tree for a ListViewItem (Tile view)](##Accessibility-tree-for-a-ListViewItem-(Tile-view)) - -# Overview - -[ListView](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview) is a Win32 native control provided by Windows. -Windows Forms runtime provides a support for [UI Automation](https://docs.microsoft.com/dotnet/framework/ui-automation/ui-automation-overview) and, thus, responsible for providing required accessible objects with correct properties and actions to make all aspects of the `ListView` control accessible for customers. - -# ListView - -## Accessibility tree for ListView - -`ListView` accessibility tree must contain all visible items based on the selected `View` [view](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.view). - -
-1. Details view -
- -![listview-inspect-details-view-tree][listview-inspect-details-view-tree] - -
-
- -
-2. LargeIcon view -
- -![listview-inspect-largeicon-view-tree][listview-inspect-largeicon-view-tree] - -
-
- -
-3. List view -
- -![listview-inspect-list-view-tree][listview-inspect-list-view-tree] - -
-
- -
-4. SmallIcon view -
- -![listview-inspect-smallicon-view-tree][listview-inspect-smallicon-view-tree] - -
-
- -
-5. Tile view -
- -![listview-inspect-tile-view-tree][listview-inspect-tile-view-tree] - -
-
- -# ListViewGroup - -The `ListView` always contains one or more [ListViewGroup](https://docs.microsoft.com/dotnet/api/system.windows.forms.listviewgroup), but depending on a configuration of the operating system, application and/or the `ListView` itself, these [groups](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.groups) can be visible or not. - -## Accessibility tree for a ListView with displayed ListViewGroups - -A `ListViewGroup` is display if the following conditions are met: -1. An application has [visual styles](https://docs.microsoft.com/dotnet/api/system.windows.forms.application.enablevisualstyles) are enabled. -2. A `ListView` is not in a [virtual mode](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.virtualmode). -3. The [ShowGroups](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.showgroups) property has `true` value -4. A `ListView` has one or more [groups](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.groups) -5. A `ListView` is not in a `List` view - -```cs -ListViewGroup listViewGroup = new ListViewGroup("Test group"); -listView.Groups.Add(listViewGroup); - -listView.ShowGroups = true; -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0, group: listViewGroup)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0, group: listViewGroup)); -listView.Items.Add(new ListViewItem(new string[] { "Item 3", "SubItem 31" }, imageIndex: 0)); -``` - -
-1. Details view -
- -![listview-withgroup-inspect-details-view-tree][listview-withgroup-inspect-details-view-tree] - -
-
- -
-2. LargeIcon view -
- -![listview-withgroup-inspect-largeicon-view-tree][listview-withgroup-inspect-largeicon-view-tree] - -
-
- -
-3. List view -
- -![listview-withgroup-inspect-list-view-tree][listview-withgroup-inspect-list-view-tree] - -
-
- -
-4. SmallIcon view -
- -![listview-withgroup-inspect-smallicon-view-tree][listview-withgroup-inspect-smallicon-view-tree] - -
-
- -
-5. Tile view -
- -![listview-withgroup-inspect-tile-view-tree][listview-withgroup-inspect-tile-view-tree] - -
-
- -## Accessibility tree for a ListView with disabled visual styles -`ListViewGroups` are not visible when [visual styles](https://docs.microsoft.com/dotnet/api/system.windows.forms.application.enablevisualstyles) are disabled. - -```cs -ListViewGroup listViewGroup = new ListViewGroup("Test group"); -listView.Groups.Add(listViewGroup); - -listView.ShowGroups = true; -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0, group: listViewGroup)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0, group: listViewGroup)); -listView.Items.Add(new ListViewItem(new string[] { "Item 3", "SubItem 31" }, imageIndex: 0)); -``` - -
-1. Details view -
- -![listview-disabledstyles-inspect-details-view-tree][listview-disabledstyles-inspect-details-view-tree] - -
-
- -
-2. LargeIcon view -
- -![listview-disabledstyles-inspect-largeicon-view-tree][listview-disabledstyles-inspect-largeicon-view-tree] - -
-
- -
-3. List view -
- -![listview-disabledstyles-inspect-list-view-tree][listview-disabledstyles-inspect-list-view-tree] - -
-
- -
-4. SmallIcon view -
- -![listview-disabledstyles-inspect-smallicon-view-tree][listview-disabledstyles-inspect-smallicon-view-tree] - -
-
- -
-5. Tile view -
- -![listview-disabledstyles-inspect-tile-view-tree][listview-disabledstyles-inspect-tile-view-tree] - -
-
- -## Accessibility tree for a ListView with disabled ListViewGroups -`ListViewGroups` are not visible when [ShowGroups](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.showgroups) property is set to `false`. - -```cs -ListViewGroup listViewGroup = new ListViewGroup("Test group"); -listView.Groups.Add(listViewGroup); - -listView.ShowGroups = false; -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0, group: listViewGroup)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0, group: listViewGroup)); -listView.Items.Add(new ListViewItem(new string[] { "Item 3", "SubItem 31" }, imageIndex: 0)); -``` - -
-1. Details view -
- -![listview-showgroupdisabled-inspect-details-view-tree][listview-showgroupdisabled-inspect-details-view-tree] - -
-
- -
-2. LargeIcon view -
- -![listview-showgroupdisabled-inspect-largeicon-view-tree][listview-showgroupdisabled-inspect-largeicon-view-tree] - -
-
- -
-3. List view -
- -![listview-showgroupdisabled-inspect-list-view-tree][listview-showgroupdisabled-inspect-list-view-tree] - -
-
- -
-4. SmallIcon view -
- -![listview-showgroupdisabled-inspect-smallicon-view-tree][listview-showgroupdisabled-inspect-smallicon-view-tree] - -
-
- -
-5. Tile view -
- -![listview-showgroupdisabled-inspect-tile-view-tree][listview-showgroupdisabled-inspect-tile-view-tree] - -
-
- -## Accessibility tree for a ListView in virtual mode -`ListViewGroups` are not visible when `ListView` is in [virtual mode](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.virtualmode). - -```cs -ListViewGroup listViewGroup = new ListViewGroup("Test group"); -listView.Groups.Add(listViewGroup); - -listView.VirtualMode = virtualMode; -listView.VirtualListSize = 3; - -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -ListViewItem listItem1 = new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0, group: listViewGroup)); -ListViewItem listItem2 = new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0, group: listViewGroup)); -ListViewItem listItem3 = new ListViewItem(new string[] { "Item 3", "SubItem 31", "SubItem 32", "SubItem 33" }, imageIndex: 0)); - -listView.RetrieveVirtualItem += (s, e) => - { - e.Item = e.ItemIndex switch - { - 0 => listItem1, - 1 => listItem2, - 2 => listItem3, - _ => throw new NotImplementedException() - }; - }; - -listItem1.SetItemIndex(listView, 0); -listItem2.SetItemIndex(listView, 1); -listItem3.SetItemIndex(listView, 2); -``` - -
-1. Details view -
- -![listview-virtualmode-inspect-details-view-tree][listview-virtualmode-inspect-details-view-tree] - -
-
- -
-2. LargeIcon view -
- -![listview-virtualmode-inspect-largeicon-view-tree][listview-virtualmode-inspect-largeicon-view-tree] - -
-
- -
-3. List view -
- -![listview-virtualmode-inspect-list-view-tree][listview-virtualmode-inspect-list-view-tree] - -
-
- -
-4. SmallIcon view -
- -![listview-virtualmode-inspect-smallicon-view-tree][listview-virtualmode-inspect-smallicon-view-tree] - -
-
- -
-5. Tile view -
- -The ListView in virtual mode does not support "Tile" view - -
-
- -## Accessibility tree for a ListView without ListViewGroups -`ListViewGroups` are not visible when `ListView` has no [groups](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.groups). - -```cs -listView.ShowGroups = true; -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 3", "SubItem 31" }, imageIndex: 0)); -``` - -
-1. Details view -
- -![listview-withoutgroup-inspect-details-view-tree][listview-withoutgroup-inspect-details-view-tree] - -
-
- -
-2. LargeIcon view -
- -![listview-withoutgroup-inspect-largeicon-view-tree][listview-withoutgroup-inspect-largeicon-view-tree] - -
-
- -
-3. List view -
- -![listview-withoutgroup-inspect-list-view-tree][listview-withoutgroup-inspect-list-view-tree] - -
-
- -
-4. SmallIcon view -
- -![listview-withoutgroup-inspect-smallicon-view-tree][listview-withoutgroup-inspect-smallicon-view-tree] - -
-
- -
-5. Tile view -
- -![listview-withoutgroup-inspect-tile-view-tree][listview-withoutgroup-inspect-tile-view-tree] - -
-
- -# ListViewSubItem - -## Accessibility tree for a ListViewItem -A [ListViewSubItem](https://docs.microsoft.com/dotnet/api/system.windows.forms.listviewitem) is display if the following conditions are met: -1. A `ListView` is in a `List` or `Details` [views](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.view). -2. A `ListView` has one or more [ListViewSubItems](https://docs.microsoft.com/dotnet/api/system.windows.forms.listviewitem.subitems) -3. A `ListView` has one or more [Columns](https://docs.microsoft.com/dotnet/api/system.windows.forms.listviewitem.subitems) -4. The `ListViewItem` has a [TileSize](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.tilesize) enough to display `ListViewSubItems` (only for `Tile` view) - - -```cs -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0)); - -listView.TileSize = new Size(100, 100); -``` - -
-1. Details view -
- -![listviewsubitem-inspect-details-view-tree][listviewsubitem-inspect-details-view-tree] - -
-
- -
-2. LargeIcon view -
- -![listviewsubitem-inspect-largeicon-view-tree][listviewsubitem-inspect-largeicon-view-tree] -This view does not support ListViewSubItems - -
-
- -
-3. List view -
- -![listviewsubitem-inspect-list-view-tree][listviewsubitem-inspect-list-view-tree] -This view does not support ListViewSubItems - -
-
- -
-4. SmallIcon view -
- -![listviewsubitem-inspect-smallicon-view-tree][listviewsubitem-inspect-smallicon-view-tree] -This view does not support ListViewSubItems - -
-
- -
-5. Tile view -
- -![listviewsubitem-inspect-tile-view-tree][listviewsubitem-inspect-tile-view-tree] - -
-
- -## Accessibility tree for a ListViewItem (Details view) - -It is typical for this mode that when displaying accessibility objects for `ListViewSubItems` in the Inspect tree, the main parameter is not the number of [ListViewSubItems](https://docs.microsoft.com/dotnet/api/system.windows.forms.listviewitem.subitems), but the number of [Columns](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.columns) that the user can see. - -In the case when the number of `Columns` and `ListViewSubItems` is the same, the user sees that all `Columns` contain data and all `ListViewSubItems` are displayed in the Accessibility tree. - -```cs -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0)); -``` - -![listviewsubitem-inspect-details-view-tree][listviewsubitem-inspect-details-view-tree] - -If the number of `Columns` is less than the number of `ListViewSubItems`, then the user sees only those `ListViewSubItems` for which there are `Columns`. As a result, only `ListViewSubItems` with matching `Columns` are displayed in the Inspector tree. `ListViewSubItems` without corresponding `Columns` on the screen and in the Accessibility tree are not displayed. - -```cs -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0)); -``` - -![listviewsubitem-twocolumns-inspect-details-view-tree][listviewsubitem-twocolumns-inspect-details-view-tree] - -If the number of `Columns` is greater than the number of `ListViewSubItems`, then a fake accessibility object is displayed for non-existent `ListViewSubItems`. This is because whether they exist or not, the user sees the cell for the `ListViewSubItem`, so it should have an accessibility object to interact with the Accessibility tree. - -```cs -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21" }, imageIndex: 0)); -``` - -![listviewsubitem-twosubitems-inspect-details-view-tree][listviewsubitem-twosubitems-inspect-details-view-tree] - -## Accessibility tree for a ListViewItem (Tile view) -This view takes many factors into account when displaying `ListViewSubItems`. - -The first `ListViewSubItem` (with 0 index) is never shown in the Accessibility tree, as its data is displayed within the `ListViewItem`. `ListViewItem.FragmentNavigate(NavigateDirection.FirstChild)`, `ListViewItem.FragmentNavigate(NavigateDirection.LastChild)` and -`ListViewSubItem.FragmentNavigate(NavigateDirection.PreviousSibling)` methods, also never return a 0-indexed `ListViewSubItem` - -All [ListViewSubItem](https://docs.microsoft.com/dotnet/api/system.windows.forms.listviewitem) is display if the following conditions are met: -1. A `ListView` has one or more [ListViewSubItems](https://docs.microsoft.com/dotnet/api/system.windows.forms.listviewitem.subitems) -2. A `ListView` has one or more [Columns](https://docs.microsoft.com/dotnet/api/system.windows.forms.listviewitem.subitems) -3. The `ListViewItem` has a [TileSize](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.tilesize) enough to display `ListViewSubItems` - -```cs -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0)); - -listView.TileSize = new Size(100, 100); -``` - -![listviewsubitem-inspect-tile-view-tree][listviewsubitem-inspect-tile-view-tree] - -If the number of `Columns` is less than the number of `ListViewSubItems`, then only `ListViewSubItems` with corresponding `Columns` are displayed. The rest of the `ListViewSubItems` are hidden both on the screen and in the Accessibility tree. - -```cs -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0)); - -listView.TileSize = new Size(100, 100); -``` - -![listviewsubitem-twocolumns-inspect-tile-view-tree][listviewsubitem-twocolumns-inspect-tile-view-tree] - -If the number of `ListViewSubItems` is less than the number of `Columns`, then only existing `ListViewSubItems` are displayed in the Accessibility tree (as opposed to the `Details` view), since nonexistent `ListViewSubItems` are not displayed on the screen and the user cannot interact with them. - -```cs -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22" }, imageIndex: 0)); - -listView.TileSize = new Size(100, 100); -``` - -![listviewsubitem-threeitems-inspect-tile-view-tree][listviewsubitem-threeitems-inspect-tile-view-tree] - -If the [TileSize](https://docs.microsoft.com/dotnet/api/system.windows.forms.listview.tilesize) of the `ListViewItem` is too small, then only those `ListViewSubItems` that are included in the visible area of ​​the `ListViewItem` are displayed. The rest of the `ListViewSubItems` are hidden both on the screen and in the Accessibility tree. - -```cs -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0)); - -listView.TileSize = new Size(100, 40); -``` - -![listviewsubitem-smallsize-inspect-tile-view-tree][listviewsubitem-smallsize-inspect-tile-view-tree] - -`ListViewSubItems` are not displayed when [visual styles](https://docs.microsoft.com/dotnet/api/system.windows.forms.application.enablevisualstyles) are disabled for an application. As a result, `ListViewSubItems` are also hidden in the Accessibility tree - -```cs -listView.Columns.Add(new ColumnHeader { Text = "Column 1" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 2" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 3" }); -listView.Columns.Add(new ColumnHeader { Text = "Column 4" }); - -listView.Items.Add(new ListViewItem(new string[] { "Item 1", "SubItem 11", "SubItem 12", "SubItem 13" }, imageIndex: 0)); -listView.Items.Add(new ListViewItem(new string[] { "Item 2", "SubItem 21", "SubItem 22", "SubItem 23" }, imageIndex: 0)); - -listView.TileSize = new Size(100, 100); -``` - -![listviewsubitem-disabledvisualstyles-inspect-tile-view-tree][listviewsubitem-disabledvisualstyles-inspect-tile-view-tree] - -[listview-inspect-details-view-tree]: ../images/listview-inspect-details-view-tree.png -[listview-inspect-largeicon-view-tree]: ../images/listview-inspect-largeicon-view-tree.png -[listview-inspect-list-view-tree]: ../images/listview-inspect-list-view-tree.png -[listview-inspect-smallicon-view-tree]: ../images/listview-inspect-smallicon-view-tree.png -[listview-inspect-tile-view-tree]: ../images/listview-inspect-tile-view-tree.png -[listview-withgroup-inspect-details-view-tree]: ../images/listview-withgroup-inspect-details-view-tree.png -[listview-withgroup-inspect-largeicon-view-tree]: ../images/listview-withgroup-inspect-largeicon-view-tree.png -[listview-withgroup-inspect-list-view-tree]: ../images/listview-withgroup-inspect-list-view-tree.png -[listview-withgroup-inspect-smallicon-view-tree]: ../images/listview-withgroup-inspect-smallicon-view-tree.png -[listview-withgroup-inspect-tile-view-tree]: ../images/listview-withgroup-inspect-tile-view-tree.png -[listview-disabledstyles-inspect-details-view-tree]: ../images/listview-disabledstyles-inspect-details-view-tree.png -[listview-disabledstyles-inspect-largeicon-view-tree]: ../images/listview-disabledstyles-inspect-largeicon-view-tree.png -[listview-disabledstyles-inspect-list-view-tree]: ../images/listview-disabledstyles-inspect-list-view-tree.png -[listview-disabledstyles-inspect-smallicon-view-tree]: ../images/listview-disabledstyles-inspect-smallicon-view-tree.png -[listview-disabledstyles-inspect-tile-view-tree]: ../images/listview-disabledstyles-inspect-tile-view-tree.png -[listview-showgroupdisabled-inspect-details-view-tree]: ../images/listview-showgroupdisabled-inspect-details-view-tree.png -[listview-showgroupdisabled-inspect-largeicon-view-tree]: ../images/listview-showgroupdisabled-inspect-largeicon-view-tree.png -[listview-showgroupdisabled-inspect-list-view-tree]: ../images/listview-showgroupdisabled-inspect-list-view-tree.png -[listview-showgroupdisabled-inspect-smallicon-view-tree]: ../images/listview-showgroupdisabled-inspect-smallicon-view-tree.png -[listview-showgroupdisabled-inspect-tile-view-tree]: ../images/listview-showgroupdisabled-inspect-tile-view-tree.png -[listview-withoutgroup-inspect-details-view-tree]: ../images/listview-withoutgroup-inspect-details-view-tree.png -[listview-withoutgroup-inspect-largeicon-view-tree]: ../images/listview-withoutgroup-inspect-largeicon-view-tree.png -[listview-withoutgroup-inspect-list-view-tree]: ../images/listview-withoutgroup-inspect-list-view-tree.png -[listview-withoutgroup-inspect-smallicon-view-tree]: ../images/listview-withoutgroup-inspect-smallicon-view-tree.png -[listview-withoutgroup-inspect-tile-view-tree]: ../images/listview-withoutgroup-inspect-tile-view-tree.png -[listview-virtualmode-inspect-details-view-tree]: ../images/listview-virtualmode-inspect-details-view-tree.png -[listview-virtualmode-inspect-largeicon-view-tree]: ../images/listview-virtualmode-inspect-largeicon-view-tree.png -[listview-virtualmode-inspect-list-view-tree]: ../images/listview-virtualmode-inspect-list-view-tree.png -[listview-virtualmode-inspect-smallicon-view-tree]: ../images/listview-virtualmode-inspect-smallicon-view-tree.png -[listviewsubitem-inspect-details-view-tree]: ../images/listviewsubitem-inspect-details-view-tree.png -[listviewsubitem-inspect-largeicon-view-tree]: ../images/listviewsubitem-inspect-largeicon-view-tree.png -[listviewsubitem-inspect-list-view-tree]: ../images/listviewsubitem-inspect-list-view-tree.png -[listviewsubitem-inspect-smallicon-view-tree]: ../images/listviewsubitem-inspect-smallicon-view-tree.png -[listviewsubitem-inspect-tile-view-tree]: ../images/listviewsubitem-inspect-tile-view-tree.png -[listviewsubitem-twocolumns-inspect-details-view-tree]: ../images/listviewsubitem-twocolumns-inspect-details-view-tree.png -[listviewsubitem-twosubitems-inspect-details-view-tree]: ../images/listviewsubitem-twosubitems-inspect-details-view-tree.png -[listviewsubitem-twocolumns-inspect-tile-view-tree]: ../images/listviewsubitem-twocolumns-inspect-tile-view-tree.png -[listviewsubitem-threeitems-inspect-tile-view-tree]: ../images/listviewsubitem-threeitems-inspect-tile-view-tree.png -[listviewsubitem-smallsize-inspect-tile-view-tree]: ../images/listviewsubitem-smallsize-inspect-tile-view-tree.png -[listviewsubitem-disabledvisualstyles-inspect-tile-view-tree]: ../images/listviewsubitem-disabledvisualstyles-inspect-tile-view-tree.png \ No newline at end of file diff --git a/docs/accessibility/monthcalendar-expected-behavior.md b/docs/accessibility/monthcalendar-expected-behavior.md deleted file mode 100644 index b5578c66dee..00000000000 --- a/docs/accessibility/monthcalendar-expected-behavior.md +++ /dev/null @@ -1,1374 +0,0 @@ -# MonthCalendarAccessibleObject expected properties and behavior - -This document describes the expected behavior of `MonthCalendarAccessibleObject` -when using accessibility tools such as Inspect, Narrator or Accessibility Insights, and -expected accessibility properties of all visible items -of the [MonthCalendar control](https://docs.microsoft.com/dotnet/api/system.windows.forms.monthcalendar). - - -- [Overview](#Overview) -- [Accessibility Tools](#Accessibility-Tools) - - [Inspect](#Inspect) - - [Accessibility tree](##Accessibility-tree) - - [Accessibility properties](##Accessibility-properties) - - [Accessibility actions](##Accessibility-actions) - - [ElementProviderFromPoint (get an item when hovering by mouse) behavior](##ElementProviderFromPoint-(get-an-item-when-hovering-by-mouse)-behavior) - - [Narrator](#Narrator) - - [AccessibilityInsights](#AccessibilityInsights) -- [Behavior test cases](#Behavior-test-cases) -- [Additional dev points that don't affect users](#Additional-dev-points-that-don't-affect-users) - - -# Overview - -[MonthCalendar](https://docs.microsoft.com/dotnet/api/system.windows.forms.monthcalendar) is a native Windows control, wrapped by Windows Forms SDK. Windows Forms provide a [UIA support](https://docs.microsoft.com/dotnet/framework/ui-automation/ui-automation-overview) for all -MonthCalendar accessible objects and their children making the MonthCalendar control accessible for Windows Forms end users. - -Expected properties and actions of a MonthCalendar and its parts in different accessibility tools are listed below. -:point_up: A checked item means that the current implementation provides the full support, and the unchecked item means the expected implementation is currently unavailable. - -# Accessibility Tools - -## Inspect - -### Accessibility tree - -MonthCalendar accessibility tree must contain all visible items based on its view. - -
-1. Month view - -![monthcalendar-inspect-month-view-tree][monthcalendar-inspect-month-view-tree] - -
-
- -
-2. Year view - -![monthcalendar-inspect-year-view-tree][monthcalendar-inspect-year-view-tree] - -
-
- -
-3. Decade view - -![monthcalendar-inspect-decade-view-tree][monthcalendar-inspect-decade-view-tree] - -
-
- -
-4. Century view - -![monthcalendar-inspect-century-view-tree][monthcalendar-inspect-century-view-tree] - -
-
- -### Accessibility properties - - -
-1. Month view -
- -MonthCalendar: -- [x] `ControlType` = "calendar" always -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `HasKeyboardFocus` = `true`, if the control is in focus -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `HelpText` = "MonthCalendar(Control)" -- [x] Correct grid Column and Row count -- [x] `Name` is empty, if it is not set -- [x] `Role` = "table" -- [x] `Value` = selected dates (e.g. "Saturday, April 10, 2021 - Wednesday, April 14, 2021") -- [x] Column and row headers = `null` -- [x] `State` = "focusable" + "focused", if the control is in focus -- [x] Supports Grid, LegacyIAccessible, Table, Value patterns - -Previous/Next buttons: -- [x] `Name` = "Previous" or "Next" -- [x] `ControlType` = "button" -- [x] `IsKeyboardFocusable` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled and there are next/previous calendars -- [x] `HasKeyboardFocus` = `false` -- [x] Has a default action and description -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Today button: -- [x] `Name` = a button text (e.g. "Today: 3/20/2021") -- [x] `ControlType` = "button" -- [x] `IsKeyboardFocusable` = `false` -- [x] `HasKeyboardFocus` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] Has a default action and description -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Calendar: -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "pane" -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the calendar contains the focused cell -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] Has correct GridItem properties -- [x] `Role` == "client" -- [x] `State` = "focusable, selectable" + has "focused", "selected", if the calendar contains the focused cell -- [x] Doesn't have TableItems columns and rows -- [x] Supports GridItem, LegacyIAccessible, TableItem patterns - -Calendar header button: -- [x] `Name` = the button text (e.g. "March 2021") -- [x] `HasKeyboardFocus` = `false` -- [x] `IsKeyboardFocusable` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `DefaultAction` = "Click" -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Calendar body: -- [x] `Name` = the header text (e.g. March 2021) -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the calendar contains the focused cell -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "table" -- [x] Correct grid Column and Row count (headers are not included) -- [x] `Role` = "table" -- [x] `State` = "default" -- [x] Supports Grid, LegacyIAccessible, Table patterns - -Calendar row: -- [x] `Name` is empty -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the row contains the focused cell -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `ControlType` = "pane" -- [x] `Role` = "row" -- [x] `State` = "normal" -- [x] `Description` = "Week {number}" for date rows. `Description` is empty for a header row -- [x] Supports LegacyIAccessible pattern - -Cell of the header row (day of week): -- [x] `Name` = the cell text (e.g. "Mon" or "Fri") -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "header" -- [x] `HasKeyboardFocus` = always `false` -- [x] `IsKeyboardFocusable` = `false` -- [x] `Role` = "column header" -- [x] `State` = "normal" -- [x] Doesn't have a `Description` -- [x] Doesn't have a `DefaultAction` -- [x] Supports LegacyIAccessible pattern - -The first cell of date rows (week number): -- [x] `Name` = "Week {the cell text}" (e.g. "Week 12" or "Week 36" - a week number) -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "header" -- [x] `HasKeyboardFocus` = always `false` -- [x] `IsKeyboardFocusable` = `false` -- [x] `Role` = "row header" -- [x] `State` = "normal" -- [x] Doesn't have a `Description` -- [x] Doesn't have a `DefaultAction` -- [x] Supports LegacyIAccessible pattern - -Date cell: -- [x] `Name` = the day long name (e.g. "Wednesday, July 14, 2021") -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "DataItem" ("item" in the accessibility tree) -- [x] `HasKeyboardFocus` = `true`, if the cell is focused and the control in focus -- [x] `IsKeyboardFocusable` = `true`, if the control is enabled -- [x] Correct GridItem pattern properties -- [x] `Description` = "Week {number}, {day of week}" (e.g. "Week 10, Friday") -- [x] `DefaultAction` = "Click" -- [x] `Role` = "cell" -- [x] `State` = "focusable, selectable", if the control is enabled (the order of the states doesn't matter),
- "selected, focusable, selectable", if the cell is selected,
- "focused, selected, focusable, selectable", if the cell is selected and focused.
- :warning: Important point: if a user selects several cells, all of them should have "selected" state, but only one of them should have "focused" state. -- [x] Correct TableItem column and row headers items -- [x] Supports Invoke, GridItem, LegacyIAccessible, TableItem patterns - -
-
- -
-2. Year view -
- -MonthCalendar: -- [x] `ControlType` = "calendar" always -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `HasKeyboardFocus` = `true`, if the control is in focus -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `HelpText` = "MonthCalendar(Control)" -- [x] Correct grid Column and Row count -- [x] `Name` is empty, if it is not set -- [x] `Role` = "table" -- [x] `Value` = a selected month (e.g. "September 2022") -- [x] Column and row headers = null -- [x] `State` = "focusable" + "focused" if the control is in focus -- [x] Supports Grid, LegacyIAccessible, Table, Value patterns - -Previous/Next buttons: -- [x] `Name` = "Previous" or "Next" -- [x] `ControlType` = "button" -- [x] `IsKeyboardFocusable` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled and there are next/previous calendars -- [x] `HasKeyboardFocus` = `false` -- [x] Has a default action and description -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Today button: -- [x] `Name` = a button text (e.g. "Today: 3/20/2021") -- [x] `ControlType` = "button" -- [x] `IsKeyboardFocusable` = `false` -- [x] `HasKeyboardFocus` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] Has a default action and description -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Calendar: -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "pane" -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the calendar contains the focused cell -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] Has correct GridItem properties -- [x] `Role` == "client" -- [x] `State` = "focusable, selectable" + has "focused", "selected", if the calendar contains the focused cell -- [x] Doesn't have TableItems columns and rows -- [x] Supports GridItem, LegacyIAccessible, TableItem patterns - -Calendar header button: -- [x] `Name` = the button text (e.g. "2021") -- [x] `HasKeyboardFocus` = `false` -- [x] `IsKeyboardFocusable` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] Has a default action -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Calendar body: -- [x] `Name` = the header text (e.g. "2021") -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the calendar contains the focused cell -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "table" -- [x] Correct grid Column and Row count (headers are not included) -- [x] `Role` = "table" -- [x] `State` = "default" -- [x] Supports Grid, LegacyIAccessible, Table patterns - -Calendar row: -- [x] `Name` is empty -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the row contains the focused cell -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `ControlType` = "pane" -- [x] `Role` = "row" -- [x] `State` = "normal" -- [x] `Description` is empty -- [x] Supports LegacyIAccessible pattern - -Month cell: -- [x] `Name` = the cell text (e.g. "May") -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "DataItem" ("item" in the accessibility tree) -- [x] `HasKeyboardFocus` = `true`, if the cell is focused -- [x] `IsKeyboardFocusable` = `true`, if the control is enabled -- [x] Correct GridItem pattern properties -- [x] `Description` is empty -- [x] `Role` = "cell" -- [x] `State` = "focusable, selectable" if the control is enabled. (the order of the states doesn't matter)
- "focused, selected, focusable, selectable" if the cell is selected and focused
- :warning: Important point: if a user can't select several cells in this view, so only one cell should have "selected" state, and this cell should have "focused" state. -- [x] Doesn't have TableItem column and row headers items -- [x] Supports GridItem, LegacyIAccessible, TableItem patterns - -
-
- -
-3. Decade view -
- -MonthCalendar: -- [x] `ControlType` = "calendar" always -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `HasKeyboardFocus` = `true`, if the control is in focus -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `HelpText` = "MonthCalendar(Control)" -- [x] Correct grid Column and Row count -- [x] `Name` is empty, if it is not set -- [x] `Role` = "table" -- [x] `Value` = a selected year (e.g. "2022") -- [x] Column and row headers = null -- [x] `State` = "focusable" + "focused" if the control is in focus -- [x] Supports Grid, LegacyIAccessible, Table, Value patterns - -Previous/Next buttons: -- [x] `Name` = "Previous" or "Next" -- [x] `ControlType` = "button" -- [x] `IsKeyboardFocusable` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled and there are next/previous calendars -- [x] `HasKeyboardFocus` = `false` -- [x] Has a default action and description -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Today button: -- [x] `Name` = a button text (e.g. "Today: 3/20/2021") -- [x] `ControlType` = "button" -- [x] `IsKeyboardFocusable` = `false` -- [x] `HasKeyboardFocus` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] Has a default action and description -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Calendar: -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "pane" -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the calendar contains the focused cell -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] Has correct GridItem properties -- [x] `Role` == "client" -- [x] `State` = "focusable, selectable" + has "focused", "selected", if the calendar contains the focused cell -- [x] Doesn't have TableItems columns and rows -- [x] Supports GridItem, LegacyIAccessible, TableItem patterns - -Calendar header button: -- [x] `Name` = the button text (e.g. "2020-2029") -- [x] `HasKeyboardFocus` = `false` -- [x] `IsKeyboardFocusable` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] Has a default action -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Calendar body: -- [x] `Name` = the header text (e.g. "2020-2029") -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the calendar contains the focused cell -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "table" -- [x] Correct grid Column and Row count (headers are not included) -- [x] `Role` = "table" -- [x] `State` = "default" -- [x] Supports Grid, LegacyIAccessible, Table patterns - -Calendar row: -- [x] `Name` is empty -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the row contains the focused cell -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `ControlType` = "pane" -- [x] `Role` = "row" -- [x] `State` = "normal" -- [x] `Description` is empty -- [x] Supports LegacyIAccessible pattern - -Year cell: -- [x] `Name` = the cell text (e.g. "2020") -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "DataItem" ("item" in the accessibility tree) -- [x] `HasKeyboardFocus ` = `true`, if the cell is focused -- [x] `IsKeyboardFocusable` = `true`, if the control is enabled -- [x] Correct GridItem pattern properties -- [x] `Description` is empty -- [x] `Role` = "cell" -- [x] `State` = "focusable, selectable" if the control is enabled. (the order of the states doesn't matter)
- "focused, selected, focusable, selectable" if the cell is selected and focused
- :warning: Important point: if a user can't select several cells in this view, so only one cell should have "selected" state, and this cell should have "focused" state. -- [x] Doesn't have TableItem column and row headers items -- [x] Supports GridItem, LegacyIAccessible, TableItem patterns - -
-
- -
-4. Century view -
- -MonthCalendar: -- [x] `ControlType` = "calendar" always -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `HasKeyboardFocus` = `true`, if the control is in focus -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `HelpText` = "MonthCalendar(Control)" -- [x] Correct grid Column and Row count -- [x] `Name` is empty, if it is not set -- [x] `Role` = "table" -- [x] `Value` = a selected decade (e.g. "2020-2029") -- [x] Column and row headers = null -- [x] `State` = "focusable" + "focused" if the control is in focus -- [x] Supports Grid, LegacyIAccessible, Table, Value patterns - -Previous/Next buttons: -- [x] `Name` = "Previous" or "Next" -- [x] `ControlType` = "button" -- [x] `IsKeyboardFocusable` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled and there are next/previous calendars -- [x] `HasKeyboardFocus` = `false` -- [x] Has a default action and description -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Today button: -- [x] `Name` = a button text (e.g. "Today: 3/20/2021") -- [x] `ControlType` = "button" -- [x] `IsKeyboardFocusable` = `false` -- [x] `HasKeyboardFocus` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] Has a default action and description -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Calendar: -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "pane" -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the calendar contains the focused cell -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] Has correct GridItem properties -- [x] `Role` == "client" -- [x] `State` = "focusable, selectable" + has "focused", "selected", if the calendar contains the focused cell -- [x] Doesn't have TableItems columns and rows -- [x] Supports GridItem, LegacyIAccessible, TableItem patterns - -Calendar header button: -- [x] `Name` = the button text (e.g. "2000-2099") -- [x] `HasKeyboardFocus` = `false` -- [x] `IsKeyboardFocusable` = `false` -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] Has a default action -- [x] `Role` = "push button" -- [x] `State` = "normal" -- [x] Supports Invoke and LegacyIAccessible - -Calendar body: -- [x] `Name` = the header text (e.g. "2000-2099") -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the calendar contains the focused cell -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "table" -- [x] Correct grid Column and Row count (headers are not included) -- [x] `Role` = "table" -- [x] `State` = "default" -- [x] Supports Grid, LegacyIAccessible, Table patterns - -Calendar row: -- [x] `Name` is empty -- [x] `HasKeyboardFocus` = `true`, if the control is in focus and the row contains the focused cell -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `IsKeyboardFocusable` = `true`, if the calendar is enabled -- [x] `ControlType` = "pane" -- [x] `Role` = "row" -- [x] `State` = "normal" -- [x] `Description` is empty -- [x] Supports LegacyIAccessible pattern - -Decade cell: -- [x] `Name` = the cell text (e.g. "2020-2029") -- [x] `IsEnabled` = `true`, if the control is enabled -- [x] `ControlType` = "DataItem" ("item" in the accessibility tree) -- [x] `HasKeyboardFocus` = `true`, if the cell is focused -- [x] `IsKeyboardFocusable` = `true`, if the control is enabled -- [x] Correct GridItem pattern properties -- [x] `Description` is empty -- [x] `Role` = "cell" -- [x] `State` = "focusable, selectable" if the control is enabled. (the order of the states doesn't matter)
- "focused, selected, focusable, selectable" if the cell is selected and focused
- :warning: Important point: if a user can't select several cells in this view, so only one cell should have "selected" state, and this cell should have "focused" state. -- [x] Doesn't have TableItem column and row headers items -- [x] Supports GridItem, LegacyIAccessible, TableItem patterns - -
-
- -### Accessibility actions - -Here are described accessibility actions of supported patterns. -:point_up: The "Focus" action has unexpected behavior, because when you call it from Inspect, -the testing form loses focus. Then the form gets focus, in this case, -MonthCalendar.OnGotFocus handler works, that raises accessibility focus event for the focused cell accessible object. - -
-1. Month view -
- -MonthCalendar: -- [x] Focus - focuses on the focused cell -- [ ] Grid.GetItem- returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] Value.SetValue - does nothing -- [x] LegacyIAccessible.Select - does nothing, because the MonthCalendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Previous/Next buttons: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (moves to the previous/next month) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (works in the debug mode only, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Today button: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (moves to the today cell) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar: -- [ ] Focus - focuses on the focused cell, if the calendar contains it. And does nothing, if the calendar doesn't contain the focused cell -- [x] LegacyIAccessible.Select - does nothing, because the calendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar header button: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (changes the calendar view) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar body: -- [ ] Focus - focuses on the focused cell, if the calendar contains it. And does nothing, if the calendar doesn't contain the focused cell -- [ ] Grid.GetItem - returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.Select - does nothing, because the body is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar row: -- [ ] Focus - focuses on the focused cell, if the row contains it. And does nothing, if the row doesn't contain the focused cell -- [x] LegacyIAccessible.Select - does nothing, because the row is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Cell of the header row (day of week): -- [ ] Focus - does nothing -- [x] LegacyIAccessible.Select - does nothing, because the header cell is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -The first cell of date rows (week numbers): -- [ ] Focus - does nothing -- [x] LegacyIAccessible.Select - does nothing, because the header cell is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Date cell: -- [x] Focus - focuses on the focused cell -- [x] Invoke.Invoke - clicks the cell (select it) -- [x] LegacyIAccessible.Select - selects the cell -- [x] LegacyIAccessible.DoDefaultAction - selects the cell -- [x] LegacyIAccessible.SetValue - does nothing - -
-
- -
-2. Year view -
- -MonthCalendar: -- [x] Focus - focuses on the focused cell -- [ ] Grid.GetItem- returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] Value.SetValue - does nothing -- [x] LegacyIAccessible.Select - does nothing, because the MonthCalendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Previous/Next buttons: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (moves to the previous/next month) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (works in the debug mode only, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Today button: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (moves to the today cell) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar: -- [ ] Focus - focuses on the focused cell, if the calendar contains it. And does nothing, if the calendar doesn't contain the focused cell -- [x] LegacyIAccessible.Select - does nothing, because the calendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar header button: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (changes the calendar view) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar body: -- [ ] Focus - focuses on the focused cell, if the calendar contains it. And does nothing, if the calendar doesn't contain the focused cell -- [ ] Grid.GetItem - returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.Select - does nothing, because the body is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar row: -- [ ] Focus - focuses on the focused cell, if the row contains it. And does nothing, if the row doesn't contain the focused cell -- [x] LegacyIAccessible.Select - does nothing, because the row is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Month cell: -- [x] Focus - focuses on the focused cell -- [x] Invoke.Invoke - clicks the cell (changes the view) -- [x] LegacyIAccessible.Select - selects the cell -- [x] LegacyIAccessible.DoDefaultAction - click the cell -- [x] LegacyIAccessible.SetValue - does nothing - - -
-
- -
-3. Decade view -
- -MonthCalendar: -- [x] Focus - focuses on the focused cell -- [ ] Grid.GetItem- returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] Value.SetValue - does nothing -- [x] LegacyIAccessible.Select - does nothing, because the MonthCalendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Previous/Next buttons: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (moves to the previous/next month) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (works in the debug mode only, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Today button: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (moves to the today cell) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar: -- [ ] Focus - focuses on the focused cell, if the calendar contains it. And does nothing, if the calendar doesn't contain the focused cell -- [x] LegacyIAccessible.Select - does nothing, because the calendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar header button: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (changes the calendar view) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar body: -- [ ] Focus - focuses on the focused cell, if the calendar contains it. And does nothing, if the calendar doesn't contain the focused cell -- [ ] Grid.GetItem - returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.Select - does nothing, because the body is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar row: -- [ ] Focus - focuses on the focused cell, if the row contains it. And does nothing, if the row doesn't contain the focused cell -- [x] LegacyIAccessible.Select - does nothing, because the row is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Year cell: -- [x] Focus - focuses on the focused cell -- [x] Invoke.Invoke - clicks the cell (changes the view) -- [x] LegacyIAccessible.Select - selects the cell -- [x] LegacyIAccessible.DoDefaultAction - click the cell -- [x] LegacyIAccessible.SetValue - does nothing - -
-
- -
-4. Century view -
- -MonthCalendar: -- [x] Focus - focuses on the focused cell -- [ ] Grid.GetItem- returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] Value.SetValue - does nothing -- [x] LegacyIAccessible.Select - does nothing, because the MonthCalendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Previous/Next buttons: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (moves to the previous/next month) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (works in the debug mode only, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Today button: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (moves to the today cell) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar: -- [ ] Focus - focuses on the focused cell, if the calendar contains it. And does nothing, if the calendar doesn't contain the focused cell -- [x] LegacyIAccessible.Select - does nothing, because the calendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar header button: -- [ ] Focus - the button is not keyboard focusable, so does nothing -- [x] Invoke.Invoke - clicks the button (changes the calendar view) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar body: -- [ ] Focus - focuses on the focused cell, if the calendar contains it. And does nothing, if the calendar doesn't contain the focused cell -- [ ] Grid.GetItem - returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.Select - does nothing, because the body is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar row: -- [ ] Focus - focuses on the focused cell, if the row contains it. And does nothing, if the row doesn't contain the focused cell -- [x] LegacyIAccessible.Select - does nothing, because the row is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Decade cell: -- [x] Focus - focuses on the focused cell -- [x] Invoke.Invoke - clicks the cell (changes the view) -- [x] LegacyIAccessible.Select - selects the cell -- [x] LegacyIAccessible.DoDefaultAction - click the cell -- [x] LegacyIAccessible.SetValue - does nothing - -
-
- -### ElementProviderFromPoint (get an item when hovering by mouse) behavior - -- [x] Returns a MonthCalendar accessible object, if mouse isn't hovering any element -- [x] Returns a "Previous" button accessible object, if mouse is hovering it -- [x] Returns a "Next" button accessible object, if mouse is hovering it -- [x] Returns a "Today" button accessible object, if mouse is hovering the "Today" text, or to the right of the text -- [x] Returns a calendar header button accessible object (e.g. "March 2021"), if mouse is hovering it -- [x] Returns a day of week cell accessible object (e.g. "Sat"), if its MonthCalendar is in the Month view and mouse is hovering it -- [x] Returns a week number cell accessible object (e.g. "18"), if - - `ShowWeekNumber` = `true`, - - its MonthCalendar is in the Month view - - mouse is hovering this cell -- [x] Returns a day/month/year/years cell accessible object, if this cell is visible, and mouse is hovering it -- [x] Returns an accessible object of a gray cell of the next/previous calendar, if it is, and if mouse is hovering it
Screenshot![monthcalendar-gray-dates-accessible-from-point][monthcalendar-gray-dates-accessible-from-point]
-- [x] Returns a calendar accessible object, if its Bounds contains mouse coordinates, and if there is no any cell in this point
Screenshot![monthcalendar-calendar-accessible-from-point][monthcalendar-calendar-accessible-from-point]
-- [x] Returns a MonthCalendar accessible object, if `MaxDate` and `MinDate` are set, and several months are missing there (they are invisible) and if mouse is hovering some invisible calendar
Screenshot![monthcalendar-control-accessible-from-point][monthcalendar-control-accessible-from-point]
-- [x] Returns an accessible object of the first week number of a calendar, if mouse is hovering it, and if the calendar first row is partial (a specific case - there is a workaround that fixes a bug of Win API)
Screenshot![monthcalendar-first-weeknumber-accessible-from-point][monthcalendar-first-weeknumber-accessible-from-point]
-- [x] Doesn't return week number cells accessible objects of the last calendar, if `MaxDate` is set, and mouse is hovering them
Screenshot![monthcalendar-last-weeknumbers-accessible-from-point][monthcalendar-last-weeknumbers-accessible-from-point]
-- [x] Returns a correct accessible object, that is visible, if `MaxDate`, `MinDate`, `FirstDayOfWeek` are changed or the display range is changed via the "Next"/"Previous" buttons - -## Narrator - -
-1. Month view -
- -- [x] Announces dates when moving through them -- [x] Moves through all the accessibility tree nodes in the "Scan" mode -- [ ] Moves through all the accessibility tree nodes in the "Scan" mode after the display range is changed -- [x] Focuses on the focused cell when the control gets focus -- [ ] Focuses on the focused cell, if `MaxDate`, `MinDate`, `FirstDayOfWeek` are changed or the display range is changed via the "Next"/"Previous" buttons - -
-
- -
-2. Year view -
- -- [x] Announces dates when moving through them -- [x] Moves through all the accessibility tree nodes in the "Scan" mode -- [ ] Moves through all the accessibility tree nodes in the "Scan" mode after the display range is changed -- [x] Focuses on the focused cell when the control gets focus -- [ ] Focuses on the focused cell, if `MaxDate`, `MinDate`, `FirstDayOfWeek` are changed or the display range is changed via the "Next"/"Previous" buttons - -
-
- -
-3. Decade view -
- -- [x] Announces dates when moving through them -- [x] Moves through all the accessibility tree nodes in the "Scan" mode -- [ ] Moves through all the accessibility tree nodes in the "Scan" mode after the display range is changed -- [x] Focuses on the focused cell when the control gets focus -- [ ] Focuses on the focused cell, if `MaxDate`, `MinDate`, `FirstDayOfWeek` are changed or the display range is changed via the "Next"/"Previous" buttons - -
-
- -
-4. Century view -
- -- [x] Announces dates when moving through them -- [x] Moves through all the accessibility tree nodes in the "Scan" mode -- [ ] Moves through all the accessibility tree nodes in the "Scan" mode after the display range is changed -- [x] Focuses on the focused cell when the control gets focus -- [ ] Focuses on the focused cell, if `MaxDate`, `MinDate`, `FirstDayOfWeek` are changed or the display range is changed via the "Next"/"Previous" buttons - -
-
- -## AccessibilityInsights - -
-1. Month view -
- -- [x] There are no any AI errors -- [x] The accessibility tree is correct -- [x] AI gets a correct visible accessible object when hovering the mouse (an element from the point) -- [x] AI sees correct item patterns and does supported pattern Actions correctly - -MonthCalendar: -- [ ] Grid.GetItem- returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] Value.SetValue - does nothing -- [x] LegacyIAccessible.Select - does nothing, because the MonthCalendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Previous/Next buttons: -- [ ] Invoke.Invoke - clicks the button (moves to the previous/next month) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button -- [x] LegacyIAccessible.SetValue - does nothing - -Today button: -- [x] Invoke.Invoke - clicks the button (moves to the today cell) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [x] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar: -- [x] LegacyIAccessible.Select - does nothing, because the calendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar header button: -- [x] Invoke.Invoke - clicks the button (changes the calendar view) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [x] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar body: -- [ ] Grid.GetItem - returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.Select - does nothing, because the body is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar row: -- [x] LegacyIAccessible.Select - does nothing, because the row is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Cell of the header row (day of week): -- [x] LegacyIAccessible.Select - does nothing, because the header cell is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -The first cell of date rows (week numbers): -- [x] LegacyIAccessible.Select - does nothing, because the header cell is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Date cell: -- [x] Invoke.Invoke - clicks the cell (select it) -- [x] LegacyIAccessible.Select - selects the cell -- [ ] LegacyIAccessible.DoDefaultAction - selects the cell (AI issue) -- [x] LegacyIAccessible.SetValue - does nothing - -
-
- -
-2. Year view -
- -- [x] There are no any AI errors -- [x] The accessibility tree is correct. -- [x] AI gets a correct visible accessible object when hovering the mouse (an element from the point). -- [x] AI sees correct items patterns and does supported pattern Actions correctly: - -MonthCalendar: -- [ ] Grid.GetItem- returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] Value.SetValue - does nothing -- [x] LegacyIAccessible.Select - does nothing, because the MonthCalendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Previous/Next buttons: -- [ ] Invoke.Invoke - clicks the button (moves to the previous/next month) (AI issue) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (AI issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Today button: -- [x] Invoke.Invoke - clicks the button (moves to the today cell) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [x] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar: -- [x] LegacyIAccessible.Select - does nothing, because the calendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar header button: -- [x] Invoke.Invoke - clicks the button (changes the calendar view) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [x] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar body: -- [ ] Grid.GetItem - returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.Select - does nothing, because the body is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar row: -- [x] LegacyIAccessible.Select - does nothing, because the row is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Month cell: -- [x] Invoke.Invoke - clicks the cell (select it) -- [x] LegacyIAccessible.Select - selects the cell -- [ ] LegacyIAccessible.DoDefaultAction - selects the cell (AI issue) -- [x] LegacyIAccessible.SetValue - does nothing - -
-
- -
-3. Decade view -
- -- [x] There are no any AI errors -- [x] The accessibility tree is correct. -- [x] AI gets a correct visible accessible object when hovering the mouse (an element from the point). -- [x] AI sees correct items patterns and does supported pattern Actions correctly: - -MonthCalendar: -- [ ] Grid.GetItem- returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] Value.SetValue - does nothing -- [x] LegacyIAccessible.Select - does nothing, because the MonthCalendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Previous/Next buttons: -- [ ] Invoke.Invoke - clicks the button (moves to the previous/next month) (AI issue) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (AI issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Today button: -- [x] Invoke.Invoke - clicks the button (moves to the today cell) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [x] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar: -- [x] LegacyIAccessible.Select - does nothing, because the calendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar header button: -- [x] Invoke.Invoke - clicks the button (changes the calendar view) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [x] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar body: -- [ ] Grid.GetItem - returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.Select - does nothing, because the body is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar row: -- [x] LegacyIAccessible.Select - does nothing, because the row is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Year cell: -- [x] Invoke.Invoke - clicks the cell (select it) -- [x] LegacyIAccessible.Select - selects the cell -- [ ] LegacyIAccessible.DoDefaultAction - selects the cell (AI issue) -- [x] LegacyIAccessible.SetValue - does nothing - -
-
- -
-4. Century view -
- -- [x] There are no any AI errors -- [x] The accessibility tree is correct. -- [x] AI gets a correct visible accessible object when hovering the mouse (an element from the point). -- [x] AI sees correct items patterns and does supported pattern Actions correctly: - -MonthCalendar: -- [ ] Grid.GetItem- returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] Value.SetValue - does nothing -- [x] LegacyIAccessible.Select - does nothing, because the MonthCalendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Previous/Next buttons: -- [ ] Invoke.Invoke - clicks the button (moves to the previous/next month) (AI issue) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [ ] LegacyIAccessible.DoDefaultAction - clicks the button (AI issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Today button: -- [x] Invoke.Invoke - clicks the button (moves to the today cell) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [x] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar: -- [x] LegacyIAccessible.Select - does nothing, because the calendar is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar header button: -- [x] Invoke.Invoke - clicks the button (changes the calendar view) -- [x] LegacyIAccessible.Select - does nothing, because the button is not selectable -- [x] LegacyIAccessible.DoDefaultAction - clicks the button (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar body: -- [ ] Grid.GetItem - returns OK for the correct row and column, returns FAIL for incorrect arguments (doesn't work, it's Inspect Issue) -- [x] LegacyIAccessible.Select - does nothing, because the body is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Calendar row: -- [x] LegacyIAccessible.Select - does nothing, because the row is not selectable -- [x] LegacyIAccessible.DoDefaultAction - does nothing -- [x] LegacyIAccessible.SetValue - does nothing - -Decade cell: -- [x] Invoke.Invoke - clicks the cell (select it) -- [x] LegacyIAccessible.Select - selects the cell -- [ ] LegacyIAccessible.DoDefaultAction - selects the cell (AI issue) -- [x] LegacyIAccessible.SetValue - does nothing - -
-
- -# Behavior test cases - -
-1. Month view -
- -- [x] **Case:** Change the Today date (set `TodayDate` of a MonthCalendar) -
**Expected:** Nothing happens -- [x] **Case:** Click on a gray date cell (of the next or previous calendars) -
**Expected:** The monthCalendar changes the display range. Its accessibility tree rebuilds. -- [x] **Case:** Size of the control is changed that the control changes calendars count -
**Expected:** The accessibility tree is rebuilt. ElementProviderFromPoint returns visible items correctly -- [x] **Case:** A calendar of a MonthCalendar has non-full rows -
**Expected:** Inspect sees only visible items in that row -- [x] **Case:** A calendar of a MonthCalendar has some empty rows -
**Expected:** These rows are not in the accessibility tree -- [x] **Case:** The first week number cell in the first calendar in a MonthCalendar is in a non-full row -
**Expected:** Inspect sees that cell correctly with the correct name -- [x] **Case:** The last week number cells of the last non-full calendar have the same values for empty rows -
**Expected:** They are not in the accessibility tree -- [x] **Case:** Select some dates (e.g. 10-15th of September), move to right, thereby the focused cell -will be in right (e.g. 15th of September). Set `MinDate` of the calendar less then the selected range (e.g. 1st of September). -
**Expected:** The selected range doesn't change. The focused cell doesn't change. -The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select some dates (e.g. 10-15th of September), move to left, thereby the focused cell -will be in left (e.g. 10th of September). Set `MinDate` of the calendar less then the selected range (e.g. 1st of September). -
**Expected:** The selected range doesn't change. The focused cell doesn't change. -The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select some dates (e.g. 10-15th of September), move to right, thereby the focused cell -will be in right (e.g. 15th of September). Set `MaxDate` of the calendar more then the selected range (e.g. 20th of September). -
**Expected:** The selected range doesn't change. The focused cell doesn't change. -The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select some dates (e.g. 10-15th of September), move to left, thereby the focused cell -will be in left (e.g. 10th of September). Set `MaxDate` of the calendar more then the selected range (e.g. 20th of September). -
**Expected:** The selected range doesn't change. The focused cell doesn't change. -The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select some dates (e.g. 10-15th of September), move to right, thereby the focused cell -will be in right (e.g. 15th of September). Set `MinDate` of the calendar more then the start of the selected range, -but less then the end of the selected range (e.g. 13th of September). -
**Expected:** The selected range changes. The focused cell doesn't change. -The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select some dates (e.g. 10-15th of September), move to left, thereby the focused cell -will be in left (e.g. 10th of September). Set `MinDate` of the calendar more then the start of the selected range, -but less then the end of the selected range (e.g. 13th of September). -
**Expected:** The selected range changes. The focused cell changes (13th of September). -The new focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select some dates (e.g. 10-15th of September), move to right, thereby the focused cell -will be in right (e.g. 15th of September). Set `MaxDate` of the calendar more then the start of the selected range, -but less then the end of the selected range (e.g. 13th of September). -
**Expected:** The selected range changes. The focused cell changes (13th of September). -The new focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select some dates (e.g. 10-15th of September), move to left, thereby the focused cell -will be in left (e.g. 10th of September). Set `MaxDate` of the calendar more then the start of the selected range, -but less then the end of the selected range (e.g. 13th of September). -
**Expected:** The selected range changes. The focused cell cell doesn't change. -The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select some dates (e.g. 10-15th of September), move to right, thereby the focused cell -will be in right (e.g. 15th of September). Set new `FirstDayOfWeek` (e.g. Friday). -
**Expected:** The selected range doesn't change. The focused cell doesn't change. -The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select some dates (e.g. 10-15th of September), move to left, thereby the focused cell -will be in left (e.g. 10th of September). Set new `FirstDayOfWeek` (e.g. Friday). -
**Expected:** The selected range doesn't change. The focused cell doesn't change. -The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** `MinDate` is more then the selected range. -
**Expected:** The focused cell changes. The new focused cell has "focused" accessibility state. -- [x] **Case:** `MaxDate` is less then the selected range. -
**Expected:** The focused cell changes. The new focused cell has "focused" accessibility state. -- [x] **Case:** A MonthCalendar has 1 calendar. -
**Expected:** Accessibility tree has 1 calendar. -- [x] **Case:** A MonthCalendar has several calendars. -
**Expected:** Accessibility tree has the same count of calendars. -- [x] **Case:** `MinDate` is set for a MonthCalendar. -
**Expected:** Dates before `MinDate` are invisible and are not accessible. -- [x] **Case:** `MaxDate` is set for a MonthCalendar. -
**Expected:** Dates after `MaxDate` are invisible and are not accessible. -- [x] **Case:** `MaxDate` and `MinDate` are set for a MonthCalendar. -They are has a more date range then the display range of the MonthCalendar. -
**Expected:** Accessibility tree has all visible calendars. All dates are accessible. -- [x] **Case:** `MaxDate` and `MinDate` are set for a MonthCalendar. -They are has a less date range then the display range of the MonthCalendar. -Thereby the MonthCalendar has several partially visible calendars -(e.g. the MonthCalendar can contain 6 calendars, but 3 of them are visible due `MinDate` and `MinDate`). -
**Expected:** Accessibility tree has the count of visible calendars only (e.g. 3). -Invisible calendars are not accessible. Invisible dates of partial calendars are not accessible. - -
-
- -
-2. Year view -
- -- [x] **Case:** Change the Today date (set `TodayDate` of a MonthCalendar) -
**Expected:** Nothing happens -- [x] **Case:** Click on a gray month cell (of the next or previous calendars) -
**Expected:** The monthCalendar changes the display range. It accessibility tree rebuilds. -- [x] **Case:** Size of the control is changed that the control changes calendars count -
**Expected:** The accessibility tree is rebuilt. ElementProviderFromPoint returns visible items correctly -- [x] **Case:** A calendar of a MonthCalendar has non-full rows -
**Expected:** Inspect sees only visible items in that row -- [x] **Case:** A calendar of a MonthCalendar has some empty rows -
**Expected:** These rows are not in the accessibility tree -- [x] **Case:** There are no week number and day of week cells in calendars -
**Expected:** There are no any invisible items (week number and day of week cells) in the accessibility tree -- [x] **Case:** Select one month cell (e.g. September), user can't select several cell in this view, -so the selected cell is focused. Set `MinDate` of the calendar less then the selected cell (e.g. 1st of June). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. September), user can't select several cell in this view, -so the selected cell is focused. Set `MinDate` of the calendar more then the selected cell (e.g. 1st of December). -
**Expected:** The focused cell changes (e.g. December). The new focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. September), user can't select several cell in this view, -so the selected cell is focused. Set `MaxDate` of the calendar less then the selected cell (e.g. 1st of June). -
**Expected:** The focused cell changes (e.g. June). The new focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. September), user can't select several cell in this view, -so the selected cell is focused. Set `MaxDate` of the calendar more then the selected cell (e.g. 1st of December). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. September), user can't select several cell in this view, -so the selected cell is focused. Set `MinDate` of the calendar with the same month (e.g. 30th of September). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. September), user can't select several cell in this view, -so the selected cell is focused. Set `MaxDate` of the calendar with the same month (e.g. 1st of September). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** `MinDate` is more then the selected range. -
**Expected:** The focused cell changes. The new focused cell has "focused" accessibility state. -- [x] **Case:** `MaxDate` is less then the selected range. -
**Expected:** The focused cell changes. The new focused cell has "focused" accessibility state. -- [x] **Case:** A MonthCalendar has 1 calendar. -
**Expected:** Accessibility tree has 1 calendar. -- [x] **Case:** A MonthCalendar has several calendars. -
**Expected:** Accessibility tree has the same count of calendars. -- [x] **Case:** `MinDate` is set for a MonthCalendar. -
**Expected:** Dates before `MinDate` are invisible and are not accessible. -- [x] **Case:** `MaxDate` is set for a MonthCalendar. -
**Expected:** Dates after `MaxDate` are invisible and are not accessible. -- [x] **Case:** `MaxDate` and `MinDate` are set for a MonthCalendar. -They are has a more date range then the display range of the MonthCalendar. -
**Expected:** Accessibility tree has all visible calendars. All dates are accessible. -- [x] **Case:** `MaxDate` and `MinDate` are set for a MonthCalendar. -They are has a less date range then the display range of the MonthCalendar. -Thereby the MonthCalendar has several partially visible calendars -(e.g. the MonthCalendar can contain 6 calendars, but 3 of them are visible due `MinDate` and `MinDate`). -
**Expected:** Accessibility tree has the count of visible calendars only (e.g. 3). -Invisible calendars are not accessible. Invisible dates of partial calendars are not accessible. - -
-
- -
-3. Decade view -
- -- [x] **Case:** Change the Today date (set `TodayDate` of a MonthCalendar) -
**Expected:** Nothing happens -- [x] **Case:** Click on a gray year cell (of the next or previous calendars) -
**Expected:** The monthCalendar changes the display range. It accessibility tree rebuilds. -- [x] **Case:** Size of the control is changed that the control changes calendars count -
**Expected:** The accessibility tree is rebuilt. ElementProviderFromPoint returns visible items correctly -- [x] **Case:** A calendar of a MonthCalendar has non-full rows -
**Expected:** Inspect sees only visible items in that row -- [x] **Case:** A calendar of a MonthCalendar has some empty rows -
**Expected:** These rows are not in the accessibility tree -- [x] **Case:** There are no week number and day of week cells in calendars -
**Expected:** There are no any invisible items (week number and day of week cells) in the accessibility tree -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MinDate` of the calendar less then the selected cell (e.g. 1st of June 2019). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MinDate` of the calendar more then the selected cell (e.g. 1st of December 2021). -
**Expected:** The focused cell changes (e.g. 2021). The new focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MaxDate` of the calendar less then the selected cell (e.g. 1st of June 2019). -
**Expected:** The focused cell changes (e.g. 2019). The new focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MaxDate` of the calendar more then the selected cell (e.g. 1st of December 2021). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MinDate` of the calendar with the same year (e.g. 31th of December 2020). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MaxDate` of the calendar with the same year (e.g. 1st of January 2020). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** `MinDate` is more then the selected range. -
**Expected:** The focused cell changes. The new focused cell has "focused" accessibility state. -- [x] **Case:** `MaxDate` is less then the selected range. -
**Expected:** The focused cell changes. The new focused cell has "focused" accessibility state. -- [x] **Case:** A MonthCalendar has 1 calendar. -
**Expected:** Accessibility tree has 1 calendar. -- [x] **Case:** A MonthCalendar has several calendars. -
**Expected:** Accessibility tree has the same count of calendars. -- [x] **Case:** `MinDate` is set for a MonthCalendar. -
**Expected:** Dates before `MinDate` are invisible and are not accessible. -- [x] **Case:** `MaxDate` is set for a MonthCalendar. -
**Expected:** Dates after `MaxDate` are invisible and are not accessible. -- [x] **Case:** `MaxDate` and `MinDate` are set for a MonthCalendar. -They are has a more date range then the display range of the MonthCalendar. -
**Expected:** Accessibility tree has all visible calendars. All dates are accessible. -- [x] **Case:** `MaxDate` and `MinDate` are set for a MonthCalendar. -They are has a less date range then the display range of the MonthCalendar. -Thereby the MonthCalendar has several partially visible calendars -(e.g. the MonthCalendar can contain 6 calendars, but 3 of them are visible due `MinDate` and `MinDate`). -
**Expected:** Accessibility tree has the count of visible calendars only (e.g. 3). -Invisible calendars are not accessible. Invisible dates of partial calendars are not accessible. - -
-
- -
-4. Century view -
- -- [x] **Case:** Change the Today date (set `TodayDate` of a MonthCalendar) -
**Expected:** Nothing happens -- [x] **Case:** Click on a gray decade cell (of the next or previous calendars) -
**Expected:** The monthCalendar changes the display range. It accessibility tree rebuilds. -- [x] **Case:** Size of the control is changed that the control changes calendars count -
**Expected:** The accessibility tree is rebuilt. ElementProviderFromPoint returns visible items correctly -- [x] **Case:** A calendar of a MonthCalendar has non-full rows -
**Expected:** Inspect sees only visible items in that row -- [x] **Case:** A calendar of a MonthCalendar has some empty rows -
**Expected:** These rows are not in the accessibility tree -- [x] **Case:** There are no week number and day of week cells in calendars -
**Expected:** There are no any invisible items (week number and day of week cells) in the accessibility tree -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MinDate` of the calendar less then the selected cell (e.g. 1st of June 2019). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MinDate` of the calendar more then the selected cell (e.g. 1st of December 2021). -
**Expected:** The focused cell changes (e.g. 2021). The new focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MaxDate` of the calendar less then the selected cell (e.g. 1st of June 2019). -
**Expected:** The focused cell changes (e.g. 2019). The new focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MaxDate` of the calendar more then the selected cell (e.g. 1st of December 2021). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MinDate` of the calendar with the same year (e.g. 31th of December 2020). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** Select one month cell (e.g. 2020), user can't select several cell in this view, -so the selected cell is focused. Set `MaxDate` of the calendar with the same year (e.g. 1st of January 2020). -
**Expected:** The focused cell doesn't change. The focused cell has "focused" accessibility state (check Inspect). -- [x] **Case:** `MinDate` is more then the selected range. -
**Expected:** The focused cell changes. The new focused cell has "focused" accessibility state. -- [x] **Case:** `MaxDate` is less then the selected range. -
**Expected:** The focused cell changes. The new focused cell has "focused" accessibility state. -- [x] **Case:** A MonthCalendar has 1 calendar. -
**Expected:** Accessibility tree has 1 calendar. -- [x] **Case:** A MonthCalendar has several calendars. -
**Expected:** Accessibility tree has the same count of calendars. -- [x] **Case:** `MinDate` is set for a MonthCalendar. -
**Expected:** Dates before `MinDate` are invisible and are not accessible. -- [x] **Case:** `MaxDate` is set for a MonthCalendar. -
**Expected:** Dates after `MaxDate` are invisible and are not accessible. -- [x] **Case:** `MaxDate` and `MinDate` are set for a MonthCalendar. -They are has a more date range then the display range of the MonthCalendar. -
**Expected:** Accessibility tree has all visible calendars. All dates are accessible. -- [x] **Case:** `MaxDate` and `MinDate` are set for a MonthCalendar. -They are has a less date range then the display range of the MonthCalendar. -Thereby the MonthCalendar has several partially visible calendars -(e.g. the MonthCalendar can contain 6 calendars, but 3 of them are visible due `MinDate` and `MinDate`). -
**Expected:** Accessibility tree has the count of visible calendars only (e.g. 3). -Invisible calendars are not accessible. Invisible dates of partial calendars are not accessible. - -
-
- -# Additional dev points that don't affect users - -- Rebuild the accessibility tree, if the calendar `View`, `MaxDate`, `MinDate`, `TodayDate`, `Size` are changed -or Next or Previous buttons are clicked (i.e. the display range is changed). -- Invoke method of button accessible objects of MonthCalendar simulates mouse moving, clicks and then returns the mouse position back. -Windows doesn't provide API to simulate MonthCalendar buttons clicks via messages. - -[monthcalendar-inspect-month-view-tree]: ../images/monthcalendar-inspect-month-view-tree.png -[monthcalendar-inspect-year-view-tree]: ../images/monthcalendar-inspect-year-view-tree.png -[monthcalendar-inspect-decade-view-tree]: ../images/monthcalendar-inspect-decade-view-tree.png -[monthcalendar-inspect-century-view-tree]: ../images/monthcalendar-inspect-century-view-tree.png -[monthcalendar-gray-dates-accessible-from-point]: ../images/monthcalendar-gray-dates-accessible-from-point.png -[monthcalendar-calendar-accessible-from-point]: ../images/monthcalendar-calendar-accessible-from-point.png -[monthcalendar-control-accessible-from-point]: ../images/monthcalendar-control-accessible-from-point.png -[monthcalendar-first-weeknumber-accessible-from-point]: ../images/monthcalendar-first-weeknumber-accessible-from-point.png -[monthcalendar-last-weeknumbers-accessible-from-point]: ../images/monthcalendar-last-weeknumbers-accessible-from-point.png \ No newline at end of file diff --git a/docs/building.md b/docs/building.md deleted file mode 100644 index 25f26541301..00000000000 --- a/docs/building.md +++ /dev/null @@ -1,77 +0,0 @@ -# Building Windows Forms - -## Prerequisites - -Follow the prerequisites listed at [Developer Guide](developer-guide.md). - -## Building - -### Building from command line (Preferred) - -* Run `.\build.cmd` from the repository root. This builds the `Winforms.sln` using the default config (Debug|Any CPU). -* To specify a build configuration, add `-configuration` followed by the config such as `.\build -configuration Release`. - -Note that this does **not** build using your machine-wide installed version of the dotnet sdk. It builds using the repo-local .NET SDK specified in the global.json in the repository root. - -### Building from Visual Studio - -1. .NET 6.0 and above branches need VisualStudio 2022 to build. -2. Run `.\restore.cmd` from the repository root. -3. Run `.\start-vs.cmd` from the repository root. This will prepend the repo-local .NET SDK to the path, and open `Winforms.sln` in Visual Studio. -4. You should now be able to build as you normally would. - -### Building from Visual Studio Code - -1. (Optional) Run `.\restore.cmd` from the repository root. -1. Run `.\start-code.cmd` from the repository root. This will prepend the repo-local .NET SDK to the path, and open `Winforms.sln` in Visual Studio Code. -1. You should now be able to build and test as you normally would from command line (or VS Code, if you have set it). - -## Build outputs - -* All build outputs are generated under the `artifacts` folder. -* Binaries are under `artifacts\bin`. - * For example, `System.Windows.Forms.dll` can be found under `artifacts\bin\System.Windows.Forms\Debug\net6.0`. -* Logs are found under `artifacts\log`. -* Packages are found under `artifacts\packages`. - -## Running apps from VS - -1. Right click on the project you wish to run and select 'Set as startup project'. -2. F5. - -## Running apps from command line - -1. Build the solution: `.\build.cmd` -2. Navigate to the project you wish to run, e.g. to run AccessibilityTests test app: - ``` - winforms> pushd .\src\System.Windows.Forms\tests\AccessibilityTests - winforms\src\System.Windows.Forms\tests\AccessibilityTests> dotnet run - ``` -3. (Alternatively) Navigate to `.\artifacts\bin\AccessibilityTests\Debug\net6.0` and run the app manually. - -## Troubleshooting build errors - -* Most build errors are compile errors and can be dealt with accordingly. -* Other error may be from MSBuild tasks. You need to examine the build logs to investigate. - * The logs are generated at `.\artifacts\log\Debug\Build.binlog` - * The file format is an MSBuild Binary Log. Install the [MSBuild Structured Log Viewer][msbuild-log-viewer] to view them. -* Windows Forms uses Visual Studio MSBuild but for certain features we require the latest MSBuild from .NET Core/.NET SDK. If you are on an official version of [Visual Studio][VS-download] (i.e. not a Preview version), then you may need to enable previews for .NET Core/.NET SDKs in VS. - * you can do this in VS under Tools->Options->Environment->Preview Features->Use previews of the .Net Core SDK (Requires restart) - -## Creating a package - -To create the Microsoft.Private.Winforms package, run `.\build -pack` - -## Localization - -If you need to add a new localization string or update an existing one, follow these steps: - -- Modify `Resource\SR.resx` file adding or updating necessary strings in the project that contains the said strings. (It is often faster/easier to open SR.resx in an XML editor). -- Regenerate the localization files by rebuilding the solution/project from Visual Studio, or by executing `.\build.cmd` command. You can also build just the modified project by running `dotnet build` from the project's root. - -[comment]: <> (URI Links) - -[corefx-windows-instructions]: https://github.com/dotnet/corefx/blob/master/Documentation/building/windows-instructions.md -[latest-core-build]: https://github.com/dotnet/core/blob/master/daily-builds.md -[msbuild-log-viewer]: https://msbuildlog.com/ -[VS-download]: https://visualstudio.microsoft.com/downloads/ diff --git a/docs/debugging.md b/docs/debugging.md deleted file mode 100644 index 89c6cdd500e..00000000000 --- a/docs/debugging.md +++ /dev/null @@ -1,44 +0,0 @@ -# Debugging - -There are two recommended ways to debug Windows Forms binaries. Both require that you first [build from source](building.md). - -Once you are ready to debug your changes on an existing Windows Forms application, please follow one of the two following recommended techniques for relating your changes back to your project. You should then be able to set breakpoints and debug as expected. - -If you do not want to modify your local SDK, you may with to perform technique 2. However if you do not want to add an additional reference to your project, technique 1 may be better for you. - -## 1. Copy your changes into the SDK - -Copy the resulting assembly(-ies) from your local build. - -- They are located at `[Path-to-repo]\winforms\artifacts\bin\System.Windows.Forms\Debug\net7.0` -- And need to be copied to the system dotnet folder `[Drive]:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\[Version]` - -:warning: If you have updated any public APIs, you'll need to overwrite the ref assemblies too (since that's what VS uses when resolving types): -- The ref assemblies compile to `[Path-to-repo]\winforms\artifacts\bin\System.Windows.Forms\Debug\net7.0\ref` -- These need to be copied to `[Drive]:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\[Version]` - -where: -- **[Drive]** is your OS drive (for example, C:), -- **[Path-to-repo]** is the additional path to our repository from the base drive, and -- **[Version]** is your WindowsDesktop version directory (for example, 5.0.0-rc.2.20464.5). - - - -**NOTE** Make sure to make a backup copy of assemblies you replace, you will modify your SDK. Alternatively you can repair the install or reinstall. - -## 2. Point your project to your experimental binary(-ies) - -Add references to the binary(-ies) to your project ported to .NET. For example, for System.Windows.Forms, you should add the following reference: - -```xml - - - - - - -``` - -where: -- **[Drive]** is the drive you have our repository in, and -- **[Path-to-repo]** is the additional path to our repository from the base drive. diff --git a/docs/design/anchor-layout-changes-in-net80.md b/docs/design/anchor-layout-changes-in-net80.md deleted file mode 100644 index adcd7695157..00000000000 --- a/docs/design/anchor-layout-changes-in-net80.md +++ /dev/null @@ -1,126 +0,0 @@ -# Anchor layout changes in .NET 8.0 - - -## Description - -We have multiple [issues](https://github.com/dotnet/winforms/issues?q=is%3Aissue+is%3Aopen+anchor+label%3A%22area%3A+anchor%2Fscaling%22) reported in WinForms around the anchor layout being problematic on higher DPI scale monitors, irrespective of application DPI mode. This document outlines the changes being made in .NET 8.0 to address these issues, which is aligned with the larger goal to support all supported application DPI modes in WinForms. - -## Problem in Scope - -The position of an anchored control with respect to its parent should be able to be determined at design time and should only need to be changed if there were explicit changes in the control's bounds or when the control is scaled in response to a DPI changed event. Bounds changes that happen as result of the parent control's bounds changing shouldn't alter a control's relative position in the parent's rectangle. However, currently the layout engine computes the anchored control's relative position every time there are changes to the control's bounds or the control's location-related properties. - -For example, the following simple code snippet copied from a Control's `InitializeComponent` method demonstrates the impact of the "over-eager" computations. The number of unnecessary computations can increase quite dramatically for nested layouts. - -```CS -// The following line triggers layout to compute anchors with the default button size and without a parent control. -this.button7.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - -// The following line triggers layout again to compute anchors with the default button size with a new location but still without a parent control. -this.button7.Location = new System.Drawing.Point(9, 47); - -// The following line triggers layout once again to compute anchors with the button's new size but still without a parent control. -this.button7.Size = new System.Drawing.Size(134, 23); - -// The following line triggers layout to compute anchors with button's current size and the default size for the parent control. -this.Controls.Add(button7); - -// The following line triggers layout to compute anchors with the button's current size and a new size for the parent control. -// These sizes still may be changed for the current DPI depending on application's DPI mode. -this.Size = new System.Drawing.Size(828, 146); - -// The following line triggers layout to compute anchors with the button's current size and new size for the parent control. -// The current DPI is still not applied. -this.ResumeLayout(false); -``` -The above snippet does not represent the complete set of instances where anchor computations are unnecessary and may hold invalid anchor values. It gets even more complicated when nested UserControls are involved. - -In addition, the original anchor calculation implementation was designed prior to adding high DPI support to WinForms. - -## Known issues - -Customer reported issues can be largely grouped as follows: - - -### Missing controls - -Calculation of control's anchors with default sizes may result in negative anchors and, thus, result in an invalid location for the anchored controls. - -![MissingControls](../images/AnchorLayoutKnownIssue_MissingControl.png) - - -### Overlapped Controls - -Related to the "Missing controls" issue above, if the parent control is scaled to match the current monitor's DPI, and the control's anchor calculations happen out of sync with this scaling, controls may overlap: - -![OverlappedControls](../images/AnchorLayoutKnownIssue_OverlappedControl.png) - - -## Proposed solution - - The proposal is that we calculate anchors for a control only if the following conditions are met: - -- The control is parented. -- The control's parent's layout is resumed. - - The initial anchor calculations would now happen whenever parent's layout is resumed, or when control is parented/resized and parent's layout is not suspended. The anchors will be recalculated whenever there are changes in geometry (`Size`, `Location`, etc.) or hierarchy (`ParentChanged`). - -### Anchor calculations - -The following image illustrates anchors calculation with respect to a control's parent's display rectangle. The "orange" rectangle is the parent's display rectangle, and the "blue" rectangle is the anchored control's (button) bounds. -- `Left` arrow indicates the X coordinate of the button location with respect to the parent's display rectangle. -- `Top` arrow indicates the Y coordinate of the button location with respect to the parent's display rectangle. -- `Right` arrow indicates the distance from right edge of the parent's rectangle where button is placed. -- `Right` arrow indicates the distance from the bottom edge of the parent's rectangle where the button is placed. - - ![AnchorCalculations](../images/AnchorCalculations.png) - - -In the above image the boundary marked in "orange" is a container hosting the control (boundary marked with "blue"). The control can define its anchor property to explicitly tell the layout engine how its bounds change relative to its parent's bounds. - -For example: -```CS -this.button14.Anchor = (System.Windows.Forms.AnchorStyles.Bottom - | System.Windows.Forms.AnchorStyles.Left - | System.Windows.Forms.AnchorStyles.Top - | System.Windows.Forms.AnchorStyles.Right ); -``` -When the control's `Anchor` property is set, the anchors (that is, left, top, right, bottom values) are computed and stored in an internal struct `AnchorInfo`. The only time the anchor values can be negative is when the control is placed/position outside/overlapped with the hosting control's bounds. - -The following code snippet demonstrates anchor calculations: - -```CS -private static void ComputeAnchorInfo(IArrangedElement element) -{ - AnchorInfo? anchorInfo = GetAnchorInfo(element); - if (anchorInfo is null) - { - anchorInfo = new(); - SetAnchorInfo(element, anchorInfo); - } - Rectangle displayRect = element.Container.DisplayRectangle; - Rectangle elementBounds = GetCachedBounds(element); - int x = elementBounds.X; - int y = elementBounds.Y; - anchorInfo.Left = x; - anchorInfo.Top = y; - anchorInfo.Right = displayRect.Width - (x + elementBounds.Width); - anchorInfo.Bottom = displayRect.Height - (y + elementBounds.Height); -} -``` - -## Risk mitigation - -The layout engine, in general, is quite complex, and any changes in it carry a very high risk. In order to reduce the risks and to provide backward compatibility, the new anchor calculations are put behind a feature switch `System.Windows.Forms.AnchorLayoutV2`. The switch is disabled by default for Windows Forms applications. - -Developers need to opt-in to get this new feature by setting the switch value to `true` in the [runtimeconfig.json](https://learn.microsoft.com/dotnet/core/runtime-config/#runtimeconfigjson). -Snippet for runtimeconfig.template.json: -```JSON -{ - "configProperties": { - "System.Windows.Forms.AnchorLayoutV2": true - } -} -``` - - - diff --git a/docs/designer-accessibility.md b/docs/designer-accessibility.md deleted file mode 100644 index d2b8778ddf2..00000000000 --- a/docs/designer-accessibility.md +++ /dev/null @@ -1,37 +0,0 @@ -# Working around accessibility issues in the Windows Forms Out of Process Designer - -The introduction of Windows Forms (WinForms) to .NET Core 3.1 and beyond is enabling developers to migrate their applications from .NET Framework to the more modern .NET versions. In order to support the designing of these applications within Visual Studio the team was required to create an entirely new Out of Process (OOP) Designer, which is currently still in a preview state. For more information on the technical reasons for this change, and the current status of the designer, see [our recent blog post](https://devblogs.microsoft.com/dotnet/state-of-the-windows-forms-designer-for-net-applications/). - -There are several features that still need to be implemented in the OOP designer, foremost of which is supporting the use of Assistive Technologies such as NVDA, Narrator, and Jaws while using the OOP designer. As much as the team wanted to fully support accessibility right out of the gate with this new designer, technical reasons prevented getting an early start on this feature, and resulted in unfortunate user experiences and deadlocks under assistive technology tooling in certain scenarios. - -While the team is rebuilding the experience under the new model, it is straightforward to work around the current accessibility issues by using the classic .NET Framework in-process designer and building output assemblies in both .NET and .NET Framework 4.7.2 (or 4.8). In order to multi-target and use the .NET Framework designer use the following steps: - -1. Create your .NET WinForms 3.1 (C\# only), 5 or 6 app (both VB and C\#). - -2. Before the designer by opening a Form or a UserControl, edit the *.csproj* - file. - -3. In that file you will find the following entry, telling the compiler what - .NET version to build against: - -``` - - WinExe - net6.0-windows - enable - true - enable - - -``` -4. Change the `net6.0-windows` to the following: `net472;net6.0-windows` - -**Note:** it is important to use **net472** (or net48 if you want to target against .NET Framework 4.8) **first** in the list of targeted frameworks. This tells Visual Studio to load the in-process .NET Framework rather than the .NET OOP WinForms designer. - -Once you’ve completed the above steps, you can build your application and interact with the forms directly as you have always done. When you build binaries, they will be built targeting both .NET 6 and .NET Framework 4.7.2. - -:warning: There are limitations around only using the features and types available in both .NET Framework 4.7.2 and .NET 6. If you want to use .NET 6 features, you will need to use C\# preprocessor directives. - -We will be communicating out as soon as full accessibility support is available in the WinForms .NET OOP designer so that you can remove the need to multi-target. In the meantime, this workaround should allow you to build your .NET Windows Forms applications with the respective accessibility features supported at design time. - -Happy Coding! diff --git a/docs/designer/designer-high-dpi-mode.md b/docs/designer/designer-high-dpi-mode.md deleted file mode 100644 index 1fd8266cff5..00000000000 --- a/docs/designer/designer-high-dpi-mode.md +++ /dev/null @@ -1,38 +0,0 @@ -# Designer HighDpi mode -Visual Studio 2022 and beyond by default launch in PerMonitor DpiAwareness mode but it also supports SystemAware and Unaware DpiAwareness modes when users launch it with [custom settings](https://docs.microsoft.com/visualstudio/designers/disable-dpi-awareness?view=vs-2022). The WinForms designer does not fully support PerMonitor DpiAwareness mode yet and by default launches in SystemAware mode. - -In .NET 6, as part of unifying the information sharing between WinForms designer and WinForms runtime, we added [support](https://aka.ms/applicationconfiguration) for specifying the application dpi mode as a build time property on the project and share it for both designtime and at runtime. - -## Issues - The Winforms designer, when operating in SystemAware/PermonitorV2 mode, serializes layout metrics into the source file based on the Dpi setting of the current display device on which it is being rendered. This may lead to two kinds of problems. - - 1. WinForms applications developed on a machine with DPI settings different from the machine where they are executed may encounter layout inconsistencies. - - 2. Within a team of multiple developers collaborating on the same project, this situation can lead to unintentional modifications in the serialized source code, even if they are unrelated to the intended changes. As a consequence, it introduces additional overhead in the code review and merging process. - -The following example demonstrates an undesired modification in the serialized WinForms source code. - -![Unwanted Serialization changes](../images/Serialization.png) - - -Up until now, developers have been advised to adhere to the instructions given [here](https://go.microsoft.com/fwlink/?linkid=875609) and restart Visual Studio in DpiUnAware mode to resolve these problems. Nevertheless, this process requires individual developers to do it every time they work on the project, adding inconvenience. Additionally, the entire Visual Studio IDE would be launched as DPI Unaware resulting in a blurry IDE experience. - -## Solution - -In Visual Studio 2022 Version 17.8, we are introducing a new [configuration]((https://aka.ms/applicationconfiguration)) option called `ForceDesignerDpiUnaware`, distinct from `ApplicationHighDpiMode`. This option enables developers to enforce DpiUnAware mode for all WinForms designers in the project, regardless of the `ApplicationHighDpiMode`, which continues to take effect during runtime. The rest of the Visual Studio environment remains in PerMonitor mode and renders crisply. - - -```CS - - - - WinExe - net7.0-windows - enable - true - enable - SystemAware - true - -``` - diff --git a/docs/designer/modernization-of-code-behind-in-OOP-designer/images/Form1-Designer-C#-comparison.png b/docs/designer/modernization-of-code-behind-in-OOP-designer/images/Form1-Designer-C#-comparison.png deleted file mode 100644 index 8350c22fd1d..00000000000 Binary files a/docs/designer/modernization-of-code-behind-in-OOP-designer/images/Form1-Designer-C#-comparison.png and /dev/null differ diff --git a/docs/designer/modernization-of-code-behind-in-OOP-designer/images/Form1-Designer-VB-comparison.png b/docs/designer/modernization-of-code-behind-in-OOP-designer/images/Form1-Designer-VB-comparison.png deleted file mode 100644 index 3008da0acda..00000000000 Binary files a/docs/designer/modernization-of-code-behind-in-OOP-designer/images/Form1-Designer-VB-comparison.png and /dev/null differ diff --git a/docs/designer/modernization-of-code-behind-in-OOP-designer/modernization-of-code-behind-in-oop-designer.md b/docs/designer/modernization-of-code-behind-in-OOP-designer/modernization-of-code-behind-in-oop-designer.md deleted file mode 100644 index 8fe91b18459..00000000000 --- a/docs/designer/modernization-of-code-behind-in-OOP-designer/modernization-of-code-behind-in-oop-designer.md +++ /dev/null @@ -1,199 +0,0 @@ -# Modernization of code-behind in WinForms OOP designer - -## Background - -The WinForms designer saves visual representations of user controls or forms on the design surface to code-behind file (`Form1.Designer.cs` or `Form1.Designer.vb`). Control instances that developer sees on the design surface are represented as a CodeDOM tree (see [Using the CodeDOM](https://learn.microsoft.com/dotnet/framework/reflection-and-codedom/using-the-codedom)), that tree is saved to the generated code-behind file in the `InitializeComponent` method. We call this feature design time serialization. - -Previously COM-based [CodeModel interface](https://learn.microsoft.com/dotnet/api/envdte.codemodel?view=visualstudiosdk-2022) was used to write code into the editor's buffer as well as to generate CodeDOM tree from the source code when designer was loading. This COM object was accessible from the main thread only, which prevented parallelization in source code processing. Also, being more than 20 years old, it did not support some of the newer language features, for example the `nameof()` expression. - -## What's different - -Starting with [Visual Studio 2022 v17.5 Preview 3](https://visualstudio.microsoft.com/vs/preview/), the WinForms out-of-process designer uses [Roslyn](https://github.com/dotnet/roslyn) for design time serialization. - -In Preview 3, designer serializes more modern code into `InitializeComponent`. We have worked hard to ensure that you can take projects between this version of Visual Studio and earlier versions. Someday in the future, we may build on the improvements in our serialization to enable performance enhancements and use newer language features. These potential future investments may break the backwards compatibility with earlier VS versions - but we will be sure to inform our developers well ahead of such changes so that you can prepare. - -## Why change it - -* The use of Roslyn unblocks multithreaded serialization and deserialization to solve performance delays in designer load and unload scenarios. -* Code-behind generation now respects `.editorconfig` settings and thus matches code style in the source files. -* If implicit usings feature is enabled in project properties, global namespaces are not repeated in type names. -* Further modernization of code-behind is unblocked. -* Newly generated code will work with modern Roslyn analyzers. - -## How the new code looks like - -While `InitializeComponent` method is meant for the designer use only, and manual modifications to this method are not supported, developers might see some unexpected changes in `Form1.Designer.cs` and `Form1.designer.vb` files when comparing versions in the source control tools. This is a one-time code churn. Once the designer file is regenerated in v17.5 Preview 3 or newer and saved, designer will generate code only for controls modified in the design surface. - -For example, `InitializeComponent` method for a form with a button will be modified like this on the first save: - -![Comparison of Form1.Designer.cs as generated by Visual Studio 2022 v17.4 or earlier against the same file generated by v17.5 Preview 3](./images/Form1-Designer-C%23-comparison.png) - -Code generated by VisualStudio v17.4 or earlier: - -```cs -private void InitializeComponent() -{ - this.button1 = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // button1 - // - this.button1.Location = new System.Drawing.Point(58, 60); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(136, 69); - this.button1.TabIndex = 0; - this.button1.Text = "button1"; - this.button1.UseVisualStyleBackColor = true; - // - // Form1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(270, 208); - this.Controls.Add(this.button1); - this.Name = "Form1"; - this.Text = "Form1"; - this.ResumeLayout(false); - -} -``` - -Code generated by VisualStudio v17.5 Preview 3, or newer: - -```cs -private void InitializeComponent() -{ - button1 = new Button(); - SuspendLayout(); - // - // button1 - // - button1.Location = new Point(58, 60); - button1.Name = "button1"; - button1.Size = new Size(136, 69); - button1.TabIndex = 0; - button1.Text = "button1"; - button1.UseVisualStyleBackColor = true; - // - // Form1 - // - AutoScaleDimensions = new SizeF(10F, 25F); - AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(270, 208); - Controls.Add(button1); - Name = "Form1"; - Text = "Form1"; - ResumeLayout(false); -} -``` - -### Support for code style settings - -The above code was generated for default C# code style settings, thus `this` access qualifier was removed in the Preview 3 version. - -To preserve legacy code generation style in `InitializeComponent` method, set style preferences to legacy values in [`.editorconfig` file](https://learn.microsoft.com/visualstudio/ide/create-portable-custom-editor-options). - -```ini -[*.designer.cs] - -# this. preferences -dotnet_style_qualification_for_event = true -dotnet_style_qualification_for_field = true -dotnet_style_qualification_for_method = true -dotnet_style_qualification_for_property = true - -[*.vb] - -# Me. preferences -dotnet_style_qualification_for_event = true -dotnet_style_qualification_for_field = true -dotnet_style_qualification_for_method = true -dotnet_style_qualification_for_property = true -``` - -### Support for implicit usings property - -Namespace names were removed from the type names in Preview 3 version. They are not needed for type resolution because design time serialization looks up the [implicit usings](https://learn.microsoft.com/dotnet/core/tutorials/top-level-templates#implicit-using-directives) property, available in C# starting with .NET 6 for C#, from the project file: - -```xml - - - - WinExe - net8.0-windows - enable - true - enable - - - -``` - -When implicit usings property is disabled in the C# project file, namespace names are generated. - -### Similar changes are present in Visual Basic - -![Comparison of Form1.Designer.vb as generated by Visual Studio 2022 v17.4 or earlier against the same file generated by v17.5 Preview 3](./images/Form1-Designer-VB-comparison.png) - -Code generated by VisualStudio v17.4 or earlier: - -```vb - -Private Sub InitializeComponent() - Me.Button1 = New System.Windows.Forms.Button() - Me.SuspendLayout() - ' - 'Button1 - ' - Me.Button1.Location = New System.Drawing.Point(58, 60) - Me.Button1.Name = "Button1" - Me.Button1.Size = New System.Drawing.Size(136, 69) - Me.Button1.TabIndex = 0 - Me.Button1.Text = "Button1" - Me.Button1.UseVisualStyleBackColor = True - ' - 'Form1 - ' - Me.AutoScaleDimensions = New System.Drawing.SizeF(10.0!, 25.0!) - Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(270, 208) - Me.Controls.Add(Me.Button1) - Me.Name = "Form1" - Me.Text = "Form1" - Me.ResumeLayout(False) - -End Sub -``` - -Code generated by VisualStudio v17.5 Preview 3, or newer: - -```vb - -Private Sub InitializeComponent() - Button1 = New Button() - SuspendLayout() - ' - ' Button1 - ' - Button1.Location = New Point(58, 60) - Button1.Name = "Button1" - Button1.Size = New Size(136, 69) - Button1.TabIndex = 0 - Button1.Text = "Button1" - Button1.UseVisualStyleBackColor = True - ' - ' Form1 - ' - AutoScaleDimensions = New SizeF(10.0F, 25.0F) - AutoScaleMode = AutoScaleMode.Font - ClientSize = New Size(270, 208) - Controls.Add(Button1) - Name = "Form1" - Text = "Form1" - ResumeLayout(False) -End Sub -``` - -## Summary - -New code-behind in WinForm apps looks differently because it follows code style settings defined for the project. Under the covers, the design time serialization was redesigned in order to move from `EnvDTE.CodeModel` to `Roslyn`. We are planning to build upon this foundation in the future Visual Studio releases. Code-behind generated by the older releases will load into v17.5 Preview 3 or later releases and will work as expected. Code-behind generated by v17.5 Preview 3 can be loaded in the previous releases of the Visual Studio, but we are considering generating modern code that might not be supported by the previous versions of deserializer. diff --git a/docs/designer/net-inproc-designer.md b/docs/designer/net-inproc-designer.md deleted file mode 100644 index 0b6e9d0cfa1..00000000000 --- a/docs/designer/net-inproc-designer.md +++ /dev/null @@ -1,142 +0,0 @@ -# How to use Windows Forms .NET Framework designer for .NET applications - -The OOP designer is a port of the original .NET Framework Windows Forms designer that was run inside the Visual Studio's process. And whilst the team is aiming for parity there are still functional gaps between the original designer and the new OOP designer. With that it is possible that you may find yourself in a situtation where the OOP designer is not working as expected, and you'd want to use the .NET Framework designer to carry you on. - -This guide will walk you through the steps that enable a substantial use of the .NET Framework designer to design Windows Forms .NET applications. Please note, that due to the changes in the default font and new APIs in Windows Forms .NET, the .NET Framework designer won't be able to provide 100% parity. - -## 1. Create Windows Forms .NET app - -Create a new Windows Forms application targeting .NET from Visual Studio or your favorite command line interface. - -### Create in Visual Studio - -`VS2022`: - -1. _File > Add > New Project... > Windows Forms App (.NET Core)_, choose C# or Visual Basic -2. Specify project name, e.g. `SimpleWinForms` - - - -### Create from command line - -Open your favorite console, create a new folder for your application: - -```cmd -md SimpleWinForms -cd SimpleWinForms -dotnet new winforms -n SimpleWinForms -dotnet new sln -dotnet sln add SimpleWinForms -``` - -:point_up: **TIP:** You can have the folder name different from the project's name. Use the option `-n` (or `-name`) for that when using `dotnet new`. - -:point_up: **TIP:** For Visual Basic projects use the option `-lang vb` when using `dotnet new`. - -After creating the project, you can run the application: -```cmd -dotnet run --project SimpleWinForms\SimpleWinForms.csproj -``` - - -## 2. Enable .NET Framework designer support - -There are few options available to help you to design UI for your .NET Core project. - - -### Option 1: multi-target your app - -1. Open `SimpleWinForms.sln` - -2. Open the `SimpleWinForms` project file by double clicking on it in Solution Explorer. Change the ``TargetFramework`` property from: - - ```diff - - net6.0-windows - + net472;net6.0-windows - ``` - -3. Add for any and every form file you have in this ``ItemGroup``: - - ```xml - - - Form - - - Form1.cs - - - ``` - - After doing these steps this is what you should end up with: - - ![edit-project-file][edit-project-file] - - -### Option 2: Shadow .NET Frameowk project - -1. Open `SimpleWinForms.sln` - -2. Add a new **Windows Forms App (.NET Framework)** project (VS2017: _Visual C# > Windows Desktop_ / VS2019+: _C# : Windows : Desktop_) to the solution (_File > Add > New Project..._) - - ![add-netfx-project][add-netfx-project] - -3. Name the new .NET Framework project as the .NET project, but add ".Designer" to it (e.g. `SimpleWinForms.Designer`) - -4. Go to the .NET Framework project properties and set the default namespace to the .NET project's namespace - - ![edit-namespace][edit-namespace] - -5. Delete the existing Form files in both projects - -6. Add a new Windows Form in the .NET Framework project's context menu _Add > Windows Form..._ - - ![add-new-form][add-new-form] - -7. In the section list, click on *Windows Forms*, and chose *Windows Form* from the installed templates - - ![add-new-form-dialog][add-new-form-dialog] - -8. Give the name and click `[Add]`. - - :exclamation: **IMPORTANT**: You need to trigger a form change event for the Designer to create a `resx` file. You can do it by resizing the form for a couple of pixels or changing the form's `Text` property. Don't forget to save. - -9. Now we move the form to the .NET project.
-In the Solution Explorer click on the form and press CTRL+X to cut it; and then paste it in to the .NET project (CTRL+V). Check that the main form file, the .designer file and the resource file for the form are all present. - -10. Then we link the form back into the .NET Framework project back.
-Remember: We can only use the .NET Framework designer, but we want to have only one set of files. So the form files, of course, belong to the .NET project but we want to edit them in the context of the .NET Framework project (thus using the .NET Framework designer). - - * To do this open the context menu on the .NET Framework project in the Solution Explorer, and pick _Add > Existing Item_ - - * In the File Open Dialog, navigate to the .NET project, select the *Form.cs*, *Form.Designer.cs* and *Form.resx* files and choose *Add as Link* option. - - ![add-as-link][add-as-link] - -11. Compile the solution to see if the file references were set up correctly - -1. As the last but important step, we need to re-nest the linked form files.
-If you installed the [File Nesting Visual Studio Extension][file-nesting-extension] then that is done easily: Select both the *Form.Designer.cs* and *Form.resx* file, and from the context menu click _File Nesting > Nest Items_. In the dialog, pick the main form file (Form.cs), and click OK. - -Now, whenever you need to use the Designer on one of the .NET Form or UserControl files, simply open the linked files in the .NET Framework project with the Windows Forms Designer. - - -### More information - -If you are porting an existing .NET Framework application to .NET you may wish to read the following blog posts: -* [Porting desktop apps to .NET](https://devblogs.microsoft.com/dotnet/porting-desktop-apps-to-net-core/) -* [.NET Upgrade Assistant](https://devblogs.microsoft.com/dotnet/introducing-the-net-upgrade-assistant-preview/) -* [Using the Windows Forms designer for .NET projects](https://devblogs.microsoft.com/dotnet/how-to-port-desktop-applications-to-net-core-3-0/#user-content-using-the-winforms-designer-for-net-core-projects) - -[comment]: <> (URI Links) - -[file-nesting-extension]: https://marketplace.visualstudio.com/items?itemName=MadsKristensen.FileNesting - -[comment]: <> (Images) - -[add-netfx-project]: ../images/add-netfx-project.png -[edit-namespace]: ../images/edit-namespace.png -[add-new-form]: ../images/add-new-form.png -[add-new-form-dialog]: ../images/add-new-form-dialog.png -[add-as-link]: ../images/add-as-link.png -[edit-project-file]: ../images/edit-project-file.png diff --git a/docs/designer/readme.md b/docs/designer/readme.md deleted file mode 100644 index c3304536cb3..00000000000 --- a/docs/designer/readme.md +++ /dev/null @@ -1,22 +0,0 @@ -# Windows Forms Out-Of-Process Designer - -The Windows Forms out-of-process designer is currently available as a preview Visual Studio feature in [Visual Studio 2019 or later](https://visualstudio.microsoft.com/vs/preview/). It can be enabled in **Tools -> Options -> Environment -> Preview Features** dialog by checking the **Use the preview Windows Forms out-of-process designer for .NET apps** checkbox. - Releases of .NET Windows Forms Designer are tied to Visual Studio Preview releases, so update to the latest Visual Studio Preview version to get the newest designer features. - -:heavy_exclamation_mark: The latest designer feature shipped in `Visual Studio 2022 v17.5 Preview 3` is [Modernization of code-behind generation](./modernization-of-code-behind-in-OOP-designer/modernization-of-code-behind-in-oop-designer.md). - -For the latest news on the designer please refer to [the series of blogs](https://devblogs.microsoft.com/search?query=winforms&blog=%2Fdotnet%2F): - -* [Custom Controls for WinForms' Out-Of-Process Designer](https://devblogs.microsoft.com/dotnet/custom-controls-for-winforms-out-of-process-designer/) -* [Visual Basic WinForms Apps in .NET 5 and Visual Studio 16.8](https://devblogs.microsoft.com/dotnet/visual-basic-winforms-apps-in-net-5-and-visual-studio-16-8/) -* [Databinding with the OOP Windows Forms Designer](https://devblogs.microsoft.com/dotnet/databinding-with-the-oop-windows-forms-designer/) -* [State of the Windows Forms Designer for .NET Applications as of 01/13/2022](https://devblogs.microsoft.com/dotnet/state-of-the-windows-forms-designer-for-net-applications/) - -### WinForms out of process designer SDK - -For more information about creating custom control libraries, including sample code and templates refer to the [WinForms Designer Extensibility Repo](https://github.com/microsoft/winforms-designer-extensibility/). Details about how to use the WinForms Designer Extensibility SDK and structure a control library nuget package can be found there as well. Download the Extensibility SDK from [NuGet](https://www.nuget.org/packages/Microsoft.WinForms.Designer.SDK). - -## Table of Content - -* [How to use .NET Framework designer for .NET applications](net-inproc-designer.md) -* [How to troubleshoot the out-of-process designer](troubleshooting.md) diff --git a/docs/designer/troubleshooting.md b/docs/designer/troubleshooting.md deleted file mode 100644 index 48a0b833413..00000000000 --- a/docs/designer/troubleshooting.md +++ /dev/null @@ -1,43 +0,0 @@ -# How to troubleshoot the Windows Forms Out-Of-Process designer - -Whilst the Windows Forms Out-Of-Process Designer (or the OOP designer) is by far and large is a black box to the users, it is still possible to find out more information on its state. - -## Logging - -Once the OOP designer is started, its log is available in the Visual Studio Output window: - -![image](https://user-images.githubusercontent.com/4403806/154604523-081f6197-d597-4416-9877-72fb61d12b8a.png) - -The default verbosity is set to _Warnings_, which includes Warnings and Errors (prior to VS 2022 17.2 was _None_, i.e. logging disabled). You can change the logging level to terser or more verbose under **Tools -> Options -> Windows Forms Designer -> General -> Logging Level**, e.g.: - -![image](https://user-images.githubusercontent.com/4403806/154607481-44fa404a-894e-4656-95b8-efdeced2ace0.png) - -## "Designer never loads" problems and possible ways to resolve those - -### Connection Timeouts - -When the OOP designer starts it launches the designer server process (aka DesignToolsServer.exe). If the server process fails to launch or connect to the Visual Studio, you may see the following error: - -``` -[02:59:20.7198643] [MyProj]: Timed out waiting for the design tools server process launch to complete. -[02:59:20.7668637] Microsoft.DotNet.DesignTools.Client.ServerException: Timed out waiting for the design tools server process launch to complete. -``` - -The default connection timeout is set to _2 minutes_ (prior to VS 2022 17.1p5 was _10 seconds_). VS 2022 17.2 introduces the ability to increase the connection timeout, if necessary. You can change it under **Tools -> Options -> Windows Forms Designer -> General -> Connection timeout**, e.g.: - -![image](https://user-images.githubusercontent.com/4403806/154607521-8665597b-b2e5-448b-adcb-a2c147570501.png) - -There can be various reasons why the server process may be taking longer than the allocated time. For example, some users have reported to have solutions with a large number of projects. The designer performs a shadow copying of the necessary files and folders before it can render your form or control, and if you have a slow hard drive, or the project files are located on a network drive, it can have a significant effect on how fast files are copied to the shadow cache folder. - -### Antivirus is blocking the server process executables - -Some customers have reported that the connection timeouts were caused by configurations of their antivirus services. In such cases it is recommended to add exclusion rules for `devevn.exe` and `DesignToolsServer.exe`, and this can unblock these executables and can increase the I/O of the shadow cache. For example, to add an exception to the Windows Defender so that it is not slowed down by the system call hooks Defender uses to provide real-time protection can be done with the following PowerShell command: - -```powershell -Add-MpPreference -ExclusionProcess 'devenv.exe' -Add-MpPreference -ExclusionProcess 'DesignToolsServer.exe' -``` - -### `Switch.System.IO.UseLegacyPathHandling` override is enabled - -The designer server process uses [long paths](https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation) and requires [path normalizations](https://docs.microsoft.com/dotnet/framework/migration-guide/mitigation-path-normalization), the behaviours that can be altered by `Switch.System.IO.UseLegacyPathHandling` appcontext switch. The default value of the switch is `false`, and if the value is set to `true` either in devenv.exe.config (which is located somewhere like C:\Program Files\Microsoft Visual Studio\2022\Common7\IDE) or in the [registry](https://docs.microsoft.com/dotnet/api/system.appcontext?view=net-6.0#appcontext-for-library-consumers) it will prevent the designer from loading with `Argument Exception: Illegal characters in path` error. diff --git a/docs/developer-guide.md b/docs/developer-guide.md deleted file mode 100644 index 17cc4a88de9..00000000000 --- a/docs/developer-guide.md +++ /dev/null @@ -1,53 +0,0 @@ -# Developer Guide - -The following document describes the setup and workflow that is recommended for working on the Windows Forms project. It assumes that you have read the [Contributing Guide](../CONTRIBUTING.md). - -The [Issue Guide](issue-guide.md) describes our approach to using GitHub issues. - -## Machine Setup - -Windows Forms requires the following workloads and components be selected when installing Visual Studio 2022 (17.0.0): - -* Required Workloads: - * .NET Desktop Development - * Desktop development with C++ -* [Required Individual Components][required-individual-components]: - * Windows 10 SDK - * C++/CLI support - - - :warning: CMake 3.21.0 or later is required. Install CMake from the [official website][cmake-download] or via [Chocolatey][chocolatey]: - ``` - choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' - ``` - -* Useful Visual Studio extensions: - * [Editor guidelines](https://marketplace.visualstudio.com/items?itemName=PaulHarrington.EditorGuidelines), see https://github.com/dotnet/winforms/pull/4836 for more information - * [VS Color Output](https://marketplace.visualstudio.com/items?itemName=MikeWard-AnnArbor.VSColorOutput64) - * [Productivity Power Tools](https://marketplace.visualstudio.com/items?itemName=VisualStudioPlatformTeam.ProductivityPowerPack2022) - -## Workflow - -We use the following workflow for building as well as testing features and fixes. - -You first need to [fork][fork] then [clone][clone] this Windows Forms repository. This is a one-time task. - -1. [Build](building.md) the repository. -2. [Debug](debugging.md) the change, as needed. -3. [Test](testing.md) the change, to validate quality. - -## More Information - -* [How to write good docs for .NET](https://review.docs.microsoft.com/help/contribute-ref/how-to-write-net-docs?branch=main) -* [.NET Docs and Guidelines][net-runtime-instructions] -* ["help wanted" issues][help wanted] - -[comment]: <> (URI Links) - -[net-runtime-instructions]: https://github.com/dotnet/runtime/tree/master/docs -[fork]: https://guides.github.com/activities/forking/ -[clone]: https://www.git-scm.com/docs/git-clone -[help wanted]: https://github.com/dotnet/winforms/issues?q=is%3Aopen+is%3Aissue+label%3A"help%20wanted" -[chocolatey]: https://chocolatey.org/ -[cmake-download]: https://cmake.org/download/ -[required-individual-components]: ../WinForms.vsconfig diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100644 index 5fd9c988107..00000000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,40 +0,0 @@ -# Getting started with Windows Forms for .NET - -This document describes the experience of using Windows Forms on .NET. The [Developer Guide](developer-guide.md) describes how to develop features and fixes for Windows Forms. - -## Installation - -Choose one of these options: - -1. [.NET 7.0 SDK (recommended)][.net-7.0-sdk] - -1. [.NET 8.0 daily build (latest changes, could be less stable)][.net-daily] - -## Creating new applications - -You can create a new WinForms application with `dotnet new` command, using the following commands: - -```cmd -dotnet new winforms -o MyWinFormsApp -cd MyWinFormsApp -dotnet run -``` - -## Designing Forms - -You can try the Windows Forms Core Designer Visual Studio extension, see [Windows Forms Designer documentation](designer-releases/readme.md). As an alternative, you can use [this workaround](winforms-designer.md). - -## Samples - -Check out the [.NET Windows Forms samples][.net-samples] for both basic and advanced scenarios. Additionally, there is a collection of [Windows Forms sample applications on Microsoft Learn][MSDN-winforms-samples]. - -## Porting existing applications - -To port your existing Windows Forms application from .NET Framework to .NET 6 or .NET 7, refer to our [porting guidelines](porting-guidelines.md). - -[comment]: <> (URI Links) - -[.net-7.0-sdk]: https://dotnet.microsoft.com/download/dotnet/7.0 -[.net-daily]: https://github.com/dotnet/installer/blob/master/README.md#installers-and-binaries -[.net-samples]: https://github.com/dotnet/samples/tree/main/windowsforms -[MSDN-winforms-samples]: https://learn.microsoft.com/samples/browse/?terms=windows%20forms diff --git a/docs/images/AnchorCalculations.png b/docs/images/AnchorCalculations.png deleted file mode 100644 index 045f35cc0fe..00000000000 Binary files a/docs/images/AnchorCalculations.png and /dev/null differ diff --git a/docs/images/AnchorLayoutKnownIssue_MissingControl.png b/docs/images/AnchorLayoutKnownIssue_MissingControl.png deleted file mode 100644 index d05148183be..00000000000 Binary files a/docs/images/AnchorLayoutKnownIssue_MissingControl.png and /dev/null differ diff --git a/docs/images/AnchorLayoutKnownIssue_OverlappedControl.png b/docs/images/AnchorLayoutKnownIssue_OverlappedControl.png deleted file mode 100644 index 5f000e99f22..00000000000 Binary files a/docs/images/AnchorLayoutKnownIssue_OverlappedControl.png and /dev/null differ diff --git a/docs/images/RuntimeOptionsDemo.gif b/docs/images/RuntimeOptionsDemo.gif deleted file mode 100644 index 4a8c951d789..00000000000 Binary files a/docs/images/RuntimeOptionsDemo.gif and /dev/null differ diff --git a/docs/images/Serialization.png b/docs/images/Serialization.png deleted file mode 100644 index cfc6dfbb5cd..00000000000 Binary files a/docs/images/Serialization.png and /dev/null differ diff --git a/docs/images/accessibleobject-getpropertyvalue-implementation.png b/docs/images/accessibleobject-getpropertyvalue-implementation.png deleted file mode 100644 index a5241c640f4..00000000000 Binary files a/docs/images/accessibleobject-getpropertyvalue-implementation.png and /dev/null differ diff --git a/docs/images/accessibleobject-role-implementation.png b/docs/images/accessibleobject-role-implementation.png deleted file mode 100644 index 4e990f4b23d..00000000000 Binary files a/docs/images/accessibleobject-role-implementation.png and /dev/null differ diff --git a/docs/images/add-as-link.png b/docs/images/add-as-link.png deleted file mode 100644 index 273467c8aa8..00000000000 Binary files a/docs/images/add-as-link.png and /dev/null differ diff --git a/docs/images/add-netfx-project.png b/docs/images/add-netfx-project.png deleted file mode 100644 index 16cfb0ded1c..00000000000 Binary files a/docs/images/add-netfx-project.png and /dev/null differ diff --git a/docs/images/add-new-form-dialog.png b/docs/images/add-new-form-dialog.png deleted file mode 100644 index 3097558d4b2..00000000000 Binary files a/docs/images/add-new-form-dialog.png and /dev/null differ diff --git a/docs/images/add-new-form.png b/docs/images/add-new-form.png deleted file mode 100644 index 0ad61cab4cb..00000000000 Binary files a/docs/images/add-new-form.png and /dev/null differ diff --git a/docs/images/edit-namespace.png b/docs/images/edit-namespace.png deleted file mode 100644 index 0f711c2468b..00000000000 Binary files a/docs/images/edit-namespace.png and /dev/null differ diff --git a/docs/images/edit-project-file.png b/docs/images/edit-project-file.png deleted file mode 100644 index f8ed8fa1d98..00000000000 Binary files a/docs/images/edit-project-file.png and /dev/null differ diff --git a/docs/images/inspect-accessibility-properties.png b/docs/images/inspect-accessibility-properties.png deleted file mode 100644 index 044e98598b6..00000000000 Binary files a/docs/images/inspect-accessibility-properties.png and /dev/null differ diff --git a/docs/images/listview-disabledstyles-inspect-details-view-tree.png b/docs/images/listview-disabledstyles-inspect-details-view-tree.png deleted file mode 100644 index 3eee33ed84f..00000000000 Binary files a/docs/images/listview-disabledstyles-inspect-details-view-tree.png and /dev/null differ diff --git a/docs/images/listview-disabledstyles-inspect-largeicon-view-tree.png b/docs/images/listview-disabledstyles-inspect-largeicon-view-tree.png deleted file mode 100644 index 121407d7c82..00000000000 Binary files a/docs/images/listview-disabledstyles-inspect-largeicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-disabledstyles-inspect-list-view-tree.png b/docs/images/listview-disabledstyles-inspect-list-view-tree.png deleted file mode 100644 index 46a7fa1179d..00000000000 Binary files a/docs/images/listview-disabledstyles-inspect-list-view-tree.png and /dev/null differ diff --git a/docs/images/listview-disabledstyles-inspect-smallicon-view-tree.png b/docs/images/listview-disabledstyles-inspect-smallicon-view-tree.png deleted file mode 100644 index 0b77a98ca1e..00000000000 Binary files a/docs/images/listview-disabledstyles-inspect-smallicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-disabledstyles-inspect-tile-view-tree.png b/docs/images/listview-disabledstyles-inspect-tile-view-tree.png deleted file mode 100644 index 9464c7841c3..00000000000 Binary files a/docs/images/listview-disabledstyles-inspect-tile-view-tree.png and /dev/null differ diff --git a/docs/images/listview-inspect-details-view-tree.png b/docs/images/listview-inspect-details-view-tree.png deleted file mode 100644 index be04669913f..00000000000 Binary files a/docs/images/listview-inspect-details-view-tree.png and /dev/null differ diff --git a/docs/images/listview-inspect-largeicon-view-tree.png b/docs/images/listview-inspect-largeicon-view-tree.png deleted file mode 100644 index bcddd7edbd8..00000000000 Binary files a/docs/images/listview-inspect-largeicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-inspect-list-view-tree.png b/docs/images/listview-inspect-list-view-tree.png deleted file mode 100644 index 5b72d1053f6..00000000000 Binary files a/docs/images/listview-inspect-list-view-tree.png and /dev/null differ diff --git a/docs/images/listview-inspect-smallicon-view-tree.png b/docs/images/listview-inspect-smallicon-view-tree.png deleted file mode 100644 index 11bbe975cad..00000000000 Binary files a/docs/images/listview-inspect-smallicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-inspect-tile-view-tree.png b/docs/images/listview-inspect-tile-view-tree.png deleted file mode 100644 index 5f2c3ae60ef..00000000000 Binary files a/docs/images/listview-inspect-tile-view-tree.png and /dev/null differ diff --git a/docs/images/listview-showgroupdisabled-inspect-details-view-tree.png b/docs/images/listview-showgroupdisabled-inspect-details-view-tree.png deleted file mode 100644 index 45fa6d51261..00000000000 Binary files a/docs/images/listview-showgroupdisabled-inspect-details-view-tree.png and /dev/null differ diff --git a/docs/images/listview-showgroupdisabled-inspect-largeicon-view-tree.png b/docs/images/listview-showgroupdisabled-inspect-largeicon-view-tree.png deleted file mode 100644 index 9fbb8067bcf..00000000000 Binary files a/docs/images/listview-showgroupdisabled-inspect-largeicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-showgroupdisabled-inspect-list-view-tree.png b/docs/images/listview-showgroupdisabled-inspect-list-view-tree.png deleted file mode 100644 index 1af9c8e64e8..00000000000 Binary files a/docs/images/listview-showgroupdisabled-inspect-list-view-tree.png and /dev/null differ diff --git a/docs/images/listview-showgroupdisabled-inspect-smallicon-view-tree.png b/docs/images/listview-showgroupdisabled-inspect-smallicon-view-tree.png deleted file mode 100644 index ce75f72e289..00000000000 Binary files a/docs/images/listview-showgroupdisabled-inspect-smallicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-showgroupdisabled-inspect-tile-view-tree.png b/docs/images/listview-showgroupdisabled-inspect-tile-view-tree.png deleted file mode 100644 index f1cb002e778..00000000000 Binary files a/docs/images/listview-showgroupdisabled-inspect-tile-view-tree.png and /dev/null differ diff --git a/docs/images/listview-virtualmode-inspect-details-view-tree.png b/docs/images/listview-virtualmode-inspect-details-view-tree.png deleted file mode 100644 index 8d8a31fb784..00000000000 Binary files a/docs/images/listview-virtualmode-inspect-details-view-tree.png and /dev/null differ diff --git a/docs/images/listview-virtualmode-inspect-largeicon-view-tree.png b/docs/images/listview-virtualmode-inspect-largeicon-view-tree.png deleted file mode 100644 index 34d9f72bbcf..00000000000 Binary files a/docs/images/listview-virtualmode-inspect-largeicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-virtualmode-inspect-list-view-tree.png b/docs/images/listview-virtualmode-inspect-list-view-tree.png deleted file mode 100644 index 11c8c008e98..00000000000 Binary files a/docs/images/listview-virtualmode-inspect-list-view-tree.png and /dev/null differ diff --git a/docs/images/listview-virtualmode-inspect-smallicon-view-tree.png b/docs/images/listview-virtualmode-inspect-smallicon-view-tree.png deleted file mode 100644 index cb5479b9738..00000000000 Binary files a/docs/images/listview-virtualmode-inspect-smallicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-withgroup-inspect-details-view-tree.png b/docs/images/listview-withgroup-inspect-details-view-tree.png deleted file mode 100644 index 40cfd5a8fa6..00000000000 Binary files a/docs/images/listview-withgroup-inspect-details-view-tree.png and /dev/null differ diff --git a/docs/images/listview-withgroup-inspect-largeicon-view-tree.png b/docs/images/listview-withgroup-inspect-largeicon-view-tree.png deleted file mode 100644 index c972260088a..00000000000 Binary files a/docs/images/listview-withgroup-inspect-largeicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-withgroup-inspect-list-view-tree.png b/docs/images/listview-withgroup-inspect-list-view-tree.png deleted file mode 100644 index 2a121373c24..00000000000 Binary files a/docs/images/listview-withgroup-inspect-list-view-tree.png and /dev/null differ diff --git a/docs/images/listview-withgroup-inspect-smallicon-view-tree.png b/docs/images/listview-withgroup-inspect-smallicon-view-tree.png deleted file mode 100644 index 2496ea168e3..00000000000 Binary files a/docs/images/listview-withgroup-inspect-smallicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-withgroup-inspect-tile-view-tree.png b/docs/images/listview-withgroup-inspect-tile-view-tree.png deleted file mode 100644 index 01cd4a9d870..00000000000 Binary files a/docs/images/listview-withgroup-inspect-tile-view-tree.png and /dev/null differ diff --git a/docs/images/listview-withoutgroup-inspect-details-view-tree.png b/docs/images/listview-withoutgroup-inspect-details-view-tree.png deleted file mode 100644 index 8acee9cd7eb..00000000000 Binary files a/docs/images/listview-withoutgroup-inspect-details-view-tree.png and /dev/null differ diff --git a/docs/images/listview-withoutgroup-inspect-largeicon-view-tree.png b/docs/images/listview-withoutgroup-inspect-largeicon-view-tree.png deleted file mode 100644 index 0930c8f2b14..00000000000 Binary files a/docs/images/listview-withoutgroup-inspect-largeicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-withoutgroup-inspect-list-view-tree.png b/docs/images/listview-withoutgroup-inspect-list-view-tree.png deleted file mode 100644 index 59c95ce176f..00000000000 Binary files a/docs/images/listview-withoutgroup-inspect-list-view-tree.png and /dev/null differ diff --git a/docs/images/listview-withoutgroup-inspect-smallicon-view-tree.png b/docs/images/listview-withoutgroup-inspect-smallicon-view-tree.png deleted file mode 100644 index 19399a8e997..00000000000 Binary files a/docs/images/listview-withoutgroup-inspect-smallicon-view-tree.png and /dev/null differ diff --git a/docs/images/listview-withoutgroup-inspect-tile-view-tree.png b/docs/images/listview-withoutgroup-inspect-tile-view-tree.png deleted file mode 100644 index 0d6cffd12b7..00000000000 Binary files a/docs/images/listview-withoutgroup-inspect-tile-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-disabledvisualstyles-inspect-tile-view-tree.png b/docs/images/listviewsubitem-disabledvisualstyles-inspect-tile-view-tree.png deleted file mode 100644 index 654e370bed1..00000000000 Binary files a/docs/images/listviewsubitem-disabledvisualstyles-inspect-tile-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-inspect-details-view-tree.png b/docs/images/listviewsubitem-inspect-details-view-tree.png deleted file mode 100644 index e071d578122..00000000000 Binary files a/docs/images/listviewsubitem-inspect-details-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-inspect-largeicon-view-tree.png b/docs/images/listviewsubitem-inspect-largeicon-view-tree.png deleted file mode 100644 index cd6f82e192a..00000000000 Binary files a/docs/images/listviewsubitem-inspect-largeicon-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-inspect-list-view-tree.png b/docs/images/listviewsubitem-inspect-list-view-tree.png deleted file mode 100644 index d9b47c5718c..00000000000 Binary files a/docs/images/listviewsubitem-inspect-list-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-inspect-smallicon-view-tree.png b/docs/images/listviewsubitem-inspect-smallicon-view-tree.png deleted file mode 100644 index 268611c9f73..00000000000 Binary files a/docs/images/listviewsubitem-inspect-smallicon-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-inspect-tile-view-tree.png b/docs/images/listviewsubitem-inspect-tile-view-tree.png deleted file mode 100644 index fc4823974d6..00000000000 Binary files a/docs/images/listviewsubitem-inspect-tile-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-smallsize-inspect-tile-view-tree.png b/docs/images/listviewsubitem-smallsize-inspect-tile-view-tree.png deleted file mode 100644 index 6937a27b169..00000000000 Binary files a/docs/images/listviewsubitem-smallsize-inspect-tile-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-threeitems-inspect-tile-view-tree.png b/docs/images/listviewsubitem-threeitems-inspect-tile-view-tree.png deleted file mode 100644 index 378b9218f34..00000000000 Binary files a/docs/images/listviewsubitem-threeitems-inspect-tile-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-twocolumns-inspect-details-view-tree.png b/docs/images/listviewsubitem-twocolumns-inspect-details-view-tree.png deleted file mode 100644 index 2293cec2e86..00000000000 Binary files a/docs/images/listviewsubitem-twocolumns-inspect-details-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-twocolumns-inspect-tile-view-tree.png b/docs/images/listviewsubitem-twocolumns-inspect-tile-view-tree.png deleted file mode 100644 index f9742c7377c..00000000000 Binary files a/docs/images/listviewsubitem-twocolumns-inspect-tile-view-tree.png and /dev/null differ diff --git a/docs/images/listviewsubitem-twosubitems-inspect-details-view-tree.png b/docs/images/listviewsubitem-twosubitems-inspect-details-view-tree.png deleted file mode 100644 index 3123cbfc417..00000000000 Binary files a/docs/images/listviewsubitem-twosubitems-inspect-details-view-tree.png and /dev/null differ diff --git a/docs/images/monthcalendar-calendar-accessible-from-point.png b/docs/images/monthcalendar-calendar-accessible-from-point.png deleted file mode 100644 index 351b7317f18..00000000000 Binary files a/docs/images/monthcalendar-calendar-accessible-from-point.png and /dev/null differ diff --git a/docs/images/monthcalendar-control-accessible-from-point.png b/docs/images/monthcalendar-control-accessible-from-point.png deleted file mode 100644 index 3ee32846fc9..00000000000 Binary files a/docs/images/monthcalendar-control-accessible-from-point.png and /dev/null differ diff --git a/docs/images/monthcalendar-first-weeknumber-accessible-from-point.png b/docs/images/monthcalendar-first-weeknumber-accessible-from-point.png deleted file mode 100644 index 71b3c1c5901..00000000000 Binary files a/docs/images/monthcalendar-first-weeknumber-accessible-from-point.png and /dev/null differ diff --git a/docs/images/monthcalendar-gray-dates-accessible-from-point.png b/docs/images/monthcalendar-gray-dates-accessible-from-point.png deleted file mode 100644 index f8c8989a28c..00000000000 Binary files a/docs/images/monthcalendar-gray-dates-accessible-from-point.png and /dev/null differ diff --git a/docs/images/monthcalendar-inspect-century-view-tree.png b/docs/images/monthcalendar-inspect-century-view-tree.png deleted file mode 100644 index 52848915eeb..00000000000 Binary files a/docs/images/monthcalendar-inspect-century-view-tree.png and /dev/null differ diff --git a/docs/images/monthcalendar-inspect-decade-view-tree.png b/docs/images/monthcalendar-inspect-decade-view-tree.png deleted file mode 100644 index 1c127bbc6c7..00000000000 Binary files a/docs/images/monthcalendar-inspect-decade-view-tree.png and /dev/null differ diff --git a/docs/images/monthcalendar-inspect-month-view-tree.png b/docs/images/monthcalendar-inspect-month-view-tree.png deleted file mode 100644 index df77fca6dc4..00000000000 Binary files a/docs/images/monthcalendar-inspect-month-view-tree.png and /dev/null differ diff --git a/docs/images/monthcalendar-inspect-year-view-tree.png b/docs/images/monthcalendar-inspect-year-view-tree.png deleted file mode 100644 index cb5ef726d42..00000000000 Binary files a/docs/images/monthcalendar-inspect-year-view-tree.png and /dev/null differ diff --git a/docs/images/monthcalendar-last-weeknumbers-accessible-from-point.png b/docs/images/monthcalendar-last-weeknumbers-accessible-from-point.png deleted file mode 100644 index a198818096a..00000000000 Binary files a/docs/images/monthcalendar-last-weeknumbers-accessible-from-point.png and /dev/null differ diff --git a/docs/images/templates-check-installed.png b/docs/images/templates-check-installed.png deleted file mode 100644 index b10c4c9487a..00000000000 Binary files a/docs/images/templates-check-installed.png and /dev/null differ diff --git a/docs/infra/automation.md b/docs/infra/automation.md deleted file mode 100644 index 23af9d9e4a2..00000000000 --- a/docs/infra/automation.md +++ /dev/null @@ -1,7 +0,0 @@ -## Automation - -### Fabric Bot - -This repository uses Fabric Bot to automate issue and pull request management. All automation rules are defined in the [`.github/fabricbot.json`](.github/fabricbot.json) file. - -At this moment Fabric Bot has not published a JSON schema for the configuration format. In order to make changes to the configuration file, you should use the [`Fabric Bot portal`](https://portal.fabricbot.ms/bot/) to load the configuration file via the "Import Configuration" option and make changes using the editor. You need to be signed out from the portal in order for this option to appear. diff --git a/docs/issue-guide.md b/docs/issue-guide.md deleted file mode 100644 index 7a8c8211aef..00000000000 --- a/docs/issue-guide.md +++ /dev/null @@ -1,124 +0,0 @@ -# Issue Guide - -This page outlines how WinForms team thinks about and handles issues. -For us, issues on GitHub represent actionable work that should be done at some future point. -It may be as simple as a small product or test bug or as large as the work tracking the design of a new feature. - -We will keep issues open even if the WinForms team internally has no plans to address them in an upcoming release, as long as we believe they are in line with our direction. - -# How to file issues - -You can help us streamline our response time to your feedback and ideas by filing high-quality reports. - -### Known Issues - -If you encounter an issue using the latest .NET 5.0 SDK, please: - -1. Explore [this repositories issues][winforms-issues], and then -1. [Open a new issue][new-issue] if there is none. - -### Bug reports - -In general, try to be specific. Get straight to the main point. Leave additional details, options, and alternatives to the end (hint: separate them visually). Don't write long bug reports, unless you have to. - -* Include a minimal reproduction (repro) in your bug if at all possible (chop off dependencies, remove as much code as possible). If it is not possible, say why.
- :warning: Note: Yes, it may take some time to minimize a repro from your larger app - but that is exactly what we would do in most cases anyway. Issues with clear, concise reproduction guidelines are easier for us to investigate; such issues will have higher chance of being addressed quickly. -* Include call-stacks, symptom descriptions, and differences between actual and expected behaviors. - -### Feature and API suggestions - -Assume that the reader has minimal knowledge and experience with writing apps/libraries that would benefit from the feature, so try and write to that audience. Provide clear description of your suggestion, and explain scenarios in which it would be helpful and why (motivation). - -Prepare code examples that showcase the need and general usefulness of the proposal. Specifically: -* Code that shows the surface area of the API. -* Code that shows real world scenarios, and how they would otherwise be handled. -* Details showing the usage/consumption of the proposed new package, and alternatives (e.g. not having this be a separate package). - -:warning: All new API or changes to public API must undergo an API review process. Learn more what the [API review process][api-review-process] entails. - -Here are few example of a good API proposal: -* https://github.com/dotnet/runtime/issues/15725 -* https://github.com/dotnet/runtime/issues/15725 - - -## Assignee - -We assign each issue to assignee, when the assignee is ready to pick up the work and start working on it. -If the issue is not assigned to anyone and you want to pick it up, please say so - we will assign the issue to you. -If the issue is already assigned to someone, please coordinate with the assignee before you start working on it. - -## Up-votes on issues - -Up-votes on first post of each issue are useful hint for our prioritization. -We can [sort issues by number of up-votes][up-votes], and we will review the top list on a regular basis. - -## Triage rules - -Guidance for triage of issues for Windows Forms team members: - -1. Issue has no **Assignee**, unless someone is working on the issue at the moment. -1. Use **help wanted** as much as possible, ideally with a quick note about next steps / complexity of the issue. -1. Set milestone to **Future**, unless you can 95%-commit you can fund the issue in specific milestone. -1. Each issue has exactly one "*issue type*" label (**bug**, **enhancement**, **api-suggestion**, **test-bug**, **test-enhancement**, **question**, **documentation**, etc.). -1. Don't be afraid to say no, or close issues — just explain why and be polite. -1. Don't be afraid to be wrong - just be flexible when new information appears. - -Feel free to use other labels if it helps your triage efforts (for example, **needs-more-info**, **design-discussion**, **tenet-compatibility**, etc.). - -### Motivation for triage rules - -1. Issue has no **Assignee**, unless someone is working on the issue at the moment. - * Motivation: Observation is that contributors are less likely to grab assigned issues, no matter what the repository rules say. - -1. Use **help wanted** as much as possible, ideally with a quick note about next steps / complexity of the issue.
- NB: Per [https://up-for-grabs.net][up-for-grabs-net], such issues should be no longer than few nights' worth of work. They should be actionable (that is, no mysterious CI failures that can't be tested in the open). - -1. Set milestone to **Future**, unless you can 95%-commit you can fund the issue in specific milestone. - * Motivation: Helps communicate desire/timeline to community. Can spark further priority/impact discussion. - -1. Each issue has exactly one "*issue type*" label (**bug**, **enhancement**, **api-suggestion**, **test-bug**, **test-enhancement**, **question**, **documentation**, etc.). - * Don't be afraid to be wrong when deciding 'bug' vs. 'test-bug' (flip a coin if you must). The most useful values for tracking are 'api-*' vs. 'enhancement', 'question', and 'documentation'. - - -# Pull-Request (PR) Guide - -Each PR has to have reviewer approval from at least one Windows Forms team member who is not author of the change, before it can be merged. - - -1. Please don't set any labels on PRs. - * exceptions: - * **NO-MERGE** may be supplied by the WinForms team in order to indicate that the PR should be halted; a reason should be given in the comments - * **waiting-on-testing** may be supplied by the WinForms team to inform the PR author(s) that their PR is being delayed due to internal, manual testing; this action does not require action by the author(s). - * Motivation: All the important info (*issue type* label, API approval label, etc.) is already captured on the associated issue. - -1. Push PRs forward, don't let them go stale (response every 5+ days, ideally no PRs older than 2 weeks). - -1. Close stuck or long-term blocked PRs (for example, due to missing API approval, etc.) and reopen them once they are unstuck. - * **Motivation: Keep only active PRs. WIP (work-in-progress) PRs should be rare and should not become stale (2+ weeks old). If a PR is stale and there is not immediate path forward, consider closing the PR until it is unblocked/unstuck. - -1. Link PR to related issue via [auto-closing][auto-closing] (add "Fixes #12345" into your PR description). - -[comment]: <> (URI Links) - - -[winforms-issues]: https://github.com/dotnet/winforms/issues -[new-issue]: https://github.com/dotnet/winforms/issues/new/choose -[api-review-process]: https://github.com/dotnet/runtime/blob/master/docs/project/api-review-process.md -[labels]: https://github.com/dotnet/winforms/labels -[api-suggestion]: https://github.com/dotnet/winforms/labels/api-suggestion -[API Review process]: https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/api-review-process.md -[bug]: https://github.com/dotnet/winforms/labels/bug -[enhancement]: https://github.com/dotnet/winforms/labels/enhancement -[test-bug]: https://github.com/dotnet/winforms/labels/test-bug -[test-enhancement]: https://github.com/dotnet/winforms/labels/test-enhancement -[question]: https://github.com/dotnet/winforms/labels/question -[documentation]: https://github.com/dotnet/winforms/labels/documentation -[label-description]: https://github.com/dotnet/winforms/labels -[help wanted]: https://github.com/dotnet/winforms/labels/help%20wanted -[needs-more-info]: https://github.com/dotnet/winforms/labels/needs-more-info -[tenet-compatibility]: https://github.com/dotnet/winforms/labels/tenet-compatibility -[milestones]: https://github.com/dotnet/winforms/milestones -[up-votes]: #upvotes-on-issues -[sort issues by number of up-votes]: https://github.com/dotnet/winforms/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc -[up-for-grabs-net]: https://up-for-grabs.net -[auto-closing]: https://help.github.com/articles/closing-issues-via-commit-messages/ \ No newline at end of file diff --git a/docs/list-of-diagnostics.md b/docs/list-of-diagnostics.md deleted file mode 100644 index a64334ad409..00000000000 --- a/docs/list-of-diagnostics.md +++ /dev/null @@ -1,54 +0,0 @@ -# List of Diagnostics Produced by Windows Forms .NET APIs - -## Obsoletions - -Per https://github.com/dotnet/designs/blob/main/accepted/2020/better-obsoletion/better-obsoletion.md and similar to https://github.com/dotnet/runtime/blob/main/docs/project/list-of-diagnostics.md, we now have a strategy for marking existing APIs as `[Obsolete]`. This takes advantage of the new diagnostic id and URL template mechanisms introduced to `ObsoleteAttribute` in .NET 5. - -The diagnostic id values reserved for obsoletions are `WFDEV001` through `WFDEV999`. When obsoleting an API, claim the next three-digit identifier in the `WFDEV###` sequence and add it to the list below. The URL template for all obsoletions is `https://aka.ms/winforms-warnings/{0}`. The `{0}` placeholder is replaced by the compiler with the `WFDEV###` identifier. - -The acceptance criteria for adding an obsoletion includes: - -* Add the obsoletion to the table below, claiming the next diagnostic id - * Ensure the description is meaningful within the context of this table, and without requiring the context of the calling code -* Add new constants to `src\Common\src\Obsoletions.cs`, following the existing conventions - * A `...Message` const using the same description added to the table below - * A `...DiagnosticId` const for the `WFDEV###` id -* Annotate `src` files by referring to the constants defined from `Obsoletions.cs` - * Specify the `UrlFormat = Obsoletions.SharedUrlFormat` - * Example: `[Obsolete(Obsoletions.DomainUpDownAccessibleObjectMessage, DiagnosticId = Obsoletions.DomainUpDownAccessibleObjectDiagnosticId, UrlFormat = Obsoletions.SharedUrlFormat)]` - * If the `Obsoletions` type is not available in the project, link it into the project - * `` -* Apply the `:book: documentation: breaking` label to the PR that introduces the obsoletion -* Follow up with the breaking change process to communicate and document the breaking change - * In the breaking-change issue filed in [dotnet/docs](https://github.com/dotnet/docs), specifically mention that this breaking change is an obsoletion with a `WFDEV` diagnostic id - * The documentation team will produce a PR that adds the obsoletion to the [WFDEV warnings](https://learn.microsoft.com/dotnet/desktop/winforms/wfdev-diagnostics/obsoletions-overview) page - * That PR will also add a new URL specific to this diagnostic ID; e.g. [WFDEV001](https://learn.microsoft.com/dotnet/desktop/winforms/wfdev-diagnostics/wfdev001) - * Connect with `@gewarren` or `@BillWagner` with any questions -* Register the `WFDEV###` URL in `aka.ms` - * The vanity name will be `winforms-warnings/WFDEV###` - * Ensure the link's group owner matches the group owner of `winforms-warnings/WFDEV001` - * Connect with `@igveliko` or `@gewarren` with any questions - -### Obsoletion Diagnostics (`WFDEV001` - `WFDEV999`) - -| Diagnostic ID | Description | -| :---------------- | :---------- | -| __`WFDEV001`__ | Casting to/from IntPtr is unsafe, use `WParamInternal`. | -| __`WFDEV001`__ | Casting to/from IntPtr is unsafe, use `LParamInternal`. | -| __`WFDEV001`__ | Casting to/from IntPtr is unsafe, use `ResultInternal`. | -| __`WFDEV002`__ | `DomainUpDown.DomainUpDownAccessibleObject` is no longer used to provide accessible support for `DomainUpDown` controls. Use `ControlAccessibleObject` instead. | -| __`WFDEV003`__ | `DomainUpDown.DomainItemAccessibleObject` is no longer used to provide accessible support for `DomainUpDown` items. | - - -## Analyzer Warnings - -The diagnostic id values reserved for Windows Forms .NET analyzer warnings are WF??001 through WF??999. - -### Analyzer Diagnostics (`WF??001` - `WF??999`) - -| Diagnostic ID | Description | -| :---------------- | :---------- | -| __`WFAC001`__ | Unsupported project type. | -| __`WFAC002`__ | Unsupported property value. | -| __`WFAC010`__ | Unsupported high DPI configuration. | - diff --git a/docs/porting-guidelines.md b/docs/porting-guidelines.md deleted file mode 100644 index 4f9c793613a..00000000000 --- a/docs/porting-guidelines.md +++ /dev/null @@ -1,149 +0,0 @@ -# Port existing applications to .NET 5.0 - ->We suggest doing migration in a separate branch or, if you're not using version ->control, creating a copy of your project so you have a clean state to go back ->to if necessary. - -The migration process includes two steps: **preparing your project for porting** to -.NET and **porting** itself. - -For additional information and assistance, we recommend checking out [this article on the dotnet blog][dotnet-blog-port-guide] as well as the [accompanying video tutorial][dotnet-blog-port-video]. - - -## Breaking changes - -Review the following resources that describe breaking changes between Windows Forms on .NET Framework and .NET: - -* The [Breaking changes in Windows Forms (.NET Framework to .NET Core)](https://docs.microsoft.com/dotnet/core/porting/winforms-breaking-changes) describes breaking changes you need to be aware of when migrating your applications from .NET Framework -* The [Breaking changes in Windows Forms (.NET Core to .NET)](https://docs.microsoft.com/dotnet/core/compatibility/winforms) describes breaking changes you need to be aware of when migrating your applications from .NET Core 3.x versions to .NET 5.0 onwards. - -## Prepare your project for porting - -1. **Run [.NET Portability Analyzer][api-port]** first to determine if there are - any APIs your application depends on that are missing in .NET. If there - are, you have a few options. - * Remove not supported APIs or replace them with those, that are included in - .NET - * Separate your code into different projects: the one that contains only - .NET supported APIs and another with APIs not supported in .NET. - Migrate only the first project. - -1. **Start from a working solution**. Ensure the solution opens, builds, and runs without any issues. - -1. **Replace `packages.config` with `PackageReference`**. If your project uses - NuGet packages, you will need to add the same NuGet packages to the new .NET - project. .NET projects support only `PackageReference` for adding - NuGet packages. To move your NuGet references from `packages.config` to your - project file, right-click on `packages.config` -> **Migrate packages.config - to PackageReference...**. - - You can learn more about this migration in our [docs][pkg-config]. - -1. **Migrate to the SDK-style .csproj file**. The new SDK-style `.csproj` format is leaner and easier to read. To be able to simply copy-paste your references from the old project to the new one, you first need to migrate your old project file to SDK-style so both project are in the same format. You can either do it by hand or use a third-party tool [CsprojToVs2017][sdk-tool]. - - After using the tool you still might need to delete some reference by hand; for example: - - ```xml - - - - ``` - - After you've migrated to the new SDK-style format, ensure your project builds and runs successfully. - -1. **Configure assembly file generation**. Most existing projects include an `AssemblyInfo.cs` file in the Properties folder. The new project style uses a different approach and generates the same assembly attributes as part of the build process. As a result, you might end up with two `AssemblyInfo.cs` files and your build will fail. There are two ways to resolve this problem. You can either: - * Disable `AssemblyInfo.cs` generation on build by setting the property: - - ```xml - false - ``` - * Move the static values from `AssemblyInfo.cs` to properties in the new `.csproj` file. - - Build and run to make sure you did not introduce any issues while preparing your project. Now it is time to port it. - - - -## Port your project - -### Automated porting - -1. Try porting your project using [`try-convert` tool](https://github.com/dotnet/try-convert), which we built to help migrations.
-NB: The tool may not work for all possible projects, in that case please read on. - -### Manual porting - -1. **Add .NET Windows Forms project**. Add a new .NET 5.0 Windows Forms project to the solution. - -1. **Add ``**. Copy the `` elements from the `.csproj` file of the original project to the new project's `.csproj` file.
-Note: The new project format does not use the `Name` and `ProjectGuid` elements, so you can safely delete those. - -1. **Restore/Build**. At this point, it's a good idea to restore/build to make sure all dependencies are properly configured. - -1. **Link files**. Link all files from your existing .NET Framework WinForms project to the .NET 5.0 WinForms project by adding following to the `.csproj` file. - - ```xml - - - - - ``` - -1. **Align default namespace and assembly name**. Since you're linking to designer generated files (for example, `Resources.Designer.cs`) you generally want to make sure that the .NET version of your application uses the same namespace and the same assembly name. Copy the following settings from your .NET Framework project: - - ```xml - - - - - ``` - -1. **Run new project**. Set your new .NET project as StartUp Project and run it. Make sure everything works. - -1. **Copy or leave linked**. Now instead of linking the files, you can actually copy them from the old .NET Framework WinForms project to the new .NET 5.0 WinForms project. After that you can get rid of the old project. - -## Migration tips - -### Include the System.Windows.Forms.Datavisualization Pack - -If you wish to use types previously associated with the [Charting control in the .NET Framework][framework-charting], you should add a package reference to the [NuGet package of Data Visualization][nuget-dataviz] ported to .NET. For more information about Data Visualization and the Charting control in .NET, including a sample application demonstrating its use, see the [winforms-datavisualization repository][dataviz] - -### Include the Windows.Compatibility Pack - -Windows applications like Windows Forms and WPF often use APIs that aren't referenced by default in .NET. The reason is that .NET tries to reduce the risk that new applications accidentally depend on legacy technologies or on APIs that are Windows-only. However, when porting existing Windows applications, neither of these two aspects is a concern. To simplify your porting efforts, you can simply reference the [Windows Compatibility Pack][compat-pack], which will give -you access to many more APIs. - -```cmd -dotnet add package Microsoft.Windows.Compatibility -``` - -### Migrating WCF clients - -.NET has its own implementation of `System.ServiceModel` with some -differences: - -* It is available as a set of NuGet packages (also included in the [Windows - Compatibility Pack][compat-pack]). -* There are [unsupported features][wcf-supported] that you should review. -* The binding and endpoint address must be specified in the service client constructor. Otherwise, if you reuse the `ServiceReference` created by Visual Studio, you may get the following error: - -```cs -System.PlatformNotSupportedException: 'Configuration files are not supported.' -``` - -### Additional Types and Namespaces - -You can search for additional types which you may need in porting your apps to .NET on [APIs of DotNet][apisofnet]. For example, when you search for the type `System.AppDomain`, you will see that the type has been moved to `System.Runtime.Extensions` namespace starting in .NET 2.0. - -[comment]: <> (URI Links) - -[dotnet-blog-port-guide]: https://devblogs.microsoft.com/dotnet/how-to-port-desktop-applications-to-net-core-3-0/ -[dotnet-blog-port-video]: https://www.youtube.com/watch?v=upVQEUc_KwU -[api-port]: https://blogs.msdn.microsoft.com/dotnet/2018/08/08/are-your-windows-forms-and-wpf-applications-ready-for-net-core-3-0/ -[pkg-config]: https://docs.microsoft.com/en-us/nuget/reference/migrate-packages-config-to-package-reference -[sdk-tool]:https://github.com/hvanbakel/CsprojToVs2017 -[framework-charting]: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.datavisualization.charting -[nuget-dataviz]: https://www.nuget.org/packages/System.windows.forms.datavisualization -[dataviz]: https://github.com/dotnet/winforms-datavisualization -[compat-pack]: https://docs.microsoft.com/en-us/dotnet/core/porting/windows-compat-pack -[wcf-supported]: https://github.com/dotnet/wcf/blob/master/release-notes/SupportedFeatures-v2.1.0.md -[apisofnet]: https://apisof.net/ diff --git a/docs/release-activity.md b/docs/release-activity.md deleted file mode 100644 index f21cc7240ad..00000000000 --- a/docs/release-activity.md +++ /dev/null @@ -1,46 +0,0 @@ -# Runtime release procedures - -## Milestone releases (dotnet/winforms + dotnet/windowsdesktop) - -1. Merge any outstanding PRs, if necessary -2. Ensure the HEAD of the main branch builds successfully and all tests pass -3. Publish any unpublished API - run [.\eng\ApiCompatibility\mark-shipped.cmd](https://github.com/dotnet/winforms/blob/main/eng/ApiCompatibility/mark-shipped.cmd) - -4. Commit and wait for a successful build - -5. (Milestone releases) Create "release/X.Y-qwe" branch (e.g. release/6.0-preview5) and push it into the main public trunk and the internal trunk. -Wait for both build successfully. -* Main public trunk: https://github.com/dotnet/winforms/ -* Internal trunk: -6. Disable loc on "release/X.Y-qwe" branch (e.g.: https://github.com/dotnet/winforms/pull/6753) -7. Switch back to the main branch -8. Update the Service Fabric bot with the new release label in .\github\fabricbot.json. Refer to .\docs\infra\automation.md, if have questions. -9. Update the branding (e.g.: https://github.com/dotnet/winforms/commit/719b2112778ffd1e7ded559ea2736b4011428117) -10. Commit and wait for a successful build. - -11. Create new [milestone](https://github.com/dotnet/winforms/milestones) for the new release before updating following bot service. - -12. Move work items to this new milestone if they were on previous milestone and close the previous milestone. - -13. Update necessary reports with the progress - -14. If you are responsible for [dotnet/windowsdesktop](https://github.com/dotnet/windowsdesktop) repo, make sure you change the branding there too. - -## Servicing releases (dotnet/winforms + dotnet/windowsdesktop) - -[NET Servicing - Overview (azure.com)](https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/545/NET-Servicing) - -1. Merge internal servicing branch (i.e. internal/internal/release/*) into the public branch, if necessary. - -2. Update the branding (e.g.: https://github.com/dotnet/winforms/commit/480bd703c5af93b9e23dc7435c6029d685be7097) -3. Commit and wait for a successful build. - -4. Ensure the HEAD of the servicing branch builds successfully and all tests pass - -5. Update [dotnet/installer](https://github.com/dotnet/installer) with the released version (e.g.: https://github.com/dotnet/installer/commit/34ed90f436809631e254b9e15628cbcad7307629) - -6. Create a new [milestone](https://github.com/dotnet/winforms/milestones). - -7. Close the current milestone on the GitHub, ensuring all open issues/PRs are either closed or bumped to the following milestone - -8. Merge any outstanding PRs, if necessary diff --git a/docs/roadmap.md b/docs/roadmap.md deleted file mode 100644 index 4c5da68a7a9..00000000000 --- a/docs/roadmap.md +++ /dev/null @@ -1,54 +0,0 @@ -# Windows Forms Roadmap - -This roadmap communicates priorities for evolving and extending the scope of Windows Forms. For general information regarding .NET plans, see [.NET roadmap](https://github.com/dotnet/core/blob/master/roadmap.md). - -* [Future](#future) -* [Present](#present) - -This repository is a community effort and we welcome community feedback on our plans. The best way to give your feedback is to open an issue in this repo. -We also invite contributions. The [help wanted issues](https://github.com/dotnet/winforms/issues?q=is%3Aopen+is%3Aissue+label%3A"help%20wanted") on GitHub are a good place to start. - -## Future - -Here is the list of improvements we are planning to work on in the future. - -### Accessibility improvements - -Including support for standard [WCAG2.1]( https://www.w3.org/TR/WCAG21/), such as enabling tooltips for controls on `Tab` ([#2726](https://github.com/dotnet/winforms/issues/2726)), etc. - -### High DPI improvements - -* Fix existing scaling bugs in Per Monitor DPI aware applications -* Enable all controls to support Per Monitor V2 mode -* Add a new "clean" way of calculating location/size information in PMA mode - -### Performance improvements - -Establish a base line and improve runtime and designer performance. - -### Testing infrastructure - -Add testing infrastructure and improve test coverage. - -## Some potential features - -We also are gathering feedback regarding what other features you'd like to see in WinForms. Please let us know if any of those or something else would be useful for your applications. You an create a feature request in this repo or vote for an existing one. - -### Add and improve wrappers for missing Win32 controls - -Such as Ribbon Control, Balloons, SearchBox, improvements around ListView, etc. - -### Add support for OS themes in WinForms applications - -Enable dark theme, etc. - -## Present - -### Windows Forms runtime - -**Under considerations**.
A number of aspects are being considered including (but not limited to) layout engine and high DPI support, theming, new controls and components. - -### Windows Forms Designer - -We continue the work on the designer to to achieve the parity with the .NET Framework designer. -This involves adding the remaining controls and features and improving stability and performance for the designer. diff --git a/docs/runtime-configuration.md b/docs/runtime-configuration.md deleted file mode 100644 index a578b6a7eac..00000000000 --- a/docs/runtime-configuration.md +++ /dev/null @@ -1,294 +0,0 @@ -# Support for application runtime configuration in Windows Forms applications - -## Overview - -.NET Windows Forms applications currently have limited [application -configurations](https://aka.ms/applicationconfiguration) capabilities that are defined via MSBuils properties and are emitted into source code using source -generators at compile time. This document outlines expansion of those application-wide configurations further to cover runtime config options for .NET Windows Forms applications. - -## .NET Framework runtime configuration - -.NET Framework Windows Forms applications use `app.config` to define runtime configurations and application-wide settings. The following are the various sections in the app.config that define the application's runtime behavior. - -### AppContext switches - -These settings are used to opt-in or opt-out of a particular feature from Windows Forms runtime. Refer to the [AppContext Switches](https://docs.microsoft.com/dotnet/framework/configure-apps/file-schema/runtime/appcontextswitchoverrides-element) documentation for more information. - -```xml - - - - - -``` -### `System.Windows.Forms.ApplicationConfigurationSection` section - -This was introduced in .NET Framework 4.7, and it is primarily used by Windows Forms runtime to enable high DPI and other accessibility improvements. Please refer to the [ApplicationConfigurationSection](https://docs.microsoft.com/dotnet/framework/configure-apps/file-schema/winforms/windows-forms-add-configuration-element) documentation for more information. - -```xml - - - - - -``` - -### Application-wide and user-specific settings - -These are commonly defined via the Settings designer in Visual Studio, which serializes those into `app.config`. Refer to the [Application Settings](https://docs.microsoft.com/dotnet/desktop/winforms/advanced/using-application-settings-and-user-settings) documentation for more information. - -```xml - - - - LocalButton - - - - - - - - LocalBox - - - -``` - - -## .NET 7+ runtime configuration - -`app.config` has limited support in .NET due to performance and reliability reasons. .NET runtime and other .NET teams use `runtimeconfig.json` to define .NET runtime configurations and `appsettings.json` to define application-level settings. In this proposal, we are leveraging `runtimeconfig.json` to define Windows Forms runtime configurations. - -While this proposal is focusing on providing an alternative solution for existing configuration sections `AppContextSwitchOverrides` and `System.Windows.Forms.ApplicationConfigurationSection` that are primarily used for specifying feature flags impacting Windows Forms runtime behavior, we will be looking into alternatives for `Application Settings` that doesn't require `app.config` in the future releases of .NET. - - -### Goals: - -- A replacement for `AppContextSwitchOverrides` and `System.Windows.Forms.ApplicationConfigurationSection` of `app.config`. -- Users should be able to update/modify Windows Forms applications runtime configurations without recompiling the application. -- The existing applications should be able to seamlessly upgrade to the new configuration model when targeting .NET 7+ runtime. -- The existing [application configuration MSBuild properties](https://aka.ms/applicationconfiguration) continue to work. - -### Out of scope: - -- App settings that are serialized by the Settings designer/editor page. Applications should continue to use the current model. -- Dynamic/real-time (re-)loading of configuration values from `runtimeconfig.json`. -- Unification of comple/runtime configurations into one place, e.g., `runtimeconfig.json`. - - -### Design proposal - -Windows Forms switches will be added to **`runtimeConfig.template.json`** to the [`configProperties` section](https://docs.microsoft.com/dotnet/core/runtime-config) with the rest of the .NET switches. To avoid name conflics Windows Forms specific switches will be prefixed with `System.Windows.Forms`: - -```json -{ - "configProperties": { - "System.Globalization.UseNls": true, - "System.Net.DisableIPv6": true, - "System.GC.Concurrent": false, - "System.Threading.ThreadPool.MinThreads": 4, - "System.Threading.ThreadPool.MaxThreads": 25, - - // Windows Forms specific switches - "System.Windows.Forms.ScaleTopLevelFormMinMaxSizeForDpi": true, - "System.Windows.Forms.CustomEnumProperty": "EnumValue" - } -} -``` - - -#### Reading Windows Forms runtime configurations - -When a project is [built](https://docs.microsoft.com/dotnet/core/runtime-config/#runtimeconfigjson), an `[appname].runtimeconfig.json` file is generated in the output directory. If a `runtimeconfig.template.json` file exists in the same folder as the project file, any configuration options it contains are inserted into the `[appname].runtimeconfig.json` file. - -This proposal focuses primarily on enabling the runtime configurations for Windows Forms applications. A support for analyzers and source generators may be considered in the future .NET releases. We will revisit this implementation to improve user-experience further, as we make progress. - -For example, the content of `[appname].runtimeconfig.json` generated from above content: - -```json -{ - "runtimeOptions": { - "tfm": "net7.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "7.0.0-preview.7.22375.6" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "7.0.0-preview.7.22377.1" - } - ], - "configProperties": { - "System.Globalization.UseNls": true, - "System.Net.DisableIPv6": true, - "System.GC.Concurrent": false, - "System.Threading.ThreadPool.MinThreads": 4, - "System.Threading.ThreadPool.MaxThreads": 25, - - "System.Windows.Forms.ScaleTopLevelFormMinMaxSizeForDpi": true, - "System.Windows.Forms.StringProperty": "string", - "System.Windows.Forms.CustomProperty": "CustomValue" - } - } -} -``` - -The target framework information added to `[appname].runtimeconfig.json` file always match with the application target framework irrespective of runtime/SDK installed on the machine or runtime used ([roll-forward scenarios](https://docs.microsoft.com/dotnet/core/versions/selection#framework-dependent-apps-roll-forward)) by the Windows Forms application. - -#### .NET runtime support in reading `runtimeconfig.json` - -The Windows Forms runtime is leveraging the [support](https://github.com/dotnet/runtime/blob/5098d45cc1bf9649fab5df21f227da4b80daa084/src/native/corehost/runtime_config.cpp) provided by .NET runtime in reading `[appname].runtimeconfig.json` file, and thus get all plumbing required for various hosting and environment scenarios. The Windows Forms runtime adds the following wrapper on top of .NET runtime implementation to improve the performance by caching configuration options, and also by defining custom defaults values for the Windows Forms specific feature flags. This wrapper is very similar to the [.NET runtime's implementation](https://github.com/dotnet/runtime/blob/04dac7b0fede29d44f896c5fd793754f83974175/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs). - -The below example illustrates how to define `ScaleTopLevelFormMinMaxSizeForDpi` feature flag, opt-in by default, for an application targeting .NET 8 or later running on Windows 10: - -```cs -internal static partial class LocalAppContextSwitches -{ - private const string ScaleTopLevelFormMinMaxSizeForDpiSwitchName = "System.Windows.Forms.ScaleTopLevelFormMinMaxSizeForDpi"; - - private static readonly FrameworkName? s_targetFrameworkName = GetTargetFrameworkName(); - private static readonly bool s_isNetCoreApp = (s_targetFrameworkName?.Identifier) == ".NETCoreApp"; - - private static int s_scaleTopLevelFormMinMaxSize; - - public static bool ScaleTopLevelFormMinMaxSizeForDpi - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => GetCachedSwitchValue(ScaleTopLevelFormMinMaxSizeForDpiSwitchName, ref s_scaleTopLevelFormMinMaxSize); - } - - private static FrameworkName? GetTargetFrameworkName() - { - string? targetFrameworkName = AppContext.TargetFrameworkName; - return targetFrameworkName is null ? null : new FrameworkName(targetFrameworkName); - } - - private static bool GetCachedSwitchValue(string switchName, ref int cachedSwitchValue) - { - // The cached switch value has 3 states: 0 - unknown, 1 - true, -1 - false - if (cachedSwitchValue < 0) - return false; - if (cachedSwitchValue > 0) - return true; - - return GetSwitchValue(switchName, ref cachedSwitchValue); - } - - private static bool GetSwitchValue(string switchName, ref int cachedSwitchValue) - { - bool hasSwitch = AppContext.TryGetSwitch(switchName, out bool isSwitchEnabled); - if (!hasSwitch) - { - isSwitchEnabled = GetSwitchDefaultValue(switchName); - } - - // Is caching switches disabled?. - AppContext.TryGetSwitch("TestSwitch.LocalAppContext.DisableCaching", out bool disableCaching); - if (!disableCaching) - { - cachedSwitchValue = isSwitchEnabled ? 1 /*true*/ : -1 /*false*/; - } - - return isSwitchEnabled; - } - - // Provides default values for switches based on OS and Targetframework versions. - private static bool GetSwitchDefaultValue(string switchName) - { - if (!s_isNetCoreApp) - { - return false; - } - - if (OsVersion.IsWindows10_1703OrGreater) - { - if (s_targetFrameworkName!.Version.CompareTo(new Version("8.0")) >= 0) - { - if (switchName == ScaleTopLevelFormMinMaxSizeForDpiSwitchName) - { - return true; - } - } - } - - return false; - } -} -``` - - -The Windows Forms runtime then uses the static `LocalAppContextSwitches` class to access the runtime configurations. The below sample demonstrates the use of the feature switch `System.Windows.Forms.ScaleTopLevelFormMinMaxSizeForDpi` to scale min/max size of a container control: - -```cs -internal void ScaleContainerForDpi(int deviceDpiNew, int deviceDpiOld, Rectangle suggestedRectangle) -{ - CommonProperties.xClearAllPreferredSizeCaches(this); - SuspendAllLayout(this); - try - { - if (LocalAppContextSwitches.ScaleTopLevelFormMinMaxSizeForDpi) - { - // The suggested rectangle comes from Windows, and it does not match with our calculations for scaling controls by AutoscaleFactor. - // Hence, we cannot use AutoscaleFactor here for scaling the control properties. See the below description for more details. - float xScaleFactor = (float)suggestedRectangle.Width / Width; - float yScaleFactor = (float)suggestedRectangle.Height / Height; - ScaleMinMaxSize(xScaleFactor, yScaleFactor, updateFormSize: false); - } - - // If this container is a top-level window, we would receive WM_DPICHANGED message that - // has SuggestedRectangle for the control. We are forced to use this in such cases to - // make the control placed in right location with respect to the new monitor that triggered - // WM_DPICHANGED event. Failing to apply SuggestedRectangle will result in a circular WM_DPICHANGED - // events on the control. - - // Note: SuggestedRectangle supplied by WM_DPICHANGED event is DPI (not Font) scaled. if top-level window is - // Font scaled, we might see deviations in the expected bounds and may result in adding Scrollbars (horizontal/vertical) - User32.SetWindowPos( - new HandleRef(this, HandleInternal), - User32.HWND_TOP, - suggestedRectangle.X, - suggestedRectangle.Y, - suggestedRectangle.Width, - suggestedRectangle.Height, - User32.SWP.NOZORDER | User32.SWP.NOACTIVATE); - - // Bounds are already scaled for the top-level window. We would need to skip scaling of - // this control further by the 'OnFontChanged' event. - _isScaledByDpiChangedEvent = true; - - // Factor is used only to scale Font. After that AutoscaleFactor kicks in to scale controls. - var factor = ((float)deviceDpiNew) / deviceDpiOld; - - // DpiFontscache is available only in PermonitorV2 mode applications. - if (!TryGetDpiFont(deviceDpiNew, out Font? fontForDpi)) - { - Font currentFont = Font; - fontForDpi = currentFont.WithSize(currentFont.Size * factor); - AddToDpiFonts(deviceDpiNew, fontForDpi); - } - - ScaledControlFont = fontForDpi; - if (IsFontSet()) - { - SetScaledFont(fontForDpi); - } - else - { - using (new LayoutTransaction(ParentInternal, this, PropertyNames.Font)) - { - OnFontChanged(EventArgs.Empty); - } - } - } - finally - { - // We want to perform layout for DPI-changed high DPI improvements - setting the second parameter to 'true' - ResumeAllLayout(this, true); - _isScaledByDpiChangedEvent = false; - } -} -``` - -![OptinSwitch](images/RuntimeOptionsDemo.gif) \ No newline at end of file diff --git a/docs/serialization/register-custom-type-converter.md b/docs/serialization/register-custom-type-converter.md deleted file mode 100644 index 47b4bb80c8b..00000000000 --- a/docs/serialization/register-custom-type-converter.md +++ /dev/null @@ -1,76 +0,0 @@ -# Manually Registering a TypeConverter to a Class -A [type converter](https://learn.microsoft.com/dotnet/api/system.componentmodel.typeconverter) is usually bound to a class by adding the [`TypeConverterAttribute`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typeconverterattribute) to the class. When you cannot apply this attribute or want to override it you can programmatically assign a converter instead. This document outlines how to accomplish this. - -## Prerequisite -Follow the steps to implement your own custom type converter listed [here](https://learn.microsoft.com/dotnet/api/system.componentmodel.typeconverter#notes-to-inheritors). - -## Registering Your TypeConverter - -### Background -A [`TypeConverter`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typeconverter) for a given type is found via the `TypeDescriptor` static method [`GetConverter()`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typedescriptor.getconverter). To provide custom `TypeDescriptor` behavior you must create and register a custom type descriptor ([`ICustomTypeDescriptor`](https://learn.microsoft.com/dotnet/api/system.componentmodel.icustomtypedescriptor)) via a [`TypeDescriptionProvider`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typedescriptionprovider). - -### Implementing An ICustomTypeDescriptor -Inherit from [`CustomTypeDescriptor`](https://learn.microsoft.com/dotnet/api/system.componentmodel.customtypedescriptor) to get default [`ICustomTypeDescriptor`](https://learn.microsoft.com/dotnet/api/system.componentmodel.icustomtypedescriptor) behavior and override [`GetConverter()`](https://learn.microsoft.com/dotnet/api/system.componentmodel.customtypedescriptor.getconverter) to return your custom type converter. -```c# -private class CustomConverterDescriptor : CustomTypeDescriptor -{ - private TypeConverter _converter; - - public CustomConverterDescriptor(ICustomTypeDescriptor parent, TypeConverter converter) : base(parent) - => _converter = converter; - - public override TypeConverter GetConverter() => _converter; -} -``` - -An `ICustomTypeDescriptor` is accessed through [`TypeDescriptionProvider.GetTypeDescriptor()`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typedescriptionprovider.gettypedescriptor). This method needs to be overridden to provide your newly created `ICustomTypeDescriptor`. Have another class inherit from `TypeDescriptionProvider` to preserve the default behavior and override `GetTypeDescriptor()` to provide `CustomConverterDescriptor`. - -```c# -public class CustomConverterProvider : TypeDescriptionProvider -{ - private TypeConverter _converter; - - public CustomConverterProvider(TypeDescriptionProvider parent, TypeConverter converter) : base(parent) - => _converter = converter; - - public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) - => new CustomConverterDescriptor(base.GetTypeDescriptor(objectType, instance), _converter); - - // Consider nesting CustomConverterDescriptor here -} -``` -Note: The parent `TypeDescriptionProvider` to be passed to the constructor can be found via [`TypeDescriptor.GetProvider()`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typedescriptor.getprovider) and passing in the type that is intended to be associated to your custom type converter. An example of this will follow. - -### Registration/Deregistration -Once you have `CustomConverterProvider` and `CustomConverterDescriptor` as outlined above, finish up registering your custom `TypeConverter` to a type by calling [`TypeDescriptor.AddProvider()`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typedescriptor.addprovider) with parameters `CustomConverterProvider` and the type you want your custom converter to be associated with. -```c# -TypeDescriptionProvider parentProvider = TypeDescriptor.GetProvider(type); -CustomConverterProvider newProvider = new(parentProvider, converter); -TypeDescriptor.AddProvider(newProvider, type); -``` - -At this point, calling [`TypeDescriptor.GetConverter()`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typedescriptor.getconverter) with the same type that was passed to `TypeDescriptor.AddProvider()` will now return your custom type converter. To restore the previous behavior call [`TypeDescriptor.RemoveProvider()`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typedescriptor.removeprovider). -```c# -TypeDescriptor.RemoveProvider(newProvider, type); -``` - -## Additional Information - -### TypeDescriptor.GetConverter() Details -This is a static method on [`TypeDescriptor`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typedescriptor) that will run through its private list of [`TypeDescriptionProviders`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typedescriptionprovider) and get the provider associated with the type. Once the right provider is found, it will then call [`TypeDescriptionProvider.GetTypeDescriptor()`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typedescriptionprovider.gettypedescriptor) to get an [ICustomTypeDescriptor](https://learn.microsoft.com/dotnet/api/system.componentmodel.icustomtypedescriptor) and call [`ICustomTypeDescriptor.GetConverter()`](https://learn.microsoft.com/dotnet/api/system.componentmodel.icustomtypedescriptor.getconverter) to grab the [`TypeConverter`](https://learn.microsoft.com/dotnet/api/system.componentmodel.typeconverter). -```mermaid -sequenceDiagram -title TypeDescriptor.GetConverter() Flow - -participant TypeDescriptor -participant CustomConverterProvider#58;TypeDescriptionProvider -participant CustomConverterDescriptor#58;CustomTypeDescriptor -participant CustomTypeConverter#58;TypeConverter -note right of CustomConverterProvider#58;TypeDescriptionProvider: Call TypeDescriptor.RemoveProvider() to no longer associate your custom type converter with a given type -TypeDescriptor->>CustomConverterProvider#58;TypeDescriptionProvider: TypeDescriptor.GetConverter() -note over TypeDescriptor,CustomConverterProvider#58;TypeDescriptionProvider: Must call TypeDescriptor.AddProvider() with a given type first -CustomConverterProvider#58;TypeDescriptionProvider->>CustomConverterDescriptor#58;CustomTypeDescriptor: CustomConverterProvider.GetTypeDescriptor() -note over CustomConverterProvider#58;TypeDescriptionProvider,CustomConverterDescriptor#58;CustomTypeDescriptor: Must override GetTypeDescriptor() to return CustomConverterDescriptor first -CustomConverterDescriptor#58;CustomTypeDescriptor->>CustomTypeConverter#58;TypeConverter: CustomConverterDescriptor.GetConverter() -note over CustomConverterDescriptor#58;CustomTypeDescriptor,CustomTypeConverter#58;TypeConverter: Must override GetConverter() to return CustomTypeConverter first -``` \ No newline at end of file diff --git a/docs/src/System/Windows/Forms/TaskDialog/Issue_AccessViolation_NavigationInButtonClicked.md b/docs/src/System/Windows/Forms/TaskDialog/Issue_AccessViolation_NavigationInButtonClicked.md deleted file mode 100644 index 31a525b6be0..00000000000 --- a/docs/src/System/Windows/Forms/TaskDialog/Issue_AccessViolation_NavigationInButtonClicked.md +++ /dev/null @@ -1,99 +0,0 @@ -# Windows Task Dialog Issue - -## Access Violation when receiving [`TDN_NAVIGATED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-navigated) within [`TDN_BUTTON_CLICKED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-button-clicked) - -An Access violation can occur when receiving a navigation notification ([`TDN_NAVIGATED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-navigated)) -within a [`TDN_BUTTON_CLICKED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-button-clicked) -notification (e.g. due to running the message loop) and then returning `S_OK`. - -* Run the code. -* Click on the "My Custom Button" button. -* Notice that the dialog navigates and an inner dialog shows. -* Close the inner dialog by clicking the OK button. -* **Issue:** In most cases, an access violation occurs now (if not, try again a - few times). -* Notice the problem also occurs when you (after the navigation) first close - the original dialog, and then close the inner dialog. -* The problem can be avoided by returning `S_FALSE` from the `TDN_BUTTON_CLICKED` - notification. - -```cpp -#include "stdafx.h" -#include "CommCtrl.h" - -HRESULT WINAPI TaskDialogCallbackProc(_In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ LONG_PTR lpRefData) -{ - switch (msg) { - case TDN_BUTTON_CLICKED: - if (wParam == 100) { - TASKDIALOGCONFIG* navigationConfig = new TASKDIALOGCONFIG; - *navigationConfig = { 0 }; - navigationConfig->cbSize = sizeof(TASKDIALOGCONFIG); - - navigationConfig->pszMainInstruction = L"After navigation !!!"; - navigationConfig->pszContent = L"Text"; - navigationConfig->pszMainIcon = MAKEINTRESOURCEW(0xFFF7); - - // Navigate the dialog. - SendMessageW(hwnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)navigationConfig); - delete navigationConfig; - - // After that, run the event loop by show an inner dialog. - TaskDialog(nullptr, nullptr, L"Inner Dialog", L"Inner Dialog", nullptr, 0, 0, nullptr); - } - - break; - } - - return S_OK; -} - -void ShowTaskDialogNavigationInButtonClickedNotification() -{ - TASKDIALOGCONFIG* tConfig = new TASKDIALOGCONFIG; - *tConfig = { 0 }; - tConfig->cbSize = sizeof(TASKDIALOGCONFIG); - - tConfig->nDefaultRadioButton = 100; - tConfig->pszMainInstruction = L"Before navigation"; - tConfig->pfCallback = TaskDialogCallbackProc; - - // Create 50 radio buttons. - int radioButtonCount = 50; - TASKDIALOG_BUTTON* radioButtons = new TASKDIALOG_BUTTON[radioButtonCount]; - for (int i = 0; i < radioButtonCount; i++) { - radioButtons[i].nButtonID = 100 + i; - radioButtons[i].pszButtonText = L"My Radio Button"; - } - tConfig->pRadioButtons = radioButtons; - tConfig->cRadioButtons = radioButtonCount; - - // Create a custom button. - TASKDIALOG_BUTTON* customButton = new TASKDIALOG_BUTTON; - customButton->nButtonID = 100; - customButton->pszButtonText = L"My Custom Button"; - tConfig->pButtons = customButton; - tConfig->cButtons = 1; - - int nButton, nRadioButton; - BOOL checkboxSelected; - TaskDialogIndirect(tConfig, &nButton, &nRadioButton, &checkboxSelected); - - delete customButton; - delete radioButtons; - delete tConfig; -} - -int APIENTRY wWinMain(_In_ HINSTANCE hInstance, - _In_opt_ HINSTANCE hPrevInstance, - _In_ LPWSTR lpCmdLine, - _In_ int nCmdShow) -{ - UNREFERENCED_PARAMETER(hPrevInstance); - UNREFERENCED_PARAMETER(lpCmdLine); - - ShowTaskDialogNavigationInButtonClickedNotification(); - - return 0; -} -``` \ No newline at end of file diff --git a/docs/src/System/Windows/Forms/TaskDialog/Issue_AccessViolation_NavigationInRadioButtonClicked.md b/docs/src/System/Windows/Forms/TaskDialog/Issue_AccessViolation_NavigationInRadioButtonClicked.md deleted file mode 100644 index 37519e57cd6..00000000000 --- a/docs/src/System/Windows/Forms/TaskDialog/Issue_AccessViolation_NavigationInRadioButtonClicked.md +++ /dev/null @@ -1,85 +0,0 @@ -# Windows Task Dialog Issue - -## Access Violation when receiving [`TDN_NAVIGATED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-navigated) within [`TDN_RADIO_BUTTON_CLICKED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-radio-button-clicked) - -An Access Violation occurs when receiving a navigation notification -([`TDN_NAVIGATED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-navigated)) -within a [`TDN_RADIO_BUTTON_CLICKED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-radio-button-clicked) -notification (e.g. due to running the message loop). - -* Run the code and select one of the radio buttons. -* Notice the dialog has navigated and an inner dialog is opened. -* Close the inner dialog. -* **Issue:** Notice the application crashes with an access violation. - -```cpp -#include "stdafx.h" -#include "CommCtrl.h" - -HRESULT WINAPI TaskDialogCallbackProc(_In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ LONG_PTR lpRefData) -{ - switch (msg) { - case TDN_RADIO_BUTTON_CLICKED: - // When the user clicked the second radio button, navigate the dialog, then show an inner dialog. - - // Navigate - TASKDIALOGCONFIG* navigationConfig = new TASKDIALOGCONFIG; - *navigationConfig = { 0 }; - navigationConfig->cbSize = sizeof(TASKDIALOGCONFIG); - - navigationConfig->pszMainInstruction = L"After navigation !!"; - - SendMessageW(hwnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)navigationConfig); - delete navigationConfig; - - // After navigating, run the event loop by showing an inner dialog. - TaskDialog(nullptr, nullptr, L"Inner Dialog", L"Inner Dialog", nullptr, 0, 0, nullptr); - - break; - } - - return S_OK; -} - -void ShowTaskDialogRadioButtonsBehavior() -{ - TASKDIALOGCONFIG* tConfig = new TASKDIALOGCONFIG; - *tConfig = { 0 }; - tConfig->cbSize = sizeof(TASKDIALOGCONFIG); - - tConfig->dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON; - tConfig->pszMainInstruction = L"Before Navigation"; - tConfig->pfCallback = TaskDialogCallbackProc; - - // Create 2 radio buttons. - int radioButtonCount = 2; - - TASKDIALOG_BUTTON* radioButtons = new TASKDIALOG_BUTTON[radioButtonCount]; - for (int i = 0; i < radioButtonCount; i++) { - radioButtons[i].nButtonID = 100 + i; - radioButtons[i].pszButtonText = i == 0 ? L"Radio Button 1" : L"Radio Button 2"; - } - tConfig->pRadioButtons = radioButtons; - tConfig->cRadioButtons = radioButtonCount; - - int nButton, nRadioButton; - BOOL checkboxSelected; - TaskDialogIndirect(tConfig, &nButton, &nRadioButton, &checkboxSelected); - - delete radioButtons; - delete tConfig; -} - -int APIENTRY wWinMain(_In_ HINSTANCE hInstance, - _In_opt_ HINSTANCE hPrevInstance, - _In_ LPWSTR lpCmdLine, - _In_ int nCmdShow) -{ - UNREFERENCED_PARAMETER(hPrevInstance); - UNREFERENCED_PARAMETER(lpCmdLine); - - ShowTaskDialogRadioButtonsBehavior(); - - return 0; -} -``` \ No newline at end of file diff --git a/docs/src/System/Windows/Forms/TaskDialog/Issue_ButtonClickHandlerCalledTwice.md b/docs/src/System/Windows/Forms/TaskDialog/Issue_ButtonClickHandlerCalledTwice.md deleted file mode 100644 index 5fe0db805f9..00000000000 --- a/docs/src/System/Windows/Forms/TaskDialog/Issue_ButtonClickHandlerCalledTwice.md +++ /dev/null @@ -1,95 +0,0 @@ -# Windows Task Dialog Issue - -## [`TDN_BUTTON_CLICKED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-button-clicked) notification sent twice when pressing a button with its access key - -When you "click" a button by pressing its access key (mnemonic) and the dialog -is still open when the message loop continues, the [`TDN_BUTTON_CLICKED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-button-clicked) -notification is sent twice instead of once. - -* Run the code. -* Click one of the buttons with the mouse, or press space or enter, and notice - that the counter increments by 1. -* **Issue:** Press Alt+M or Alt+N and - notice the counter increments by 2. - -```cpp -#include "stdafx.h" -#include "CommCtrl.h" - -int counter = 0; -wchar_t* counterTextBuffer; -HRESULT WINAPI ShowTaskDialogButtonClickHandlerCalledTwice_Callback(_In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ LONG_PTR lpRefData) { - switch (msg) { - case TDN_BUTTON_CLICKED: - // Increment the counter. - counter++; - swprintf_s(counterTextBuffer, 100, L"Counter: %d", counter); - SendMessageW(hwnd, TDM_SET_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)counterTextBuffer); - - // When the user clicks the custom button, return false so that the dialog - // stays open. - if (wParam == 100) { - return S_FALSE; - } - else if (wParam == IDNO) { - // Otherwise, when the user clicks the common button, run the message loop. - MSG msg; - int bRet; - while ((bRet = GetMessageW(&msg, nullptr, 0, 0)) != 0) { - if (bRet == -1) { - // Error - } - else { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - } - } - - break; - } - - return S_OK; -} - -void ShowTaskDialogButtonClickHandlerCalledTwice() { - counterTextBuffer = new wchar_t[100]; - - TASKDIALOGCONFIG* tConfig = new TASKDIALOGCONFIG; - *tConfig = { 0 }; - tConfig->cbSize = sizeof(TASKDIALOGCONFIG); - - tConfig->dwFlags = TDF_USE_COMMAND_LINKS; - tConfig->pszMainInstruction = L"Text..."; - tConfig->pfCallback = ShowTaskDialogButtonClickHandlerCalledTwice_Callback; - - // Create a custom button and a common ("No") button. - tConfig->dwCommonButtons = TDCBF_NO_BUTTON; - - TASKDIALOG_BUTTON customButton = { 0 }; - customButton.nButtonID = 100; - customButton.pszButtonText = L"&My Button"; - tConfig->pButtons = &customButton; - tConfig->cButtons = 1; - - int nButton, nRadioButton; - BOOL checkboxSelected; - TaskDialogIndirect(tConfig, &nButton, &nRadioButton, &checkboxSelected); - - delete tConfig; - delete[] counterTextBuffer; -} - -int APIENTRY wWinMain(_In_ HINSTANCE hInstance, - _In_opt_ HINSTANCE hPrevInstance, - _In_ LPWSTR lpCmdLine, - _In_ int nCmdShow) -{ - UNREFERENCED_PARAMETER(hPrevInstance); - UNREFERENCED_PARAMETER(lpCmdLine); - - ShowTaskDialogButtonClickHandlerCalledTwice(); - - return 0; -} -``` \ No newline at end of file diff --git a/docs/src/System/Windows/Forms/TaskDialog/Issue_RadioButton_InfiniteLoop.md b/docs/src/System/Windows/Forms/TaskDialog/Issue_RadioButton_InfiniteLoop.md deleted file mode 100644 index f728f9e9d74..00000000000 --- a/docs/src/System/Windows/Forms/TaskDialog/Issue_RadioButton_InfiniteLoop.md +++ /dev/null @@ -1,76 +0,0 @@ -# Windows Task Dialog Issue - -## Infinite loop with radio buttons - -An infinite loop occurs when sending a -[`TDM_CLICK_RADIO_BUTTON`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdm-click-radio-button) message within a -[`TDN_RADIO_BUTTON_CLICKED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-radio-button-clicked) notification. - -* Run the code and select the second radio button. -* **Issue:** Notice that the GUI doesn't respond any more. When debugging, you can see that - the callback is flooded with `TDN_RADIO_BUTTON_CLICKED` notifications even though we - don't send any more messages to the dialog. - -```cpp -#include "stdafx.h" -#include "CommCtrl.h" - -bool done = false; -HRESULT WINAPI TaskDialogCallbackProc(_In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ LONG_PTR lpRefData) -{ - switch (msg) { - case TDN_RADIO_BUTTON_CLICKED: - // When the user clicked the second radio button, select the first one. - // However, do this only once. - if (wParam == 101 && !done) { - done = true; - SendMessageW(hwnd, TDM_CLICK_RADIO_BUTTON, 100, 0); - } - break; - } - - return S_OK; -} - -void ShowTaskDialogRadioButtonsBehavior() -{ - TASKDIALOGCONFIG* tConfig = new TASKDIALOGCONFIG; - *tConfig = { 0 }; - tConfig->cbSize = sizeof(TASKDIALOGCONFIG); - - tConfig->dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON; - tConfig->pszMainInstruction = L"Radio Button Example"; - tConfig->pfCallback = TaskDialogCallbackProc; - - // Create 2 radio buttons. - int radioButtonCount = 2; - - TASKDIALOG_BUTTON* radioButtons = new TASKDIALOG_BUTTON[radioButtonCount]; - for (int i = 0; i < radioButtonCount; i++) { - radioButtons[i].nButtonID = 100 + i; - radioButtons[i].pszButtonText = i == 0 ? L"Radio Button 1" : L"Radio Button 2"; - } - tConfig->pRadioButtons = radioButtons; - tConfig->cRadioButtons = radioButtonCount; - - int nButton, nRadioButton; - BOOL checkboxSelected; - TaskDialogIndirect(tConfig, &nButton, &nRadioButton, &checkboxSelected); - - delete radioButtons; - delete tConfig; -} - -int APIENTRY wWinMain(_In_ HINSTANCE hInstance, - _In_opt_ HINSTANCE hPrevInstance, - _In_ LPWSTR lpCmdLine, - _In_ int nCmdShow) -{ - UNREFERENCED_PARAMETER(hPrevInstance); - UNREFERENCED_PARAMETER(lpCmdLine); - - ShowTaskDialogRadioButtonsBehavior(); - - return 0; -} -``` \ No newline at end of file diff --git a/docs/src/System/Windows/Forms/TaskDialog/Issue_RadioButton_WeirdBehavior.md b/docs/src/System/Windows/Forms/TaskDialog/Issue_RadioButton_WeirdBehavior.md deleted file mode 100644 index e4b3ce23614..00000000000 --- a/docs/src/System/Windows/Forms/TaskDialog/Issue_RadioButton_WeirdBehavior.md +++ /dev/null @@ -1,115 +0,0 @@ -# Windows Task Dialog Issue - -## Weird behavior with radio buttons - -Weird behavior occurs when running the message loop within an -[`TDN_RADIO_BUTTON_CLICKED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-radio-button-clicked) -notification. - -* Run the code. -* Notice that within the - [`TDN_TIMER`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-timer) notification, a - [`TDM_CLICK_RADIO_BUTTON`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdm-click-radio-button) is - sent to select the second radio button which causes an inner dialog to be shown within - the [`TDN_RADIO_BUTTON_CLICKED`](https://docs.microsoft.com/en-us/windows/desktop/Controls/tdn-radio-button-clicked) - notification, but the radio button is only selected after - the inner dialog is closed (and therefore the notification handler returns).
- While that seems like a strange/undesired behavior, it is actually the documented behavior: - > "The specified radio button ID is sent to the TaskDialogCallbackProc callback function - as part of a TDN_RADIO_BUTTON_CLICKED notification code. After the callback function - returns, the radio button will be selected." - - (For the .NET implementation that has the `TaskDialogRadioButton.CheckedChanged` event - that is expected to show already the new state, this can be worked-around by ignoring - `TDN_RADIO_BUTTON_CLICKED` notifications caused by the code itself, and instead raising - the events after sending the `TDM_CLICK_RADIO_BUTTON` message.) - However, this special behavior might be related to the following issue (and the other - code samples regarding radio buttons): -* When you click one of the radio buttons and then immediately close the inner dialog, - everything works. -* Now try the following: Click the first radio button (but do NOT close the inner dialog), - then click the second radio button. -* Now close the most inner dialog (showing call count 2), and then the other inner dialog. -* **Issue:** Notice that the dialog changed the selection of the radio button and shows the inner - dialog again. When you close it, even more inner dialogs open. -* During that time, when you focus the original dialog, it will switch the selected radio - button again. - -```cpp -#include "stdafx.h" -#include "CommCtrl.h" - -int callCount = 0; -int timerCounter = 0; -HRESULT WINAPI TaskDialogCallbackProc(_In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ LONG_PTR lpRefData) -{ - switch (msg) { - case TDN_TIMER: - if (timerCounter < 4) { - timerCounter++; - } - else if (timerCounter == 4) { - timerCounter++; - - // Select the second radio button. - SendMessageW(hwnd, TDM_CLICK_RADIO_BUTTON, 101, 0); - } - - break; - - case TDN_RADIO_BUTTON_CLICKED: - callCount++; - wchar_t* instruction = new wchar_t[200]; - swprintf_s(instruction, 100, L"InnerDialog - CallCount: %d", callCount); - TaskDialog(nullptr, nullptr, L"Inner Dialog", instruction, nullptr, 0, 0, nullptr); - delete instruction; - callCount--; - - break; - } - - return S_OK; -} - -void ShowTaskDialogRadioButtonsBehavior() -{ - TASKDIALOGCONFIG* tConfig = new TASKDIALOGCONFIG; - *tConfig = { 0 }; - tConfig->cbSize = sizeof(TASKDIALOGCONFIG); - - tConfig->dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON | TDF_CALLBACK_TIMER; - tConfig->pszMainInstruction = L"Radio Button Example"; - tConfig->pfCallback = TaskDialogCallbackProc; - - // Create 2 radio buttons. - int radioButtonCount = 2; - - TASKDIALOG_BUTTON* radioButtons = new TASKDIALOG_BUTTON[radioButtonCount]; - for (int i = 0; i < radioButtonCount; i++) { - radioButtons[i].nButtonID = 100 + i; - radioButtons[i].pszButtonText = i == 0 ? L"Radio Button 1" : L"Radio Button 2"; - } - tConfig->pRadioButtons = radioButtons; - tConfig->cRadioButtons = radioButtonCount; - - int nButton, nRadioButton; - BOOL checkboxSelected; - TaskDialogIndirect(tConfig, &nButton, &nRadioButton, &checkboxSelected); - - delete radioButtons; - delete tConfig; -} - -int APIENTRY wWinMain(_In_ HINSTANCE hInstance, - _In_opt_ HINSTANCE hPrevInstance, - _In_ LPWSTR lpCmdLine, - _In_ int nCmdShow) -{ - UNREFERENCED_PARAMETER(hPrevInstance); - UNREFERENCED_PARAMETER(lpCmdLine); - - ShowTaskDialogRadioButtonsBehavior(); - - return 0; -} -``` \ No newline at end of file diff --git a/docs/testing-in-vs.md b/docs/testing-in-vs.md deleted file mode 100644 index 16b846dc5fd..00000000000 --- a/docs/testing-in-vs.md +++ /dev/null @@ -1,69 +0,0 @@ -# Windows Forms Testing in Visual Studio - -Visual Studio executes unit tests differently from the command line. This page describes some of those differences and covers common problems and workarounds. - -## Assert.Same() failures - -### Problem - -`Assert.Same()` calls that pass when running tests from the command line can often fail when running through Visual Studio. This has to do with a quirk in the xUnit Visual Studio test adapter. - -### Cause - -* When using `[Theory]` combined with `[InlineData]`, `[ClassData]`, or `[MemberData]`, the xUnit VS test adapter does performs "discovery enumeration", before the test is actually executed - * It does this to populate the Test Explorer window with all the test cases before they run -* The process running this enumeration executes in a **different App domain** than the tests themselves -* This means objects passed in to the test methods have **different references** than expected (when comparing strings, for example) - -### Solution(s) - -There are two ways to get around this problem: - -1. Use a custom *DataAttribute (inheriting from the appropriate *DataAttributeBase class) and set `DisableDiscoveryEnumeration = true` in the constructor - * For an example of this, see [MauiDataAttribute.cs](https://github.com/dotnet/winforms/blob/afa8a0779f261e46fe7eb1611142bea143622578/src/System.Windows.Forms/tests/IntegrationTests/System.Windows.Forms.Maui.IntegrationTests/MauiDataAttribute.cs#L42) - * This is not really preferred, and should only be used when your test data can't be resolved at compile-time - - OR - -1. Use Assert.Equal() when comparing against objects created by `[InlineData]`, `[ClassData]`, or `[MemberData]` - * You can still use Assert.Same() in all other cases - -## Tests don't execute - -### Problem - -* When launching tests through Visual Studio, no tests execute -* Click on `View -> Output` and select `Tests` from the `Show output from:` dropdown -* You might see an error that looks like `Testhost process exited with error: It was not possible to find any compatible framework version. The specified framework 'Microsoft.NETCore.App', version 'XXX' was not found` - -### Cause (long) - -* The .net core SDK and the .net core runtime (Microsoft.NetCore.App) are two different things. -* The SDK targets a specific NetCore.App. This version is automatically downloaded into your local .dotnet folder when you build from command line, and is also installed when you install a dotnet sdk machine-wide. - * If you don’t specify an explicit NetCore.App version, you will use the one that the SDK targets. - * If you’re interested in seeing what this version is, look at `\.dotnet\sdk\\dotnet.runtimeconfig.json` -* The winforms (runtime) repo DOES specify an explicit NetCore.App version, and we use the one published by the core-setup repo. - * If you look at [Directory.Build.Targets](https://github.com/dotnet/winforms/blob/ac0426561b158522eb8564de2bedd28f28148f8d/Directory.Build.targets#L35), you can see where this is set -* `$(VSRedistCommonNetCoreSharedFrameworkx6480PackageVersion)` is set in [Versions.props](https://github.com/dotnet/winforms/blob/ac0426561b158522eb8564de2bedd28f28148f8d/eng/Versions.props#L19), and gets automatically updated when we ingest dependencies from core-setup. (These PR's are automatically merged in if the build passes) - * You can see where the dependency comes from by looking at [Version.Details.xml](https://github.com/dotnet/winforms/blob/ac0426561b158522eb8564de2bedd28f28148f8d/eng/Version.Details.xml#L13) - * The reason we use the version from core-setup instead of the version built-in to the SDK is we don’t want to wait for the runtime to come all the way through the SDK repo to consume it -* Running tests from the command line (.\build -test) works because the build scripts automatically download both the sdk AND the NetCore.App that you need AND add the .dotnet folder to your PATH when running. - * You can verify this by checking the .dotnet folder in your repo root. The NetCore.App is in the shared folder. -* However, Visual Studio doesn’t care about your local .dotnet folder. It always looks at your machine-wide installs (unless you manually add things to your PATH before launching VS) - * If you don’t have the required SDK installed machine-wide, your code won’t build (through VS). - * If you don’t have the required NetCore.App installed machine-wide, your code won’t run (through VS). -* **This is why unit tests can fail immediately through VS.** - * Note that just installing the SDK **IS NOT ENOUGH** if you are using an explicit NetCore.App version. -* Since the command line builds automatically download everything you need, we just have to tell VS where this stuff lives - -### Solution(s) - -There are two ways to get around this problem: - -1. Add your local `\.dotnet` folder to the front of your PATH variable - * This is **not preferred** because Visual Studio will always look here first, and can break other things, like if you need to build against a higher version of the SDK - - OR - -1. Close VS, run `\build-local.ps1`, then re-open VS - * This will do a restore (to download the stuff), do a build, then symlink the stuff you need from your local .dotnet folder to your machine-wide SDK install folder `(C:\Program Files\dotnet\...)`. Then VS will know about it too 😊 diff --git a/docs/testing.md b/docs/testing.md deleted file mode 100644 index 957d524b48e..00000000000 --- a/docs/testing.md +++ /dev/null @@ -1,335 +0,0 @@ -# Windows Forms Testing - -This document describes our approach to testing. - -* [Building tests](#building-tests) -* [Unit Tests](#unit-tests) - * [Running unit tests](#running-unit-tests) - - [Unit testing from the command line](#unit-testing-from-the-command-line) - - [Troubleshooting command-line unit test errors](#troubleshooting-command-line-unit-test-errors) - - [Unit testing from Visual Studio](#unit-testing-from-visual-studio) - - [Troubleshooting Visual Studio unit test errors](#troubleshooting-visual-studio-unit-test-errors) - * [Adding new unit tests](#adding-new-unit-tests) - - [Test placement](#therefore-you-just-need-to-put-your-tests-in-the-right-place-in-order-for-them-to-run) - - [Unit Test best practices](#unit-test-best-practices) - - [Naming](#naming) - - [Decoration](#decoration) - - [Disposal](#dispose-created-objects) - - [Theory tests](#theory-tests#theory-tests) - - [Throw unhandled exceptions](#throw-unhandled-exceptions) -* [Rendering Tests](#rendering-tests) -* [Functional Tests](#functional-tests) - * [Running functional tests](#running-functional-tests) - - [Functional testing from the command line](#functional-testing-from-the-command-line) - - [Troubleshooting command-line functional test errors](#troubleshooting-command-line-functional-test-errors) - - [Functional testing from Visual Studio](#functional-testing-from-visual-studio) - - [Troubleshooting Visual Studio functional test errors](#troubleshooting-visual-studio-functional-test-errors) - * [Adding new functional tests](#adding-new-functional-tests) - - [Test placement](#therefore-you-just-need-to-put-your-tests-in-the-right-place-in-order-for-them-to-run-1) - * [Testing for Accessibility](#testing-for-accessibility) - * [Running and debugging crashed tests](#running-and-debugging-crashed-tests) - - -# Building tests - -Tests are automatically built when running `.\build` since all test projects are referenced in `Winforms.sln` at the repository root. - -# Unit Tests - -## Running unit tests - -### Unit testing from the command line - -To execute unit tests, run `.\build -test` - -If all the tests are successful, you should see something like this: - -```console - Running tests: E:\src\repos\github\winforms\artifacts\bin\System.Windows.Forms.Tests\Debug\net6.0\System.Windows.Forms.Tests.dll [net6.0|x64] - Tests succeeded: E:\src\repos\github\winforms\artifacts\bin\System.Windows.Forms.Tests\Debug\net6.0\System.Windows.Forms.Tests.dll [net6.0|x64] - -Build succeeded. - 0 Warning(s) - 0 Error(s) -``` - -### Troubleshooting command-line unit test errors - -When testing from the command line, a failed test should look something like this: - -```console -Running tests: E:\src\repos\github\winforms\artifacts\bin\System.Windows.Forms.Tests\Debug\net6.0\System.Windows.Forms.Tests.dll [net6.0|x64] -XUnit : error : Tests failed: E:\src\repos\github\winforms\artifacts\TestResults\Debug\System.Windows.Forms.Tests_net6.0_x64.html [net6.0|x64] [E:\src\repos\github\winforms\src\System.Windows.Forms\tests\UnitTests\System.Windows.Forms.Tests.csproj] -XUnit : error : Tests failed: E:\src\repos\github\winforms\artifacts\TestResults\Debug\System.Windows.Forms.Tests_net6.0_x64.html [net6.0|x64] [E:\src\repos\github\winforms\src\System.Windows.Forms\tests\UnitTests\System.Windows.Forms.Tests.csproj] - -Build FAILED. -``` - -* The test summary can be found under artifacts\log -* To see the actual test(s) that failed, along with their error message(s), open the .html file that is displayed in the error message (which is always under `artifacts\TestResults`) - -### Unit testing from Visual Studio - -To test from Visual Studio, start Visual Studio via `.\start-vs.cmd`, and test how you normally would (using the Test Explorer, for example) - -### Troubleshooting Visual Studio unit test errors - -* When testing from Visual Studio, test errors show up as normal in the Test Explorer. -* To troubleshoot, debug the selected test and set breakpoints as you normally would. -* For common issues when running tests through Visual Studio, see [Testing in Visual Studio](testing-in-vs.md) - -## Adding new unit tests - -Tests are built and executed by file name convention - -* Every WinForms binary has its own folder under src in the repository root (src\System.Windows.Forms, for example) -* Each of those folders has a tests folder under it (src\System.Windows.Forms\tests, for example) -* Each tests folder contains an xUnit test project (System.Windows.Forms.Tests.csproj) - * These test projects automatically build when running `.\build` - * The tests from these projects automatically execute when running `.\build -test`.
- It is also possible to execute individual tests via `dotnet test --filter ` command by switching to the desired test project directory first. - - -### Therefore, you just need to put your tests in the right place in order for them to run - -* Browse to the tests folder for the binary you are testing. -* There should be one file per class being tested, and the file name should match the class name followed by a "**Tests**" suffix. - * For example, if I wanted to test the `Button` class in System.Windows.Forms.dll, I would look for a **ButtonTests.cs** under src\System.Windows.Forms\tests. - * For example, if I wanted to test the `Button.ButtonAccessibleObject` class in System.Windows.Forms.dll, I would look for a **Button.ButtonAccessibleObjectTests.cs** under src\System.Windows.Forms\tests. -* If the file exists, add your tests there. If it doesn't exist, feel free to create it. - * **Note that you don't have to modify the csproj at all.** Since the project is a Microsoft.NET.Sdk project, all source files next to it are automatically included. - -### Unit Test best practices - -#### Naming - -* Test files names should match the class they are testing followed by a "**Tests**" suffix. - * For example, tests for the `Button` class should be in ButtonTests.cs. - * For example, tests for the `Button.ButtonAccessibleObject` class should be in **Button.ButtonAccessibleObjectTests.cs**. -* Test class names should match the class they are testing, followed by a "**Tests**" suffix. - * For example, tests for the `Button` class should in the `ButtonTests` class. - * For example, tests for the `Button.ButtonAccessibleObject` class should in the `Button_ButtonAccessibleObjectTests` class. -* Test names should start with the class they are testing. - * For example, all tests for the `Button` class should start with "Button". -* Test names should end with a description of what the test does - this is very useful when viewing test results, and when browsing in the test explorer. As far as naming conventions are concerned we don't mandate a specific one, as long as a test name clearly communicates its purpose. - * For example, `Button_AutoSizeModeGetSet` or `MyButton_Click_should_throw_ArgumentNullException`. - -#### Decoration - -* All tests that deal with UI controls or types that require synchronization context must be decorated with `WinFormsFact` or `WinFormsTheory` attributes. -* Other tests can be decorated with `StaFact`, `StaTheory`, `Fact` or `Theory` - -#### Dispose created objects - -* All tests creating disposable objects (e.g. UI controls) must dispose them. Otherwise it could lead to memory leaks (bad but not terminal) and race conditions that could lead to deadlocked tests (terminal). - ```cs - [WinFormsFact] - public void ButtonBase_GetAutoSizeMode_Invoke_ReturnsExpected() - { - using SubButtonBase control = new(); - Assert.Equal(AutoSizeMode.GrowOnly, control.GetAutoSizeMode()); - } - ``` - -#### Theory tests - -Quite often there may be multiple tests that test exactly the same functionality but with different input parameters (e.g. `null`, `""`, `" "` for a `string` argument). -In such cases instead of creating multiple tests it is preferred to have a theory test, which is in another words a data-driven test. - -When writing theories note the following: - -1. theory test must be [correctly decorated](#Decoration) - -2. theories must avoid creating UI controls. E.g. instead of writing: - ```cs - public static IEnumerable GetButton_TestData() - { - yield return new object[] { new Button() }; - yield return new object[] { new Button() { Text = "bla" } }; - } - - [WinFormsTheory] - [MemberData(nameof(GetButton_TestData))] - public void Ctor_Control_DataGridViewCellStyle(Button button) { ... } - ``` - prefer the following: - ```cs - public static IEnumerable GetButton_TestData() - { - yield return new object[] { string.Empty }; - yield return new object[] { "bla" }; - } - - [WinFormsTheory] - [MemberData(nameof(GetButton_TestData))] - public void Ctor_Control_DataGridViewCellStyle(string buttonText) - { - using Button button = new() { Text = buttonText }; - ... - } - ``` - -3. theories must not reuse disposable components.
- In situations where following the above recommendation could be impractical, it is maybe acceptable to create disposable controls for each theory data, e.g.: - ```cs - public static IEnumerable GetButton_TestData() - { - yield return new object[] { new Button(), new DataGridViewCellStyle() }; - yield return new object[] { new Button() { Text = "bla" }, new DataGridViewCellStyle() }; - } - ``` - xUnit tries its best to [dispose](https://github.com/xunit/xunit/blob/56476a9691bb061661190b183733c5d8a2c6ef4d/src/xunit.execution/Sdk/Frameworks/TestMethodTestCase.cs#L191-L197) of disposable objects. - However objects must not be shared across theories, as it could lead to unknown state, e.g. - ```cs - // ** DO NOT DO THIS! ** - public static IEnumerable GetButton_TestData() - { - Button button = new(); - yield return new object[] { button, new DataGridViewCellStyle() }; - yield return new object[] { button { Text = "bla" }, new DataGridViewCellStyle() }; // the button could already be disposed by the time this theory runs - } - ``` - - -Also be beware and be mindful of VS-specific behaviours: https://xunit.net/faq/theory-data-stability-in-vs - - -#### Strategy - -##### Unit tests should be part of the same PR as code changes - -* Unit tests must be added for any change to public APIs. -* We will accept unit tests for internal/private methods as well. Some non-public API can be accessed directly (e.g. `internal`), some via subclassing (e.g. `virtual`) or via the public surface. However there are plenty of instances where a non-public API can't be easily accessed or arranged for. In this cases we use [`TestAccessor` pattern](https://github.com/dotnet/winforms/blob/main/src/System.Windows.Forms.Primitives/tests/TestUtilities/TestAccessor.cs) to arrange, act and assert. - -##### Code Coverage - -* In Visual Studio Test Explorer, select all tests, right click and execute 'Analyze code coverage for selected tests' command. This will run all tests and give a summary of blocks covered in 'Code Coverage Results' window. The summary can be drilled down to method level. -* Any code change accompanied with unit tests is expected to increase code coverage for the code modified. - -##### Avoid duplicating tests just for different inputs - -* Use `WinFormsTheory`, `StaTheory` or `Theory` attributes for this, followed by either `[InlineData]` or `[MemberData]`. See existing tests for examples on how to use these attributes -* The exception to this is if the code behavior is fundamentally different based on the inputs. For example, if a method throws an `ArgumentException` for invalid inputs, that should be a separate test. - -##### One test (or test data) per code path please - -* The most common exception to this is when testing a property, most people test get/set together - -##### Whenever possible, mock up dependencies to run tests in isolation - -* For example, if your method accepts an abstraction, use Moq to mock it up -* Search for Mock in the existing tests for examples, and see [Moq](https://github.com/Moq/moq4/wiki/Quickstart) for details on how to use Moq. - - -# Rendering Tests - -We use [Enhance Metafiles](https://docs.microsoft.com/windows/win32/gdi/enhanced-format-metafiles) (or EMF for short) to validate rendering operations, i.e. assert that correct shapes were drawn with expected colours and brushes. - -A typical "rendering" assertion test would looks something like this: -```cs -[WinFormsFact] -public void MyControl_Rendering() -{ - // 1. Create a control to validate rendering for. - // 2. Add the control to a form, and make sure the form is created - using Form form = new Form(); - using MyControl control = new() { ... }; - form.Controls.Add(control); - Assert.NotEqual(IntPtr.Zero, form.Handle); - - // Create an Enhance Metafile into which we will render the control - using EmfScope emf = new(); - DeviceContextState state = new DeviceContextState(emf); - - // Render the control - control.PrintToMetafile(emf); - - // We can see the rendering steps by invoking this command: - // string records = emf.RecordsToString(); - - // Assert the rendering was as expected - emf.Validate( - state, - ... - ); -} -``` - - -# Functional Tests - -> :warning: There is a very blurry line between unit and functional tests in Windows Forms realm. A lot of our implementations depend on ambient contexts (such as Win32, COM, etc.). We classify tests as "functional" or "integration" that require process-wide settings (such as visual styles) or require user-like interactions (e.g. mouse gestures). - -Currently, there is a single functional test suite in the repository: the **WinformsControlsTest**. There is an xUnit project that executes various commands against this binary. - -## Running functional tests - -### Functional testing from the command line - -To execute functional tests, run `.\build -integrationTest` - -You will see various windows open and close very quickly. If all the tests are successful, you should see something like this: - -```console - Running tests: E:\src\repos\github\winforms\artifacts\bin\System.Windows.Forms.IntegrationTests\Debug\net6.0\System.Windows.Forms.IntegrationTests.dll [net6.0|x64] - Tests succeeded: E:\src\repos\github\winforms\artifacts\bin\System.Windows.Forms.IntegrationTests\Debug\net6.0\System.Windows.Forms.IntegrationTests.dll [net6.0|x64] - -Build succeeded. - 0 Warning(s) - 0 Error(s) -``` - - - -### Troubleshooting command-line functional test errors - -Since these run in xUnit, functional test errors can be examined in the same way as unit test failures. - -### Functional testing from Visual Studio - -To test from Visual Studio, open Winforms.sln in Visual Studio and test how you normally would (using the Test Explorer, for example) - -### Troubleshooting Visual Studio functional test errors - -* When testing from Visual Studio, test errors show up as normal in the test explorer. -* To troubleshoot, debug the selected test and set breakpoints as you normally would. - -## Adding new functional tests - -Functional tests are built and executed by file name convention - -* Every WinForms binary has its own folder under src in the repository root (src\System.Windows.Forms, for example) -* Each of those folders has a tests folder under it (src\System.Windows.Forms\tests, for example), each of which may contain an IntegrationTests folder -* Each of these folders contains an IntegrationTest xUnit project (System.Windows.Forms.IntegrationTests.csproj) - * These test projects automatically build when running `.\build` - * The tests from these projects automatically execute when running `.\build -integrationTest` - -### Therefore, you just need to put your tests in the right place in order for them to run - -* Browse to the tests folder for the binary you are testing -* There should be one file per class being tested, and the file name should match the class name. - * For example, if I wanted to test the `Button` class in System.Windows.Forms.dll, I would look for a Button.cs under src\System.Windows.Forms\tests -* If the file exists, add your tests there. If it doesn't exist, feel free to create it. - * **Note that you don't have to modify the csproj at all.** Since the project is a Microsoft.NET.Sdk project, all source files next to it are automatically included - - -# Testing for Accessibility - -Our goal is to make writing accessible WinForms applications easy. Specifically, all default property values should yield accessible experience. To test that controls are accessible, find or add the changed control to [AccessibilityTests application](https://github.com/dotnet/winforms/tree/main/src/System.Windows.Forms/tests/AccessibilityTests) and run [Accessibility Insights for Windows](https://accessibilityinsights.io/docs/en/windows/overview) on it. - - -# Running and debugging crashed tests - -At times tests may fail in way that makes it difficult to debug (e.g., the [test runner process crashes](https://github.com/dotnet/runtime/issues/76219)). In this case, it's good to replicate the issue locally and collect a memory dump to have a better understanding whether the issue is caused by the change in Windows Forms SDK, or, for example, by the .NET runtime. - -* Configure your workstation to automatically collect memory dumps following [Collecting User-Mode Dumps guide](https://learn.microsoft.com/windows/win32/wer/collecting-user-mode-dumps) guide. -* Run `.\start-code.cmd` -* In the VS Code terminal run the following commands to run the tests: - ``` - .\restore.cmd - pushd .\src\System.Windows.Forms\tests\UnitTests - dotnet test - ``` -* Upon the test process crash, navigate to the collected memory dump and inspect it in [WinDbg](https://learn.microsoft.com/windows-hardware/drivers/debugger/debugger-download-tools) (or [MSFT internal](https://www.osgwiki.com/wiki/WinDbg)) (or another tool of your choice). - -❕If you need to debug an x86-related issue, run tests with `-a x86` argument, e.g., `dotnet test -a x86`, and then use the 32-bit version of WinDbg to open the dump. diff --git a/eng/CustomPackaging.targets b/eng/CustomPackaging.targets new file mode 100644 index 00000000000..438d669e6f5 --- /dev/null +++ b/eng/CustomPackaging.targets @@ -0,0 +1,45 @@ + + + + + + + + + $(ArtifactsDir)packages\$(Configuration)\Shipping + WTG.System.Windows.Forms.$(PackageVersion).nupkg + $(PackagesOutputDir)\$(OriginalPackageName) + System.Windows.Forms.$(PackageVersion).nupkg + $(RepoRoot)\bin\$(CustomPackageName) + + + $(ArtifactsDir)bin\System.Windows.Forms.Design\$(Configuration)\net8.0 + + + $(RepoRoot)CreateCustomPackage.ps1 + + + + + + + + + + + + + + + + + + + + + diff --git a/eng/Publishing.props b/eng/Publishing.props index 10bc8c8684d..579a1360d90 100644 --- a/eng/Publishing.props +++ b/eng/Publishing.props @@ -2,5 +2,6 @@ 3 + true diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 680e2a75825..0e8106a31ad 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,29 +179,29 @@ Note: if the Uri is a new place, you will need to add a subscription from that p - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + f311667e0587f19c3fa9553a909975662107a351 - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + f311667e0587f19c3fa9553a909975662107a351 - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + f311667e0587f19c3fa9553a909975662107a351 - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + f311667e0587f19c3fa9553a909975662107a351 - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + f311667e0587f19c3fa9553a909975662107a351 - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + f311667e0587f19c3fa9553a909975662107a351 diff --git a/eng/Versions.props b/eng/Versions.props index b691f7fc423..c015d3879be 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,49 +1,52 @@ - 8 + 0 0 - 3 + 24 - servicing - - + preview + 1 $(MajorVersion).$(MinorVersion).$(PatchVersion) true true - release + + + prerelease + - 8.0.3-servicing.24114.23 + 8.0.1-servicing.23580.1 8.0.0 8.0.0 + 8.0.0 8.0.0 8.0.0 8.0.0 5.0.0-preview.7.20320.5 - 8.0.3-servicing.24114.23 + 8.0.1-servicing.23580.1 8.0.0 6.0.0 8.0.0 8.0.0 8.0.0 - 8.0.3 + 8.0.1 8.0.0 8.0.0 - 8.0.3 - 8.0.3 - 8.0.3-servicing.24114.23 + 8.0.1 + 8.0.0 + 8.0.1-servicing.23580.1 8.0.0 8.0.0 8.0.0 8.0.0 8.0.0 8.0.0 - 8.0.3-servicing.24114.23 - 8.0.3-servicing.24114.23 - 8.0.3-servicing.24114.23 + 8.0.1-servicing.23580.1 + 8.0.1-servicing.23580.1 + 8.0.1-servicing.23580.1 @@ -56,9 +59,9 @@ - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 17.4.0-preview-20220707-01 diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index 6c65e81925f..efa2fd72bfa 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -35,7 +35,7 @@ Set-StrictMode -Version 2.0 . $PSScriptRoot\tools.ps1 # Add source entry to PackageSources -function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $Password) { +function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $pwd) { $packageSource = $sources.SelectSingleNode("add[@key='$SourceName']") if ($packageSource -eq $null) @@ -48,12 +48,11 @@ function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Usern else { Write-Host "Package source $SourceName already present." } - - AddCredential -Creds $creds -Source $SourceName -Username $Username -Password $Password + AddCredential -Creds $creds -Source $SourceName -Username $Username -pwd $pwd } # Add a credential node for the specified source -function AddCredential($creds, $source, $username, $password) { +function AddCredential($creds, $source, $username, $pwd) { # Looks for credential configuration for the given SourceName. Create it if none is found. $sourceElement = $creds.SelectSingleNode($Source) if ($sourceElement -eq $null) @@ -82,17 +81,18 @@ function AddCredential($creds, $source, $username, $password) { $passwordElement.SetAttribute("key", "ClearTextPassword") $sourceElement.AppendChild($passwordElement) | Out-Null } - $passwordElement.SetAttribute("value", $Password) + + $passwordElement.SetAttribute("value", $pwd) } -function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $Password) { +function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $pwd) { $maestroPrivateSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]") Write-Host "Inserting credentials for $($maestroPrivateSources.Count) Maestro's private feeds." ForEach ($PackageSource in $maestroPrivateSources) { Write-Host "`tInserting credential for Maestro's feed:" $PackageSource.Key - AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -Password $Password + AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -pwd $pwd } } @@ -144,13 +144,13 @@ if ($disabledSources -ne $null) { $userName = "dn-bot" # Insert credential nodes for Maestro's private feeds -InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -Password $Password +InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -pwd $Password # 3.1 uses a different feed url format so it's handled differently here $dotnet31Source = $sources.SelectSingleNode("add[@key='dotnet3.1']") if ($dotnet31Source -ne $null) { - AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password - AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password + AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password } $dotnetVersions = @('5','6','7','8') @@ -159,9 +159,9 @@ foreach ($dotnetVersion in $dotnetVersions) { $feedPrefix = "dotnet" + $dotnetVersion; $dotnetSource = $sources.SelectSingleNode("add[@key='$feedPrefix']") if ($dotnetSource -ne $null) { - AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password - AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password + AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password } } -$doc.Save($filename) +$doc.Save($filename) \ No newline at end of file diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml new file mode 100644 index 00000000000..a2709d10562 --- /dev/null +++ b/eng/common/templates-official/job/job.yml @@ -0,0 +1,263 @@ +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + +parameters: +# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + cancelTimeoutInMinutes: '' + condition: '' + container: '' + continueOnError: false + dependsOn: '' + displayName: '' + pool: '' + steps: [] + strategy: '' + timeoutInMinutes: '' + variables: [] + workspace: '' + templateContext: '' + +# Job base template specific parameters + # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md + artifacts: '' + enableMicrobuild: false + enablePublishBuildArtifacts: false + enablePublishBuildAssets: false + enablePublishTestResults: false + enablePublishUsingPipelines: false + enableBuildRetry: false + disableComponentGovernance: '' + componentGovernanceIgnoreDirectories: '' + mergeTestResults: false + testRunTitle: '' + testResultsFormat: '' + name: '' + preSteps: [] + runAsPublic: false +# Sbom related params + enableSbom: true + PackageVersion: 7.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + +jobs: +- job: ${{ parameters.name }} + + ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}: + cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }} + + ${{ if ne(parameters.condition, '') }}: + condition: ${{ parameters.condition }} + + ${{ if ne(parameters.container, '') }}: + container: ${{ parameters.container }} + + ${{ if ne(parameters.continueOnError, '') }}: + continueOnError: ${{ parameters.continueOnError }} + + ${{ if ne(parameters.dependsOn, '') }}: + dependsOn: ${{ parameters.dependsOn }} + + ${{ if ne(parameters.displayName, '') }}: + displayName: ${{ parameters.displayName }} + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + + ${{ if ne(parameters.strategy, '') }}: + strategy: ${{ parameters.strategy }} + + ${{ if ne(parameters.timeoutInMinutes, '') }}: + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + + ${{ if ne(parameters.templateContext, '') }}: + templateContext: ${{ parameters.templateContext }} + + variables: + - ${{ if ne(parameters.enableTelemetry, 'false') }}: + - name: DOTNET_CLI_TELEMETRY_PROFILE + value: '$(Build.Repository.Uri)' + - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}: + - name: EnableRichCodeNavigation + value: 'true' + # Retry signature validation up to three times, waiting 2 seconds between attempts. + # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures + - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY + value: 3,2000 + - ${{ each variable in parameters.variables }}: + # handle name-value variable syntax + # example: + # - name: [key] + # value: [value] + - ${{ if ne(variable.name, '') }}: + - name: ${{ variable.name }} + value: ${{ variable.value }} + + # handle variable groups + - ${{ if ne(variable.group, '') }}: + - group: ${{ variable.group }} + + # handle template variable syntax + # example: + # - template: path/to/template.yml + # parameters: + # [key]: [value] + - ${{ if ne(variable.template, '') }}: + - template: ${{ variable.template }} + ${{ if ne(variable.parameters, '') }}: + parameters: ${{ variable.parameters }} + + # handle key-value variable syntax. + # example: + # - [key]: [value] + - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}: + - ${{ each pair in variable }}: + - name: ${{ pair.key }} + value: ${{ pair.value }} + + # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds + - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: DotNet-HelixApi-Access + + ${{ if ne(parameters.workspace, '') }}: + workspace: ${{ parameters.workspace }} + + steps: + - ${{ if ne(parameters.preSteps, '') }}: + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - task: MicroBuildSigningPlugin@3 + displayName: Install MicroBuild plugin + inputs: + signType: $(_SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + env: + TeamName: $(_TeamName) + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + + - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: + - task: NuGetAuthenticate@1 + + - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}: + - task: DownloadPipelineArtifact@2 + inputs: + buildType: current + artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }} + targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }} + itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }} + + - ${{ each step in parameters.steps }}: + - ${{ step }} + + - ${{ if eq(parameters.enableRichCodeNavigation, true) }}: + - task: RichCodeNavIndexer@0 + displayName: RichCodeNav Upload + inputs: + languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }} + environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'production') }} + richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin + uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} + continueOnError: true + + - template: /eng/common/templates-official/steps/component-governance.yml + parameters: + ${{ if eq(parameters.disableComponentGovernance, '') }}: + ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: + disableComponentGovernance: false + ${{ else }}: + disableComponentGovernance: true + ${{ else }}: + disableComponentGovernance: ${{ parameters.disableComponentGovernance }} + componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: MicroBuildCleanup@1 + displayName: Execute Microbuild cleanup tasks + condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + env: + TeamName: $(_TeamName) + + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - task: CopyFiles@2 + displayName: Gather binaries for publish to artifacts + inputs: + SourceFolder: 'artifacts/bin' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' + - task: CopyFiles@2 + displayName: Gather packages for publish to artifacts + inputs: + SourceFolder: 'artifacts/packages' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish pipeline artifacts + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' + PublishLocation: Container + ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} + continueOnError: true + condition: always() + - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: + - task: 1ES.PublishPipelineArtifact@1 + inputs: + targetPath: 'artifacts/log' + artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: 'Publish logs' + continueOnError: true + condition: always() + + - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' + PublishLocation: Container + ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + continueOnError: true + condition: always() + + - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: + - task: PublishTestResults@2 + displayName: Publish XUnit Test Results + inputs: + testResultsFormat: 'xUnit' + testResultsFiles: '*.xml' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}: + - task: PublishTestResults@2 + displayName: Publish TRX Test Results + inputs: + testResultsFormat: 'VSTest' + testResultsFiles: '*.trx' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: + - template: /eng/common/templates-official/steps/generate-sbom.yml + parameters: + PackageVersion: ${{ parameters.packageVersion}} + BuildDropPath: ${{ parameters.buildDropPath }} + IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + + - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - task: 1ES.PublishPipelineArtifact@1 + inputs: + targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' + artifactName: 'BuildConfiguration' + displayName: 'Publish build retry configuration' + continueOnError: true \ No newline at end of file diff --git a/eng/common/templates-official/job/onelocbuild.yml b/eng/common/templates-official/job/onelocbuild.yml new file mode 100644 index 00000000000..ba9ba493032 --- /dev/null +++ b/eng/common/templates-official/job/onelocbuild.yml @@ -0,0 +1,112 @@ +parameters: + # Optional: dependencies of the job + dependsOn: '' + + # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool + pool: '' + + CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex + GithubPat: $(BotAccount-dotnet-bot-repo-PAT) + + SourcesDirectory: $(Build.SourcesDirectory) + CreatePr: true + AutoCompletePr: false + ReusePr: true + UseLfLineEndings: true + UseCheckedInLocProjectJson: false + SkipLocProjectJsonGeneration: false + LanguageSet: VS_Main_Languages + LclSource: lclFilesInRepo + LclPackageId: '' + RepoType: gitHub + GitHubOrg: dotnet + MirrorRepo: '' + MirrorBranch: main + condition: '' + JobNameSuffix: '' + +jobs: +- job: OneLocBuild${{ parameters.JobNameSuffix }} + + dependsOn: ${{ parameters.dependsOn }} + + displayName: OneLocBuild${{ parameters.JobNameSuffix }} + + variables: + - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat + - name: _GenerateLocProjectArguments + value: -SourcesDirectory ${{ parameters.SourcesDirectory }} + -LanguageSet "${{ parameters.LanguageSet }}" + -CreateNeutralXlfs + - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}: + - name: _GenerateLocProjectArguments + value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson + - template: /eng/common/templates-official/variables/pool-providers.yml + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + ${{ if eq(parameters.pool, '') }}: + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + + steps: + - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: + - task: Powershell@2 + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1 + arguments: $(_GenerateLocProjectArguments) + displayName: Generate LocProject.json + condition: ${{ parameters.condition }} + + - task: OneLocBuild@2 + displayName: OneLocBuild + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + inputs: + locProj: eng/Localize/LocProject.json + outDir: $(Build.ArtifactStagingDirectory) + lclSource: ${{ parameters.LclSource }} + lclPackageId: ${{ parameters.LclPackageId }} + isCreatePrSelected: ${{ parameters.CreatePr }} + isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} + ${{ if eq(parameters.CreatePr, true) }}: + isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} + ${{ if eq(parameters.RepoType, 'gitHub') }}: + isShouldReusePrSelected: ${{ parameters.ReusePr }} + packageSourceAuth: patAuth + patVariable: ${{ parameters.CeapexPat }} + ${{ if eq(parameters.RepoType, 'gitHub') }}: + repoType: ${{ parameters.RepoType }} + gitHubPatVariable: "${{ parameters.GithubPat }}" + ${{ if ne(parameters.MirrorRepo, '') }}: + isMirrorRepoSelected: true + gitHubOrganization: ${{ parameters.GitHubOrg }} + mirrorRepo: ${{ parameters.MirrorRepo }} + mirrorBranch: ${{ parameters.MirrorBranch }} + condition: ${{ parameters.condition }} + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish Localization Files + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc' + PublishLocation: Container + ArtifactName: Loc + condition: ${{ parameters.condition }} + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish LocProject.json + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/' + PublishLocation: Container + ArtifactName: Loc + condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/eng/common/templates-official/job/publish-build-assets.yml b/eng/common/templates-official/job/publish-build-assets.yml new file mode 100644 index 00000000000..53138622fe7 --- /dev/null +++ b/eng/common/templates-official/job/publish-build-assets.yml @@ -0,0 +1,155 @@ +parameters: + configuration: 'Debug' + + # Optional: condition for the job to run + condition: '' + + # Optional: 'true' if future jobs should run even if this job fails + continueOnError: false + + # Optional: dependencies of the job + dependsOn: '' + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool + pool: {} + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + + # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing + publishUsingPipelines: false + + # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing + publishAssetsImmediately: false + + artifactsPublishingAdditionalParameters: '' + + signingValidationAdditionalParameters: '' + +jobs: +- job: Asset_Registry_Publish + + dependsOn: ${{ parameters.dependsOn }} + timeoutInMinutes: 150 + + ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + displayName: Publish Assets + ${{ else }}: + displayName: Publish to Build Asset Registry + + variables: + - template: /eng/common/templates-official/variables/pool-providers.yml + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: Publish-Build-Assets + - group: AzureDevOps-Artifact-Feeds-Pats + - name: runCodesignValidationInjection + value: false + - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + - template: /eng/common/templates-official/post-build/common-variables.yml + + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + steps: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: DownloadBuildArtifacts@0 + displayName: Download artifact + inputs: + artifactName: AssetManifests + downloadPath: '$(Build.StagingDirectory)/Download' + checkDownloadedFiles: true + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + + - task: NuGetAuthenticate@1 + + - task: PowerShell@2 + displayName: Publish Build Assets + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet + /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' + /p:BuildAssetRegistryToken=$(MaestroAccessToken) + /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com + /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} + /p:OfficialBuildId=$(Build.BuildNumber) + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + + - task: powershell@2 + displayName: Create ReleaseConfigs Artifact + inputs: + targetType: inline + script: | + New-Item -Path "$(Build.StagingDirectory)/ReleaseConfigs" -ItemType Directory -Force + $filePath = "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt" + Add-Content -Path $filePath -Value $(BARBuildId) + Add-Content -Path $filePath -Value "$(DefaultChannels)" + Add-Content -Path $filePath -Value $(IsStableBuild) + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish ReleaseConfigs Artifact + inputs: + PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs' + PublishLocation: Container + ArtifactName: ReleaseConfigs + + - task: powershell@2 + displayName: Check if SymbolPublishingExclusionsFile.txt exists + inputs: + targetType: inline + script: | + $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt" + if(Test-Path -Path $symbolExclusionfile) + { + Write-Host "SymbolExclusionFile exists" + Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true" + } + else{ + Write-Host "Symbols Exclusion file does not exists" + Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false" + } + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish SymbolPublishingExclusionsFile Artifact + condition: eq(variables['SymbolExclusionFile'], 'true') + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' + PublishLocation: Container + ArtifactName: ReleaseConfigs + + - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + - template: /eng/common/templates-official/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: PowerShell@2 + displayName: Publish Using Darc + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + arguments: -BuildId $(BARBuildId) + -PublishingInfraVersion 3 + -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' + -MaestroToken '$(MaestroApiAccessToken)' + -WaitPublishingFinish true + -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' + -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + + - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: + - template: /eng/common/templates-official/steps/publish-logs.yml + parameters: + JobLabel: 'Publish_Artifacts_Logs' diff --git a/eng/common/templates-official/job/source-build.yml b/eng/common/templates-official/job/source-build.yml new file mode 100644 index 00000000000..8aba3b44bb2 --- /dev/null +++ b/eng/common/templates-official/job/source-build.yml @@ -0,0 +1,67 @@ +parameters: + # This template adds arcade-powered source-build to CI. The template produces a server job with a + # default ID 'Source_Build_Complete' to put in a dependency list if necessary. + + # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed. + jobNamePrefix: 'Source_Build' + + # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for + # managed-only repositories. This is an object with these properties: + # + # name: '' + # The name of the job. This is included in the job ID. + # targetRID: '' + # The name of the target RID to use, instead of the one auto-detected by Arcade. + # nonPortable: false + # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than + # linux-x64), and compiling against distro-provided packages rather than portable ones. + # skipPublishValidation: false + # Disables publishing validation. By default, a check is performed to ensure no packages are + # published by source-build. + # container: '' + # A container to use. Runs in docker. + # pool: {} + # A pool to use. Runs directly on an agent. + # buildScript: '' + # Specifies the build script to invoke to perform the build in the repo. The default + # './build.sh' should work for typical Arcade repositories, but this is customizable for + # difficult situations. + # jobProperties: {} + # A list of job properties to inject at the top level, for potential extensibility beyond + # container and pool. + platform: {} + +jobs: +- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }} + displayName: Source-Build (${{ parameters.platform.name }}) + + ${{ each property in parameters.platform.jobProperties }}: + ${{ property.key }}: ${{ property.value }} + + ${{ if ne(parameters.platform.container, '') }}: + container: ${{ parameters.platform.container }} + + ${{ if eq(parameters.platform.pool, '') }}: + # The default VM host AzDO pool. This should be capable of running Docker containers: almost all + # source-build builds run in Docker, including the default managed platform. + # /eng/common/templates-official/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')] + demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open + + ${{ if eq(variables['System.TeamProject'], 'internal') }}: + name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] + image: 1es-mariner-2-pt + os: linux + + ${{ if ne(parameters.platform.pool, '') }}: + pool: ${{ parameters.platform.pool }} + + workspace: + clean: all + + steps: + - template: /eng/common/templates-official/steps/source-build.yml + parameters: + platform: ${{ parameters.platform }} diff --git a/eng/common/templates-official/job/source-index-stage1.yml b/eng/common/templates-official/job/source-index-stage1.yml new file mode 100644 index 00000000000..4b633739170 --- /dev/null +++ b/eng/common/templates-official/job/source-index-stage1.yml @@ -0,0 +1,68 @@ +parameters: + runAsPublic: false + sourceIndexPackageVersion: 1.0.1-20230228.2 + sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json + sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" + preSteps: [] + binlogPath: artifacts/log/Debug/Build.binlog + condition: '' + dependsOn: '' + pool: '' + +jobs: +- job: SourceIndexStage1 + dependsOn: ${{ parameters.dependsOn }} + condition: ${{ parameters.condition }} + variables: + - name: SourceIndexPackageVersion + value: ${{ parameters.sourceIndexPackageVersion }} + - name: SourceIndexPackageSource + value: ${{ parameters.sourceIndexPackageSource }} + - name: BinlogPath + value: ${{ parameters.binlogPath }} + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: source-dot-net stage1 variables + - template: /eng/common/templates-official/variables/pool-providers.yml + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + ${{ if eq(parameters.pool, '') }}: + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $(DncEngPublicBuildPool) + demands: ImageOverride -equals windows.vs2019.amd64.open + ${{ if eq(variables['System.TeamProject'], 'internal') }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + + steps: + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} + + - task: UseDotNet@2 + displayName: Use .NET Core SDK 6 + inputs: + packageType: sdk + version: 6.0.x + installationPath: $(Agent.TempDirectory)/dotnet + workingDirectory: $(Agent.TempDirectory) + + - script: | + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + displayName: Download Tools + # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. + workingDirectory: $(Agent.TempDirectory) + + - script: ${{ parameters.sourceIndexBuildCommand }} + displayName: Build Repository + + - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output + displayName: Process Binlog into indexable sln + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) + displayName: Upload stage1 artifacts to source index + env: + BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) diff --git a/eng/common/templates-official/jobs/codeql-build.yml b/eng/common/templates-official/jobs/codeql-build.yml new file mode 100644 index 00000000000..b68d3c2f319 --- /dev/null +++ b/eng/common/templates-official/jobs/codeql-build.yml @@ -0,0 +1,31 @@ +parameters: + # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md + continueOnError: false + # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + jobs: [] + # Optional: if specified, restore and use this version of Guardian instead of the default. + overrideGuardianVersion: '' + +jobs: +- template: /eng/common/templates-official/jobs/jobs.yml + parameters: + enableMicrobuild: false + enablePublishBuildArtifacts: false + enablePublishTestResults: false + enablePublishBuildAssets: false + enablePublishUsingPipelines: false + enableTelemetry: true + + variables: + - group: Publish-Build-Assets + # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in + # sync with the packages.config file. + - name: DefaultGuardianVersion + value: 0.109.0 + - name: GuardianPackagesConfigFile + value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config + - name: GuardianVersion + value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} + + jobs: ${{ parameters.jobs }} + diff --git a/eng/common/templates-official/jobs/jobs.yml b/eng/common/templates-official/jobs/jobs.yml new file mode 100644 index 00000000000..857a0f8ba43 --- /dev/null +++ b/eng/common/templates-official/jobs/jobs.yml @@ -0,0 +1,97 @@ +parameters: + # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md + continueOnError: false + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: Enable publishing using release pipelines + enablePublishUsingPipelines: false + + # Optional: Enable running the source-build jobs to build repo from source + enableSourceBuild: false + + # Optional: Parameters for source-build template. + # See /eng/common/templates-official/jobs/source-build.yml for options + sourceBuildParameters: [] + + graphFileGeneration: + # Optional: Enable generating the graph files at the end of the build + enabled: false + # Optional: Include toolset dependencies in the generated graph files + includeToolset: false + + # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + jobs: [] + + # Optional: Override automatically derived dependsOn value for "publish build assets" job + publishBuildAssetsDependsOn: '' + + # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage. + publishAssetsImmediately: false + + # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml) + artifactsPublishingAdditionalParameters: '' + signingValidationAdditionalParameters: '' + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + + enableSourceIndex: false + sourceIndexParams: {} + +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + +jobs: +- ${{ each job in parameters.jobs }}: + - template: ../job/job.yml + parameters: + # pass along parameters + ${{ each parameter in parameters }}: + ${{ if ne(parameter.key, 'jobs') }}: + ${{ parameter.key }}: ${{ parameter.value }} + + # pass along job properties + ${{ each property in job }}: + ${{ if ne(property.key, 'job') }}: + ${{ property.key }}: ${{ property.value }} + + name: ${{ job.job }} + +- ${{ if eq(parameters.enableSourceBuild, true) }}: + - template: /eng/common/templates-official/jobs/source-build.yml + parameters: + allCompletedJobId: Source_Build_Complete + ${{ each parameter in parameters.sourceBuildParameters }}: + ${{ parameter.key }}: ${{ parameter.value }} + +- ${{ if eq(parameters.enableSourceIndex, 'true') }}: + - template: ../job/source-index-stage1.yml + parameters: + runAsPublic: ${{ parameters.runAsPublic }} + ${{ each parameter in parameters.sourceIndexParams }}: + ${{ parameter.key }}: ${{ parameter.value }} + +- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: + - template: ../job/publish-build-assets.yml + parameters: + continueOnError: ${{ parameters.continueOnError }} + dependsOn: + - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.publishBuildAssetsDependsOn }}: + - ${{ job.job }} + - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.jobs }}: + - ${{ job.job }} + - ${{ if eq(parameters.enableSourceBuild, true) }}: + - Source_Build_Complete + + runAsPublic: ${{ parameters.runAsPublic }} + publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} + publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }} + enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }} diff --git a/eng/common/templates-official/jobs/source-build.yml b/eng/common/templates-official/jobs/source-build.yml new file mode 100644 index 00000000000..08e5db9bb11 --- /dev/null +++ b/eng/common/templates-official/jobs/source-build.yml @@ -0,0 +1,46 @@ +parameters: + # This template adds arcade-powered source-build to CI. A job is created for each platform, as + # well as an optional server job that completes when all platform jobs complete. + + # The name of the "join" job for all source-build platforms. If set to empty string, the job is + # not included. Existing repo pipelines can use this job depend on all source-build jobs + # completing without maintaining a separate list of every single job ID: just depend on this one + # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'. + allCompletedJobId: '' + + # See /eng/common/templates-official/job/source-build.yml + jobNamePrefix: 'Source_Build' + + # This is the default platform provided by Arcade, intended for use by a managed-only repo. + defaultManagedPlatform: + name: 'Managed' + container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8' + + # Defines the platforms on which to run build jobs. One job is created for each platform, and the + # object in this array is sent to the job template as 'platform'. If no platforms are specified, + # one job runs on 'defaultManagedPlatform'. + platforms: [] + +jobs: + +- ${{ if ne(parameters.allCompletedJobId, '') }}: + - job: ${{ parameters.allCompletedJobId }} + displayName: Source-Build Complete + pool: server + dependsOn: + - ${{ each platform in parameters.platforms }}: + - ${{ parameters.jobNamePrefix }}_${{ platform.name }} + - ${{ if eq(length(parameters.platforms), 0) }}: + - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }} + +- ${{ each platform in parameters.platforms }}: + - template: /eng/common/templates-official/job/source-build.yml + parameters: + jobNamePrefix: ${{ parameters.jobNamePrefix }} + platform: ${{ platform }} + +- ${{ if eq(length(parameters.platforms), 0) }}: + - template: /eng/common/templates-official/job/source-build.yml + parameters: + jobNamePrefix: ${{ parameters.jobNamePrefix }} + platform: ${{ parameters.defaultManagedPlatform }} diff --git a/eng/common/templates-official/post-build/common-variables.yml b/eng/common/templates-official/post-build/common-variables.yml new file mode 100644 index 00000000000..c24193acfc9 --- /dev/null +++ b/eng/common/templates-official/post-build/common-variables.yml @@ -0,0 +1,22 @@ +variables: + - group: Publish-Build-Assets + + # Whether the build is internal or not + - name: IsInternalBuild + value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} + + # Default Maestro++ API Endpoint and API Version + - name: MaestroApiEndPoint + value: "https://maestro-prod.westus2.cloudapp.azure.com" + - name: MaestroApiAccessToken + value: $(MaestroAccessToken) + - name: MaestroApiVersion + value: "2020-02-20" + + - name: SourceLinkCLIVersion + value: 3.0.0 + - name: SymbolToolVersion + value: 1.0.1 + + - name: runCodesignValidationInjection + value: false diff --git a/eng/common/templates-official/post-build/post-build.yml b/eng/common/templates-official/post-build/post-build.yml new file mode 100644 index 00000000000..5c98fe1c0f3 --- /dev/null +++ b/eng/common/templates-official/post-build/post-build.yml @@ -0,0 +1,285 @@ +parameters: + # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. + # Publishing V1 is no longer supported + # Publishing V2 is no longer supported + # Publishing V3 is the default + - name: publishingInfraVersion + displayName: Which version of publishing should be used to promote the build definition? + type: number + default: 3 + values: + - 3 + + - name: BARBuildId + displayName: BAR Build Id + type: number + default: 0 + + - name: PromoteToChannelIds + displayName: Channel to promote BARBuildId to + type: string + default: '' + + - name: enableSourceLinkValidation + displayName: Enable SourceLink validation + type: boolean + default: false + + - name: enableSigningValidation + displayName: Enable signing validation + type: boolean + default: true + + - name: enableSymbolValidation + displayName: Enable symbol validation + type: boolean + default: false + + - name: enableNugetValidation + displayName: Enable NuGet validation + type: boolean + default: true + + - name: publishInstallersAndChecksums + displayName: Publish installers and checksums + type: boolean + default: true + + - name: SDLValidationParameters + type: object + default: + enable: false + publishGdn: false + continueOnError: false + params: '' + artifactNames: '' + downloadArtifacts: true + + # These parameters let the user customize the call to sdk-task.ps1 for publishing + # symbols & general artifacts as well as for signing validation + - name: symbolPublishingAdditionalParameters + displayName: Symbol publishing additional parameters + type: string + default: '' + + - name: artifactsPublishingAdditionalParameters + displayName: Artifact publishing additional parameters + type: string + default: '' + + - name: signingValidationAdditionalParameters + displayName: Signing validation additional parameters + type: string + default: '' + + # Which stages should finish execution before post-build stages start + - name: validateDependsOn + type: object + default: + - build + + - name: publishDependsOn + type: object + default: + - Validate + + # Optional: Call asset publishing rather than running in a separate stage + - name: publishAssetsImmediately + type: boolean + default: false + +stages: +- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + - stage: Validate + dependsOn: ${{ parameters.validateDependsOn }} + displayName: Validate Build Assets + variables: + - template: common-variables.yml + - template: /eng/common/templates-official/variables/pool-providers.yml + jobs: + - job: + displayName: NuGet Validation + condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true')) + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ + -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ + + - job: + displayName: Signing Validation + condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true')) + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + itemPattern: | + ** + !**/Microsoft.SourceBuild.Intermediate.*.nupkg + + # This is necessary whenever we want to publish/restore to an AzDO private feed + # Since sdk-task.ps1 tries to restore packages we need to do this authentication here + # otherwise it'll complain about accessing a private feed. + - task: NuGetAuthenticate@1 + displayName: 'Authenticate to AzDO Feeds' + + # Signing validation will optionally work with the buildmanifest file which is downloaded from + # Azure DevOps above. + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task SigningValidation -restore -msbuildEngine vs + /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' + /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' + ${{ parameters.signingValidationAdditionalParameters }} + + - template: ../steps/publish-logs.yml + parameters: + StageLabel: 'Validation' + JobLabel: 'Signing' + BinlogToolVersion: $(BinlogToolVersion) + + - job: + displayName: SourceLink Validation + condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true') + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Blob Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: BlobArtifacts + checkDownloadedFiles: true + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 + arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -ExtractPath $(Agent.BuildDirectory)/Extract/ + -GHRepoName $(Build.Repository.Name) + -GHCommit $(Build.SourceVersion) + -SourcelinkCliVersion $(SourceLinkCLIVersion) + continueOnError: true + +- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}: + - stage: publish_using_darc + ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + dependsOn: ${{ parameters.publishDependsOn }} + ${{ else }}: + dependsOn: ${{ parameters.validateDependsOn }} + displayName: Publish using Darc + variables: + - template: common-variables.yml + - template: /eng/common/templates-official/variables/pool-providers.yml + jobs: + - job: + displayName: Publish Using Darc + timeoutInMinutes: 120 + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: NuGetAuthenticate@1 + + - task: PowerShell@2 + displayName: Publish Using Darc + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + arguments: -BuildId $(BARBuildId) + -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} + -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' + -MaestroToken '$(MaestroApiAccessToken)' + -WaitPublishingFinish true + -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' + -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' diff --git a/eng/common/templates-official/post-build/setup-maestro-vars.yml b/eng/common/templates-official/post-build/setup-maestro-vars.yml new file mode 100644 index 00000000000..0c87f149a4a --- /dev/null +++ b/eng/common/templates-official/post-build/setup-maestro-vars.yml @@ -0,0 +1,70 @@ +parameters: + BARBuildId: '' + PromoteToChannelIds: '' + +steps: + - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}: + - task: DownloadBuildArtifacts@0 + displayName: Download Release Configs + inputs: + buildType: current + artifactName: ReleaseConfigs + checkDownloadedFiles: true + + - task: PowerShell@2 + name: setReleaseVars + displayName: Set Release Configs Vars + inputs: + targetType: inline + pwsh: true + script: | + try { + if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') { + $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt + + $BarId = $Content | Select -Index 0 + $Channels = $Content | Select -Index 1 + $IsStableBuild = $Content | Select -Index 2 + + $AzureDevOpsProject = $Env:System_TeamProject + $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId + $AzureDevOpsBuildId = $Env:Build_BuildId + } + else { + $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}" + + $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' + $apiHeaders.Add('Accept', 'application/json') + $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") + + $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + + $BarId = $Env:BARBuildId + $Channels = $Env:PromoteToMaestroChannels -split "," + $Channels = $Channels -join "][" + $Channels = "[$Channels]" + + $IsStableBuild = $buildInfo.stable + $AzureDevOpsProject = $buildInfo.azureDevOpsProject + $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId + $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId + } + + Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId" + Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels" + Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild" + + Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject" + Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId" + Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId" + } + catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + exit 1 + } + env: + MAESTRO_API_TOKEN: $(MaestroApiAccessToken) + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }} diff --git a/eng/common/templates-official/post-build/trigger-subscription.yml b/eng/common/templates-official/post-build/trigger-subscription.yml new file mode 100644 index 00000000000..da669030daf --- /dev/null +++ b/eng/common/templates-official/post-build/trigger-subscription.yml @@ -0,0 +1,13 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Triggering subscriptions + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 + arguments: -SourceRepo $(Build.Repository.Uri) + -ChannelId ${{ parameters.ChannelId }} + -MaestroApiAccessToken $(MaestroAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates-official/steps/add-build-to-channel.yml b/eng/common/templates-official/steps/add-build-to-channel.yml new file mode 100644 index 00000000000..f67a210d62f --- /dev/null +++ b/eng/common/templates-official/steps/add-build-to-channel.yml @@ -0,0 +1,13 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Add Build to Channel + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 + arguments: -BuildId $(BARBuildId) + -ChannelId ${{ parameters.ChannelId }} + -MaestroApiAccessToken $(MaestroApiAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates-official/steps/build-reason.yml b/eng/common/templates-official/steps/build-reason.yml new file mode 100644 index 00000000000..eba58109b52 --- /dev/null +++ b/eng/common/templates-official/steps/build-reason.yml @@ -0,0 +1,12 @@ +# build-reason.yml +# Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons +# to include steps (',' separated). +parameters: + conditions: '' + steps: [] + +steps: + - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}: + - ${{ parameters.steps }} + - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}: + - ${{ parameters.steps }} diff --git a/eng/common/templates-official/steps/component-governance.yml b/eng/common/templates-official/steps/component-governance.yml new file mode 100644 index 00000000000..0ecec47b0c9 --- /dev/null +++ b/eng/common/templates-official/steps/component-governance.yml @@ -0,0 +1,13 @@ +parameters: + disableComponentGovernance: false + componentGovernanceIgnoreDirectories: '' + +steps: +- ${{ if eq(parameters.disableComponentGovernance, 'true') }}: + - script: "echo ##vso[task.setvariable variable=skipComponentGovernanceDetection]true" + displayName: Set skipComponentGovernanceDetection variable +- ${{ if ne(parameters.disableComponentGovernance, 'true') }}: + - task: ComponentGovernanceComponentDetection@0 + continueOnError: true + inputs: + ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/execute-codeql.yml b/eng/common/templates-official/steps/execute-codeql.yml new file mode 100644 index 00000000000..9b4a5ffa30a --- /dev/null +++ b/eng/common/templates-official/steps/execute-codeql.yml @@ -0,0 +1,32 @@ +parameters: + # Language that should be analyzed. Defaults to csharp + language: csharp + # Build Commands + buildCommands: '' + overrideParameters: '' # Optional: to override values for parameters. + additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")' + # Optional: if specified, restore and use this version of Guardian instead of the default. + overrideGuardianVersion: '' + # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth + # diagnosis of problems with specific tool configurations. + publishGuardianDirectoryToPipeline: false + # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL + # parameters rather than relying on YAML. It may be better to use a local script, because you can + # reproduce results locally without piecing together a command based on the YAML. + executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1' + # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named + # 'continueOnError', the parameter value is not correctly picked up. + # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter + # optional: determines whether to continue the build if the step errors; + sdlContinueOnError: false + +steps: +- template: /eng/common/templates-official/steps/execute-sdl.yml + parameters: + overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }} + executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }} + overrideParameters: ${{ parameters.overrideParameters }} + additionalParameters: '${{ parameters.additionalParameters }} + -CodeQLAdditionalRunConfigParams @("BuildCommands < ${{ parameters.buildCommands }}", "Language < ${{ parameters.language }}")' + publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }} + sdlContinueOnError: ${{ parameters.sdlContinueOnError }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/execute-sdl.yml b/eng/common/templates-official/steps/execute-sdl.yml new file mode 100644 index 00000000000..07426fde05d --- /dev/null +++ b/eng/common/templates-official/steps/execute-sdl.yml @@ -0,0 +1,88 @@ +parameters: + overrideGuardianVersion: '' + executeAllSdlToolsScript: '' + overrideParameters: '' + additionalParameters: '' + publishGuardianDirectoryToPipeline: false + sdlContinueOnError: false + condition: '' + +steps: +- task: NuGetAuthenticate@1 + inputs: + nuGetServiceConnections: GuardianConnect + +- task: NuGetToolInstaller@1 + displayName: 'Install NuGet.exe' + +- ${{ if ne(parameters.overrideGuardianVersion, '') }}: + - pwsh: | + Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl + . .\sdl.ps1 + $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }} + Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" + displayName: Install Guardian (Overridden) + +- ${{ if eq(parameters.overrideGuardianVersion, '') }}: + - pwsh: | + Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl + . .\sdl.ps1 + $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts + Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" + displayName: Install Guardian + +- ${{ if ne(parameters.overrideParameters, '') }}: + - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }} + displayName: Execute SDL (Overridden) + continueOnError: ${{ parameters.sdlContinueOnError }} + condition: ${{ parameters.condition }} + +- ${{ if eq(parameters.overrideParameters, '') }}: + - powershell: ${{ parameters.executeAllSdlToolsScript }} + -GuardianCliLocation $(GuardianCliLocation) + -NugetPackageDirectory $(Build.SourcesDirectory)\.packages + -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) + ${{ parameters.additionalParameters }} + displayName: Execute SDL + continueOnError: ${{ parameters.sdlContinueOnError }} + condition: ${{ parameters.condition }} + +- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}: + # We want to publish the Guardian results and configuration for easy diagnosis. However, the + # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default + # tooling files. Some of these files are large and aren't useful during an investigation, so + # exclude them by simply deleting them before publishing. (As of writing, there is no documented + # way to selectively exclude a dir from the pipeline artifact publish task.) + - task: DeleteFiles@1 + displayName: Delete Guardian dependencies to avoid uploading + inputs: + SourceFolder: $(Agent.BuildDirectory)/.gdn + Contents: | + c + i + condition: succeededOrFailed() + + - publish: $(Agent.BuildDirectory)/.gdn + artifact: GuardianConfiguration + displayName: Publish GuardianConfiguration + condition: succeededOrFailed() + + # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration + # with the "SARIF SAST Scans Tab" Azure DevOps extension + - task: CopyFiles@2 + displayName: Copy SARIF files + inputs: + flattenFolders: true + sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/ + contents: '**/*.sarif' + targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs + condition: succeededOrFailed() + + # Use PublishBuildArtifacts because the SARIF extension only checks this case + # see microsoft/sarif-azuredevops-extension#4 + - task: PublishBuildArtifacts@1 + displayName: Publish SARIF files to CodeAnalysisLogs container + inputs: + pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs + artifactName: CodeAnalysisLogs + condition: succeededOrFailed() \ No newline at end of file diff --git a/eng/common/templates-official/steps/generate-sbom.yml b/eng/common/templates-official/steps/generate-sbom.yml new file mode 100644 index 00000000000..1bf43bf807a --- /dev/null +++ b/eng/common/templates-official/steps/generate-sbom.yml @@ -0,0 +1,48 @@ +# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated. +# PackageName - The name of the package this SBOM represents. +# PackageVersion - The version of the package this SBOM represents. +# ManifestDirPath - The path of the directory where the generated manifest files will be placed +# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. + +parameters: + PackageVersion: 8.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + PackageName: '.NET' + ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom + IgnoreDirectories: '' + sbomContinueOnError: true + +steps: +- task: PowerShell@2 + displayName: Prep for SBOM generation in (Non-linux) + condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin')) + inputs: + filePath: ./eng/common/generate-sbom-prep.ps1 + arguments: ${{parameters.manifestDirPath}} + +# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461 +- script: | + chmod +x ./eng/common/generate-sbom-prep.sh + ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}} + displayName: Prep for SBOM generation in (Linux) + condition: eq(variables['Agent.Os'], 'Linux') + continueOnError: ${{ parameters.sbomContinueOnError }} + +- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: 'Generate SBOM manifest' + continueOnError: ${{ parameters.sbomContinueOnError }} + inputs: + PackageName: ${{ parameters.packageName }} + BuildDropPath: ${{ parameters.buildDropPath }} + PackageVersion: ${{ parameters.packageVersion }} + ManifestDirPath: ${{ parameters.manifestDirPath }} + ${{ if ne(parameters.IgnoreDirectories, '') }}: + AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}' + +- task: 1ES.PublishPipelineArtifact@1 + displayName: Publish SBOM manifest + continueOnError: ${{parameters.sbomContinueOnError}} + inputs: + targetPath: '${{parameters.manifestDirPath}}' + artifactName: $(ARTIFACT_NAME) + diff --git a/eng/common/templates-official/steps/publish-logs.yml b/eng/common/templates-official/steps/publish-logs.yml new file mode 100644 index 00000000000..04012fed182 --- /dev/null +++ b/eng/common/templates-official/steps/publish-logs.yml @@ -0,0 +1,23 @@ +parameters: + StageLabel: '' + JobLabel: '' + +steps: +- task: Powershell@2 + displayName: Prepare Binlogs to Upload + inputs: + targetType: inline + script: | + New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + continueOnError: true + condition: always() + +- task: 1ES.PublishBuildArtifacts@1 + displayName: Publish Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' + PublishLocation: Container + ArtifactName: PostBuildLogs + continueOnError: true + condition: always() diff --git a/eng/common/templates-official/steps/retain-build.yml b/eng/common/templates-official/steps/retain-build.yml new file mode 100644 index 00000000000..83d97a26a01 --- /dev/null +++ b/eng/common/templates-official/steps/retain-build.yml @@ -0,0 +1,28 @@ +parameters: + # Optional azure devops PAT with build execute permissions for the build's organization, + # only needed if the build that should be retained ran on a different organization than + # the pipeline where this template is executing from + Token: '' + # Optional BuildId to retain, defaults to the current running build + BuildId: '' + # Azure devops Organization URI for the build in the https://dev.azure.com/ format. + # Defaults to the organization the current pipeline is running on + AzdoOrgUri: '$(System.CollectionUri)' + # Azure devops project for the build. Defaults to the project the current pipeline is running on + AzdoProject: '$(System.TeamProject)' + +steps: + - task: powershell@2 + inputs: + targetType: 'filePath' + filePath: eng/common/retain-build.ps1 + pwsh: true + arguments: > + -AzdoOrgUri: ${{parameters.AzdoOrgUri}} + -AzdoProject ${{parameters.AzdoProject}} + -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} + -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} + displayName: Enable permanent build retention + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + BUILD_ID: $(Build.BuildId) \ No newline at end of file diff --git a/eng/common/templates-official/steps/send-to-helix.yml b/eng/common/templates-official/steps/send-to-helix.yml new file mode 100644 index 00000000000..3eb7e2d5f84 --- /dev/null +++ b/eng/common/templates-official/steps/send-to-helix.yml @@ -0,0 +1,91 @@ +# Please remember to update the documentation if you make changes to these parameters! +parameters: + HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ + HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' + HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number + HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues + HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group + HelixConfiguration: '' # optional -- additional property attached to a job + HelixPreCommands: '' # optional -- commands to run before Helix work item execution + HelixPostCommands: '' # optional -- commands to run after Helix work item execution + WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects + WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects + WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects + CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload + XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true + XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects + XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects + XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner + XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects + IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion + DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json + DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json + WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." + IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set + HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net ) + Creator: '' # optional -- if the build is external, use this to specify who is sending the job + DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO + condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() + continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false + +steps: + - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY\eng\common\helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"' + displayName: ${{ parameters.DisplayNamePrefix }} (Windows) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog + displayName: ${{ parameters.DisplayNamePrefix }} (Unix) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} diff --git a/eng/common/templates-official/steps/source-build.yml b/eng/common/templates-official/steps/source-build.yml new file mode 100644 index 00000000000..829f17c34d1 --- /dev/null +++ b/eng/common/templates-official/steps/source-build.yml @@ -0,0 +1,129 @@ +parameters: + # This template adds arcade-powered source-build to CI. + + # This is a 'steps' template, and is intended for advanced scenarios where the existing build + # infra has a careful build methodology that must be followed. For example, a repo + # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline + # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to + # GitHub. Using this steps template leaves room for that infra to be included. + + # Defines the platform on which to run the steps. See 'eng/common/templates-official/job/source-build.yml' + # for details. The entire object is described in the 'job' template for simplicity, even though + # the usage of the properties on this object is split between the 'job' and 'steps' templates. + platform: {} + +steps: +# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.) +- script: | + set -x + df -h + + # If building on the internal project, the artifact feeds variable may be available (usually only if needed) + # In that case, call the feed setup script to add internal feeds corresponding to public ones. + # In addition, add an msbuild argument to copy the WIP from the repo to the target build location. + # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those + # changes. + internalRestoreArgs= + if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then + # Temporarily work around https://github.com/dotnet/arcade/issues/7709 + chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh + $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw) + internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true' + + # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo. + # This only works if there is a username/email configured, which won't be the case in most CI runs. + git config --get user.email + if [ $? -ne 0 ]; then + git config user.email dn-bot@microsoft.com + git config user.name dn-bot + fi + fi + + # If building on the internal project, the internal storage variable may be available (usually only if needed) + # In that case, add variables to allow the download of internal runtimes if the specified versions are not found + # in the default public locations. + internalRuntimeDownloadArgs= + if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then + internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' + fi + + buildConfig=Release + # Check if AzDO substitutes in a build config from a variable, and use it if so. + if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then + buildConfig='$(_BuildConfig)' + fi + + officialBuildArgs= + if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then + officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)' + fi + + targetRidArgs= + if [ '${{ parameters.platform.targetRID }}' != '' ]; then + targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}' + fi + + runtimeOsArgs= + if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then + runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}' + fi + + baseOsArgs= + if [ '${{ parameters.platform.baseOS }}' != '' ]; then + baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}' + fi + + publishArgs= + if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then + publishArgs='--publish' + fi + + assetManifestFileName=SourceBuild_RidSpecific.xml + if [ '${{ parameters.platform.name }}' != '' ]; then + assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml + fi + + ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ + --configuration $buildConfig \ + --restore --build --pack $publishArgs -bl \ + $officialBuildArgs \ + $internalRuntimeDownloadArgs \ + $internalRestoreArgs \ + $targetRidArgs \ + $runtimeOsArgs \ + $baseOsArgs \ + /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \ + /p:ArcadeBuildFromSource=true \ + /p:AssetManifestFileName=$assetManifestFileName + displayName: Build + +# Upload build logs for diagnosis. +- task: CopyFiles@2 + displayName: Prepare BuildLogs staging directory + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: | + **/*.log + **/*.binlog + artifacts/source-build/self/prebuilt-report/** + TargetFolder: '$(Build.StagingDirectory)/BuildLogs' + CleanTargetFolder: true + continueOnError: true + condition: succeededOrFailed() + +- task: 1ES.PublishPipelineArtifact@1 + displayName: Publish BuildLogs + inputs: + targetPath: '$(Build.StagingDirectory)/BuildLogs' + artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt) + continueOnError: true + condition: succeededOrFailed() + +# Manually inject component detection so that we can ignore the source build upstream cache, which contains +# a nupkg cache of input packages (a local feed). +# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir' +# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets +- task: ComponentGovernanceComponentDetection@0 + displayName: Component Detection (Exclude upstream cache) + inputs: + ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/source-build/self/src/artifacts/obj/source-built-upstream-cache' diff --git a/eng/common/templates-official/variables/pool-providers.yml b/eng/common/templates-official/variables/pool-providers.yml new file mode 100644 index 00000000000..beab7d1bfba --- /dev/null +++ b/eng/common/templates-official/variables/pool-providers.yml @@ -0,0 +1,45 @@ +# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool, +# otherwise it should go into the "normal" pools. This separates out the queueing and billing of released branches. + +# Motivation: +# Once a given branch of a repository's output has been officially "shipped" once, it is then considered to be COGS +# (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing +# (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS. +# Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services +# team needs to move resources around and create new and potentially differently-named pools. Using this template +# file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming. + +# How to use: +# This yaml assumes your shipped product branches use the naming convention "release/..." (which many do). +# If we find alternate naming conventions in broad usage it can be added to the condition below. +# +# First, import the template in an arcade-ified repo to pick up the variables, e.g.: +# +# variables: +# - template: /eng/common/templates-official/variables/pool-providers.yml +# +# ... then anywhere specifying the pool provider use the runtime variables, +# $(DncEngInternalBuildPool) +# +# pool: +# name: $(DncEngInternalBuildPool) +# image: 1es-windows-2022-pt + +variables: + # Coalesce the target and source branches so we know when a PR targets a release branch + # If these variables are somehow missing, fall back to main (tends to have more capacity) + + # Any new -Svc alternative pools should have variables added here to allow for splitting work + + - name: DncEngInternalBuildPool + value: $[ + replace( + replace( + eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), + True, + 'NetCore1ESPool-Svc-Internal' + ), + False, + 'NetCore1ESPool-Internal' + ) + ] \ No newline at end of file diff --git a/eng/common/templates-official/variables/sdl-variables.yml b/eng/common/templates-official/variables/sdl-variables.yml new file mode 100644 index 00000000000..dbdd66d4a4b --- /dev/null +++ b/eng/common/templates-official/variables/sdl-variables.yml @@ -0,0 +1,7 @@ +variables: +# The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in +# sync with the packages.config file. +- name: DefaultGuardianVersion + value: 0.109.0 +- name: GuardianPackagesConfigFile + value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config \ No newline at end of file diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index e24ca2f46f9..8ec5c4f2d9f 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -15,6 +15,7 @@ parameters: timeoutInMinutes: '' variables: [] workspace: '' + templateContext: '' # Job base template specific parameters # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md @@ -68,6 +69,9 @@ jobs: ${{ if ne(parameters.timeoutInMinutes, '') }}: timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + ${{ if ne(parameters.templateContext, '') }}: + templateContext: ${{ parameters.templateContext }} + variables: - ${{ if ne(parameters.enableTelemetry, 'false') }}: - name: DOTNET_CLI_TELEMETRY_PROFILE diff --git a/eng/common/templates/steps/generate-sbom.yml b/eng/common/templates/steps/generate-sbom.yml index a06373f38fa..2b21eae4273 100644 --- a/eng/common/templates/steps/generate-sbom.yml +++ b/eng/common/templates/steps/generate-sbom.yml @@ -5,7 +5,7 @@ # IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. parameters: - PackageVersion: 7.0.0 + PackageVersion: 8.0.0 BuildDropPath: '$(Build.SourcesDirectory)/artifacts' PackageName: '.NET' ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom diff --git a/eng/packageContent.targets b/eng/packageContent.targets index 15ab175e45f..3bae9d4bd4a 100644 --- a/eng/packageContent.targets +++ b/eng/packageContent.targets @@ -42,7 +42,7 @@ - $([MSBuild]::NormalizePath('$(_DotnetApiDocsFilesRoot)', '$(AssemblyName).xml')) + $([MSBuild]::NormalizePath('$(_DotnetApiDocsFilesRoot)', 'System.Windows.Forms.xml')) $([System.IO.Path]::ChangeExtension('$(TargetRefPath)', '.xml')) @@ -56,9 +56,9 @@ This means we build a real assembly that has no associated official intellisense docs. Contact the intellisense team for guidance. --> - + />> --> diff --git a/eng/pipelines/build-PR.yml b/eng/pipelines/build-PR.yml new file mode 100644 index 00000000000..ac8d2fa3f02 --- /dev/null +++ b/eng/pipelines/build-PR.yml @@ -0,0 +1,154 @@ +parameters: + name: '' + targetArchitecture: null + timeoutInMinutes: 120 + enableMicrobuild: true + enablePublishBuildArtifacts: true + enablePublishTestResults: true + enablePublishBuildAssets: true + enablePublishUsingPipelines: true + +jobs: + - job: ${{ parameters.name }} + displayName: ${{ parameters.name }} + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + variables: + - template: /eng/common/templates/variables/pool-providers.yml + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $(DncEngPublicBuildPool) + demands: ImageOverride -equals windows.vs2022preview.amd64.open + ${{ if ne(variables['System.TeamProject'], 'public') }}: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals windows.vs2022preview.amd64 + strategy: + matrix: + ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: + Debug: + _BuildConfig: Debug + # override some variables for debug + _SignType: test + # Code coverage uploads fail on internal PRs + ${{ if eq(variables['System.TeamProject'], 'public') }}: + _Coverage: false + Release: + _BuildConfig: Release + _Coverage: false + workspace: + clean: all + + steps: + - checkout: self + clean: true + + - ${{ if ne(variables['System.TeamProject'], 'public') }}: + - task: PowerShell@2 + displayName: Setup Private Feeds Credentials + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 + arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token + env: + Token: $(dn-bot-dnceng-artifact-feeds-rw) + + - task: MicroBuildSigningPlugin@2 + displayName: Install MicroBuild plugin for Signing + inputs: + signType: $(_SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + continueOnError: false + condition: and(succeeded(), + in(variables['_SignType'], 'real', 'test')) + # NuGet's http cache lasts 30 minutes. If we're on a static machine, this may interfere with + # auto-update PRs by preventing the CI build from fetching the new version. Delete the cache. + - powershell: Remove-Item -Recurse -ErrorAction Ignore "$env:LocalAppData\NuGet\v3-cache" + displayName: Clear NuGet http cache (if exists) + + - script: C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe queue pause + displayName: Pause NGEN x86 + + - script: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe queue pause + displayName: Pause NGEN x64 + + # Build and rename binlog + # The /p:Coverage argument is passed here since some build properties change to accommodate running with + # coverage. This is part of the workarounds for https://github.com/tonerdo/coverlet/issues/362 and + # https://github.com/tonerdo/coverlet/issues/363. + - script: eng\cibuild.cmd + -restore + -build + -configuration $(_BuildConfig) + /p:Platform=${{ parameters.targetArchitecture }} + /p:TargetArchitecture=${{ parameters.targetArchitecture }} + $(_OfficialBuildIdArgs) + $(_InternalRuntimeDownloadArgs) + /p:Coverage=$(_Coverage) + /bl:$(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig)\BuildSrc-${{ parameters.targetArchitecture }}.binlog + displayName: Build + + # Run Unit Tests + # Tests are run with /m:1 to work around https://github.com/tonerdo/coverlet/issues/364 + - script: eng\cibuild.cmd + -test + -configuration $(_BuildConfig) + /p:Platform=${{ parameters.targetArchitecture }} + /p:TargetArchitecture=${{ parameters.targetArchitecture }} + $(_OfficialBuildIdArgs) + $(_InternalRuntimeDownloadArgs) + /p:Coverage=$(_Coverage) + /p:TestRunnerAdditionalArguments='-notrait Category=IgnoreForCI -notrait Category=failing' + /bl:$(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig)\Test-${{ parameters.targetArchitecture }}.binlog + /m:1 + displayName: Run Unit Tests + condition: and(eq(variables['System.TeamProject'], 'public'), ne('${{ parameters.targetArchitecture }}', 'arm64')) + + # Run Integration Tests + # Tests are run with /m:1 to avoid parallelism across different assemblies which can lead to + # UI race conditions + - script: eng\cibuild.cmd + -integrationTest + -configuration $(_BuildConfig) + /p:Platform=${{ parameters.targetArchitecture }} + /p:TargetArchitecture=${{ parameters.targetArchitecture }} + $(_OfficialBuildIdArgs) + $(_InternalRuntimeDownloadArgs) + /p:TestRunnerAdditionalArguments='-notrait Category=IgnoreForCI -notrait Category=failing' + /bl:$(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig)\IntegrationTest-${{ parameters.targetArchitecture }}.binlog + /m:1 + env: + XUNIT_LOGS: $(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig) + displayName: Run Integration Tests + # UI tests are blocked from execution until we find solution for https://github.com/dotnet/winforms/issues/9318. + condition: and(eq(variables['System.TeamProject'], 'public'), ne('${{ parameters.targetArchitecture }}', 'arm64'), contains(variables['System.PullRequest.TargetBranch'], 'main'), false) + retryCountOnTaskFailure: 3 + + # Create Nuget package, sign, and publish + - script: eng\cibuild.cmd + -restore + -pack + -sign $(_SignArgs) + -publish $(_PublishArgs) + -configuration $(_BuildConfig) + $(_OfficialBuildIdArgs) + $(_InternalRuntimeDownloadArgs) + /bl:$(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig)\PackSignPublish-${{ parameters.targetArchitecture }}.binlog + displayName: Pack, Sign, and Publish + + # Upload code coverage data + - script: $(Build.SourcesDirectory)/.dotnet/dotnet msbuild -restore + eng/CodeCoverage.proj + /p:Configuration=$(_BuildConfig) + $(_InternalRuntimeDownloadArgs) + /bl:$(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig)\CodeCoverage-${{ parameters.targetArchitecture }}.binlog + displayName: Upload coverage to codecov.io + condition: and(succeeded(), eq(variables._Coverage, 'true')) + + # Generate SBOM for the internal leg only + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - template: ..\common\templates\steps\generate-sbom.yml + parameters: + name: Generate_SBOM_${{ parameters.name }} + + - template: post-build-PR.yml + parameters: + name: ${{ parameters.name }} diff --git a/eng/pipelines/post-build-PR.yml b/eng/pipelines/post-build-PR.yml new file mode 100644 index 00000000000..38565cb561d --- /dev/null +++ b/eng/pipelines/post-build-PR.yml @@ -0,0 +1,92 @@ + +parameters: + name: '' + enableMicrobuild: true + enablePublishBuildArtifacts: true + enablePublishTestResults: true + enablePublishBuildAssets: true + enablePublishUsingPipelines: true + testResultsFormat: 'xunit' + +steps: + - ${{ if eq(parameters.enableRichCodeNavigation, true) }}: + - task: RichCodeNavIndexer@0 + displayName: RichCodeNav Upload + inputs: + languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }} + environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'production') }} + richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin + continueOnError: true + + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: MicroBuildCleanup@1 + displayName: Execute Microbuild cleanup tasks + condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + env: + TeamName: $(_TeamName) + + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if or(eq(parameters.artifacts.publish.artifacts, 'true'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - task: CopyFiles@2 + displayName: Gather binaries for publish to artifacts + inputs: + SourceFolder: 'artifacts/bin' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' + - task: CopyFiles@2 + displayName: Gather packages for publish to artifacts + inputs: + SourceFolder: 'artifacts/packages' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' + - task: PublishBuildArtifacts@1 + displayName: Publish pipeline artifacts + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' + PublishLocation: Container + ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} + continueOnError: true + condition: always() + - ${{ if or(eq(parameters.artifacts.publish.logs, 'true'), ne(parameters.artifacts.publish.logs, '')) }}: + - publish: artifacts/log + artifact: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: Publish logs + continueOnError: true + condition: always() + + - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: + - task: PublishBuildArtifacts@1 + displayName: Publish Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' + PublishLocation: Container + ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + continueOnError: true + condition: always() + + - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: + - task: PublishTestResults@2 + displayName: Publish XUnit Test Results + inputs: + testResultsFormat: 'xUnit' + testResultsFiles: '*.xml' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + + - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}: + - task: PublishTestResults@2 + displayName: Publish TRX Test Results + inputs: + testResultsFormat: 'VSTest' + testResultsFiles: '*.trx' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + diff --git a/global.json b/global.json index 4663c0d6bec..047880b6f70 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "tools": { - "dotnet": "8.0.101", + "dotnet": "8.0.100", "runtimes": { "dotnet/x64": [ "$(VSRedistCommonNetCoreSharedFrameworkx6480PackageVersion)" @@ -11,16 +11,16 @@ } }, "sdk": { - "version": "8.0.101" + "version": "8.0.100" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24113.2", - "Microsoft.DotNet.CMake.Sdk": "8.0.0-beta.24113.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24113.2", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23564.4", + "Microsoft.DotNet.CMake.Sdk": "8.0.0-beta.23564.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23564.4", "FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0", - "Microsoft.NET.Sdk.IL": "8.0.3-servicing.24114.23" + "Microsoft.NET.Sdk.IL": "8.0.1-servicing.23580.1" }, "native-tools": { "cmake": "latest" } -} +} \ No newline at end of file diff --git a/pkg/Microsoft.Private.Winforms/Microsoft.Private.Winforms.csproj b/pkg/Microsoft.Private.Winforms/Microsoft.Private.Winforms.csproj index 7b6046ee57b..2e658e683cd 100644 --- a/pkg/Microsoft.Private.Winforms/Microsoft.Private.Winforms.csproj +++ b/pkg/Microsoft.Private.Winforms/Microsoft.Private.Winforms.csproj @@ -80,7 +80,7 @@ - + @@ -91,13 +91,11 @@ - + - - - + --> diff --git a/src/Common/tests/TestUtilities/AppContextSwitchNames.cs b/src/Common/tests/TestUtilities/AppContextSwitchNames.cs deleted file mode 100644 index cfff428ac46..00000000000 --- a/src/Common/tests/TestUtilities/AppContextSwitchNames.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.Serialization.Formatters.Binary; - -namespace System; - -public static class AppContextSwitchNames -{ - /// - /// The switch that controls whether or not the is enabled. - /// - public static string EnableUnsafeBinaryFormatterSerialization { get; } - = "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization"; - - /// - /// Switch that controls switch caching. - /// - public static string LocalAppContext_DisableCaching { get; } - = "TestSwitch.LocalAppContext.DisableCaching"; -} diff --git a/src/Common/tests/TestUtilities/AppContextSwitchScope.cs b/src/Common/tests/TestUtilities/AppContextSwitchScope.cs deleted file mode 100644 index ff771db020b..00000000000 --- a/src/Common/tests/TestUtilities/AppContextSwitchScope.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System; - -/// -/// Scope for temporarily setting an switch. Use in a statement. -/// -/// -/// -/// It is recommended to create wrappers for this struct for both simplicity and to allow adding synchronization. -/// See for an example of doing this. -/// -/// -public readonly ref struct AppContextSwitchScope -{ - private readonly string _switchName; - private readonly bool _originalState; - - public AppContextSwitchScope(string switchName, bool enable) - { - if (!AppContext.TryGetSwitch(AppContextSwitchNames.LocalAppContext_DisableCaching, out bool isEnabled) - || !isEnabled) - { - // It doesn't make sense to try messing with AppContext switches if they are going to be cached. - throw new InvalidOperationException("LocalAppContext switch caching is not disabled."); - } - - AppContext.TryGetSwitch(switchName, out _originalState); - - AppContext.SetSwitch(switchName, enable); - if (!AppContext.TryGetSwitch(switchName, out isEnabled) || isEnabled != enable) - { - throw new InvalidOperationException($"Could not set {switchName} to {enable}."); - } - - _switchName = switchName; - } - - public void Dispose() - { - AppContext.SetSwitch(_switchName, _originalState); - if (!AppContext.TryGetSwitch(_switchName, out bool isEnabled) || isEnabled != _originalState) - { - throw new InvalidOperationException($"Could not reset {_switchName} to {_originalState}."); - } - } -} diff --git a/src/Common/tests/TestUtilities/BinaryFormatterScope.cs b/src/Common/tests/TestUtilities/BinaryFormatterScope.cs deleted file mode 100644 index ba22e532693..00000000000 --- a/src/Common/tests/TestUtilities/BinaryFormatterScope.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.Serialization.Formatters.Binary; - -namespace System; - -/// -/// Scope for enabling / disabling the . Use in a statement. -/// -public readonly ref struct BinaryFormatterScope -{ - private readonly AppContextSwitchScope _switchScope; - - public BinaryFormatterScope(bool enable) - { - // Prevent multiple BinaryFormatterScopes from running simultaneously. Using Monitor to allow recursion on - // the same thread. - Monitor.Enter(typeof(BinaryFormatterScope)); - _switchScope = new AppContextSwitchScope(AppContextSwitchNames.EnableUnsafeBinaryFormatterSerialization, enable); - } - - public void Dispose() - { - try - { - _switchScope.Dispose(); - } - finally - { - Monitor.Exit(typeof(BinaryFormatterScope)); - } - } - - static BinaryFormatterScope() - { - // Need to explicitly set the switch to whatever the default is as its default value is in transition. - -#pragma warning disable SYSLIB0011 // Type or member is obsolete - BinaryFormatter formatter = new(); -#pragma warning restore SYSLIB0011 // Type or member is obsolete - try - { -#pragma warning disable SYSLIB0011 // Type or member is obsolete - formatter.Serialize(null!, null!); -#pragma warning restore SYSLIB0011 - } - catch (NotSupportedException) - { - AppContext.SetSwitch(AppContextSwitchNames.EnableUnsafeBinaryFormatterSerialization, false); - return; - } - catch (ArgumentNullException) - { - AppContext.SetSwitch(AppContextSwitchNames.EnableUnsafeBinaryFormatterSerialization, true); - return; - } - - throw new InvalidOperationException(); - } -} diff --git a/src/Common/tests/TestUtilities/BinarySerialization.cs b/src/Common/tests/TestUtilities/BinarySerialization.cs deleted file mode 100644 index 02e2e5a3a20..00000000000 --- a/src/Common/tests/TestUtilities/BinarySerialization.cs +++ /dev/null @@ -1,104 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.Serialization.Formatters; -using System.Runtime.Serialization.Formatters.Binary; - -namespace System; - -public static class BinarySerialization -{ - public static void EnsureSerializableAttribute(Assembly assemblyUnderTest, HashSet serializableTypes) - { - foreach (Type type in assemblyUnderTest.GetTypes()) - { - var attributes = Attribute.GetCustomAttributes(type); - string? fullName = type.FullName; - if (fullName is null) - { - continue; - } - - if (!attributes.Any(a => a is SerializableAttribute)) - { - // the type isn't marked as serializable, verify it is not one of the types - // that we expect to be serializable - if (serializableTypes.Contains(fullName)) - { - throw new NotSupportedException($"Serializable attribute is expected on {fullName}"); - } - - continue; - } - - if (attributes.Any(a => a is CompilerGeneratedAttribute)) - { - // ignore compiler generated types, we have no control over them - continue; - } - - // Ensure SerializableAttribute is not added to any types not in the known list. - if (serializableTypes.Contains(fullName)) - { - // we have marked the type as serializable, all good - continue; - } - - throw new NotSupportedException($"Serializable attribute is not expected on {type.FullName}"); - } - } - -#pragma warning disable SYSLIB0050 // Type or member is obsolete - public static T EnsureDeserialize(string blob) - { - var @object = FromBase64String(blob); - Assert.NotNull(@object); - return Assert.IsType(@object); - - static object FromBase64String(string base64String, - FormatterAssemblyStyle assemblyStyle = FormatterAssemblyStyle.Simple) - { - byte[] raw = Convert.FromBase64String(base64String); - return FromByteArray(raw, assemblyStyle); - } - - static object FromByteArray(byte[] raw, - FormatterAssemblyStyle assemblyStyle = FormatterAssemblyStyle.Simple) - { -#pragma warning disable SYSLIB0011 // Type or member is obsolete - BinaryFormatter binaryFormatter = new() - { - AssemblyFormat = assemblyStyle - }; -#pragma warning restore SYSLIB0011 // Type or member is obsolete - - using MemoryStream serializedStream = new(raw); - return binaryFormatter.Deserialize(serializedStream); - } - } - - public static string ToBase64String(object @object, - FormatterAssemblyStyle assemblyStyle = FormatterAssemblyStyle.Simple) - { - byte[] raw = ToByteArray(@object, assemblyStyle); - return Convert.ToBase64String(raw); - - static byte[] ToByteArray(object obj, - FormatterAssemblyStyle assemblyStyle = FormatterAssemblyStyle.Simple) - { -#pragma warning disable SYSLIB0011 // Type or member is obsolete - BinaryFormatter binaryFormatter = new() - { - AssemblyFormat = assemblyStyle - }; -#pragma warning restore SYSLIB0011 // Type or member is obsolete - - using MemoryStream stream = new(); - binaryFormatter.Serialize(stream, obj); - return stream.ToArray(); - } - } -#pragma warning restore SYSLIB0050 // Type or member is obsolete -} diff --git a/src/Common/tests/TestUtilities/CommonTestHelper.cs b/src/Common/tests/TestUtilities/CommonTestHelper.cs deleted file mode 100644 index a70c320a385..00000000000 --- a/src/Common/tests/TestUtilities/CommonTestHelper.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design.Serialization; -using System.Drawing; - -namespace System.Windows.Forms.TestUtilities; - -public static class CommonTestHelper -{ - #region Primitives - - public static TheoryData GetCtrlBackspaceData() - => new() - { - { "aaa", "", 0 }, - { "---", "", 0 }, - { " aaa", "", 0 }, - { " ---", "", 0 }, - { "aaa---", "", 0 }, - { "---aaa", "---", 0 }, - { "aaa---aaa", "aaa---", 0 }, - { "---aaa---", "---", 0 }, - { "a-a", "a-", 0 }, - { "-a-", "", 0 }, - { "--a-", "--", 0 }, - { "abc", "c", -1 }, - { "a,1-b", "a,b", -1 } - }; - - public static TheoryData GetCtrlBackspaceRepeatedData() - => new() - { - { "aaa", "", 2 }, - { "---", "", 2 }, - { "aaa---aaa", "", 2 }, - { "---aaa---", "", 2 }, - { "aaa bbb", "", 2 }, - { "aaa bbb ccc", "aaa ", 2 }, - { "aaa --- ccc", "", 2 }, - { "1 2 3 4 5 6 7 8 9 0", "1 ", 9 } - }; - - public static TheoryData GetCharTheoryData() - => new() - { - '\0', - 'a' - }; - - public static TheoryData GetIntPtrTheoryData() - => new() - { - (IntPtr)(-1), - IntPtr.Zero, - (IntPtr)1 - }; - - public static TheoryData GetColorTheoryData() - => new() - { - Color.Red, - Color.Blue, - Color.Black - }; - - public static TheoryData GetColorWithEmptyTheoryData() - => new() - { - Color.Red, - Color.Empty - }; - - public static TheoryData GetPointTheoryData() => GetPointTheoryData(TestIncludeType.All); - - public static TheoryData GetPointTheoryData(TestIncludeType includeType) - { - TheoryData data = new(); - if (!includeType.HasFlag(TestIncludeType.NoPositives)) - { - data.Add(new Point()); - data.Add(new Point(10)); - data.Add(new Point(1, 2)); - } - - if (!includeType.HasFlag(TestIncludeType.NoNegatives)) - { - data.Add(new Point(int.MaxValue, int.MinValue)); - data.Add(new Point(-1, -2)); - } - - return data; - } - - public static TheoryData GetSizeTheoryData() => GetSizeTheoryData(TestIncludeType.All); - - public static TheoryData GetSizeTheoryData(TestIncludeType includeType) - { - TheoryData data = new(); - if (!includeType.HasFlag(TestIncludeType.NoPositives)) - { - data.Add(new Size()); - data.Add(new Size(new Point(1, 1))); - data.Add(new Size(1, 2)); - } - - if (!includeType.HasFlag(TestIncludeType.NoNegatives)) - { - data.Add(new Size(-1, 1)); - data.Add(new Size(1, -1)); - } - - return data; - } - - public static TheoryData GetConvertFromTheoryData() - => new() - { - { typeof(bool), false }, - { typeof(InstanceDescriptor), true }, - { typeof(int), false }, - { typeof(double), false }, - { null, false } - }; - - public static TheoryData GetEventArgsTheoryData() - => new() - { - null, - new EventArgs() - }; - - #endregion -} diff --git a/src/Common/tests/TestUtilities/ComparisonHelpers.cs b/src/Common/tests/TestUtilities/ComparisonHelpers.cs deleted file mode 100644 index a80634fa30d..00000000000 --- a/src/Common/tests/TestUtilities/ComparisonHelpers.cs +++ /dev/null @@ -1,112 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Numerics; - -namespace System; - -public static class ComparisonHelpers -{ - public static bool EqualsInteger(T x, T y, T variance) - where T : struct, IBinaryInteger - { - ArgumentOutOfRangeException.ThrowIfLessThan(variance, T.Zero); - - return T.Abs(x > y ? x - y : y - x) <= variance; - } - - public static bool EqualsFloating(T x, T y, T variance) - where T : struct, IFloatingPoint - { - ArgumentOutOfRangeException.ThrowIfLessThan(variance, T.Zero); - - if (T.IsNaN(x)) - { - return T.IsNaN(y); - } - else if (T.IsNaN(y)) - { - return false; - } - - if (T.IsNegativeInfinity(x)) - { - return T.IsNegativeInfinity(y); - } - else if (T.IsNegativeInfinity(y)) - { - return false; - } - - if (T.IsPositiveInfinity(x)) - { - return T.IsPositiveInfinity(y); - } - else if (T.IsPositiveInfinity(y)) - { - return false; - } - - if (IsNegativeZero(x)) - { - if (IsNegativeZero(y)) - { - return true; - } - - if (IsPositiveZero(variance) || IsNegativeZero(variance)) - { - return false; - } - - // When the variance is not +-0.0, then we are handling a case where - // the actual result is expected to not be exactly -0.0 on some platforms - // and we should fallback to checking if it is within the allowed variance instead. - } - else if (IsNegativeZero(y)) - { - if (IsPositiveZero(variance) || IsNegativeZero(variance)) - { - return false; - } - - // When the variance is not +-0.0, then we are handling a case where - // the actual result is expected to not be exactly -0.0 on some platforms - // and we should fallback to checking if it is within the allowed variance instead. - } - - if (IsPositiveZero(x)) - { - if (IsPositiveZero(y)) - { - return true; - } - - if (IsPositiveZero(variance) || IsNegativeZero(variance)) - { - return false; - } - - // When the variance is not +-0.0, then we are handling a case where - // the actual result is expected to not be exactly +0.0 on some platforms - // and we should fallback to checking if it is within the allowed variance instead. - } - else if (IsPositiveZero(y)) - { - if (IsPositiveZero(variance) || IsNegativeZero(variance)) - { - return false; - } - - // When the variance is not +-0.0, then we are handling a case where - // the actual result is expected to not be exactly +0.0 on some platforms - // and we should fallback to checking if it is within the allowed variance instead. - } - - return T.Abs(x > y ? x - y : y - x) <= variance; - - static unsafe bool IsNegativeZero(T value) => T.IsZero(value) && T.IsNegative(value); - - static unsafe bool IsPositiveZero(T value) => T.IsZero(value) && T.IsPositive(value); - } -} diff --git a/src/Common/tests/TestUtilities/CustomConverter.cs b/src/Common/tests/TestUtilities/CustomConverter.cs deleted file mode 100644 index aa71a40908d..00000000000 --- a/src/Common/tests/TestUtilities/CustomConverter.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; - -namespace System; - -public static class CustomConverter -{ - /// - /// Registers a TypeConverter with the specified type. - /// - public static RegistrationScope RegisterConverter(Type type, TypeConverter converter) - { - ArgumentNullException.ThrowIfNull(type); - ArgumentNullException.ThrowIfNull(converter); - - TypeDescriptionProvider parentProvider = TypeDescriptor.GetProvider(type); - CustomTypeDescriptionProvider newProvider = new(parentProvider, converter); - TypeDescriptor.AddProvider(newProvider, type); - return new RegistrationScope(type, newProvider); - } - - /// - /// Manages the registration lifetime of a TypeConverter to a type. - /// This is meant to be utilized in a statement to ensure - /// is called when going out of scope with the using. - /// - public readonly ref struct RegistrationScope - { - private readonly Type _type; - private readonly TypeDescriptionProvider _provider; - - public RegistrationScope(Type type, TypeDescriptionProvider provider) - { - _type = type; - _provider = provider; - } - - public void Dispose() => TypeDescriptor.RemoveProvider(_provider, _type); - } - - public class CustomTypeDescriptionProvider : TypeDescriptionProvider - { - private TypeConverter _converter; - - public CustomTypeDescriptionProvider(TypeDescriptionProvider parent, TypeConverter converter) : base(parent) - => _converter = converter; - - public override ICustomTypeDescriptor GetTypeDescriptor( - [DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type objectType, - object? instance) => new TypeConverterProvider(base.GetTypeDescriptor(objectType, instance), _converter); - - private class TypeConverterProvider : CustomTypeDescriptor - { - private TypeConverter _converter; - - public TypeConverterProvider(ICustomTypeDescriptor? parent, TypeConverter converter) : base(parent) - => _converter = converter; - - public override TypeConverter GetConverter() => _converter; - } - } -} diff --git a/src/Common/tests/TestUtilities/DebuggerAttributes.cs b/src/Common/tests/TestUtilities/DebuggerAttributes.cs deleted file mode 100644 index fcfd25b495f..00000000000 --- a/src/Common/tests/TestUtilities/DebuggerAttributes.cs +++ /dev/null @@ -1,232 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable disable - -using System.Reflection; -using System.Text; - -namespace System.Diagnostics; - -internal class DebuggerAttributeInfo -{ - public object Instance { get; set; } - public IEnumerable Properties { get; set; } -} - -internal static class DebuggerAttributes -{ - internal static object GetFieldValue(object obj, string fieldName) - { - return GetField(obj, fieldName).GetValue(obj); - } - - internal static void InvokeDebuggerTypeProxyProperties(object obj) - { - DebuggerAttributeInfo info = ValidateDebuggerTypeProxyProperties(obj.GetType(), obj); - foreach (PropertyInfo pi in info.Properties) - { - pi.GetValue(info.Instance, null); - } - } - - internal static DebuggerAttributeInfo ValidateDebuggerTypeProxyProperties(object obj) - { - return ValidateDebuggerTypeProxyProperties(obj.GetType(), obj); - } - - internal static DebuggerAttributeInfo ValidateDebuggerTypeProxyProperties(Type type, object obj) - { - return ValidateDebuggerTypeProxyProperties(type, type.GenericTypeArguments, obj); - } - - internal static DebuggerAttributeInfo ValidateDebuggerTypeProxyProperties(Type type, Type[] genericTypeArguments, object obj) - { - Type proxyType = GetProxyType(type, genericTypeArguments); - - // Create an instance of the proxy type, and make sure we can access all of the instance properties - // on the type without exception - object proxyInstance = Activator.CreateInstance(proxyType, obj); - IEnumerable properties = GetDebuggerVisibleProperties(proxyType); - return new DebuggerAttributeInfo - { - Instance = proxyInstance, - Properties = properties - }; - } - - public static DebuggerBrowsableState? GetDebuggerBrowsableState(MemberInfo info) - { - CustomAttributeData debuggerBrowsableAttribute = info.CustomAttributes - .SingleOrDefault(a => a.AttributeType == typeof(DebuggerBrowsableAttribute)); - // Enums in attribute constructors are boxed as ints, so cast to int? first. - return (DebuggerBrowsableState?)(int?)debuggerBrowsableAttribute?.ConstructorArguments.Single().Value; - } - - public static IEnumerable GetDebuggerVisibleFields(Type debuggerAttributeType) - { - // The debugger doesn't evaluate non-public members of type proxies. - IEnumerable visibleFields = debuggerAttributeType.GetFields() - .Where(fi => fi.IsPublic && GetDebuggerBrowsableState(fi) != DebuggerBrowsableState.Never); - return visibleFields; - } - - public static IEnumerable GetDebuggerVisibleProperties(Type debuggerAttributeType) - { - // The debugger doesn't evaluate non-public members of type proxies. GetGetMethod returns null if the getter is non-public. - IEnumerable visibleProperties = debuggerAttributeType.GetProperties() - .Where(pi => pi.GetGetMethod() is object && GetDebuggerBrowsableState(pi) != DebuggerBrowsableState.Never); - return visibleProperties; - } - - public static object GetProxyObject(object obj) => Activator.CreateInstance(GetProxyType(obj), obj); - - public static Type GetProxyType(object obj) => GetProxyType(obj.GetType()); - - public static Type GetProxyType(Type type) => GetProxyType(type, type.GenericTypeArguments); - - private static Type GetProxyType(Type type, Type[] genericTypeArguments) - { - // Get the DebuggerTypeProxyAttribute for obj - CustomAttributeData[] attrs = - type.GetTypeInfo().CustomAttributes - .Where(a => a.AttributeType == typeof(DebuggerTypeProxyAttribute)) - .ToArray(); - if (attrs.Length != 1) - { - throw new InvalidOperationException($"Expected one DebuggerTypeProxyAttribute on {type}."); - } - - CustomAttributeData cad = attrs[0]; - - Type proxyType = cad.ConstructorArguments[0].ArgumentType == typeof(Type) ? - (Type)cad.ConstructorArguments[0].Value : - Type.GetType((string)cad.ConstructorArguments[0].Value); - if (genericTypeArguments.Length > 0) - { - proxyType = proxyType.MakeGenericType(genericTypeArguments); - } - - return proxyType; - } - - internal static string ValidateDebuggerDisplayReferences(object obj) - { - // Get the DebuggerDisplayAttribute for obj - Type objType = obj.GetType(); - CustomAttributeData[] attrs = - objType.GetTypeInfo().CustomAttributes - .Where(a => a.AttributeType == typeof(DebuggerDisplayAttribute)) - .ToArray(); - if (attrs.Length != 1) - { - throw new InvalidOperationException($"Expected one DebuggerDisplayAttribute on {objType}."); - } - - CustomAttributeData cad = attrs[0]; - - // Get the text of the DebuggerDisplayAttribute - string attrText = (string)cad.ConstructorArguments[0].Value; - - string[] segments = attrText.Split(new[] { '{', '}' }); - - if (segments.Length % 2 == 0) - { - throw new InvalidOperationException($"The DebuggerDisplayAttribute for {objType} lacks a closing brace."); - } - - if (segments.Length == 1) - { - throw new InvalidOperationException($"The DebuggerDisplayAttribute for {objType} doesn't reference any expressions."); - } - - StringBuilder sb = new(); - - for (int i = 0; i < segments.Length; i += 2) - { - string literal = segments[i]; - sb.Append(literal); - - if (i + 1 < segments.Length) - { - string reference = segments[i + 1]; - bool noQuotes = reference.EndsWith(",nq"); - - reference = reference.Replace(",nq", string.Empty); - - // Evaluate the reference. - object member; - if (!TryEvaluateReference(obj, reference, out member)) - { - throw new InvalidOperationException($"The DebuggerDisplayAttribute for {objType} contains the expression \"{reference}\"."); - } - - string memberString = GetDebuggerMemberString(member, noQuotes); - - sb.Append(memberString); - } - } - - return sb.ToString(); - } - - private static string GetDebuggerMemberString(object member, bool noQuotes) - { - return member switch - { - null => "null", - byte or sbyte or short or ushort or int or uint or long or ulong or float or double => member.ToString(), - string _ when noQuotes => member.ToString(), - string => $"\"{member}\"", - _ => $"{{{member}}}" - }; - } - - private static bool TryEvaluateReference(object obj, string reference, out object member) - { - PropertyInfo pi = GetProperty(obj, reference); - if (pi is object) - { - member = pi.GetValue(obj); - return true; - } - - FieldInfo fi = GetField(obj, reference); - if (fi is object) - { - member = fi.GetValue(obj); - return true; - } - - member = null; - return false; - } - - private static FieldInfo GetField(object obj, string fieldName) - { - for (Type t = obj.GetType(); t is object; t = t.GetTypeInfo().BaseType) - { - FieldInfo fi = t.GetTypeInfo().GetDeclaredField(fieldName); - if (fi is object) - { - return fi; - } - } - - return null; - } - - private static PropertyInfo GetProperty(object obj, string propertyName) - { - for (Type t = obj.GetType(); t is object; t = t.GetTypeInfo().BaseType) - { - PropertyInfo pi = t.GetTypeInfo().GetDeclaredProperty(propertyName); - if (pi is object) - { - return pi; - } - } - - return null; - } -} diff --git a/src/Common/tests/TestUtilities/FileCleanupTestBase.cs b/src/Common/tests/TestUtilities/FileCleanupTestBase.cs deleted file mode 100644 index 1dfb32d0278..00000000000 --- a/src/Common/tests/TestUtilities/FileCleanupTestBase.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System; - -public abstract class FileCleanupTestBase : IDisposable -{ - public readonly string TestDirectory; - - protected FileCleanupTestBase() - { - TestDirectory = Path.Combine(Path.GetTempPath(), GetUniqueName()); - Directory.CreateDirectory(TestDirectory); - } - - ~FileCleanupTestBase() - { - Dispose(false); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - try - { - Directory.Delete(TestDirectory); - } - catch - { - } - } - - public string GetTestFilePath() => Path.Combine(TestDirectory, GetTestFileName()); - - public string GetTestFileName() => GetUniqueName(); - - private static string GetUniqueName() => Guid.NewGuid().ToString("D"); -} diff --git a/src/Common/tests/TestUtilities/GlobalUsings.cs b/src/Common/tests/TestUtilities/GlobalUsings.cs deleted file mode 100644 index 581f24df927..00000000000 --- a/src/Common/tests/TestUtilities/GlobalUsings.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -global using System.Diagnostics.CodeAnalysis; -global using Xunit; diff --git a/src/Common/tests/TestUtilities/ITestAccessor.cs b/src/Common/tests/TestUtilities/ITestAccessor.cs deleted file mode 100644 index d9f706c29e6..00000000000 --- a/src/Common/tests/TestUtilities/ITestAccessor.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System; - -/// -/// Interface for accessing internals from tests. -/// -/// -/// -/// A non generic representation of the accessor functionality is needed to -/// allow dynamically creating arbitrary from -/// helper methods. -/// -/// -public interface ITestAccessor -{ - /// - /// Gets a dynamic accessor to internals on the test object. - /// - /// - /// - /// This does not work for ref structs as they are not yet accessible via reflection. - /// See https://github.com/dotnet/runtime/issues/10057. - /// - /// - dynamic Dynamic { get; } - - /// - /// Creates a delegate for the given non-public method. - /// - /// - /// The method name. If null, uses the name of the delegate for the method. - /// - /// - /// - /// This provides a way to access methods that take ref structs. - /// - /// - /// - /// path); - /// - /// public int InternalGetDirectoryNameOffset(ReadOnlySpan path) - /// { - /// var accessor = typeof(System.IO.Path).TestAccessor(); - /// return accessor.CreateDelegate()(@"C:\Foo"); - /// } - /// - /// // Without ref structs you can just use Func/Action - /// var accessor = typeof(Color).TestAccessor(); - /// bool result = accessor.CreateDelegate>("IsKnownColorSystem")(KnownColor.Window); - /// ]]> - /// - TDelegate CreateDelegate(string? methodName = null) - where TDelegate : Delegate; -} diff --git a/src/Common/tests/TestUtilities/ModuleInitializer.cs b/src/Common/tests/TestUtilities/ModuleInitializer.cs deleted file mode 100644 index 2cb757018d6..00000000000 --- a/src/Common/tests/TestUtilities/ModuleInitializer.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace System; - -internal static class ModuleInitializer -{ - [ModuleInitializer] - [SuppressMessage("Usage", "CA2255:The 'ModuleInitializer' attribute should not be used in libraries", Justification = "Intentional use of module initializer to register trace listener.")] - internal static void Initialize() - { - Trace.Listeners.Clear(); - Trace.Listeners.Add(ThrowingTraceListener.Instance); - } -} diff --git a/src/Common/tests/TestUtilities/ReflectionHelper.cs b/src/Common/tests/TestUtilities/ReflectionHelper.cs deleted file mode 100644 index f5395289855..00000000000 --- a/src/Common/tests/TestUtilities/ReflectionHelper.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; - -namespace System; - -public static class ReflectionHelper -{ - public static IEnumerable GetPublicNotAbstractClasses() - { - var types = typeof(T).Assembly.GetTypes().Where(type => IsPublicNonAbstract(type)); - foreach (var type in types) - { - if (type.GetConstructor( - bindingAttr: BindingFlags.Public | BindingFlags.Instance, - binder: null, - types: Array.Empty(), - modifiers: null) is null) - { - continue; - } - - yield return type; - } - } - - public static T? InvokePublicConstructor(Type type) - { - var ctor = type.GetConstructor( - bindingAttr: BindingFlags.Public | BindingFlags.Instance, - binder: null, - types: Array.Empty(), - modifiers: null); - - if (ctor is null) - { - return default; - } - - T obj = (T)ctor.Invoke(Array.Empty()); - Assert.NotNull(obj); - return obj; - } - - private static bool IsPublicNonAbstract(Type type) - { - return !type.IsAbstract && type.IsPublic && typeof(T).IsAssignableFrom(type); - } -} diff --git a/src/Common/tests/TestUtilities/System.Windows.Forms.Common.TestUtilities.csproj b/src/Common/tests/TestUtilities/System.Windows.Forms.Common.TestUtilities.csproj deleted file mode 100644 index 21e788b7cfe..00000000000 --- a/src/Common/tests/TestUtilities/System.Windows.Forms.Common.TestUtilities.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - System.Windows.Forms.Common.TestUtilities - true - System - enable - - - - - - - - - - - - diff --git a/src/Common/tests/TestUtilities/TempFile.cs b/src/Common/tests/TestUtilities/TempFile.cs deleted file mode 100644 index 1a0d0cfa2e5..00000000000 --- a/src/Common/tests/TestUtilities/TempFile.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -namespace System.IO; - -/// -/// Represents a temporary file. Creating an instance creates a file at the specified path, -/// and disposing the instance deletes the file. -/// -/// -/// This is copied verbatim from TempFile.cs in dotnet/runtime (https://github.com/dotnet/runtime/blob/master/src/libraries/Common/tests/System/IO/TempFile.cs) -/// -public sealed class TempFile : IDisposable -{ - /// Gets the created file's path. - public string Path { get; } - - public TempFile(string path, long length = 0) : this(path, length > -1 ? new byte[length] : null) - { - } - - public TempFile(string path, byte[]? data) - { - Path = path; - - if (data is not null) - { - File.WriteAllBytes(path, data); - } - } - - public TempFile(string path, string text) - { - Path = path; - - File.WriteAllText(path, text); - } - - ~TempFile() => DeleteFile(); - - public static TempFile Create( - byte[] bytes, - [CallerMemberName] string? memberName = null, - [CallerLineNumber] int lineNumber = 0) - => new(GetFilePath(memberName, lineNumber), bytes); - - public static TempFile Create( - string text, - [CallerMemberName] string? memberName = null, - [CallerLineNumber] int lineNumber = 0) - => new(GetFilePath(memberName, lineNumber), text); - - public static TempFile Create( - long length = -1, - [CallerMemberName] string? memberName = null, - [CallerLineNumber] int lineNumber = 0) - => new(GetFilePath(memberName, lineNumber), length); - - public void AssertExists() => Assert.True(File.Exists(Path)); - - public string ReadAllText() => File.ReadAllText(Path); - - public void Dispose() - { - GC.SuppressFinalize(this); - DeleteFile(); - } - - private void DeleteFile() - { - try - { File.Delete(Path); } - catch { /* Ignore exceptions on disposal paths */ } - } - - private static string GetFilePath(string? memberName, int lineNumber) - { - string file = $"{IO.Path.GetRandomFileName()}_{memberName}_{lineNumber}"; - return IO.Path.Combine(IO.Path.GetTempPath(), file); - } -} diff --git a/src/Common/tests/TestUtilities/TestAccessor.cs b/src/Common/tests/TestUtilities/TestAccessor.cs deleted file mode 100644 index e5a91cd1982..00000000000 --- a/src/Common/tests/TestUtilities/TestAccessor.cs +++ /dev/null @@ -1,214 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Dynamic; -using System.Reflection; - -namespace System; - -/// -/// Internals (including privates) access wrapper for tests. -/// -/// The type of the class being accessed. -/// -/// Does not allow access to public members- use the object directly. -/// -/// One should strive to *not* access internal state where otherwise avoidable. -/// Ask yourself if you can test the contract of the object in question -/// *without* manipulating internals directly. Often you can. -/// -/// Where internals access is more useful are testing building blocks of more -/// complicated objects, such as internal helper methods or classes. -/// -/// This can be used to access private/internal objects as well via -/// -/// -/// This class can also be derived from to create a strongly typed wrapper -/// that can then be associated via an extension method for the given type -/// to provide consistent discovery and access. -/// -/// -/// { -/// public TestAccessor(Guid instance) : base(instance) {} -/// -/// public int A => Dynamic._a; -/// } -/// -/// public static partial class TestAccessors -/// { -/// public static GuidTestAccessor TestAccessor(this Guid guid) -/// => new GuidTestAccessor(guid); -/// } -/// ]]> -/// -public class TestAccessor : ITestAccessor -{ - private static readonly Type s_type = typeof(T); - protected readonly T? _instance; - private readonly DynamicWrapper _dynamicWrapper; - - /// The type instance, can be null for statics. - public TestAccessor(T? instance) - { - _instance = instance; - _dynamicWrapper = new DynamicWrapper(_instance); - } - - /// - public TDelegate CreateDelegate(string? methodName = null) - where TDelegate : Delegate - { - Type type = typeof(TDelegate); - MethodInfo? invokeMethodInfo = type.GetMethod("Invoke"); - Type[] types = invokeMethodInfo is null ? Array.Empty() : invokeMethodInfo.GetParameters().Select(pi => pi.ParameterType).ToArray(); - - // To make it easier to write a class wrapper with a number of delegates, - // we'll take the name from the delegate itself when unspecified. - methodName ??= type.Name; - - MethodInfo? methodInfo = s_type.GetMethod( - methodName, - BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, - binder: null, - types, - modifiers: null); - - if (methodInfo is null) - throw new ArgumentException($"Could not find non public method {methodName}."); - - return (TDelegate)methodInfo.CreateDelegate(type, methodInfo.IsStatic ? null : _instance); - } - - /// - public dynamic Dynamic => _dynamicWrapper; - - private class DynamicWrapper : DynamicObject - { - private readonly object? _instance; - - public DynamicWrapper(object? instance) - => _instance = instance; - - public override bool TryInvokeMember(InvokeMemberBinder binder, object?[]? args, out object? result) - { - result = null; - ArgumentNullException.ThrowIfNull(args); - ArgumentNullException.ThrowIfNull(binder); - - MethodInfo? methodInfo = null; - Type? type = s_type; - - do - { - try - { - methodInfo = type?.GetMethod( - binder.Name, - BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); - } - catch (AmbiguousMatchException) - { - // More than one match for the name, specify the arguments. - // We currently do not have a scenario where we are trying to pass null as an argument - // to an overloaded method. This will need to be updated once we have a scenario. - methodInfo = type?.GetMethod( - binder.Name, - BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, - binder: null, - args.Select(a => a!.GetType()).ToArray(), - modifiers: null); - } - - if (methodInfo is not null || type == typeof(object)) - { - // Found something, or already at the top of the type heirarchy - break; - } - - // Walk up the heirarchy - type = type?.BaseType; - } - while (true); - - if (methodInfo is null) - return false; - - result = methodInfo.Invoke(_instance, args); - return true; - } - - public override bool TrySetMember(SetMemberBinder binder, object? value) - { - MemberInfo? info = GetFieldOrPropertyInfo(binder.Name); - if (info is null) - return false; - - SetValue(info, value); - return true; - } - - public override bool TryGetMember(GetMemberBinder binder, out object? result) - { - result = null; - - MemberInfo? info = GetFieldOrPropertyInfo(binder.Name); - if (info is null) - return false; - - result = GetValue(info); - return true; - } - - private MemberInfo? GetFieldOrPropertyInfo(string memberName) - { - Type? type = s_type; - MemberInfo? info; - - do - { - info = (MemberInfo?)type?.GetField( - memberName, - BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic) - ?? type?.GetProperty( - memberName, - BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic); - - if (info is not null || type == typeof(object)) - { - // Found something, or already at the top of the type heirarchy - break; - } - - // Walk up the type heirarchy - type = type?.BaseType; - } - while (true); - - return info; - } - - private object? GetValue(MemberInfo memberInfo) - => memberInfo switch - { - FieldInfo fieldInfo => fieldInfo.GetValue(_instance), - PropertyInfo propertyInfo => propertyInfo.GetValue(_instance), - _ => throw new InvalidOperationException() - }; - - private void SetValue(MemberInfo memberInfo, object? value) - { - switch (memberInfo) - { - case FieldInfo fieldInfo: - fieldInfo.SetValue(_instance, value); - break; - case PropertyInfo propertyInfo: - propertyInfo.SetValue(_instance, value); - break; - default: - throw new InvalidOperationException(); - } - } - } -} diff --git a/src/Common/tests/TestUtilities/TestAccessors.cs b/src/Common/tests/TestUtilities/TestAccessors.cs deleted file mode 100644 index 50250220628..00000000000 --- a/src/Common/tests/TestUtilities/TestAccessors.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System; - -/// -/// Extension methods for associating internals test accessors with -/// types being tested. -/// -/// -/// In the System namespace for implicit discovery. -/// -public static partial class TestAccessors -{ - // Need to pass a null parameter when constructing a static instance - // of TestAccessor. As this is pretty common and never changes, caching - // the array here. - private static object?[] s_nullObjectParam = { null }; - - /// - /// Extension that creates a generic internals test accessor for a - /// given instance or Type class (if only accessing statics). - /// - /// - /// Instance or Type class (if only accessing statics). - /// - /// - /// - /// - public static ITestAccessor TestAccessor(this object instanceOrType) - { - ITestAccessor? testAccessor = instanceOrType is Type type - ? (ITestAccessor?)Activator.CreateInstance( - typeof(TestAccessor<>).MakeGenericType(type), - s_nullObjectParam) - : (ITestAccessor?)Activator.CreateInstance( - typeof(TestAccessor<>).MakeGenericType(instanceOrType.GetType()), - instanceOrType); - - if (testAccessor is null) - { - throw new ArgumentException("Cannot create TestAccessor for Nullable instances with no value."); - } - - return testAccessor; - } -} diff --git a/src/Common/tests/TestUtilities/TestIncludeType.cs b/src/Common/tests/TestUtilities/TestIncludeType.cs deleted file mode 100644 index f65421e8124..00000000000 --- a/src/Common/tests/TestUtilities/TestIncludeType.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.TestUtilities; - -[Flags] -public enum TestIncludeType -{ - All, - NoPositives, - NoNegatives -} diff --git a/src/Common/tests/TestUtilities/ThreadCultureChange.cs b/src/Common/tests/TestUtilities/ThreadCultureChange.cs deleted file mode 100644 index 715586673af..00000000000 --- a/src/Common/tests/TestUtilities/ThreadCultureChange.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Globalization; - -namespace System; - -public sealed class ThreadCultureChange : IDisposable -{ - private readonly CultureInfo _origCulture = CultureInfo.CurrentCulture; - private readonly CultureInfo _origUICulture = CultureInfo.CurrentUICulture; - - public ThreadCultureChange(string? cultureName) : - this(cultureName is object ? new CultureInfo(cultureName) : null) - { - } - - public ThreadCultureChange(CultureInfo? newCulture) : - this(newCulture, null) - { - } - - public ThreadCultureChange(CultureInfo? newCulture, CultureInfo? newUICulture) - { - if (newCulture is object) - { - _origCulture = CultureInfo.CurrentCulture; - CultureInfo.CurrentCulture = newCulture; - } - - if (newUICulture is object) - { - _origUICulture = CultureInfo.CurrentUICulture; - CultureInfo.CurrentUICulture = newUICulture; - } - } - - public void Dispose() - { - CultureInfo.CurrentCulture = _origCulture; - CultureInfo.CurrentUICulture = _origUICulture; - } -} diff --git a/src/Common/tests/TestUtilities/ThrowingTraceListener.cs b/src/Common/tests/TestUtilities/ThrowingTraceListener.cs deleted file mode 100644 index f85b1a03788..00000000000 --- a/src/Common/tests/TestUtilities/ThrowingTraceListener.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; - -namespace System; - -public sealed class ThrowingTraceListener : TraceListener -{ - public static ThrowingTraceListener Instance { get; } = new(); - - public override void Fail(string? message, string? detailMessage) - { - throw new InvalidOperationException( - (string.IsNullOrEmpty(message) ? "Assertion failed" : message) + - (string.IsNullOrEmpty(detailMessage) ? "" : Environment.NewLine + detailMessage)); - } - - public override void Write(object? o) - { - } - - public override void Write(object? o, string? category) - { - } - - public override void Write(string? message) - { - } - - public override void Write(string? message, string? category) - { - } - - public override void WriteLine(object? o) - { - } - - public override void WriteLine(object? o, string? category) - { - } - - public override void WriteLine(string? message) - { - } - - public override void WriteLine(string? message, string? category) - { - } -} diff --git a/src/Common/tests/TestUtilities/XUnit/BoolDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/BoolDataAttribute.cs deleted file mode 100644 index fe5f3e085e8..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/BoolDataAttribute.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Xunit; - -/// -/// Generates data for true/false. -/// -public class BoolDataAttribute : CommonMemberDataAttribute -{ - public BoolDataAttribute() : base(typeof(BoolDataAttribute), nameof(TheoryData)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = new(true, false); -} diff --git a/src/Common/tests/TestUtilities/XUnit/CommonMemberDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/CommonMemberDataAttribute.cs deleted file mode 100644 index 953f4837f4a..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/CommonMemberDataAttribute.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; - -namespace Xunit; - -/// -/// A custom MemberData attribute that is specialized for the CommonTestHelper type. -/// Useful to remove the need to suffix all attributes with "MemberType = ..." -/// We cannot inherit from as it is sealed, so we have to reimplement -/// ConvertDataItem inheriting from MemberDataAttributeBase. -/// -public class CommonMemberDataAttribute : MemberDataAttributeBase -{ - public CommonMemberDataAttribute(Type memberType, string memberName = "TheoryData") - : this(memberType, memberName, null) { } - - public CommonMemberDataAttribute(Type memberType, string memberName, params object[]? parameters) - : base(memberName, parameters) - { - MemberType = memberType; - } - - protected override object[]? ConvertDataItem(MethodInfo testMethod, object? item) - { - if (item is null) - { - return null; - } - - if (item is not object[] array) - { - throw new ArgumentException($"Property {MemberName} on {MemberType ?? testMethod.DeclaringType} yielded an item that is not an object[], but {item.GetType().Name}"); - } - - return array; - } -} diff --git a/src/Common/tests/TestUtilities/XUnit/EnumDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/EnumDataAttribute.cs deleted file mode 100644 index a7658589eff..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/EnumDataAttribute.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Xunit; - -/// -/// Generates data for all defined values for the specified enum type. -/// -public class EnumDataAttribute : CommonMemberDataAttribute where TEnum : struct, Enum -{ - public EnumDataAttribute() : base(typeof(EnumDataAttribute)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = new(Enum.GetValues()); -} diff --git a/src/Common/tests/TestUtilities/XUnit/FloatingPointDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/FloatingPointDataAttribute.cs deleted file mode 100644 index bace832f5d1..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/FloatingPointDataAttribute.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Numerics; - -namespace Xunit; - -/// -/// Generates data for a set of floating point number values. -/// -public class FloatingPointDataAttribute : CommonMemberDataAttribute - where TNumber : struct, IBinaryFloatingPointIeee754, IMinMaxValue -{ - public FloatingPointDataAttribute() : base(typeof(FloatingPointDataAttribute)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = new(TestData.GetFloatingPointData()); -} diff --git a/src/Common/tests/TestUtilities/XUnit/FloatingPointToleranceComparerer.cs b/src/Common/tests/TestUtilities/XUnit/FloatingPointToleranceComparerer.cs deleted file mode 100644 index 520a0c7d18e..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/FloatingPointToleranceComparerer.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Numerics; - -namespace System.XUnit; - -/// -/// Equality comparer for numbers that checks whether two values are within a specifed tolerance. -/// -public class FloatingPointToleranceComparerer : IEqualityComparer - where T : struct, IFloatingPoint -{ - private T _tolerance; - - /// The difference must be less than or equal to this number. - public FloatingPointToleranceComparerer(T tolerance) => _tolerance = T.Abs(tolerance); - - public bool Equals(T x, T y) => ComparisonHelpers.EqualsFloating(x, y, _tolerance); - - public int GetHashCode([DisallowNull] T obj) => obj.GetHashCode(); -} diff --git a/src/Common/tests/TestUtilities/XUnit/IntegerDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/IntegerDataAttribute.cs deleted file mode 100644 index 2c3a4d0d54b..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/IntegerDataAttribute.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Numerics; - -namespace Xunit; - -/// -/// Generates data for a representative set of number values. -/// -public class IntegerDataAttribute : CommonMemberDataAttribute - where TNumber : struct, IBinaryInteger, IMinMaxValue -{ - public IntegerDataAttribute() : base(typeof(IntegerDataAttribute)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = new(TestData.GetIntegerData()); -} diff --git a/src/Common/tests/TestUtilities/XUnit/InvalidEnumDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/InvalidEnumDataAttribute.cs deleted file mode 100644 index e382fb92680..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/InvalidEnumDataAttribute.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; -using System.Runtime.CompilerServices; - -namespace Xunit; - -/// -/// Generates data for an invalid enum value. -/// -public class InvalidEnumDataAttribute : CommonMemberDataAttribute where TEnum : unmanaged, Enum -{ - public InvalidEnumDataAttribute() : base(typeof(InvalidEnumDataAttribute)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = InitializeData(); - - private static unsafe ReadOnlyTheoryData InitializeData() - { - ulong maxValue = ulong.MaxValue >>> ((sizeof(ulong) - sizeof(TEnum)) * 8); - TEnum currentValue = default; - bool defined; - - List data = new(); - - if (typeof(TEnum).GetCustomAttribute() is not null) - { - // Bit flags, pull the first flag from the top. - ulong currentFlagValue = 1ul << (sizeof(TEnum) * 8) - 1; - do - { - currentValue = Unsafe.As(ref currentFlagValue); - defined = Enum.IsDefined(currentValue); - currentFlagValue >>>= 1; - } - while (defined && currentFlagValue > 0); - - if (defined) - { - throw new InvalidOperationException("Enum has all flags defined"); - } - - data.Add(currentValue); - return new(data); - } - - // Not a flags enum, add the smallest and largest undefined value. - ulong minValue = 0; - - do - { - currentValue = Unsafe.As(ref minValue); - defined = Enum.IsDefined(currentValue); - minValue++; - } - while (defined); - - data.Add(currentValue); - - do - { - currentValue = Unsafe.As(ref maxValue); - defined = Enum.IsDefined(currentValue); - maxValue--; - } - while (defined); - - data.Add(currentValue); - return new(data); - } -} diff --git a/src/Common/tests/TestUtilities/XUnit/NewAndDefaultDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/NewAndDefaultDataAttribute.cs deleted file mode 100644 index cec932e0059..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/NewAndDefaultDataAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Xunit; - -/// -/// Generates data for and the default constructor -/// for the given class type. -/// -public class NewAndDefaultDataAttribute : CommonMemberDataAttribute where TClass : new() -{ - public NewAndDefaultDataAttribute() : base(typeof(NewAndDefaultDataAttribute)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = new(new TClass(), default); -} diff --git a/src/Common/tests/TestUtilities/XUnit/NormalizedStringDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/NormalizedStringDataAttribute.cs deleted file mode 100644 index 46526385344..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/NormalizedStringDataAttribute.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Xunit; - -/// -/// Generates data to test normalization of to -/// . -/// -public class NormalizedStringDataAttribute : CommonMemberDataAttribute -{ - public NormalizedStringDataAttribute() : base(typeof(NormalizedStringDataAttribute)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = new(new TheoryData() - { - { null, string.Empty }, - { string.Empty, string.Empty }, - { "teststring", "teststring" } - }); -} - diff --git a/src/Common/tests/TestUtilities/XUnit/NullAndEmptyStringDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/NullAndEmptyStringDataAttribute.cs deleted file mode 100644 index 866f289af99..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/NullAndEmptyStringDataAttribute.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Xunit; - -/// -/// Generates data for and . -/// -public class NullAndEmptyStringDataAttribute : CommonMemberDataAttribute -{ - public NullAndEmptyStringDataAttribute() : base(typeof(NullAndEmptyStringDataAttribute)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = new(null, string.Empty); -} diff --git a/src/Common/tests/TestUtilities/XUnit/PositiveNumberDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/PositiveNumberDataAttribute.cs deleted file mode 100644 index 0214e957a8c..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/PositiveNumberDataAttribute.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Numerics; - -namespace Xunit; - -/// -/// Generates data for a representative set of positive number values. -/// -public class PositiveIntegerDataAttribute - : CommonMemberDataAttribute where TNumber : struct, IBinaryInteger, IMinMaxValue -{ - public PositiveIntegerDataAttribute() : base(typeof(PositiveIntegerDataAttribute)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = new(TestData.GetPositiveIntegerData()); -} diff --git a/src/Common/tests/TestUtilities/XUnit/ReadOnlyTheoryData.cs b/src/Common/tests/TestUtilities/XUnit/ReadOnlyTheoryData.cs deleted file mode 100644 index 52365efabde..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/ReadOnlyTheoryData.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; - -namespace Xunit; - -/// -/// Xunit compatible readonly theory data. Can be constructed around . -/// -/// -/// -/// This type avoids inadvertently adding data, which is of a particular concern when broadly sharing test data. -/// -/// -public class ReadOnlyTheoryData : IEnumerable -{ - private readonly IEnumerable _data; - - public ReadOnlyTheoryData(IEnumerable data) => _data = data; - - public ReadOnlyTheoryData(IEnumerable data) - => _data = data.Cast().Select(i => new object?[] { i }).ToArray(); - - public ReadOnlyTheoryData(IEnumerable data) - => _data = data.Select(i => new object?[] { i }).ToArray(); - - public ReadOnlyTheoryData(params object?[] data) - => _data = data.Select(i => new object?[] { i }).ToArray(); - - IEnumerator IEnumerable.GetEnumerator() => _data.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => _data.GetEnumerator(); -} diff --git a/src/Common/tests/TestUtilities/XUnit/SkipOnArchitectureAttribute.cs b/src/Common/tests/TestUtilities/XUnit/SkipOnArchitectureAttribute.cs deleted file mode 100644 index 415907fe649..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/SkipOnArchitectureAttribute.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit.Sdk; - -namespace Xunit; - -/// -/// Apply this attribute to your test method or class to skip it on a certain architecture. -/// -/// -/// -/// This attribute isn't able to distinguish Arm64 from x64. To skip tests on Arm64 use -/// . See https://github.com/dotnet/winforms/issues/7013. -/// -/// -[TraitDiscoverer("System.SkipOnArchitectureDiscoverer", "System.Windows.Forms.TestUtilities")] -[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true, Inherited = true)] -public class SkipOnArchitectureAttribute : Attribute, ITraitAttribute -{ - public SkipOnArchitectureAttribute(TestArchitectures testArchitectures, string reason) { } -} diff --git a/src/Common/tests/TestUtilities/XUnit/SkipOnArchitectureDiscoverer.cs b/src/Common/tests/TestUtilities/XUnit/SkipOnArchitectureDiscoverer.cs deleted file mode 100644 index 9b395d7f916..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/SkipOnArchitectureDiscoverer.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using Microsoft.DotNet.XUnitExtensions; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Xunit; - -/// -/// This class discovers all of the tests and test classes that have -/// applied the . -/// -public class SkipOnArchitectureDiscoverer : ITraitDiscoverer -{ - /// - /// Gets the trait values from the Category attribute. - /// - /// The trait attribute containing the trait values. - /// The trait values. - public IEnumerable> GetTraits(IAttributeInfo traitAttribute) - { - TestArchitectures testArchitectures = 0; - - if (traitAttribute.GetConstructorArguments().FirstOrDefault() is TestArchitectures architectures) - { - testArchitectures = architectures; - } - - if ((testArchitectures.HasFlag(TestArchitectures.X86) && RuntimeInformation.ProcessArchitecture == Architecture.X86) || - (testArchitectures.HasFlag(TestArchitectures.X64) && RuntimeInformation.ProcessArchitecture == Architecture.X64)) - { - return new[] { new KeyValuePair(XunitConstants.Category, XunitConstants.IgnoreForCI) }; - } - - return Array.Empty>(); - } -} diff --git a/src/Common/tests/TestUtilities/XUnit/StringDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/StringDataAttribute.cs deleted file mode 100644 index 55b91582a22..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/StringDataAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Xunit; - -/// -/// Generates data with and -/// a sample . -/// -public class StringDataAttribute : CommonMemberDataAttribute -{ - public StringDataAttribute() : base(typeof(StringDataAttribute)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = new(string.Empty, "teststring"); -} diff --git a/src/Common/tests/TestUtilities/XUnit/StringWithNullDataAttribute.cs b/src/Common/tests/TestUtilities/XUnit/StringWithNullDataAttribute.cs deleted file mode 100644 index 90933b49959..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/StringWithNullDataAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Xunit; - -/// -/// Generates data for , , and -/// a sample . -/// -public class StringWithNullDataAttribute : CommonMemberDataAttribute -{ - public StringWithNullDataAttribute() : base(typeof(StringWithNullDataAttribute)) { } - - public static ReadOnlyTheoryData TheoryData { get; } = new(null, string.Empty, "teststring"); -} diff --git a/src/Common/tests/TestUtilities/XUnit/TestArchitectures.cs b/src/Common/tests/TestUtilities/XUnit/TestArchitectures.cs deleted file mode 100644 index 4b89411a692..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/TestArchitectures.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Xunit; - -[Flags] -public enum TestArchitectures -{ - X86 = 1, - X64 = 2, - Any = ~0 -} diff --git a/src/Common/tests/TestUtilities/XUnit/TestData.cs b/src/Common/tests/TestUtilities/XUnit/TestData.cs deleted file mode 100644 index 30cf86dd4fb..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/TestData.cs +++ /dev/null @@ -1,86 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using System.Numerics; -namespace Xunit; - -/// -/// Raw, cached test data. -/// -public static class TestData -{ - /// - /// Returns a variety of floating point test cases. - /// - public static ImmutableArray GetFloatingPointData() - where T : struct, IBinaryFloatingPointIeee754, IMinMaxValue - => FloatingPointData.Data; - - /// - /// Returns a variety of integer test cases. - /// - public static ImmutableArray GetIntegerData() - where T : struct, IBinaryInteger, IMinMaxValue - => IntegerData.Data; - - /// - /// Returns a variety of positive integer test cases. - /// - public static ImmutableArray GetPositiveIntegerData() - where T : struct, IBinaryInteger, IMinMaxValue - => PositiveIntegerData.Data; - - private static class FloatingPointData - where T : struct, IBinaryFloatingPointIeee754, IMinMaxValue - { - public static ImmutableArray Data { get; } = ImmutableArray.Create(new T[] - { - T.MinValue, - T.MaxValue, - T.One, - T.Zero, - T.NegativeOne, - T.MaxValue / (T.One + T.One), - T.NaN, - T.NegativeInfinity, - T.Epsilon, - T.Epsilon * T.NegativeOne - }); - } - - private static class IntegerData - where T : struct, IBinaryInteger, IMinMaxValue - { - public static ImmutableArray Data { get; } - = ImmutableArray.Create(T.MinValue == T.Zero - ? new T[] - { - T.MinValue, - T.MaxValue, - T.One, - T.MaxValue / (T.One + T.One) - } - : new T[] - { - T.MinValue, - T.MaxValue, - T.One, - T.Zero, - T.Zero - T.One, - T.MaxValue / (T.One + T.One) - }); - } - - private static class PositiveIntegerData - where T : struct, IBinaryInteger, IMinMaxValue - { - public static ImmutableArray Data { get; } = ImmutableArray.Create(new T[] - { - T.Zero, - T.MaxValue, - T.One, - T.MaxValue / (T.One + T.One) - }); - } -} diff --git a/src/Common/tests/TestUtilities/XUnit/UseCultureAttribute.cs b/src/Common/tests/TestUtilities/XUnit/UseCultureAttribute.cs deleted file mode 100644 index 99509da412b..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/UseCultureAttribute.cs +++ /dev/null @@ -1,140 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// The original code was borrowed from https://github.com/xunit/samples.xunit/blob/93f87d5/UseCulture/UseCultureAttribute.cs -// Licensed under http://www.apache.org/licenses/LICENSE-2.0. - -using System.Globalization; -using System.Reflection; -using System.Runtime.InteropServices; -using Xunit.Sdk; - -namespace Xunit; - -/// -/// Apply this attribute to your test method to replace the and -/// with another culture. -/// -[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] -public class UseCultureAttribute : BeforeAfterTestAttribute -{ - private readonly Lazy _culture; - private readonly Lazy _uiCulture; - - // These will be set to a value that is never null in the Before method - // which will always run before it is used in the After method. - private CultureInfo _originalCulture = null!; - private CultureInfo _originalUICulture = null!; - - private bool _updateUnmanagedUiThreadCulture; - - /// - /// Replaces the culture and UI culture of the current thread with . - /// - /// The name of the culture to set for both and . - public UseCultureAttribute(string culture) - : this(culture, culture) - { - } - - /// - /// Replaces the culture and UI culture of the current thread with and . - /// - /// The name of the culture. - /// The name of the UI culture. - public UseCultureAttribute(string culture, string uiCulture) - { - _culture = new Lazy(() => new(culture, useUserOverride: false)); - _uiCulture = new Lazy(() => new(uiCulture, useUserOverride: false)); - } - - /// - /// Gets the culture. - /// - public CultureInfo Culture => _culture.Value; - - /// - /// Indicates whether the native thread UI culture should also be set. - /// - public bool SetUnmanagedUiThreadCulture { get; set; } - - /// - /// Gets the UI culture. - /// - public CultureInfo UICulture => _uiCulture.Value; - - /// - /// Stores the current - /// and - /// and replaces them with the new cultures defined in the constructor. - /// - /// The method under test - public override unsafe void Before(MethodInfo methodUnderTest) - { - _originalCulture = Thread.CurrentThread.CurrentCulture; - _originalUICulture = Thread.CurrentThread.CurrentUICulture; - - CultureInfo.DefaultThreadCurrentCulture = Culture; - Thread.CurrentThread.CurrentCulture = Culture; - Thread.CurrentThread.CurrentUICulture = UICulture; - - _updateUnmanagedUiThreadCulture = !_originalUICulture.Equals(UICulture); - if (SetUnmanagedUiThreadCulture && _updateUnmanagedUiThreadCulture) - { - SetNativeUiThreadCulture(UICulture); - } - - CultureInfo.CurrentCulture.ClearCachedData(); - CultureInfo.CurrentUICulture.ClearCachedData(); - } - - /// - /// Restores the original and - /// to - /// - /// The method under test - public override void After(MethodInfo methodUnderTest) - { - Thread.CurrentThread.CurrentCulture = _originalCulture; - Thread.CurrentThread.CurrentUICulture = _originalUICulture; - - if (SetUnmanagedUiThreadCulture && _updateUnmanagedUiThreadCulture) - { - SetNativeUiThreadCulture(_originalUICulture); - } - - CultureInfo.CurrentCulture.ClearCachedData(); - CultureInfo.CurrentUICulture.ClearCachedData(); - } - - // Thread.CurrentThread.CurrentUICulture only sets the UI culture for the managed resources. - private static unsafe void SetNativeUiThreadCulture(CultureInfo uiCulture) - { - uint pulNumLanguages = 0; - string lcid = uiCulture.LCID.ToString("X4"); - fixed (char* plcid = lcid) - { - if (Interop.SetThreadPreferredUILanguages(Interop.MUI_LANGUAGE_ID, plcid, &pulNumLanguages) == Interop.BOOL.FALSE) - { - throw new InvalidOperationException("Unable to set the desired UI language."); - } - } - } - - private static class Interop - { - internal const uint MUI_LANGUAGE_ID = 0x4; - - internal enum BOOL : int - { - FALSE = 0, - TRUE = 1, - } - - [DllImport("Kernel32.dll", ExactSpelling = true, CharSet = CharSet.Unicode)] - internal static extern unsafe BOOL SetThreadPreferredUILanguages( - uint dwFlags, - char* pwszLanguagesBuffer, - uint* pulNumLanguages); - } -} diff --git a/src/Common/tests/TestUtilities/XUnit/UseDefaultXunitCultureAttribute.cs b/src/Common/tests/TestUtilities/XUnit/UseDefaultXunitCultureAttribute.cs deleted file mode 100644 index bd89f93dc46..00000000000 --- a/src/Common/tests/TestUtilities/XUnit/UseDefaultXunitCultureAttribute.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Globalization; - -namespace Xunit; - -/// -/// Apply this attribute to your test method to replace the and -/// with another culture. -/// -[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] -public class UseDefaultXunitCultureAttribute : UseCultureAttribute -{ - public const string DefaultXunitCultureAttribute = "en-US"; - - /// - /// Replaces the culture and UI culture of the current thread with the . - /// - public UseDefaultXunitCultureAttribute() - : base(DefaultXunitCultureAttribute, DefaultXunitCultureAttribute) - { - } -} diff --git a/src/Microsoft.VisualBasic.Forms/Directory.Build.props b/src/Microsoft.VisualBasic.Forms/Directory.Build.props deleted file mode 100644 index c76d0308b56..00000000000 --- a/src/Microsoft.VisualBasic.Forms/Directory.Build.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - - Microsoft - - diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft.VisualBasic.Forms.vbproj b/src/Microsoft.VisualBasic.Forms/src/Microsoft.VisualBasic.Forms.vbproj deleted file mode 100644 index e57cd2e7598..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft.VisualBasic.Forms.vbproj +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - Microsoft.VisualBasic.Forms - true - - 15.0 - None - true - true - - - - - - - - - True - True - ProgressDialog.resx - - - True - True - VBInputBox.resx - - - - - - true - System - - - Microsoft.VisualBasic.MyServices.Internal.ProgressDialog.resources - - - Microsoft.VisualBasic.CompilerServices.VBInputBox.resources - - - - - - - AssignProjectConfiguration;$(GetCopyToOutputDirectoryItemsDependsOn) - - - diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/ApplicationBase.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/ApplicationBase.vb deleted file mode 100644 index 3ca6a80b3f3..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/ApplicationBase.vb +++ /dev/null @@ -1,120 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - -Imports ExUtils = Microsoft.VisualBasic.CompilerServices.ExceptionUtils - -Namespace Microsoft.VisualBasic.ApplicationServices - - ''' - ''' Abstract class that defines the application Startup/Shutdown model for VB - ''' Windows Applications such as console, WinForms, dll, service. - ''' - Public Class ApplicationBase - - Public Sub New() - End Sub - - ''' - ''' Returns the value of the specified environment variable. - ''' - ''' A String containing the name of the environment variable. - ''' A string containing the value of the environment variable. - ''' if name is Nothing. - ''' if the specified environment variable does not exist. - Public Function GetEnvironmentVariable(name As String) As String - - ' Framework returns Null if not found. - Dim VariableValue As String = Environment.GetEnvironmentVariable(name) - - ' Since the explicitly requested a specific environment variable and we couldn't find it, throw - If VariableValue Is Nothing Then - Throw ExUtils.GetArgumentExceptionWithArgName("name", SR.EnvVarNotFound_Name, name) - End If - - Return VariableValue - End Function - - ''' - ''' Provides access to logging capability. - ''' - ''' Returns a Microsoft.VisualBasic.Windows.Log object used for logging to OS log, debug window - ''' and a delimited text file or xml log. - Public ReadOnly Property Log() As Logging.Log - Get - If _log Is Nothing Then - _log = New Logging.Log - End If - Return _log - End Get - End Property - - ''' - ''' Returns the info about the application. If we are executing in a DLL, we still return the info - ''' about the application, not the DLL. - ''' - Public ReadOnly Property Info() As AssemblyInfo - Get - If _info Is Nothing Then - Dim Assembly As Reflection.Assembly = Reflection.Assembly.GetEntryAssembly() - If Assembly Is Nothing Then 'It can be nothing if we are an add-in or a dll on the web - Assembly = Reflection.Assembly.GetCallingAssembly() - End If - _info = New AssemblyInfo(Assembly) - End If - Return _info - End Get - End Property - - ''' - ''' Gets the information about the current culture used by the current thread. - ''' - Public ReadOnly Property Culture() As Globalization.CultureInfo - Get - Return Threading.Thread.CurrentThread.CurrentCulture - End Get - End Property - - ''' - ''' Gets the information about the current culture used by the Resource - ''' Manager to look up culture-specific resource at run time. - ''' - ''' - ''' The CultureInfo object that represents the culture used by the - ''' Resource Manager to look up culture-specific resources at run time. - ''' - Public ReadOnly Property UICulture() As Globalization.CultureInfo - Get - Return Threading.Thread.CurrentThread.CurrentUICulture - End Get - End Property - - ''' - ''' Changes the culture currently in used by the current thread. - ''' - ''' - ''' CultureInfo constructor will throw exceptions if cultureName is Nothing - ''' or an invalid CultureInfo ID. We are not catching those exceptions. - ''' - Public Sub ChangeCulture(cultureName As String) - Threading.Thread.CurrentThread.CurrentCulture = New Globalization.CultureInfo(cultureName) - End Sub - - ''' - ''' Changes the culture currently used by the Resource Manager to look - ''' up culture-specific resource at runtime. - ''' - ''' - ''' CultureInfo constructor will throw exceptions if cultureName is Nothing - ''' or an invalid CultureInfo ID. We are not catching those exceptions. - ''' - Public Sub ChangeUICulture(cultureName As String) - Threading.Thread.CurrentThread.CurrentUICulture = New Globalization.CultureInfo(cultureName) - End Sub - - Private _log As Logging.Log 'Lazy-initialized and cached log object. - Private _info As AssemblyInfo ' The executing application (the EntryAssembly) - End Class 'ApplicationBase -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/ApplyApplicationDefaultsEventArgs.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/ApplyApplicationDefaultsEventArgs.vb deleted file mode 100644 index cb198ad556f..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/ApplyApplicationDefaultsEventArgs.vb +++ /dev/null @@ -1,52 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On -Option Infer On - -Imports System.ComponentModel -Imports System.Drawing -Imports System.Runtime.InteropServices -Imports System.Windows.Forms - -Namespace Microsoft.VisualBasic.ApplicationServices - - ''' - ''' Provides context for the ApplyApplicationDefaults event. - ''' - - Public Class ApplyApplicationDefaultsEventArgs - Inherits EventArgs - - Friend Sub New(minimumSplashScreenDisplayTime As Integer, - highDpiMode As HighDpiMode) - Me.MinimumSplashScreenDisplayTime = minimumSplashScreenDisplayTime - Me.HighDpiMode = highDpiMode - End Sub - - ''' - ''' Setting this property inside the event handler causes a new default Font for Forms and UserControls to be set. - ''' - ''' - ''' When the ApplyApplicationDefault event is raised, this property contains nothing. A new default Font for the - ''' application is applied by setting this property with a value different than nothing. - ''' - Public Property Font As Font - - ''' - ''' Setting this Property inside the event handler determines how long an application's Splash dialog is displayed at a minimum. - ''' - Public Property MinimumSplashScreenDisplayTime As Integer = - WindowsFormsApplicationBase.MINIMUM_SPLASH_EXPOSURE_DEFAULT - - ''' - ''' Setting this Property inside the event handler determines the general HighDpiMode for the application. - ''' - ''' - ''' The default value for this property is SystemAware. - ''' - Public Property HighDpiMode As HighDpiMode - - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/AssemblyInfo.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/AssemblyInfo.vb deleted file mode 100644 index faa2a2ed6c2..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/AssemblyInfo.vb +++ /dev/null @@ -1,248 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - -Imports System.Collections.ObjectModel -Imports System.Reflection -Imports Microsoft.VisualBasic.CompilerServices.ExceptionUtils - -Namespace Microsoft.VisualBasic.ApplicationServices - - ''' - ''' A class that contains the information about an Application. This information can be - ''' specified using the assembly attributes (contained in AssemblyInfo.vb file in case of - ''' a VB project in Visual Studio .NET). - ''' - ''' This class is based on the FileVersionInfo class of the framework, but - ''' reduced to a number of relevant properties. - Public Class AssemblyInfo - - ''' - ''' Creates an AssemblyInfo from an assembly - ''' - ''' The assembly for which we want to obtain the information. - Public Sub New(currentAssembly As Assembly) - If currentAssembly Is Nothing Then - Throw GetArgumentNullException("CurrentAssembly") - End If - _assembly = currentAssembly - End Sub - - ''' - ''' Gets the description associated with the assembly. - ''' - ''' A String containing the AssemblyDescriptionAttribute associated with the assembly. - ''' if the AssemblyDescriptionAttribute is not defined. - Public ReadOnly Property Description() As String - Get - If _description Is Nothing Then - Dim Attribute As AssemblyDescriptionAttribute = - CType(GetAttribute(GetType(AssemblyDescriptionAttribute)), AssemblyDescriptionAttribute) - If Attribute Is Nothing Then - _description = "" - Else - _description = Attribute.Description - End If - End If - Return _description - End Get - End Property - - ''' - ''' Gets the company name associated with the assembly. - ''' - ''' A String containing the AssemblyCompanyAttribute associated with the assembly. - ''' if the AssemblyCompanyAttribute is not defined. - Public ReadOnly Property CompanyName() As String - Get - If _companyName Is Nothing Then - Dim Attribute As AssemblyCompanyAttribute = - CType(GetAttribute(GetType(AssemblyCompanyAttribute)), AssemblyCompanyAttribute) - If Attribute Is Nothing Then - _companyName = "" - Else - _companyName = Attribute.Company - End If - End If - Return _companyName - End Get - End Property - - ''' - ''' Gets the title associated with the assembly. - ''' - ''' A String containing the AssemblyTitleAttribute associated with the assembly. - ''' if the AssemblyTitleAttribute is not defined. - Public ReadOnly Property Title() As String - Get - If _title Is Nothing Then - Dim Attribute As AssemblyTitleAttribute = - CType(GetAttribute(GetType(AssemblyTitleAttribute)), AssemblyTitleAttribute) - If Attribute Is Nothing Then - _title = "" - Else - _title = Attribute.Title - End If - End If - Return _title - End Get - End Property - - ''' - ''' Gets the copyright notices associated with the assembly. - ''' - ''' A String containing the AssemblyCopyrightAttribute associated with the assembly. - ''' if the AssemblyCopyrightAttribute is not defined. - Public ReadOnly Property Copyright() As String - Get - If _copyright Is Nothing Then - Dim Attribute As AssemblyCopyrightAttribute = CType(GetAttribute(GetType(AssemblyCopyrightAttribute)), AssemblyCopyrightAttribute) - If Attribute Is Nothing Then - _copyright = "" - Else - _copyright = Attribute.Copyright - End If - End If - Return _copyright - End Get - End Property - - ''' - ''' Gets the trademark notices associated with the assembly. - ''' - ''' A String containing the AssemblyTrademarkAttribute associated with the assembly. - ''' if the AssemblyTrademarkAttribute is not defined. - Public ReadOnly Property Trademark() As String - Get - If _trademark Is Nothing Then - Dim Attribute As AssemblyTrademarkAttribute = CType(GetAttribute(GetType(AssemblyTrademarkAttribute)), AssemblyTrademarkAttribute) - If Attribute Is Nothing Then - _trademark = "" - Else - _trademark = Attribute.Trademark - End If - End If - Return _trademark - End Get - End Property - - ''' - ''' Gets the product name associated with the assembly. - ''' - ''' A String containing the AssemblyProductAttribute associated with the assembly. - ''' if the AssemblyProductAttribute is not defined. - Public ReadOnly Property ProductName() As String - Get - If _productName Is Nothing Then - Dim Attribute As AssemblyProductAttribute = CType(GetAttribute(GetType(AssemblyProductAttribute)), AssemblyProductAttribute) - If Attribute Is Nothing Then - _productName = "" - Else - _productName = Attribute.Product - End If - End If - Return _productName - End Get - End Property - - ''' - ''' Gets the version number of the assembly. - ''' - ''' A System.Version class containing the version number of the assembly - ''' Cannot use AssemblyVersionAttribute since it always return Nothing. - Public ReadOnly Property Version() As Version - Get - Return _assembly.GetName().Version - End Get - End Property - - ''' - ''' Gets the name of the file containing the manifest (usually the .exe file). - ''' - ''' A String containing the file name. - Public ReadOnly Property AssemblyName() As String - Get - Return _assembly.GetName.Name - End Get - End Property - - ''' - ''' Gets the directory where the assembly lives. - ''' - Public ReadOnly Property DirectoryPath() As String - Get - Return IO.Path.GetDirectoryName(_assembly.Location) - End Get - End Property - - ''' - ''' Returns the names of all assemblies loaded by the current application. - ''' - ''' A ReadOnlyCollection(Of Assembly) containing all the loaded assemblies. - ''' attempt on an unloaded application domain. - Public ReadOnly Property LoadedAssemblies() As ReadOnlyCollection(Of Assembly) - Get - Dim Result As New Collection(Of Assembly) - For Each Assembly As Assembly In AppDomain.CurrentDomain.GetAssemblies() - Result.Add(Assembly) - Next - Return New ReadOnlyCollection(Of Assembly)(Result) - End Get - End Property - - ''' - ''' Returns the current stack trace information. - ''' - ''' A string containing stack trace information. Value can be String.Empty. - ''' The requested stack trace information is out of range. - Public ReadOnly Property StackTrace() As String - Get - Return Environment.StackTrace - End Get - End Property - - ''' - ''' Gets the amount of physical memory mapped to the process context. - ''' - ''' - ''' A 64-bit signed integer containing the size of physical memory mapped to the process context, in bytes. - ''' - Public ReadOnly Property WorkingSet() As Long - Get - Return Environment.WorkingSet - End Get - End Property - - ''' - ''' Gets an attribute from the assembly and throw exception if the attribute does not exist. - ''' - ''' The type of the required attribute. - ''' The attribute with the given type gotten from the assembly, or Nothing. - Private Function GetAttribute(AttributeType As Type) As Object - - Debug.Assert(_assembly IsNot Nothing, "Null m_Assembly") - - Dim Attributes() As Object = _assembly.GetCustomAttributes(AttributeType, inherit:=True) - - If Attributes.Length = 0 Then - Return Nothing - Else - Return Attributes(0) - End If - End Function - - ' Private fields. - Private ReadOnly _assembly As Assembly ' The assembly with the information. - - ' Since these properties will not change during runtime, they're cached. - ' "" is not Nothing so use Nothing to mark an un-accessed property. - Private _description As String ' Cache the assembly's description. - Private _title As String ' Cache the assembly's title. - Private _productName As String ' Cache the assembly's product name. - Private _companyName As String ' Cache the assembly's company name. - Private _trademark As String ' Cache the assembly's trademark. - Private _copyright As String ' Cache the assembly's copyright. - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/CantStartSingleInstanceException.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/CantStartSingleInstanceException.vb deleted file mode 100644 index f6a9d71e011..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/CantStartSingleInstanceException.vb +++ /dev/null @@ -1,43 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On -Option Infer On - -Imports System.ComponentModel -Imports Microsoft.VisualBasic.CompilerServices.Utils - -Namespace Microsoft.VisualBasic.ApplicationServices - - ''' - ''' Exception for when we launch a single-instance application and it can't connect with the - ''' original instance. - ''' - - - Public Class CantStartSingleInstanceException : Inherits Exception - - ''' - ''' Creates a new exception - ''' - Public Sub New() - MyBase.New(GetResourceString(SR.AppModel_SingleInstanceCantConnect)) - End Sub - - Public Sub New(ByVal message As String) - MyBase.New(message) - End Sub - - Public Sub New(ByVal message As String, ByVal inner As Exception) - MyBase.New(message, inner) - End Sub - - ' Deserialization constructor must be defined since we are serializable - - - Protected Sub New(ByVal info As Runtime.Serialization.SerializationInfo, ByVal context As Runtime.Serialization.StreamingContext) - MyBase.New(info, context) - End Sub - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/ConsoleApplicationBase.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/ConsoleApplicationBase.vb deleted file mode 100644 index e438449ab72..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/ConsoleApplicationBase.vb +++ /dev/null @@ -1,62 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - -Imports System.ComponentModel - -Namespace Microsoft.VisualBasic.ApplicationServices - - ''' - ''' Abstract class that defines the application Startup/Shutdown model for VB - ''' Windows Applications such as console, winforms, dll, service. - ''' - Public Class ConsoleApplicationBase : Inherits ApplicationBase - - ''' - ''' Constructs the application Shutdown/Startup model object - ''' - ''' We have to have a parameterless constructor because the platform specific Application - ''' object derives from this one and it doesn't define a constructor. The partial class generated by the - ''' designer defines the constructor in order to configure the application. - Public Sub New() - MyBase.New() - End Sub - - ''' - ''' Returns the command line arguments for the current application. - ''' - ''' This function differs from System.Environment.GetCommandLineArgs in that the - ''' path of the executing file (the 0th entry) is omitted from the returned collection - Public ReadOnly Property CommandLineArgs() As ObjectModel.ReadOnlyCollection(Of String) - Get - If _commandLineArgs Is Nothing Then - 'Get rid of Arg(0) which is the path of the executing program. Main(args() as string) doesn't report the name of the app and neither will we - Dim EnvArgs As String() = System.Environment.GetCommandLineArgs - If EnvArgs.GetLength(0) >= 2 Then '1 element means no args, just the executing program. >= 2 means executing program + one or more command line arguments - Dim NewArgs(EnvArgs.GetLength(0) - 2) As String 'dimming z(0) gives a z() of 1 element. - Array.Copy(EnvArgs, 1, NewArgs, 0, EnvArgs.GetLength(0) - 1) 'copy everything but the 0th element (the path of the executing program) - _commandLineArgs = New ObjectModel.ReadOnlyCollection(Of String)(NewArgs) - Else - _commandLineArgs = New ObjectModel.ReadOnlyCollection(Of String)(Array.Empty(Of String)()) 'provide the empty set - End If - End If - Return _commandLineArgs - End Get - End Property - - ''' - ''' Allows derived classes to set what the command line should look like. WindowsFormsApplicationBase calls this - ''' for instance because we snag the command line from Main(). - ''' - - Protected WriteOnly Property InternalCommandLine() As ObjectModel.ReadOnlyCollection(Of String) - Set(value As ObjectModel.ReadOnlyCollection(Of String)) - _commandLineArgs = value - End Set - End Property - - Private _commandLineArgs As ObjectModel.ReadOnlyCollection(Of String) ' Lazy-initialized and cached collection of command line arguments. - End Class 'ApplicationBase -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/NoStartupFormException.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/NoStartupFormException.vb deleted file mode 100644 index 967c9c805c7..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/NoStartupFormException.vb +++ /dev/null @@ -1,42 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On -Option Infer On - -Imports System.ComponentModel -Imports Microsoft.VisualBasic.CompilerServices.Utils - -Namespace Microsoft.VisualBasic.ApplicationServices - - ''' - ''' Exception for when the WinForms VB application model isn't supplied with a startup form - ''' - - - Public Class NoStartupFormException : Inherits Exception - - ''' - ''' Creates a new exception - ''' - Public Sub New() - MyBase.New(GetResourceString(SR.AppModel_NoStartupForm)) - End Sub - - Public Sub New(message As String) - MyBase.New(message) - End Sub - - Public Sub New(message As String, inner As Exception) - MyBase.New(message, inner) - End Sub - - ' De-serialization constructor must be defined since we are serializable - - - Protected Sub New(info As Runtime.Serialization.SerializationInfo, context As Runtime.Serialization.StreamingContext) - MyBase.New(info, context) - End Sub - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/SingleInstanceHelpers.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/SingleInstanceHelpers.vb deleted file mode 100644 index 2e9ad84e522..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/SingleInstanceHelpers.vb +++ /dev/null @@ -1,93 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - -Imports System -Imports System.IO -Imports System.IO.Pipes -Imports System.Runtime.InteropServices -Imports System.Runtime.Serialization -Imports System.Threading - -Namespace Microsoft.VisualBasic.ApplicationServices - - Friend Module SingleInstanceHelpers - Private Const NamedPipeOptions As PipeOptions = PipeOptions.Asynchronous Or PipeOptions.CurrentUserOnly - - Friend Function TryCreatePipeServer(pipeName As String, ByRef pipeServer As NamedPipeServerStream) As Boolean - Try - pipeServer = New NamedPipeServerStream( - pipeName:=pipeName, - direction:=PipeDirection.In, - maxNumberOfServerInstances:=1, - transmissionMode:=PipeTransmissionMode.Byte, - options:=NamedPipeOptions) - Return True - Catch ex As Exception - pipeServer = Nothing - Return False - End Try - End Function - - Friend Async Function WaitForClientConnectionsAsync(pipeServer As NamedPipeServerStream, callback As Action(Of String()), cancellationToken As CancellationToken) As Task - While True - cancellationToken.ThrowIfCancellationRequested() - Await pipeServer.WaitForConnectionAsync(cancellationToken).ConfigureAwait(False) - Try - Dim args = Await ReadArgsAsync(pipeServer, cancellationToken).ConfigureAwait(False) - If args IsNot Nothing Then - callback(args) - End If - Finally - pipeServer.Disconnect() - End Try - End While - End Function - - Friend Async Function SendSecondInstanceArgsAsync(pipeName As String, args As String(), cancellationToken As CancellationToken) As Task - Using pipeClient As New NamedPipeClientStream( - serverName:=".", - pipeName:=pipeName, - direction:=PipeDirection.Out, - options:=NamedPipeOptions) - Await pipeClient.ConnectAsync(cancellationToken).ConfigureAwait(False) - Await WriteArgsAsync(pipeClient, args, cancellationToken).ConfigureAwait(False) - End Using - End Function - - Private Async Function ReadArgsAsync(pipeServer As NamedPipeServerStream, cancellationToken As CancellationToken) As Task(Of String()) - Const bufferLength = 1024 - Dim buffer = New Byte(bufferLength - 1) {} - Using stream As New MemoryStream - While True - Dim bytesRead = Await pipeServer.ReadAsync(buffer.AsMemory(0, bufferLength), cancellationToken).ConfigureAwait(False) - If bytesRead = 0 Then - Exit While - End If - stream.Write(buffer, 0, bytesRead) - End While - stream.Seek(0, SeekOrigin.Begin) - Dim serializer = New DataContractSerializer(GetType(String())) - Try - Return DirectCast(serializer.ReadObject(stream), String()) - Catch ex As Exception - Return Nothing - End Try - End Using - End Function - - Private Async Function WriteArgsAsync(pipeClient As NamedPipeClientStream, args As String(), cancellationToken As CancellationToken) As Task - Dim content As Byte() - Using stream As New MemoryStream - Dim serializer = New DataContractSerializer(GetType(String())) - serializer.WriteObject(stream, args) - content = stream.ToArray() - End Using - Await pipeClient.WriteAsync(content.AsMemory(0, content.Length), cancellationToken).ConfigureAwait(False) - End Function - - End Module - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/StartupEventArgs.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/StartupEventArgs.vb deleted file mode 100644 index 1520b75763e..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/StartupEventArgs.vb +++ /dev/null @@ -1,37 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On -Option Infer On - -Imports System.Collections.ObjectModel -Imports System.ComponentModel -Imports System.Runtime.InteropServices - -Namespace Microsoft.VisualBasic.ApplicationServices - - ''' - ''' Provides context for the Startup event. - ''' - - Public Class StartupEventArgs - Inherits CancelEventArgs - - ''' - ''' Creates a new instance of the StartupEventArgs. - ''' - Public Sub New(args As ReadOnlyCollection(Of String)) - If args Is Nothing Then - args = New ReadOnlyCollection(Of String)(Nothing) - End If - - CommandLine = args - End Sub - - ''' - ''' Returns the command line sent to this application - ''' - Public ReadOnly Property CommandLine() As ReadOnlyCollection(Of String) - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/StartupNextInstanceEventArgs.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/StartupNextInstanceEventArgs.vb deleted file mode 100644 index fc1f473fb1d..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/StartupNextInstanceEventArgs.vb +++ /dev/null @@ -1,45 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On -Option Infer On - -Imports System.Collections.ObjectModel -Imports System.ComponentModel - -Namespace Microsoft.VisualBasic.ApplicationServices - - ''' - ''' Provides context for the StartupNextInstance event. - ''' - - Public Class StartupNextInstanceEventArgs - Inherits EventArgs - - ''' - ''' Creates a new instance of the StartupNextInstanceEventArgs. - ''' - Public Sub New(args As ReadOnlyCollection(Of String), bringToForegroundFlag As Boolean) - If args Is Nothing Then - args = New ReadOnlyCollection(Of String)(Nothing) - End If - - CommandLine = args - BringToForeground = bringToForegroundFlag - End Sub - - ''' - ''' Indicates whether we will bring the application to the foreground when processing the - ''' StartupNextInstance event. - ''' - Public Property BringToForeground() As Boolean - - ''' - ''' Returns the command line sent to this application - ''' - ''' I'm using Me.CommandLine so that it is consistent with my.net and to assure they - ''' always return the same values - Public ReadOnly Property CommandLine() As ReadOnlyCollection(Of String) - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/UnhandledExceptionEventArgs.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/UnhandledExceptionEventArgs.vb deleted file mode 100644 index efbf9f7eac3..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/UnhandledExceptionEventArgs.vb +++ /dev/null @@ -1,31 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On -Option Infer On - -Imports System.ComponentModel -Imports System.Runtime.InteropServices -Imports System.Threading - -Namespace Microsoft.VisualBasic.ApplicationServices - - ''' - ''' Provides the exception encountered along with a flag on whether to abort the program - ''' - - Public Class UnhandledExceptionEventArgs - Inherits ThreadExceptionEventArgs - - Sub New(exitApplication As Boolean, exception As Exception) - MyBase.New(exception) - Me.ExitApplication = exitApplication - End Sub - - ''' - ''' Indicates whether the application should exit upon exiting the exception handler - ''' - Public Property ExitApplication() As Boolean - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/User.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/User.vb deleted file mode 100644 index 99acb320540..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/User.vb +++ /dev/null @@ -1,84 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On - -Imports System.ComponentModel -Imports System.Security.Principal - -Namespace Microsoft.VisualBasic.ApplicationServices - - ''' - ''' Class abstracting the computer user - ''' - Public Class User - - ''' - ''' Creates an instance of User - ''' - Public Sub New() - End Sub - - ''' - ''' The name of the current user - ''' - Public ReadOnly Property Name() As String - Get - Return InternalPrincipal.Identity.Name - End Get - End Property - - ''' - ''' The current IPrincipal which represents the current user - ''' - ''' An IPrincipal representing the current user - - Public Property CurrentPrincipal() As IPrincipal - Get - Return InternalPrincipal - End Get - Set(value As IPrincipal) - InternalPrincipal = value - End Set - End Property - - ''' - ''' Indicates whether or not the current user has been authenticated. - ''' - Public ReadOnly Property IsAuthenticated() As Boolean - Get - Return InternalPrincipal.Identity.IsAuthenticated - End Get - End Property - - ''' - ''' Indicates whether or not the current user is a member of the passed in role - ''' - ''' The name of the role - ''' True if the user is a member of the role otherwise False - Public Function IsInRole(role As String) As Boolean - Return InternalPrincipal.IsInRole(role) - End Function - - ''' - ''' The principal representing the current user. - ''' - ''' An IPrincipal representing the current user - ''' - ''' This should be overridden by derived classes that don't get the current - ''' user from the current thread - ''' - Protected Overridable Property InternalPrincipal() As IPrincipal - Get - Return System.Threading.Thread.CurrentPrincipal - End Get - Set(value As IPrincipal) - System.Threading.Thread.CurrentPrincipal = value - End Set - End Property - - End Class 'User - -End Namespace - diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBase.WinFormsAppContext.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBase.WinFormsAppContext.vb deleted file mode 100644 index 75cdbcfee4b..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBase.WinFormsAppContext.vb +++ /dev/null @@ -1,57 +0,0 @@ -Option Strict On -Option Explicit On -Option Infer On -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Security -Imports System.Windows.Forms - -Namespace Microsoft.VisualBasic.ApplicationServices - - Partial Public Class WindowsFormsApplicationBase - - ''' - ''' Encapsulates an ApplicationContext. We have our own to get the shutdown behaviors we - ''' offer in the application model. This derivation of the ApplicationContext listens for when - ''' the main form closes and provides for shutting down when the main form closes or the - ''' last form closes, depending on the mode this application is running in. - ''' - Private NotInheritable Class WinFormsAppContext - Inherits ApplicationContext - - Private ReadOnly _app As WindowsFormsApplicationBase - - Sub New(App As WindowsFormsApplicationBase) - _app = App - End Sub - - ''' - ''' Handles the two types of application shutdown: - ''' 1 - shutdown when the main form closes - ''' 2 - shutdown only after the last form closes - ''' - ''' - ''' - - Protected Overrides Sub OnMainFormClosed(sender As Object, e As EventArgs) - If _app.ShutdownStyle = ShutdownMode.AfterMainFormCloses Then - MyBase.OnMainFormClosed(sender, e) - Else 'identify a new main form so we can keep running - Dim forms As FormCollection = Application.OpenForms - - If forms.Count > 0 Then - 'Note: Initially I used Process::MainWindowHandle to obtain an open form. But that is bad for two reasons: - '1 - It appears to be broken and returns NULL sometimes even when there is still a window around. WinForms people are looking at that issue. - '2 - It returns the first window it hits from enum thread windows, which is not necessarily a windows forms form, so that doesn't help us even if it did work - 'all the time. So I'll use one of our open forms. We may not necessarily get a visible form here but that's OK. Some apps may run on an invisible window - 'and we need to keep them going until all windows close. - MainForm = forms(0) - Else - MyBase.OnMainFormClosed(sender, e) - End If - End If - End Sub - End Class - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBase.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBase.vb deleted file mode 100644 index d33cfb1fae5..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBase.vb +++ /dev/null @@ -1,1031 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On -Option Infer On - -Imports System.Collections.ObjectModel -Imports System.ComponentModel -Imports System.IO.Pipes -Imports System.Reflection -Imports System.Runtime.InteropServices -Imports System.Security -Imports System.Threading -Imports System.Windows.Forms -Imports Microsoft.VisualBasic.CompilerServices -Imports Microsoft.VisualBasic.CompilerServices.Utils - -Namespace Microsoft.VisualBasic.ApplicationServices - - ' Any changes to this enum must be reflected in ValidateAuthenticationModeEnumValue(). - Public Enum AuthenticationMode - Windows - ApplicationDefined - End Enum - - ' Any changes to this enum must be reflected in ValidateShutdownModeEnumValue(). - Public Enum ShutdownMode - AfterMainFormCloses - AfterAllFormsClose - End Enum - - ''' - ''' Signature for the ApplyApplicationDefaults event handler. - ''' - - Public Delegate Sub ApplyApplicationDefaultsEventHandler(sender As Object, e As ApplyApplicationDefaultsEventArgs) - - ''' - ''' Signature for the Startup event handler. - ''' - - Public Delegate Sub StartupEventHandler(sender As Object, e As StartupEventArgs) - - ''' - ''' Signature for the StartupNextInstance event handler. - ''' - - Public Delegate Sub StartupNextInstanceEventHandler(sender As Object, e As StartupNextInstanceEventArgs) - - ''' - ''' Signature for the Shutdown event handler. - ''' - - Public Delegate Sub ShutdownEventHandler(sender As Object, e As EventArgs) - - ''' - ''' Signature for the UnhandledException event handler. - ''' - - Public Delegate Sub UnhandledExceptionEventHandler(sender As Object, e As UnhandledExceptionEventArgs) - - ''' - ''' Provides the infrastructure for the VB Windows Forms application model. - ''' - ''' Don't put access on this definition. - Partial Public Class WindowsFormsApplicationBase : Inherits ConsoleApplicationBase - - ''' - ''' Occurs when the application is ready to accept default values for various application areas. - ''' - Public Event ApplyApplicationDefaults As ApplyApplicationDefaultsEventHandler - - ''' - ''' Occurs when the application starts. - ''' - Public Event Startup As StartupEventHandler - - ''' - ''' Occurs when attempting to start a single-instance application and the application is already active. - ''' - Public Event StartupNextInstance As StartupNextInstanceEventHandler - - ''' - ''' Occurs when the application shuts down. - ''' - Public Event Shutdown As ShutdownEventHandler - - ' Used to marshal a call to Dispose on the Splash Screen. - Private Delegate Sub DisposeDelegate() - - ' How long a subsequent instance will wait for the original instance to get on its feet. - Private Const SECOND_INSTANCE_TIMEOUT As Integer = 2500 ' milliseconds. - Friend Const MINIMUM_SPLASH_EXPOSURE_DEFAULT As Integer = 2000 ' milliseconds. - - Private ReadOnly _splashLock As New Object - Private ReadOnly _appContext As WinFormsAppContext - - ' Sync object - Private ReadOnly _networkAvailabilityChangeLock As New Object - - Private _unhandledExceptionHandlers As List(Of UnhandledExceptionEventHandler) - Private _processingUnhandledExceptionEvent As Boolean - - ' Tracks whether we need to create the network object so we can listen to the NetworkAvailabilityChanged event. - Private _turnOnNetworkListener As Boolean - - ' Whether we have made it through the processing of OnInitialize. - Private _finishedOnInitialize As Boolean - Private _networkAvailabilityEventHandlers As List(Of Devices.NetworkAvailableEventHandler) - Private _networkObject As Devices.Network - -#Disable Warning IDE0032 ' Use auto property, Justification:= - - ' Whether this app runs using Word like instancing behavior. - Private _isSingleInstance As Boolean - - ' Defines when the application decides to close. - Private _shutdownStyle As ShutdownMode - - ' Whether to use Windows XP styles. - Private _enableVisualStyles As Boolean - - ' We only need to show the splash screen once. - ' Protect the user from himself if they are overriding our app model. - Private _didSplashScreen As Boolean - - ' For splash screens with a minimum display time, this let's us know when that time - ' has expired and it is OK to close the splash screen. - Private _splashScreenCompletionSource As TaskCompletionSource(Of Boolean) - Private _formLoadWaiter As AutoResetEvent - Private _splashScreen As Form - - ' Minimum amount of time to show the splash screen. 0 means hide as soon as the app comes up. - Private _minimumSplashExposure As Integer = MINIMUM_SPLASH_EXPOSURE_DEFAULT - Private _splashTimer As Timers.Timer - Private _appSynchronizationContext As SynchronizationContext - - ' Informs My.Settings whether to save the settings on exit or not. - Private _saveMySettingsOnExit As Boolean - - ' The HighDpiMode the user picked from the AppDesigner or assigned to the ApplyHighDpiMode's Event. - Private _highDpiMode As HighDpiMode = HighDpiMode.SystemAware - -#Enable Warning IDE0032 ' Use auto property - - ''' - ''' Occurs when the network availability changes. - ''' - Public Custom Event NetworkAvailabilityChanged As Devices.NetworkAvailableEventHandler - ' This is a custom event because we want to hook up the NetworkAvailabilityChanged event only - ' if the user writes a handler for it. - ' The reason being that it is very expensive to handle and kills our application startup performance. - AddHandler(value As Devices.NetworkAvailableEventHandler) - SyncLock _networkAvailabilityChangeLock - If _networkAvailabilityEventHandlers Is Nothing Then - _networkAvailabilityEventHandlers = New List(Of Devices.NetworkAvailableEventHandler) - End If - - _networkAvailabilityEventHandlers.Add(value) - - ' We don't want to create the network object now - it takes a snapshot - ' of the executionContext and our IPrincipal isn't on the thread yet. - ' We know we need to create it and we will at the appropriate time - _turnOnNetworkListener = True - - ' But the user may be doing an AddHandler of their own in which case we need - ' to make sure to honor the request. If we aren't past OnInitialize() yet - ' we shouldn't do it but the flag above catches that case. - If _networkObject Is Nothing AndAlso _finishedOnInitialize Then - _networkObject = New Devices.Network - Dim windowsFormsApplicationBase As WindowsFormsApplicationBase = Me - AddHandler _networkObject.NetworkAvailabilityChanged, - AddressOf windowsFormsApplicationBase.NetworkAvailableEventAdaptor - End If - End SyncLock - End AddHandler - - RemoveHandler(value As Devices.NetworkAvailableEventHandler) - If _networkAvailabilityEventHandlers IsNot Nothing AndAlso - _networkAvailabilityEventHandlers.Count > 0 Then - - _networkAvailabilityEventHandlers.Remove(value) - - ' Last one to leave - turn out the lights... - If _networkAvailabilityEventHandlers.Count = 0 Then - RemoveHandler _networkObject.NetworkAvailabilityChanged, AddressOf NetworkAvailableEventAdaptor - If _networkObject IsNot Nothing Then - - ' Stop listening to network change events because we are going to go away. - _networkObject.DisconnectListener() - - ' No sense holding on to this if nobody is listening. - _networkObject = Nothing - End If - End If - End If - End RemoveHandler - - RaiseEvent(sender As Object, e As Devices.NetworkAvailableEventArgs) - If _networkAvailabilityEventHandlers IsNot Nothing Then - For Each handler As Devices.NetworkAvailableEventHandler In _networkAvailabilityEventHandlers - Try - If handler IsNot Nothing Then handler.Invoke(sender, e) - Catch ex As Exception - If Not OnUnhandledException(New UnhandledExceptionEventArgs(True, ex)) Then - - ' The user didn't write a handler so throw the error up the chain. - Throw - End If - End Try - Next - End If - End RaiseEvent - End Event - - ''' - ''' Occurs when the application encounters an unhandled exception. - ''' - Public Custom Event UnhandledException As UnhandledExceptionEventHandler - - ' This is a custom event because we want to hook up System.Windows.Forms.Application.ThreadException - ' only if the user writes a handler for this event. We only want to hook the ThreadException event - ' if the user is handling this event because the act of listening to Application.ThreadException - ' causes WinForms to snuff exceptions and we only want WinForms to do that if we are assured that - ' the user wrote their own handler to deal with the error instead. - AddHandler(value As UnhandledExceptionEventHandler) - If _unhandledExceptionHandlers Is Nothing Then - _unhandledExceptionHandlers = New List(Of UnhandledExceptionEventHandler) - End If - - _unhandledExceptionHandlers.Add(value) - - ' Only add the listener once so we don't fire the UnHandledException event over and over for the same exception - If _unhandledExceptionHandlers.Count = 1 Then - AddHandler Application.ThreadException, AddressOf OnUnhandledExceptionEventAdaptor - End If - End AddHandler - - RemoveHandler(value As UnhandledExceptionEventHandler) - If _unhandledExceptionHandlers IsNot Nothing AndAlso - _unhandledExceptionHandlers.Count > 0 Then - _unhandledExceptionHandlers.Remove(value) - - ' Last one to leave, turn out the lights... - If _unhandledExceptionHandlers.Count = 0 Then - RemoveHandler Application.ThreadException, AddressOf OnUnhandledExceptionEventAdaptor - End If - End If - End RemoveHandler - - RaiseEvent(sender As Object, e As UnhandledExceptionEventArgs) - If _unhandledExceptionHandlers IsNot Nothing Then - - ' In the case that we throw from the unhandled exception handler, we don't want to - ' run the unhandled exception handler again. - _processingUnhandledExceptionEvent = True - - For Each handler As UnhandledExceptionEventHandler In _unhandledExceptionHandlers - handler?.Invoke(sender, e) - Next - - ' Now that we are out of the unhandled exception handler, treat exceptions normally again. - _processingUnhandledExceptionEvent = False - End If - End RaiseEvent - End Event - - ''' - ''' Constructs the application Shutdown/Startup model object - ''' - ''' - ''' We have to have a parameterless ctor because the platform specific Application object - ''' derives from this one and it doesn't define a ctor because the partial class generated by the - ''' designer does that to configure the application. - Public Sub New() - Me.New(AuthenticationMode.Windows) - End Sub - - ''' - ''' Constructs the application Shutdown/Startup model object - ''' - - Public Sub New(authenticationMode As AuthenticationMode) - MyBase.New() - - ValidateAuthenticationModeEnumValue(authenticationMode, NameOf(authenticationMode)) - - ' Setup Windows Authentication if that's what the user wanted. Note, we want to do this now, - ' before the Network object gets created because the network object will be doing a - ' AsyncOperationsManager.CreateOperation() which captures the execution context. So we have - ' to have our principal on the thread before that happens. - If authenticationMode = AuthenticationMode.Windows Then - Try - ' Consider: Sadly, a call to: System.Security.SecurityManager.IsGranted(New SecurityPermission(SecurityPermissionFlag.ControlPrincipal)) - ' Will only check THIS caller so you'll always get TRUE. - ' What is needed is a way to get to the value of this on a demand basis. - ' So I try/catch instead for now but would rather be able to IF my way around this block. - Thread.CurrentPrincipal = New Principal.WindowsPrincipal(Principal.WindowsIdentity.GetCurrent) - Catch ex As SecurityException - End Try - End If - - _appContext = New WinFormsAppContext(Me) - - ' We need to set the WindowsFormsSynchronizationContext because the network object is going to - ' get created after this ctor runs (network gets created during event hookup) and we need the - ' context in place for it to latch on to. The WindowsFormsSynchronizationContext won't otherwise - ' get created until OnCreateMainForm() when the startup form is created and by then it is too late. - ' When the startup form gets created, WinForms is going to push our context into the previous context - ' and then restore it when Application.Run() exits. - _appSynchronizationContext = AsyncOperationManager.SynchronizationContext - End Sub - - ''' - ''' Entry point to kick off the VB Startup/Shutdown Application model - ''' - ''' The command line from Main() - - Public Sub Run(commandLine As String()) - - ' Prime the command line args with what we receive from Main() so that Click-Once windows - ' apps don't have to do a System.Environment call which would require permissions. - InternalCommandLine = New ReadOnlyCollection(Of String)(commandLine) - - If Not IsSingleInstance Then - DoApplicationModel() - Else - ' This is a Single-Instance application - - ' Note: Must pass the calling assembly from here so we can get the running app. - ' Otherwise, can break single instance. - Dim ApplicationInstanceID As String = GetApplicationInstanceID(Assembly.GetCallingAssembly) - Dim pipeServer As NamedPipeServerStream = Nothing - - If TryCreatePipeServer(ApplicationInstanceID, pipeServer) Then - - ' --- This is the first instance of a single-instance application to run. - ' This is the instance that subsequent instances will attach to. - Using pipeServer - Dim tokenSource = New CancellationTokenSource() -#Disable Warning BC42358 ' Call is not awaited. - WaitForClientConnectionsAsync(pipeServer, AddressOf OnStartupNextInstanceMarshallingAdaptor, cancellationToken:=tokenSource.Token) -#Enable Warning BC42358 - DoApplicationModel() - tokenSource.Cancel() - End Using - Else - - ' --- We are launching a subsequent instance. - Dim tokenSource = New CancellationTokenSource() - tokenSource.CancelAfter(SECOND_INSTANCE_TIMEOUT) - Try - Dim awaitable = SendSecondInstanceArgsAsync(ApplicationInstanceID, commandLine, cancellationToken:=tokenSource.Token).ConfigureAwait(False) - awaitable.GetAwaiter().GetResult() - Catch ex As Exception - Throw New CantStartSingleInstanceException() - End Try - End If - End If 'Single-Instance application - End Sub - - ''' - ''' Returns the collection of forms that are open. We no longer have thread - ''' affinity meaning that this is the WinForms collection that contains Forms that may - ''' have been opened on another thread then the one we are calling in on right now. - ''' - Public ReadOnly Property OpenForms() As FormCollection - Get - Return Application.OpenForms - End Get - End Property - - ''' - ''' Provides access to the main form for this application - ''' - Protected Property MainForm() As Form - Get - Return _appContext?.MainForm - End Get - Set(value As Form) - If value Is Nothing Then - Throw ExceptionUtils.GetArgumentNullException("MainForm", SR.General_PropertyNothing, "MainForm") - End If - If value Is _splashScreen Then - Throw New ArgumentException(GetResourceString(SR.AppModel_SplashAndMainFormTheSame)) - End If - _appContext.MainForm = value - End Set - End Property - - ''' - ''' Provides access to the splash screen for this application - ''' - Public Property SplashScreen() As Form - Get - Return _splashScreen - End Get - Set(value As Form) - - ' Allow for the case where they set splash screen = nothing and mainForm is currently nothing. - If value IsNot Nothing AndAlso value Is _appContext.MainForm Then - Throw New ArgumentException(GetResourceString(SR.AppModel_SplashAndMainFormTheSame)) - End If - - _splashScreen = value - End Set - End Property - - ''' - ''' The splash screen timeout specifies whether there is a minimum time that the splash - ''' screen should be displayed for. When not set then the splash screen is hidden - ''' as soon as the main form becomes active. - ''' - ''' The minimum amount of time, in milliseconds, to display the splash screen. - ''' - ''' This property, although public, used to be set in an `Overrides Function OnInitialize` _before_ - ''' calling `MyBase.OnInitialize`. We want to phase this out, and with the introduction of the - ''' ApplyApplicationDefaults events have it handled in that event, rather than as awkwardly - ''' as it is currently suggested to be used in the docs. - ''' First step for that is to make it hidden in IntelliSense. - ''' - - Public Property MinimumSplashScreenDisplayTime() As Integer - Get - Return _minimumSplashExposure - End Get - Set(value As Integer) - _minimumSplashExposure = value - End Set - End Property - - ''' - ''' Use GDI for the text rendering engine by default. - ''' The user can shadow this function to return True if they want their app - ''' to use the GDI+ render. We read this function in Main() (My template) to - ''' determine how to set the text rendering flag on the WinForms application object. - ''' - ''' True - Use GDI+ renderer. False - use GDI renderer - - Protected Shared ReadOnly Property UseCompatibleTextRendering() As Boolean - Get - Return False - End Get - End Property - - ''' - ''' Provides the WinForms application context that we are running on - ''' - - Public ReadOnly Property ApplicationContext() As ApplicationContext - Get - Return _appContext - End Get - End Property - - ''' - ''' Informs My.Settings whether to save the settings on exit or not - ''' - Public Property SaveMySettingsOnExit() As Boolean - Get - Return _saveMySettingsOnExit - End Get - Set(value As Boolean) - _saveMySettingsOnExit = value - End Set - End Property - - ''' - ''' Processes all windows messages currently in the message queue - ''' - Public Sub DoEvents() - Application.DoEvents() - End Sub - - ''' - ''' This exposes the first in a series of extensibility points for the Startup process. By default, it shows - ''' the splash screen and does rudimentary processing of the command line to see if /nosplash or its - ''' variants was passed in. - ''' - ''' - ''' Returning True indicates that we should continue on with the application Startup sequence - ''' This extensibility point is exposed for people who want to override the Startup sequence at the earliest possible point - ''' to - - Protected Overridable Function OnInitialize(commandLineArgs As ReadOnlyCollection(Of String)) As Boolean - - ' Rationale for how we process the default values and how we let the user modify - ' them on demand via the ApplyApplicationDefaults event. - ' =========================================================================================== - ' a) Users used to be able to set MinimumSplashScreenDisplayTime _only_ by overriding OnInitialize - ' in a derived class and setting `MyBase.MinimumSplashScreenDisplayTime` there. - ' We are picking this (probably) changed value up, and pass it to the ApplyDefaultsEvents - ' where it could be modified (again). So event wins over Override over default value (2 seconds). - ' b) We feed the default HighDpiMode (SystemAware) to the EventArgs. With the introduction of - ' the HighDpiMode property, we give Project System the chance to reflect the HighDpiMode - ' in the App Designer UI and have it code-generated based on a modified Application.myapp, which - ' would result it to be set in the derived constructor. (See the hidden file in the Solution Explorer - ' "My Project\Application.myapp\Application.Designer.vb for how those UI-set values get applied.) - ' Once all this is done, we give the User another chance to change the value by code through - ' the ApplyDefaults event. - Dim applicationDefaultsEventArgs = New ApplyApplicationDefaultsEventArgs( - MinimumSplashScreenDisplayTime, - HighDpiMode) - - ' Overriding MinimumSplashScreenDisplayTime needs still to keep working! - applicationDefaultsEventArgs.MinimumSplashScreenDisplayTime = MinimumSplashScreenDisplayTime - RaiseEvent ApplyApplicationDefaults(Me, applicationDefaultsEventArgs) - - If (applicationDefaultsEventArgs.Font IsNot Nothing) Then - Application.SetDefaultFont(applicationDefaultsEventArgs.Font) - End If - - MinimumSplashScreenDisplayTime = applicationDefaultsEventArgs.MinimumSplashScreenDisplayTime - - ' This creates the native window, and that means, we can no longer apply a different Default Font. - ' So, this is the earliest point in time to set the AsyncOperationManager's SyncContext. - AsyncOperationManager.SynchronizationContext = New WindowsFormsSynchronizationContext() - - _highDpiMode = applicationDefaultsEventArgs.HighDpiMode - - ' Then, it's applying what we got back as HighDpiMode. - Dim dpiSetResult = Application.SetHighDpiMode(_highDpiMode) - If dpiSetResult Then - _highDpiMode = Application.HighDpiMode - End If - Debug.Assert(dpiSetResult, "We could net set the HighDpiMode.") - - ' And finally we take care of EnableVisualStyles. - If _enableVisualStyles Then - Application.EnableVisualStyles() - End If - - ' We'll handle "/nosplash" for you. - If Not (commandLineArgs.Contains("/nosplash") OrElse Me.CommandLineArgs.Contains("-nosplash")) Then - ShowSplashScreen() - End If - - _finishedOnInitialize = True - - ' We are now at a point where we can allow the network object - ' to be created since the iPrincipal is on the thread by now. - - ' True means to not bail out but keep on running after OnInitialize() finishes - Return True - End Function - - ''' - ''' Extensibility point which raises the Startup event - ''' - ''' - - Protected Overridable Function OnStartup(eventArgs As StartupEventArgs) As Boolean - - eventArgs.Cancel = False - - ' It is important not to create the network object until the ExecutionContext has everything on it. - ' By now the principal will be on the thread so we can create the network object. - ' The timing is important because the network object has an AsyncOperationsManager in it that marshals - ' the network changed event to the main thread. The asycnOperationsManager does a CreateOperation() - ' which makes a copy of the executionContext. That execution context shows up on your thread during - ' the callback so I delay creating the network object (and consequently the capturing of the execution context) - ' until the principal has been set on the thread. This avoids the problem where My.User isn't set - ' during the NetworkAvailabilityChanged event. This problem would just extend itself to any future - ' callback that involved the asyncOperationsManager so this is where we need to create objects that - ' have a asyncOperationsContext in them. - If _turnOnNetworkListener And _networkObject Is Nothing Then - - ' The is-nothing-check is to avoid hooking the object more than once. - _networkObject = New Devices.Network - AddHandler _networkObject.NetworkAvailabilityChanged, AddressOf NetworkAvailableEventAdaptor - End If - - RaiseEvent Startup(Me, eventArgs) - - Return Not eventArgs.Cancel - End Function - - ''' - ''' Extensibility point which raises the StartupNextInstance - ''' - ''' - - - Protected Overridable Sub OnStartupNextInstance(eventArgs As StartupNextInstanceEventArgs) - - RaiseEvent StartupNextInstance(Me, eventArgs) - - ' Activate the original instance. - If eventArgs.BringToForeground AndAlso MainForm IsNot Nothing Then - If MainForm.WindowState = FormWindowState.Minimized Then - MainForm.WindowState = FormWindowState.Normal - End If - - MainForm.Activate() - End If - End Sub - - ''' - ''' At this point, the command line args should have been processed and the application will create the - ''' main form and enter the message loop. - ''' - - - Protected Overridable Sub OnRun() - - If MainForm Is Nothing Then - - ' A designer overrides OnCreateMainForm() to set the main form we are supposed to use. - OnCreateMainForm() - - If MainForm Is Nothing Then - Throw New NoStartupFormException - End If - - ' When we have a splash screen that hasn't timed out before the main form is ready to paint, we want to - ' block the main form from painting. To do that I let the form get past the Load() event and hold it until - ' the splash screen goes down. Then I let the main form continue it's startup sequence. The ordering of - ' Form startup events for reference is: Ctor(), Load Event, Layout event, Shown event, Activated event, Paint event. - AddHandler MainForm.Load, AddressOf MainFormLoadingDone - End If - - ' Run() eats all exceptions (unless running under the debugger). If the user wrote an - ' UnhandledException handler we will hook the System.Windows.Forms.Application.ThreadException event - ' (see Public Custom Event UnhandledException) which will raise our UnhandledException Event. - ' If our user didn't write an UnhandledException event, then we land in the try/catch handler for Forms.Application.Run(). - Try - Application.Run(_appContext) - Finally - - ' When Run() returns, the context we pushed in our ctor (which was a WindowsFormsSynchronizationContext) - ' is restored. But we are going to dispose it so we need to disconnect the network listener so that it - ' can't fire any events in response to changing network availability conditions through a dead context. - If _networkObject IsNot Nothing Then _networkObject.DisconnectListener() - - 'Restore the prior sync context. - AsyncOperationManager.SynchronizationContext = _appSynchronizationContext - _appSynchronizationContext = Nothing - End Try - End Sub - - ''' - ''' A designer will override this method and provide a splash screen if this application has one. - ''' - ''' For instance, a designer would override this method and emit: Me.Splash = new Splash - ''' where Splash was designated in the application designer as being the splash screen for this app - - Protected Overridable Sub OnCreateSplashScreen() - End Sub - - ''' - ''' Provides a hook that designers will override to set the main form. - ''' - - Protected Overridable Sub OnCreateMainForm() - End Sub - - ''' - ''' The last in a series of extensibility points for the Shutdown process - ''' - - Protected Overridable Sub OnShutdown() - RaiseEvent Shutdown(Me, EventArgs.Empty) - End Sub - - ''' - ''' Raises the UnHandled exception event and exits the application if the event handler indicated - ''' that execution shouldn't continue - ''' - ''' - ''' True indicates the exception event was raised / False it was not - - Protected Overridable Function OnUnhandledException(e As UnhandledExceptionEventArgs) As Boolean - - ' Does the user have a handler for this event? - If _unhandledExceptionHandlers IsNot Nothing AndAlso _unhandledExceptionHandlers.Count > 0 Then - - ' We don't put a try/catch around the handler event so that exceptions in there will - ' bubble out - else we will have a recursive exception handler. - RaiseEvent UnhandledException(Me, e) - If e.ExitApplication Then Application.Exit() - - ' User handled the event. - Return True - End If - - ' Nobody was listening to the UnhandledException event. - Return False - End Function - - ''' - ''' Uses the extensibility model to see if there is a splash screen provided for this app and if there is, - ''' displays it. - ''' - - Protected Sub ShowSplashScreen() - If Not _didSplashScreen Then - _didSplashScreen = True - - If _splashScreen Is Nothing Then - - ' If the user specified a splash screen, the designer will have overridden this method to set it. - OnCreateSplashScreen() - End If - - If _splashScreen IsNot Nothing Then - - ' Some splash screens have minimum face time they are supposed to get. - ' We'll set up a time to let us know when we can take it down. - If _minimumSplashExposure > 0 Then - - ' Don't close until the timer expires. - _splashTimer = New Timers.Timer(_minimumSplashExposure) - AddHandler _splashTimer.Elapsed, AddressOf MinimumSplashExposureTimeIsUp - _splashTimer.AutoReset = False - - ' We only need this, when we actually need to wait for it. - _splashScreenCompletionSource = New TaskCompletionSource(Of Boolean) - - ' We'll enable it in DisplaySplash() once the splash screen thread gets running. - End If - - ' Run the splash screen on another thread so we don't starve it for events and painting - ' while the main form gets its act together. - Task.Run(AddressOf DisplaySplash) - End If - End If - End Sub - - ''' - ''' Hide the splash screen. The splash screen was created on another thread - ''' thread (main thread) than the one it was run on (secondary thread for the - ''' splash screen so it doesn't block app startup. We need to invoke the close. - ''' This function gets called from the main thread by the app fx. - ''' - - - Protected Sub HideSplashScreen() - - 'This ultimately wasn't necessary. I suppose we better keep it for backwards compatibility. - SyncLock _splashLock - - ' .NET Framework 4.0 (Dev10 #590587) - we now activate the main form before calling - ' Dispose on the Splash screen. (we're just swapping the order of the two If blocks.) - ' This is to fix the issue where the main form doesn't come to the front after the - ' Splash screen disappears. - MainForm?.Activate() - - If _splashScreen IsNot Nothing AndAlso Not _splashScreen.IsDisposed Then - Dim disposeSplashDelegate As New DisposeDelegate(AddressOf _splashScreen.Dispose) - _splashScreen.Invoke(disposeSplashDelegate) - _splashScreen = Nothing - End If - End SyncLock - End Sub - - ''' - ''' Determines when this application will terminate (when the main form goes down, all forms) - ''' - Protected Friend Property ShutdownStyle() As ShutdownMode - Get - Return _shutdownStyle - End Get - Set(value As ShutdownMode) - ValidateShutdownModeEnumValue(value, NameOf(value)) - _shutdownStyle = value - End Set - End Property - - ''' - ''' Determines whether this application will use the XP Windows styles for windows, controls, etc. - ''' - Protected Property EnableVisualStyles() As Boolean - Get - Return _enableVisualStyles - End Get - Set(value As Boolean) - _enableVisualStyles = value - End Set - End Property - - ''' - ''' Gets or sets the HighDpiMode for the Application. - ''' - - Protected Property HighDpiMode() As HighDpiMode - Get - Return _highDpiMode - End Get - Set(value As HighDpiMode) - _highDpiMode = value - End Set - End Property - - - Protected Property IsSingleInstance() As Boolean - Get - Return _isSingleInstance - End Get - Set(value As Boolean) - _isSingleInstance = value - End Set - End Property - - ''' - ''' Validates that the value being passed as an AuthenticationMode enum is a legal value - ''' - ''' - Private Shared Sub ValidateAuthenticationModeEnumValue(value As AuthenticationMode, paramName As String) - If value < AuthenticationMode.Windows OrElse value > AuthenticationMode.ApplicationDefined Then - Throw New InvalidEnumArgumentException(paramName, value, GetType(AuthenticationMode)) - End If - End Sub - - ''' - ''' Validates that the value being passed as an ShutdownMode enum is a legal value - ''' - ''' - Private Shared Sub ValidateShutdownModeEnumValue(value As ShutdownMode, paramName As String) - If value < ShutdownMode.AfterMainFormCloses OrElse value > ShutdownMode.AfterAllFormsClose Then - Throw New InvalidEnumArgumentException(paramName, value, GetType(ShutdownMode)) - End If - End Sub - - ''' - ''' Displays the splash screen. We get called here from a different thread than what the - ''' main form is starting up on. This allows us to process events for the Splash screen so - ''' it doesn't freeze up while the main form is getting it together. - ''' - Private Sub DisplaySplash() - Debug.Assert(_splashScreen IsNot Nothing, "We should have never get here if there is no splash screen") - - If _splashTimer IsNot Nothing Then - - ' We only have a timer if there is a minimum time that the splash screen is supposed to be displayed. - ' Enable the timer now that we are about to show the splash screen. - _splashTimer.Enabled = True - End If - - Application.Run(_splashScreen) - End Sub - - ''' - ''' If a splash screen has a minimum time out, then once that is up we check to see whether - ''' we should close the splash screen. If the main form has activated then we close it. - ''' Note that we are getting called on a secondary thread here which isn't necessarily - ''' associated with any form. Don't touch forms from this function. - ''' - Private Sub MinimumSplashExposureTimeIsUp(sender As Object, e As Timers.ElapsedEventArgs) - - If _splashTimer IsNot Nothing Then - - 'We only have a timer if there was a minimum timeout on the splash screen. - _splashTimer.Dispose() - _splashTimer = Nothing - End If - - _splashScreenCompletionSource.SetResult(True) - End Sub - - ''' - ''' The Load() event happens before the Shown and Paint events. When we get called here - ''' we know that the form load event is done and that the form is about to paint - ''' itself for the first time. - ''' We can now hide the splash screen. - ''' Note that this function gets called from the main thread - the same thread - ''' that creates the startup form. - ''' - ''' - ''' - Private Sub MainFormLoadingDone(sender As Object, e As EventArgs) - - ' We don't want this event to call us again. - RemoveHandler MainForm.Load, AddressOf MainFormLoadingDone - - ' Now, we don't want to eat up a complete Processor Core just for waiting on the main form, - ' since this is eating up a LOT of enegery and workload, espacially on Notebooks and tablets. - If _splashScreenCompletionSource IsNot Nothing Then - - _formLoadWaiter = New AutoResetEvent(False) - - Task.Run(Async Function() As Task - Await _splashScreenCompletionSource.Task.ConfigureAwait(False) - _formLoadWaiter.Set() - End Function) - - ' Block until the splash screen time is up. - ' See MinimumSplashExposureTimeIsUp() which releases us. - _formLoadWaiter.WaitOne() - End If - - HideSplashScreen() - End Sub - - ''' - ''' Handles the Windows.Forms.Application.ThreadException event and raises our Unhandled - ''' exception event - ''' - ''' - ''' Our UnHandledException event has a different signature then the Windows.Forms.Application - ''' unhandled exception event so we do the translation here before raising our event. - ''' - Private Sub OnUnhandledExceptionEventAdaptor(sender As Object, e As ThreadExceptionEventArgs) - OnUnhandledException(New UnhandledExceptionEventArgs(True, e.Exception)) - End Sub - - Private Sub OnStartupNextInstanceMarshallingAdaptor(ByVal args As String()) - - Dim invoked = False - - Try - Dim handleNextInstance As New Action( - Sub() - invoked = True - OnStartupNextInstance(New StartupNextInstanceEventArgs( - New ReadOnlyCollection(Of String)(args), - bringToForegroundFlag:=True)) - End Sub) - - ' If we have a Main form, we need to make sure that we are on _its_ UI thread - ' before we call OnStartupNextInstance. - If MainForm IsNot Nothing Then - MainForm.Invoke(handleNextInstance) - Else - ' Otherwise, we need to make sure that we are on the thread - ' provided by the SynchronizationContext. - AsyncOperationManager. - SynchronizationContext. - Send(Sub() handleNextInstance(), Nothing) - End If - - Catch ex As Exception When Not invoked - ' Only catch exceptions thrown when the UI thread is not available, before - ' the UI thread has been created or after it has been terminated. Exceptions - ' thrown from OnStartupNextInstance() should be allowed to propagate. - End Try - End Sub - - ''' - ''' Handles the Network.NetworkAvailability event (on the correct thread) and raises the - ''' NetworkAvailabilityChanged event - ''' - ''' Contains the Network instance that raised the event - ''' Contains whether the network is available or not - Private Sub NetworkAvailableEventAdaptor(sender As Object, e As Devices.NetworkAvailableEventArgs) - RaiseEvent NetworkAvailabilityChanged(sender, e) - End Sub - - ''' - ''' Runs the user's program through the VB Startup/Shutdown application model - ''' - Private Sub DoApplicationModel() - - Dim EventArgs As New StartupEventArgs(CommandLineArgs) - - ' Only do the try/catch if we aren't running under the debugger. - ' If we do try/catch under the debugger the debugger never gets - ' a crack at exceptions which breaks the exception helper. - If Not Debugger.IsAttached Then - - ' NO DEBUGGER ATTACHED - we use a catch so that we can run our UnhandledException code - ' Note - Sadly, code changes within this IF (that don't pertain to exception handling) - ' need to be mirrored in the ELSE debugger attached clause below. - Try - If OnInitialize(CommandLineArgs) Then - If OnStartup(EventArgs) Then - OnRun() - OnShutdown() - End If - End If - Catch ex As Exception - - ' This catch is for exceptions that happen during the On* methods above, - ' but have occurred outside of the message pump (which exceptions we would - ' have already seen via our hook of System.Windows.Forms.Application.ThreadException). - If _processingUnhandledExceptionEvent Then - - ' If the UnhandledException handler threw for some reason, throw that error out to the system. - Throw - Else - - ' We had an exception, but not during the OnUnhandledException handler so give the user - ' a chance to look at what happened in the UnhandledException event handler - If Not OnUnhandledException(New UnhandledExceptionEventArgs(True, ex)) Then - - ' The user didn't write a handler so throw the error out to the system - Throw - End If - End If - End Try - Else - ' DEBUGGER ATTACHED - we don't have an uber catch when debugging so the exception - ' will bubble out to the exception helper. - ' We also don't hook up the Application.ThreadException event because WinForms ignores it - ' when we are running under the debugger. - If OnInitialize(CommandLineArgs) Then - If OnStartup(EventArgs) Then - OnRun() - OnShutdown() - End If - End If - End If - End Sub - - ''' - ''' Generates the name for the remote singleton that we use to channel multiple instances - ''' to the same application model thread. - ''' - ''' A string unique to the application that should be the same for versions of - ''' the application that have the same Major and Minor Version Number - ''' - ''' If GUID Attribute does not exist fall back to unique ModuleVersionId - Private Shared Function GetApplicationInstanceID(ByVal Entry As Assembly) As String - - Dim guidAttrib As GuidAttribute = Entry.GetCustomAttribute(Of GuidAttribute)() - - If guidAttrib IsNot Nothing Then - - Dim version As Version = Entry.GetName.Version - - If version IsNot Nothing Then - Return $"{guidAttrib.Value}{version.Major}.{version.Minor}" - Else - Return guidAttrib.Value - End If - End If - - Return Entry.ManifestModule.ModuleVersionId.ToString() - End Function - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/CompilerServices/ExceptionUtils.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/CompilerServices/ExceptionUtils.vb deleted file mode 100644 index e54eda83619..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/CompilerServices/ExceptionUtils.vb +++ /dev/null @@ -1,172 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On - -Imports Microsoft.VisualBasic.CompilerServices.Utils - -Namespace Microsoft.VisualBasic.CompilerServices - - Friend Enum vbErrors - None = 0 - FileNotFound = 53 - PermissionDenied = 70 - End Enum - - ' Implements error utilities for Basic - Friend NotInheritable Class ExceptionUtils - - ' Prevent creation. - Private Sub New() - End Sub - - Friend Shared Function VbMakeException(hr As Integer) As Exception - Dim sMsg As String - - If hr > 0 AndAlso hr <= &HFFFFI Then - sMsg = GetResourceString(CType(hr, vbErrors)) - Else - sMsg = "" - End If - VbMakeException = VbMakeExceptionEx(hr, sMsg) - End Function - - Friend Shared Function VbMakeExceptionEx(number As Integer, sMsg As String) As Exception - Dim vBDefinedError As Boolean - - VbMakeExceptionEx = BuildException(number, sMsg, vBDefinedError) - - If vBDefinedError Then - ' .NET Framework implementation calls: - ' Err().SetUnmappedError(number) - End If - - End Function - - Friend Shared Function BuildException(Number As Integer, Description As String, ByRef VBDefinedError As Boolean) As Exception - - VBDefinedError = True - - Select Case Number - - Case vbErrors.None - - Case vbErrors.FileNotFound - Return New IO.FileNotFoundException(Description) - - Case vbErrors.PermissionDenied - Return New IO.IOException(Description) - - Case Else - 'Fall below to default - VBDefinedError = False - Return New Exception(Description) - End Select - - VBDefinedError = False - Return New Exception(Description) - - End Function - - ''' - ''' Returns a new instance of ArgumentException with the message from resource file and the Exception.ArgumentName property set. - ''' - ''' The name of the argument (parameter). Not localized. - ''' The resource ID. - ''' Strings that will replace place holders in the resource string, if any. - ''' A new instance of ArgumentException. - ''' This is the preferred way to construct an argument exception. - Friend Shared Function GetArgumentExceptionWithArgName(ArgumentName As String, - ResourceID As String, ParamArray PlaceHolders() As String) As ArgumentException - - Return New ArgumentException(GetResourceString(ResourceID, PlaceHolders), ArgumentName) - End Function - - ''' - ''' Returns a new instance of ArgumentNullException with message: "Argument cannot be Nothing." - ''' - ''' The name of the argument (parameter). Not localized. - ''' A new instance of ArgumentNullException. - Friend Shared Function GetArgumentNullException(ArgumentName As String) As ArgumentNullException - - Return New ArgumentNullException(ArgumentName, GetResourceString(SR.General_ArgumentNullException)) - End Function - - ''' - ''' Returns a new instance of ArgumentNullException with the message from resource file. - ''' - ''' The name of the argument (parameter). Not localized. - ''' The resource ID. - ''' Strings that will replace place holders in the resource string, if any. - ''' A new instance of ArgumentNullException. - Friend Shared Function GetArgumentNullException(ArgumentName As String, - ResourceID As String, ParamArray PlaceHolders() As String) As ArgumentNullException - - Return New ArgumentNullException(ArgumentName, GetResourceString(ResourceID, PlaceHolders)) - End Function - - ''' - ''' Returns a new instance of IO.DirectoryNotFoundException with the message from resource file. - ''' - ''' The resource ID. - ''' Strings that will replace place holders in the resource string, if any. - ''' A new instance of IO.DirectoryNotFoundException. - Friend Shared Function GetDirectoryNotFoundException( - ResourceID As String, ParamArray PlaceHolders() As String) As IO.DirectoryNotFoundException - - Return New IO.DirectoryNotFoundException(GetResourceString(ResourceID, PlaceHolders)) - End Function - - ''' - ''' Returns a new instance of IO.FileNotFoundException with the message from resource file. - ''' - ''' The file name (path) of the not found file. - ''' The resource ID. - ''' Strings that will replace place holders in the resource string, if any. - ''' A new instance of IO.FileNotFoundException. - Friend Shared Function GetFileNotFoundException(FileName As String, - ResourceID As String, ParamArray PlaceHolders() As String) As IO.FileNotFoundException - - Return New IO.FileNotFoundException(GetResourceString(ResourceID, PlaceHolders), FileName) - End Function - - ''' - ''' Returns a new instance of InvalidOperationException with the message from resource file. - ''' - ''' The resource ID. - ''' Strings that will replace place holders in the resource string, if any. - ''' A new instance of InvalidOperationException. - Friend Shared Function GetInvalidOperationException( - ResourceID As String, ParamArray PlaceHolders() As String) As InvalidOperationException - - Return New InvalidOperationException(GetResourceString(ResourceID, PlaceHolders)) - End Function - - ''' - ''' Returns a new instance of IO.IOException with the message from resource file. - ''' - ''' The resource ID. - ''' Strings that will replace place holders in the resource string, if any. - ''' A new instance of IO.IOException. - Friend Shared Function GetIOException(ResourceID As String, ParamArray PlaceHolders() As String) As IO.IOException - - Return New IO.IOException(GetResourceString(ResourceID, PlaceHolders)) - End Function - - ''' - ''' Returns a new instance of Win32Exception with the message from resource file and the last Win32 error. - ''' - ''' The resource ID. - ''' Strings that will replace place holders in the resource string, if any. - ''' A new instance of Win32Exception. - ''' There is no way to exclude the Win32 error so this function will call Marshal.GetLastWin32Error all the time. - - Friend Shared Function GetWin32Exception( - ResourceID As String, ParamArray PlaceHolders() As String) As ComponentModel.Win32Exception - - Return New ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error(), GetResourceString(ResourceID, PlaceHolders)) - End Function - - End Class - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/CompilerServices/Utils.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/CompilerServices/Utils.vb deleted file mode 100644 index 4f4c8eeab82..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/CompilerServices/Utils.vb +++ /dev/null @@ -1,27 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Globalization - -Namespace Microsoft.VisualBasic.CompilerServices - - ' Purpose: various helpers for the vb runtime functions - Friend NotInheritable Class Utils - - Friend Shared Function GetResourceString(ResourceId As vbErrors) As String - Dim id As String = "ID" & CStr(ResourceId) - Return SR.GetResourceString(id, id) - End Function - - Friend Shared Function GetResourceString(resourceKey As String, ParamArray args() As String) As String - Return String.Format(GetCultureInfo(), resourceKey, args) - End Function - - Friend Shared Function GetCultureInfo() As CultureInfo - Return System.Threading.Thread.CurrentThread.CurrentCulture - End Function - - End Class - -End Namespace - diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Audio.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Audio.vb deleted file mode 100644 index 341112efb86..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Audio.vb +++ /dev/null @@ -1,165 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On -Imports System.IO -Imports Microsoft.VisualBasic.CompilerServices.ExceptionUtils - -Namespace Microsoft.VisualBasic - - ''' - ''' Enum for three ways to play a .wav file - ''' - Public Enum AudioPlayMode - ' Any changes to this enum must be reflected in ValidateAudioPlayModeEnum() - WaitToComplete = 0 'Synchronous - Background = 1 'Asynchronous - BackgroundLoop = 2 'Asynchronous and looping - End Enum - - Namespace Devices - - ''' - ''' An object that makes it easy to play wav files - ''' - Public Class Audio - - ''' - ''' Creates a new Audio object - ''' - Public Sub New() - End Sub - - ''' - ''' Plays a .wav file in background mode - ''' - ''' The name of the file - Public Sub Play(location As String) - Play(location, AudioPlayMode.Background) - End Sub - - ''' - ''' Plays a .wav file in the passed in mode - ''' - ''' The name of the file - ''' - ''' An enum value representing the mode, Background (async), - ''' WaitToComplete (sync) or BackgroundLoop - ''' - Public Sub Play(location As String, playMode As AudioPlayMode) - ValidateAudioPlayModeEnum(playMode, NameOf(playMode)) - Dim safeFilename As String = ValidateFilename(location) - Dim sound As Media.SoundPlayer = New Media.SoundPlayer(safeFilename) - Play(sound, playMode) - End Sub - - ''' - ''' Plays a Byte array representation of a .wav file in the passed in mode - ''' - ''' The array representing the .wav file - ''' The mode in which the array should be played - Public Sub Play(data() As Byte, playMode As AudioPlayMode) - If data Is Nothing Then - Throw GetArgumentNullException("data") - End If - ValidateAudioPlayModeEnum(playMode, NameOf(playMode)) - - Dim soundStream As MemoryStream = New MemoryStream(data) - Play(soundStream, playMode) - soundStream.Close() - End Sub - - ''' - ''' Plays a stream representation of a .wav file in the passed in mode - ''' - ''' The stream representing the .wav file - ''' The mode in which the stream should be played - Public Sub Play(stream As Stream, playMode As AudioPlayMode) - ValidateAudioPlayModeEnum(playMode, NameOf(playMode)) - If stream Is Nothing Then - Throw GetArgumentNullException("stream") - End If - - Play(New Media.SoundPlayer(stream), playMode) - End Sub - - ''' - ''' Plays a system messageBeep sound. - ''' - ''' The sound to be played - ''' Plays the sound asynchronously - Public Sub PlaySystemSound(systemSound As Media.SystemSound) - If systemSound Is Nothing Then - Throw GetArgumentNullException("systemSound") - End If - - systemSound.Play() - - End Sub - - ''' - ''' Stops the play of any playing sound - ''' - Public Sub [Stop]() - Dim sound As New Media.SoundPlayer() - sound.Stop() - End Sub - - ''' - ''' Plays the passed in SoundPlayer in the passed in mode - ''' - ''' The SoundPlayer to play - ''' The mode in which to play the sound - Private Sub Play(sound As Media.SoundPlayer, mode As AudioPlayMode) - - Debug.Assert(sound IsNot Nothing, "There's no SoundPlayer") - Debug.Assert([Enum].IsDefined(GetType(AudioPlayMode), mode), "Enum value is out of range") - - ' Stopping the sound ensures it's safe to dispose it. This could happen when we change the value of m_Sound below - _sound?.Stop() - - _sound = sound - - Select Case mode - Case AudioPlayMode.WaitToComplete - _sound.PlaySync() - Case AudioPlayMode.Background - _sound.Play() - Case AudioPlayMode.BackgroundLoop - _sound.PlayLooping() - Case Else - Debug.Fail("Unknown AudioPlayMode") - End Select - - End Sub - - ''' - ''' Gets the full name and path for the file. Throws if unable to get full name and path - ''' - ''' The filename being tested - ''' A full name and path of the file - Private Shared Function ValidateFilename(location As String) As String - If String.IsNullOrEmpty(location) Then - Throw GetArgumentNullException("location") - End If - - Return location - End Function - - ''' - ''' Validates that the value being passed as an AudioPlayMode enum is a legal value - ''' - ''' - Private Shared Sub ValidateAudioPlayModeEnum(value As AudioPlayMode, paramName As String) - If value < AudioPlayMode.WaitToComplete OrElse value > AudioPlayMode.BackgroundLoop Then - Throw New ComponentModel.InvalidEnumArgumentException(paramName, DirectCast(value, Integer), GetType(AudioPlayMode)) - End If - End Sub - - ' Object that plays the sounds. We use a private member so we can ensure we have a reference for async plays - Private _sound As Media.SoundPlayer - - End Class 'Audio - End Namespace -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Clock.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Clock.vb deleted file mode 100644 index c7ea5c6fb79..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Clock.vb +++ /dev/null @@ -1,51 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - - -Namespace Microsoft.VisualBasic.Devices - - ''' - ''' A wrapper object that acts as a discovery mechanism to quickly find out - ''' the current local time of the machine and the GMT time. - ''' - Public Class Clock - - ''' - ''' Gets a Date that is the current local date and time on this computer. - ''' - ''' A Date whose value is the current date and time. -#Disable Warning IDE0049 ' Simplify Names, Justification:= - Public ReadOnly Property LocalTime() As DateTime - Get - Return DateTime.Now - End Get - End Property - - ''' - ''' Gets a DateTime that is the current local date and time on this - ''' computer expressed as GMT time. - ''' - ''' A Date whose value is the current date and time expressed as GMT time. - Public ReadOnly Property GmtTime() As DateTime - Get - Return DateTime.UtcNow - End Get - End Property -#Enable Warning IDE0049 ' Simplify Names - - ''' - ''' This property wraps the Environment.TickCount property to get the - ''' number of milliseconds elapsed since the system started. - ''' - ''' An Integer containing the amount of time in milliseconds. - Public ReadOnly Property TickCount() As Integer - Get - Return Environment.TickCount - End Get - End Property - - End Class 'Clock -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Computer.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Computer.vb deleted file mode 100644 index f4098d32bad..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Computer.vb +++ /dev/null @@ -1,100 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - -Imports Microsoft.VisualBasic.MyServices -Imports System.Windows.Forms - -Namespace Microsoft.VisualBasic.Devices - - ''' - ''' A RAD object representing the 'computer' that serves as a discovery - ''' mechanism for finding principle abstractions in the system that you can - ''' code against such as the file system, the clipboard, performance - ''' counters, etc. It also provides functionality you would expect to see - ''' associated with the computer such as playing sound, timers, access to - ''' environment variables, etc. This class represent a general computer - ''' available from a Windows Application, Web app, Dll library, etc. - ''' - Public Class Computer : Inherits ServerComputer - - 'NOTE: The .Net design guidelines state that access to Instance members does not have to be thread-safe. Access to Shared members does have to be thread-safe. - 'Since My.Computer creates the instance of Computer in a thread-safe way, access to the Computer will necessarily be thread-safe. - 'There is nothing to prevent a user from passing our computer object across threads or creating their own instance and then getting into trouble. - ' But that is completely consistent with the rest of the FX design. It is MY.* that is thread safe and leads to best practice access to these objects. - ' If you dim them up yourself, you are responsible for managing the threading. - - ''' - ''' Gets an Audio object which can play sound files or resources. - ''' - ''' A sound object. - Public ReadOnly Property Audio() As Audio - Get - If _audio IsNot Nothing Then Return _audio - _audio = New Audio() - Return _audio - End Get - End Property - - ''' - ''' A thin wrapper for System.Windows.Forms.Clipboard - ''' - ''' An object representing the clipboard - Public ReadOnly Property Clipboard() As ClipboardProxy - Get - If s_clipboard Is Nothing Then - s_clipboard = New ClipboardProxy() - End If - - Return s_clipboard - End Get - End Property - - ''' - ''' This property returns the Mouse object containing information about - ''' the physical mouse installed to the machine. - ''' - ''' An instance of the Mouse class. - Public ReadOnly Property Mouse() As Mouse - Get - If s_mouse IsNot Nothing Then Return s_mouse - s_mouse = New Mouse - Return s_mouse - End Get - End Property - - ''' - ''' This property returns the Keyboard object representing some - ''' keyboard properties and a send keys method - ''' - ''' An instance of the Keyboard class. - Public ReadOnly Property Keyboard() As Keyboard - Get - If s_keyboardInstance IsNot Nothing Then Return s_keyboardInstance - s_keyboardInstance = New Keyboard - Return s_keyboardInstance - End Get - End Property - - ''' - ''' This property returns the primary display screen. - ''' - ''' A System.Windows.Forms.Screen object as the primary screen. - Public ReadOnly Property Screen() As Screen - Get - 'Don't cache this. The Screen class responds to display resolution changes by nulling out AllScreens, which - 'PrimaryScreen relies on to find the primary. So we always need to access the latest PrimaryScreen so we - 'will get the current resolution reported. - Return Screen.PrimaryScreen - End Get - End Property - - Private _audio As Audio 'Lazy initialized cache for the Audio class. - Private Shared s_clipboard As ClipboardProxy 'Lazy initialized cache for the clipboard class. (proxies can be shared - they have no state) - Private Shared s_mouse As Mouse 'Lazy initialized cache for the Mouse class. SHARED because Mouse behaves as a ReadOnly singleton class - Private Shared s_keyboardInstance As Keyboard 'Lazy initialized cache for the Keyboard class. SHARED because Keyboard behaves as a ReadOnly singleton class - - End Class 'Computer -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/ComputerInfo.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/ComputerInfo.vb deleted file mode 100644 index 775801fb383..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/ComputerInfo.vb +++ /dev/null @@ -1,245 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Runtime.InteropServices -Imports Microsoft.VisualBasic.CompilerServices - -Namespace Microsoft.VisualBasic.Devices - - ''' - ''' Provides configuration information about the current computer and the current process. - ''' - - Public Class ComputerInfo - - ' Keep the debugger proxy current as you change this class - see the nested ComputerInfoDebugView below. - - ''' - ''' Default constructor - ''' - Sub New() - End Sub - -#Disable Warning IDE0049 ' Simplify Names, Justification:=" - ''' - ''' Gets the total size of physical memory on the machine. - ''' - ''' A 64-bit unsigned integer containing the size of total physical memory on the machine, in bytes. - ''' If we are unable to obtain the memory status. - - Public ReadOnly Property TotalPhysicalMemory() As UInt64 - Get - Return MemoryStatus.TotalPhysicalMemory - End Get - End Property - - ''' - ''' Gets the total size of free physical memory on the machine. - ''' - ''' A 64-bit unsigned integer containing the size of free physical memory on the machine, in bytes. - ''' If we are unable to obtain the memory status. - - Public ReadOnly Property AvailablePhysicalMemory() As UInt64 - Get - Return MemoryStatus.AvailablePhysicalMemory - End Get - End Property - - ''' - ''' Gets the total size of user potion of virtual address space for calling process. - ''' - ''' A 64-bit unsigned integer containing the size of user potion of virtual address space for calling process, - ''' in bytes. - ''' If we are unable to obtain the memory status. - - Public ReadOnly Property TotalVirtualMemory() As UInt64 - Get - Return MemoryStatus.TotalVirtualMemory - End Get - End Property - - ''' - ''' Gets the total size of free user potion of virtual address space for calling process. - ''' - ''' A 64-bit unsigned integer containing the size of free user potion of virtual address space for calling process, - ''' in bytes. - ''' If we are unable to obtain the memory status. - - Public ReadOnly Property AvailableVirtualMemory() As UInt64 - Get - Return MemoryStatus.AvailableVirtualMemory - End Get - End Property -#Enable Warning IDE0049 ' Simplify Names - - ''' - ''' Gets the current UICulture installed on the machine. - ''' - ''' A CultureInfo object represents the UI culture installed on the machine. - Public ReadOnly Property InstalledUICulture() As Globalization.CultureInfo - Get - Return Globalization.CultureInfo.InstalledUICulture - End Get - End Property - - ''' - ''' Gets the full operating system name. - ''' - ''' A string contains the operating system name. - Public ReadOnly Property OSFullName() As String - Get - Return RuntimeInformation.OSDescription - End Get - End Property - - ''' - ''' Gets the platform OS name. - ''' - ''' A string containing a Platform ID like "Win32NT", "Win32S", "Win32Windows". See PlatformID enum. - ''' If cannot obtain the OS Version information. - Public ReadOnly Property OSPlatform() As String - Get - Return Environment.OSVersion.Platform.ToString - End Get - End Property - - ''' - ''' Gets the current version number of the operating system. - ''' - ''' A string contains the current version number of the operating system. - ''' If cannot obtain the OS Version information. - Public ReadOnly Property OSVersion() As String - Get - Return Environment.OSVersion.Version.ToString - End Get - End Property - - ''' - ''' Debugger proxy for the ComputerInfo class. The problem is that OSFullName can time out the debugger - ''' so we offer a view that doesn't have that field. - ''' - Friend NotInheritable Class ComputerInfoDebugView - Public Sub New(RealClass As ComputerInfo) - _instanceBeingWatched = RealClass - End Sub - -#Disable Warning IDE0049 ' Simplify Names, Justification:= - - Public ReadOnly Property TotalPhysicalMemory() As UInt64 - Get - Return _instanceBeingWatched.TotalPhysicalMemory - End Get - End Property - - - Public ReadOnly Property AvailablePhysicalMemory() As UInt64 - Get - Return _instanceBeingWatched.AvailablePhysicalMemory - End Get - End Property - - - Public ReadOnly Property TotalVirtualMemory() As UInt64 - Get - Return _instanceBeingWatched.TotalVirtualMemory - End Get - End Property - - - Public ReadOnly Property AvailableVirtualMemory() As UInt64 - Get - Return _instanceBeingWatched.AvailableVirtualMemory - End Get - End Property -#Enable Warning IDE0049 ' Simplify Names - - - Public ReadOnly Property InstalledUICulture() As Globalization.CultureInfo - Get - Return _instanceBeingWatched.InstalledUICulture - End Get - End Property - - - Public ReadOnly Property OSPlatform() As String - Get - Return _instanceBeingWatched.OSPlatform - End Get - End Property - - - Public ReadOnly Property OSVersion() As String - Get - Return _instanceBeingWatched.OSVersion - End Get - End Property - - - Private ReadOnly _instanceBeingWatched As ComputerInfo - End Class - - ''' - ''' Gets the whole memory information details. - ''' - ''' An InternalMemoryStatus class. - Private ReadOnly Property MemoryStatus() As InternalMemoryStatus - Get - If _internalMemoryStatus Is Nothing Then - _internalMemoryStatus = New InternalMemoryStatus - End If - Return _internalMemoryStatus - End Get - End Property - - Private _internalMemoryStatus As InternalMemoryStatus ' Cache our InternalMemoryStatus - - ''' - ''' Calls GlobalMemoryStatusEx and returns the correct value. - ''' - Private NotInheritable Class InternalMemoryStatus - Friend Sub New() - End Sub - -#Disable Warning IDE0049 ' Simplify Names, Justification:= - Friend ReadOnly Property TotalPhysicalMemory() As UInt64 - Get - Refresh() - Return _memoryStatusEx.ullTotalPhys - End Get - End Property - - Friend ReadOnly Property AvailablePhysicalMemory() As UInt64 - Get - Refresh() - Return _memoryStatusEx.ullAvailPhys - End Get - End Property - - Friend ReadOnly Property TotalVirtualMemory() As UInt64 - Get - Refresh() - Return _memoryStatusEx.ullTotalVirtual - End Get - End Property - - Friend ReadOnly Property AvailableVirtualMemory() As UInt64 - Get - Refresh() - Return _memoryStatusEx.ullAvailVirtual - End Get - End Property -#Enable Warning IDE0049 ' Simplify Names - - Private Sub Refresh() - _memoryStatusEx = New NativeMethods.MEMORYSTATUSEX - _memoryStatusEx.Init() - If (Not NativeMethods.GlobalMemoryStatusEx(_memoryStatusEx)) Then - Throw ExceptionUtils.GetWin32Exception(SR.DiagnosticInfo_Memory) - End If - End Sub - - Private _memoryStatusEx As NativeMethods.MEMORYSTATUSEX - End Class - End Class - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Keyboard.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Keyboard.vb deleted file mode 100644 index bb5d1689ba5..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Keyboard.vb +++ /dev/null @@ -1,117 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On - -Imports System.Windows.Forms -Imports Microsoft.VisualBasic.CompilerServices - -Namespace Microsoft.VisualBasic.Devices - - ''' - ''' A class representing a computer keyboard. Enables discovery of key - ''' state information for the most common scenarios and enables SendKeys - ''' - Public Class Keyboard - - ''' - ''' Sends keys to the active window as if typed as keyboard with wait = false. - ''' - ''' A string containing the keys to be sent (typed). - Public Sub SendKeys(keys As String) - SendKeys(keys, False) - End Sub - - ''' - ''' Sends keys to the active window as if typed at keyboard. This overloaded - ''' version uses the same conventions as the VB6 SendKeys. - ''' - ''' A string containing the keys to be sent (typed). - ''' Wait for messages to be processed before returning. - Public Sub SendKeys(keys As String, wait As Boolean) - If wait Then - System.Windows.Forms.SendKeys.SendWait(keys) - Else - System.Windows.Forms.SendKeys.Send(keys) - End If - End Sub - - ''' - ''' Gets the state (up or down) of the Shift key. - ''' - ''' True if the key is down otherwise false. - Public ReadOnly Property ShiftKeyDown() As Boolean - Get - Dim Keys As Keys = Control.ModifierKeys - Return CType(Keys And Keys.Shift, Boolean) - End Get - End Property - - ''' - ''' Gets the state (up or down) of the Alt key. - ''' - ''' True if the key is down otherwise false. - Public ReadOnly Property AltKeyDown() As Boolean - Get - Dim Keys As Keys = Control.ModifierKeys - Return CType(Keys And Keys.Alt, Boolean) - End Get - End Property - - ''' - ''' Gets the state (up or down) of the Ctrl key. - ''' - ''' True if the key is down otherwise false. - Public ReadOnly Property CtrlKeyDown() As Boolean - Get - Dim Keys As Keys = Control.ModifierKeys - Return CType(Keys And Keys.Control, Boolean) - End Get - End Property - - ''' - ''' Gets the toggle state of the Caps Lock key. - ''' - ''' True if the key is down otherwise false. - Public ReadOnly Property CapsLock() As Boolean - Get - 'Security Note: Only the state of the Caps Lock is returned - - 'The low order byte of the return value from GetKeyState is 1 if the key is - 'toggled on. - Return CType((UnsafeNativeMethods.GetKeyState(Keys.CapsLock) And 1), Boolean) - End Get - End Property - - ''' - ''' Gets the toggle state of the Num Lock key. - ''' - ''' True if the key is down otherwise false. - Public ReadOnly Property NumLock() As Boolean - Get - 'Security Note: Only the state of the Num Lock is returned - - 'The low order byte of the return value from GetKeyState is 1 if the key is - 'toggled on. - Return CType((UnsafeNativeMethods.GetKeyState(Keys.NumLock) And 1), Boolean) - End Get - End Property - - ''' - ''' Gets the toggle state of the Scroll Lock key. - ''' - ''' True if the key is down otherwise false. - Public ReadOnly Property ScrollLock() As Boolean - Get - 'Security Note: Only the state of the Scroll Lock is returned - - 'The low order byte of the return value from GetKeyState is 1 if the key is - 'toggled on. - Return CType((UnsafeNativeMethods.GetKeyState(Keys.Scroll) And 1), Boolean) - End Get - End Property - - End Class - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Mouse.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Mouse.vb deleted file mode 100644 index 0f3ca96b6d1..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Mouse.vb +++ /dev/null @@ -1,70 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - -Imports System.Windows.Forms -Imports Microsoft.VisualBasic.CompilerServices.ExceptionUtils - -Namespace Microsoft.VisualBasic.Devices - - ''' - ''' A wrapper object that acts as a discovery mechanism for finding - ''' information about the mouse on your computer such as whether the mouse - ''' exists, the number of buttons, WheelScrolls details. - ''' - ''' This class is a Singleton Class. See Common.Computer for details. - ''' - Public Class Mouse - - ''' - ''' Gets a value indicating whether the functions of the left and right - ''' mouses buttons have been swapped. - ''' - ''' - ''' true if the functions of the left and right mouse buttons are swapped. false otherwise. - ''' - ''' If no mouse is installed. - Public ReadOnly Property ButtonsSwapped() As Boolean - Get - If System.Windows.Forms.SystemInformation.MousePresent Then - Return SystemInformation.MouseButtonsSwapped - Else - Throw GetInvalidOperationException(SR.Mouse_NoMouseIsPresent) - End If - End Get - End Property - - ''' - ''' Gets a value indicating whether a mouse with a mouse wheel is installed - ''' - ''' true if a mouse with a mouse wheel is installed, false otherwise. - ''' If no mouse is installed. - Public ReadOnly Property WheelExists() As Boolean - Get - If System.Windows.Forms.SystemInformation.MousePresent Then - Return SystemInformation.MouseWheelPresent - Else - Throw GetInvalidOperationException(SR.Mouse_NoMouseIsPresent) - End If - End Get - End Property - - ''' - ''' Gets the number of lines to scroll when the mouse wheel is rotated. - ''' - ''' The number of lines to scroll. - ''' if no mouse is installed or no wheels exists. - Public ReadOnly Property WheelScrollLines() As Integer - Get - If WheelExists Then - Return SystemInformation.MouseWheelScrollLines - Else - Throw GetInvalidOperationException(SR.Mouse_NoWheelIsPresent) - End If - End Get - End Property - - End Class 'Mouse -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.vb deleted file mode 100644 index 123d1319407..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.vb +++ /dev/null @@ -1,820 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On -Imports System.ComponentModel -Imports System.Net -Imports System.Security -Imports System.Threading -Imports Microsoft.VisualBasic.CompilerServices -Imports Microsoft.VisualBasic.CompilerServices.ExceptionUtils -Imports Microsoft.VisualBasic.CompilerServices.Utils -Imports Microsoft.VisualBasic.FileIO -Imports Microsoft.VisualBasic.MyServices.Internal -Imports NetInfoAlias = System.Net.NetworkInformation - -Namespace Microsoft.VisualBasic.Devices - - ''' - ''' Used to pass network connectivity status. - ''' - Public Class NetworkAvailableEventArgs - Inherits EventArgs - Public Sub New(networkAvailable As Boolean) - IsNetworkAvailable = networkAvailable - End Sub - - Public ReadOnly Property IsNetworkAvailable() As Boolean - End Class - - - Public Delegate Sub NetworkAvailableEventHandler(sender As Object, e As NetworkAvailableEventArgs) - - ''' - ''' An object that allows easy access to some simple network properties and functionality. - ''' - Public Class Network - - ''' - ''' Event fired when connected to the network - ''' - ''' Has no meaning for this event - ''' Has no meaning for this event - Public Custom Event NetworkAvailabilityChanged As NetworkAvailableEventHandler - 'This is a custom event because we want to hook up the NetworkAvailabilityChanged event only if the user writes a handler for it. - 'The reason being that it is very expensive to handle and kills our application startup perf. - AddHandler(handler As NetworkAvailableEventHandler) - - ' Set the current state of connectedness, swallow known exceptions since user won't be able to correct problem - Try - _connected = IsAvailable - Catch ex As SecurityException - Return - Catch ex As PlatformNotSupportedException - Return - End Try - SyncLock _syncObject 'we don't want our event firing before we've finished setting up the infrastructure. Also, need to assure there are no races in here so we don't hook up the OS listener twice, etc. - If _networkAvailabilityEventHandlers Is Nothing Then _networkAvailabilityEventHandlers = New List(Of NetworkAvailableEventHandler) - _networkAvailabilityEventHandlers.Add(handler) - - 'Only setup the event Marshalling infrastructure once - If _networkAvailabilityEventHandlers.Count = 1 Then - _networkAvailabilityChangedCallback = New SendOrPostCallback(AddressOf NetworkAvailabilityChangedHandler) 'the async operation posts to this delegate - If AsyncOperationManager.SynchronizationContext IsNot Nothing Then - _synchronizationContext = AsyncOperationManager.SynchronizationContext 'We need to hang on to the synchronization context associated with the thread the network object is created on - Try ' Exceptions are thrown if the user isn't an admin. - AddHandler NetInfoAlias.NetworkChange.NetworkAddressChanged, New NetInfoAlias.NetworkAddressChangedEventHandler(AddressOf OS_NetworkAvailabilityChangedListener) 'listen to the OS event - Catch ex As PlatformNotSupportedException - Catch ex As NetInfoAlias.NetworkInformationException - End Try - End If - End If - End SyncLock - End AddHandler - - RemoveHandler(handler As NetworkAvailableEventHandler) - If _networkAvailabilityEventHandlers IsNot Nothing AndAlso _networkAvailabilityEventHandlers.Count > 0 Then - _networkAvailabilityEventHandlers.Remove(handler) - 'Last one to leave, turn out the lights... - If _networkAvailabilityEventHandlers.Count = 0 Then - RemoveHandler NetInfoAlias.NetworkChange.NetworkAddressChanged, New NetInfoAlias.NetworkAddressChangedEventHandler(AddressOf OS_NetworkAvailabilityChangedListener) 'listen to the OS event - DisconnectListener() 'Stop listening to network change events since nobody is listening to us anymore - End If - End If - End RemoveHandler - - RaiseEvent(sender As Object, e As NetworkAvailableEventArgs) - If _networkAvailabilityEventHandlers IsNot Nothing Then - For Each handler As NetworkAvailableEventHandler In _networkAvailabilityEventHandlers - If handler IsNot Nothing Then handler.Invoke(sender, e) - Next - End If - End RaiseEvent - End Event - - ''' - ''' Creates class and hooks up events - ''' - Public Sub New() - End Sub - - ''' - ''' Indicates whether or not the local machine is connected to an IP network. - ''' - ''' True if connected, otherwise False - Public ReadOnly Property IsAvailable() As Boolean - Get - - Return NetInfoAlias.NetworkInterface.GetIsNetworkAvailable() - - End Get - End Property - - ''' - ''' Sends and receives a packet to and from the passed in address. - ''' - ''' - ''' True if ping was successful, otherwise False - Public Function Ping(hostNameOrAddress As String) As Boolean - Return Ping(hostNameOrAddress, DEFAULT_PING_TIMEOUT) - End Function - - ''' - ''' Sends and receives a packet to and from the passed in Uri. - ''' - ''' A Uri representing the host - ''' True if ping was successful, otherwise False - Public Function Ping(address As Uri) As Boolean - ' We're safe from Ping(Nothing, ...) due to overload failure (Ping(String,...) vs. Ping(Uri,...)). - ' However, it is good practice to verify address before calling address.Host. - If address Is Nothing Then - Throw ExceptionUtils.GetArgumentNullException("address") - End If - Return Ping(address.Host, DEFAULT_PING_TIMEOUT) - End Function - - ''' - ''' Sends and receives a packet to and from the passed in address. - ''' - ''' The name of the host as a Url or IP Address - ''' Time to wait before aborting ping - ''' True if ping was successful, otherwise False - Public Function Ping(hostNameOrAddress As String, timeout As Integer) As Boolean - - ' Make sure a network is available - If Not IsAvailable Then - Throw ExceptionUtils.GetInvalidOperationException(SR.Network_NetworkNotAvailable) - End If - - Dim PingMaker As New NetInfoAlias.Ping - Dim Reply As NetInfoAlias.PingReply = PingMaker.Send(hostNameOrAddress, timeout, PingBuffer) - If Reply.Status = NetInfoAlias.IPStatus.Success Then - Return True - End If - Return False - End Function - - ''' - ''' Sends and receives a packet to and from the passed in Uri. - ''' - ''' A Uri representing the host - ''' Time to wait before aborting ping - ''' True if ping was successful, otherwise False - Public Function Ping(address As Uri, timeout As Integer) As Boolean - ' We're safe from Ping(Nothing, ...) due to overload failure (Ping(String,...) vs. Ping(Uri,...)). - ' However, it is good practice to verify address before calling address.Host. - If address Is Nothing Then - Throw ExceptionUtils.GetArgumentNullException("address") - End If - Return Ping(address.Host, timeout) - End Function - - ''' - ''' Downloads a file from the network to the specified path - ''' - ''' Address to the remote file, http, ftp etc... - ''' Name and path of file where download is saved - Public Sub DownloadFile(address As String, destinationFileName As String) - DownloadFile(address, destinationFileName, DEFAULT_USERNAME, DEFAULT_PASSWORD, False, DEFAULT_TIMEOUT, False) - End Sub - - ''' - ''' Downloads a file from the network to the specified path - ''' - ''' Uri to the remote file - ''' Name and path of file where download is saved - Public Sub DownloadFile(address As Uri, destinationFileName As String) - DownloadFile(address, destinationFileName, DEFAULT_USERNAME, DEFAULT_PASSWORD, False, DEFAULT_TIMEOUT, False) - End Sub - - ''' - ''' Downloads a file from the network to the specified path - ''' - ''' Address to the remote file, http, ftp etc... - ''' Name and path of file where download is saved - ''' The name of the user performing the download - ''' The user's password - Public Sub DownloadFile(address As String, destinationFileName As String, userName As String, password As String) - DownloadFile(address, destinationFileName, userName, password, False, DEFAULT_TIMEOUT, False) - End Sub - - ''' - ''' Downloads a file from the network to the specified path - ''' - ''' Uri to the remote file - ''' Name and path of file where download is saved - ''' The name of the user performing the download - ''' The user's password - Public Sub DownloadFile(address As Uri, destinationFileName As String, userName As String, password As String) - DownloadFile(address, destinationFileName, userName, password, False, DEFAULT_TIMEOUT, False) - End Sub - - ''' - ''' Downloads a file from the network to the specified path - ''' - ''' Address to the remote file, http, ftp etc... - ''' Name and path of file where download is saved - ''' The name of the user performing the download - ''' The user's password - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - ''' Indicates whether or not the file should be overwritten if local file already exists - Public Sub DownloadFile(address As String, - destinationFileName As String, - userName As String, - password As String, - showUI As Boolean, - connectionTimeout As Integer, - overwrite As Boolean) - - DownloadFile(address, destinationFileName, userName, password, showUI, connectionTimeout, overwrite, UICancelOption.ThrowException) - End Sub - - ''' - ''' Downloads a file from the network to the specified path - ''' - ''' Address to the remote file, http, ftp etc... - ''' Name and path of file where download is saved - ''' The name of the user performing the download - ''' The user's password - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - ''' Indicates whether or not the file should be overwritten if local file already exists - ''' Indicates what to do if user cancels dialog (either throw or do nothing) - Public Sub DownloadFile(address As String, - destinationFileName As String, - userName As String, - password As String, - showUI As Boolean, - connectionTimeout As Integer, - overwrite As Boolean, - onUserCancel As UICancelOption) - - ' We're safe from DownloadFile(Nothing, ...) due to overload failure (DownloadFile(String,...) vs. DownloadFile(Uri,...)). - ' However, it is good practice to verify address before calling Trim. - If String.IsNullOrWhiteSpace(address) Then - Throw ExceptionUtils.GetArgumentNullException("address") - End If - - Dim addressUri As Uri = GetUri(address.Trim()) - - ' Get network credentials - Dim networkCredentials As ICredentials = GetNetworkCredentials(userName, password) - - DownloadFile(addressUri, destinationFileName, networkCredentials, showUI, connectionTimeout, overwrite, onUserCancel) - End Sub - - ''' - ''' Downloads a file from the network to the specified path - ''' - ''' Uri to the remote file - ''' Name and path of file where download is saved - ''' The name of the user performing the download - ''' The user's password - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - ''' Indicates whether or not the file should be overwritten if local file already exists - Sub DownloadFile(address As Uri, - destinationFileName As String, - userName As String, - password As String, - showUI As Boolean, - connectionTimeout As Integer, - overwrite As Boolean) - - DownloadFile(address, destinationFileName, userName, password, showUI, connectionTimeout, overwrite, UICancelOption.ThrowException) - End Sub - - ''' - ''' Downloads a file from the network to the specified path - ''' - ''' Uri to the remote file - ''' Name and path of file where download is saved - ''' The name of the user performing the download - ''' The user's password - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - ''' Indicates whether or not the file should be overwritten if local file already exists - ''' Indicates what to do if user cancels dialog (either throw or do nothing) - Sub DownloadFile(address As Uri, - destinationFileName As String, - userName As String, - password As String, - showUI As Boolean, - connectionTimeout As Integer, - overwrite As Boolean, - onUserCancel As UICancelOption) - - ' Get network credentials - Dim networkCredentials As ICredentials = GetNetworkCredentials(userName, password) - - DownloadFile(address, destinationFileName, networkCredentials, showUI, connectionTimeout, overwrite, onUserCancel) - End Sub - - ''' - ''' Downloads a file from the network to the specified path - ''' - ''' Uri to the remote file - ''' Name and path of file where download is saved - ''' The credentials of the user performing the download - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - ''' Indicates whether or not the file should be overwritten if local file already exists - ''' Calls to all the other overloads will come through here - Sub DownloadFile(address As Uri, - destinationFileName As String, - networkCredentials As ICredentials, - showUI As Boolean, - connectionTimeout As Integer, - overwrite As Boolean) - - DownloadFile(address, destinationFileName, networkCredentials, showUI, connectionTimeout, overwrite, UICancelOption.ThrowException) - - End Sub - - ''' - ''' Downloads a file from the network to the specified path - ''' - ''' Uri to the remote file - ''' Name and path of file where download is saved - ''' The credentials of the user performing the download - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - ''' Indicates whether or not the file should be overwritten if local file already exists - ''' Indicates what to do if user cancels dialog (either throw or do nothing) - ''' Calls to all the other overloads will come through here - Sub DownloadFile(address As Uri, - destinationFileName As String, - networkCredentials As ICredentials, - showUI As Boolean, - connectionTimeout As Integer, - overwrite As Boolean, - onUserCancel As UICancelOption) - If connectionTimeout <= 0 Then - Throw GetArgumentExceptionWithArgName("connectionTimeOut", SR.Network_BadConnectionTimeout) - End If - - If address Is Nothing Then - Throw ExceptionUtils.GetArgumentNullException("address") - End If - - Using client As New WebClientExtended - client.Timeout = connectionTimeout - - ' Don't use passive mode if we're showing UI - client.UseNonPassiveFtp = showUI - - 'Construct the local file. This will validate the full name and path - Dim fullFilename As String = FileSystemUtils.NormalizeFilePath(destinationFileName, "destinationFileName") - - ' Sometime a path that can't be parsed is normalized to the current directory. This makes sure we really - ' have a file and path - If System.IO.Directory.Exists(fullFilename) Then - Throw ExceptionUtils.GetInvalidOperationException(SR.Network_DownloadNeedsFilename) - End If - - 'Throw if the file exists and the user doesn't want to overwrite - If IO.File.Exists(fullFilename) And Not overwrite Then - Throw New IO.IOException(GetResourceString(SR.IO_FileExists_Path, destinationFileName)) - End If - - ' Set credentials if we have any - If networkCredentials IsNot Nothing Then - client.Credentials = networkCredentials - End If - - Dim dialog As ProgressDialog = Nothing - If showUI AndAlso System.Environment.UserInteractive Then - dialog = New ProgressDialog With { - .Text = GetResourceString(SR.ProgressDialogDownloadingTitle, address.AbsolutePath), - .LabelText = GetResourceString(SR.ProgressDialogDownloadingLabel, address.AbsolutePath, fullFilename) - } - End If - - 'Check to see if the target directory exists. If it doesn't, create it - Dim targetDirectory As String = System.IO.Path.GetDirectoryName(fullFilename) - - ' Make sure we have a meaningful directory. If we don't, the destinationFileName is suspect - If String.IsNullOrEmpty(targetDirectory) Then - Throw ExceptionUtils.GetInvalidOperationException(SR.Network_DownloadNeedsFilename) - End If - - If Not IO.Directory.Exists(targetDirectory) Then - IO.Directory.CreateDirectory(targetDirectory) - End If - - 'Create the copier - Dim copier As New WebClientCopy(client, dialog) - - 'Download the file - copier.DownloadFile(address, fullFilename) - - 'Handle a dialog cancel - If showUI AndAlso System.Environment.UserInteractive Then - If onUserCancel = UICancelOption.ThrowException And dialog.UserCanceledTheDialog Then - Throw New OperationCanceledException() - End If - End If - - End Using - - End Sub - - ''' - ''' Uploads a file from the local machine to the specified host - ''' - ''' The file to be uploaded - ''' The full name and path of the host destination - Public Sub UploadFile(sourceFileName As String, address As String) - UploadFile(sourceFileName, address, DEFAULT_USERNAME, DEFAULT_PASSWORD, False, DEFAULT_TIMEOUT) - End Sub - - ''' - ''' Uploads a file from the local machine to the specified host - ''' - ''' The file to be uploaded - ''' Uri representing the destination - Public Sub UploadFile(sourceFileName As String, address As Uri) - UploadFile(sourceFileName, address, DEFAULT_USERNAME, DEFAULT_PASSWORD, False, DEFAULT_TIMEOUT) - End Sub - - ''' - ''' Uploads a file from the local machine to the specified host - ''' - ''' The file to be uploaded - ''' The full name and path of the host destination - ''' The name of the user performing the upload - ''' The user's password - Public Sub UploadFile(sourceFileName As String, address As String, userName As String, password As String) - UploadFile(sourceFileName, address, userName, password, False, DEFAULT_TIMEOUT) - End Sub - - ''' - ''' Uploads a file from the local machine to the specified host - ''' - ''' The file to be uploaded - ''' Uri representing the destination - ''' The name of the user performing the upload - ''' The user's password - Public Sub UploadFile(sourceFileName As String, address As Uri, userName As String, password As String) - UploadFile(sourceFileName, address, userName, password, False, DEFAULT_TIMEOUT) - End Sub - - ''' - ''' Uploads a file from the local machine to the specified host - ''' - ''' The file to be uploaded - ''' The full name and path of the host destination - ''' The name of the user performing the upload - ''' The user's password - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - Public Sub UploadFile(sourceFileName As String, - address As String, - userName As String, - password As String, - showUI As Boolean, - connectionTimeout As Integer) - - UploadFile(sourceFileName, address, userName, password, showUI, connectionTimeout, UICancelOption.ThrowException) - End Sub - - ''' - ''' Uploads a file from the local machine to the specified host - ''' - ''' The file to be uploaded - ''' The full name and path of the host destination - ''' The name of the user performing the upload - ''' The user's password - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - ''' Indicates what to do if user cancels dialog (either throw or do nothing) - Public Sub UploadFile(sourceFileName As String, - address As String, - userName As String, - password As String, - showUI As Boolean, - connectionTimeout As Integer, - onUserCancel As UICancelOption) - - ' We're safe from UploadFile(Nothing, ...) due to overload failure (UploadFile(String,...) vs. UploadFile(Uri,...)). - ' However, it is good practice to verify address before calling address.Trim. - If String.IsNullOrWhiteSpace(address) Then - Throw ExceptionUtils.GetArgumentNullException("address") - End If - - ' Getting a uri will validate the form of the host address - Dim addressUri As Uri = GetUri(address.Trim()) - - ' For uploads, we need to make sure the address includes the filename - If String.IsNullOrEmpty(IO.Path.GetFileName(addressUri.AbsolutePath)) Then - Throw ExceptionUtils.GetInvalidOperationException(SR.Network_UploadAddressNeedsFilename) - End If - - UploadFile(sourceFileName, addressUri, userName, password, showUI, connectionTimeout, onUserCancel) - - End Sub - - ''' - ''' Uploads a file from the local machine to the specified host - ''' - ''' The file to be uploaded - ''' Uri representing the destination - ''' The name of the user performing the upload - ''' The user's password - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - Public Sub UploadFile(sourceFileName As String, - address As Uri, - userName As String, - password As String, - showUI As Boolean, - connectionTimeout As Integer) - - UploadFile(sourceFileName, address, userName, password, showUI, connectionTimeout, UICancelOption.ThrowException) - End Sub - - ''' - ''' Uploads a file from the local machine to the specified host - ''' - ''' The file to be uploaded - ''' Uri representing the destination - ''' The name of the user performing the upload - ''' The user's password - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - ''' Indicates what to do if user cancels dialog (either throw or do nothing) - Public Sub UploadFile(sourceFileName As String, - address As Uri, - userName As String, - password As String, - showUI As Boolean, - connectionTimeout As Integer, - onUserCancel As UICancelOption) - - ' Get network credentials - Dim networkCredentials As ICredentials = GetNetworkCredentials(userName, password) - - UploadFile(sourceFileName, address, networkCredentials, showUI, connectionTimeout, onUserCancel) - - End Sub - - ''' - ''' Uploads a file from the local machine to the specified host - ''' - ''' The file to be uploaded - ''' Uri representing the destination - ''' The credentials of the user performing the upload - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - Public Sub UploadFile(sourceFileName As String, - address As Uri, - networkCredentials As ICredentials, - showUI As Boolean, - connectionTimeout As Integer) - - UploadFile(sourceFileName, address, networkCredentials, showUI, connectionTimeout, UICancelOption.ThrowException) - End Sub - - ''' - ''' Uploads a file from the local machine to the specified host - ''' - ''' The file to be uploaded - ''' Uri representing the destination - ''' The credentials of the user performing the upload - ''' Indicates whether or not to show a progress bar - ''' Time alloted before giving up on a connection - ''' Indicates what to do if user cancels dialog (either throw or do nothing) - Public Sub UploadFile(sourceFileName As String, - address As Uri, - networkCredentials As ICredentials, - showUI As Boolean, - connectionTimeout As Integer, - onUserCancel As UICancelOption) - sourceFileName = FileSystemUtils.NormalizeFilePath(sourceFileName, "sourceFileName") - - 'Make sure the file exists - If Not IO.File.Exists(sourceFileName) Then - Throw New IO.FileNotFoundException(GetResourceString(SR.IO_FileNotFound_Path, sourceFileName)) - End If - - If connectionTimeout <= 0 Then - Throw GetArgumentExceptionWithArgName("connectionTimeout", SR.Network_BadConnectionTimeout) - End If - - If address Is Nothing Then - Throw ExceptionUtils.GetArgumentNullException("address") - End If - - Using client As New WebClientExtended() - client.Timeout = connectionTimeout - - ' Set credentials if we have any - If networkCredentials IsNot Nothing Then - client.Credentials = networkCredentials - End If - - Dim Dialog As ProgressDialog = Nothing - If showUI AndAlso System.Environment.UserInteractive Then - Dialog = New ProgressDialog With { - .Text = GetResourceString(SR.ProgressDialogUploadingTitle, sourceFileName), - .LabelText = GetResourceString(SR.ProgressDialogUploadingLabel, sourceFileName, address.AbsolutePath) - } - End If - - 'Create the copier - Dim copier As New WebClientCopy(client, Dialog) - - 'Download the file - copier.UploadFile(sourceFileName, address) - - 'Handle a dialog cancel - If showUI AndAlso System.Environment.UserInteractive Then - If onUserCancel = UICancelOption.ThrowException And Dialog.UserCanceledTheDialog Then - Throw New OperationCanceledException() - End If - End If - End Using - - End Sub - - Friend Sub DisconnectListener() - RemoveHandler NetInfoAlias.NetworkChange.NetworkAddressChanged, New NetInfoAlias.NetworkAddressChangedEventHandler(AddressOf OS_NetworkAvailabilityChangedListener) - End Sub - - 'Listens to the AddressChanged event from the OS which comes in on an arbitrary thread - Private Sub OS_NetworkAvailabilityChangedListener(sender As Object, e As EventArgs) - SyncLock _syncObject 'Ensure we don't handle events until after we've finished setting up the event marshalling infrastructure - 'Don't call AsyncOperationManager.OperationSynchronizationContext.Post. The reason we want to go through m_SynchronizationContext is that - 'the OperationSyncronizationContext is thread static. Since we are getting called on some random thread, the context that was - 'in place when the Network object was created won't be available (it is on the original thread). To hang on to the original - 'context associated with the thread that the network object is created on, I use m_SynchronizationContext. - _synchronizationContext.Post(_networkAvailabilityChangedCallback, Nothing) - End SyncLock - End Sub - - 'Listens to the AddressChanged event which will come on the same thread that this class was created on (AsyncEventManager is responsible for getting the event here) - Private Sub NetworkAvailabilityChangedHandler(state As Object) - Dim Connected As Boolean = IsAvailable - ' Fire an event only if the connected state has changed - If _connected <> Connected Then - _connected = Connected - RaiseEvent NetworkAvailabilityChanged(Me, New NetworkAvailableEventArgs(Connected)) - End If - End Sub - - ''' - ''' A buffer for pinging. This imitates the buffer used by Ping.Exe - ''' - ''' A buffer - Private ReadOnly Property PingBuffer() As Byte() - Get - If _pingBuffer Is Nothing Then - ReDim _pingBuffer(BUFFER_SIZE - 1) - For i As Integer = 0 To BUFFER_SIZE - 1 - 'This is the same logic Ping.exe uses to fill it's buffer - _pingBuffer(i) = System.Convert.ToByte(Asc("a"c) + i Mod 23, System.Globalization.CultureInfo.InvariantCulture) - Next - End If - - Return _pingBuffer - End Get - End Property - - ''' - ''' Gets a Uri from a uri string. We also use this function to validate the UriString (remote file address) - ''' - ''' The remote file address - ''' A Uri if successful, otherwise it throws an exception - Private Shared Function GetUri(address As String) As Uri - Try - Return New Uri(address) - Catch ex As UriFormatException - 'Throw an exception with an error message more appropriate to our API - Throw GetArgumentExceptionWithArgName("address", SR.Network_InvalidUriString, address) - End Try - End Function - - ''' - ''' Gets network credentials from a userName and password - ''' - ''' The name of the user - ''' The password of the user - ''' A NetworkCredentials - Private Shared Function GetNetworkCredentials(userName As String, password As String) As ICredentials - - ' Make sure all nulls are empty strings - If userName Is Nothing Then - userName = "" - End If - - If password Is Nothing Then - password = "" - End If - - If userName.Length = 0 And password.Length = 0 Then - Return Nothing - End If - - Return New NetworkCredential(userName, password) - End Function - - 'Holds the buffer for pinging. We lazy initialize on first use - Private _pingBuffer() As Byte - - 'Size of Ping.exe buffer - Private Const BUFFER_SIZE As Integer = 32 - - ' Default timeout value - Private Const DEFAULT_TIMEOUT As Integer = 100000 - - ' Default timeout for Ping - Private Const DEFAULT_PING_TIMEOUT As Integer = 1000 - - ' UserName used in overloads where there is no userName parameter - Private Const DEFAULT_USERNAME As String = "" - - ' Password used in overloads where there is no password parameter - Private Const DEFAULT_PASSWORD As String = "" - - ' Indicates last known connection state - Private _connected As Boolean - - ' Object for syncing - Private ReadOnly _syncObject As New Object() - - Private _networkAvailabilityEventHandlers As List(Of NetworkAvailableEventHandler) 'Holds the listeners to our NetworkAvailability changed event - - Private _synchronizationContext As SynchronizationContext - Private _networkAvailabilityChangedCallback As SendOrPostCallback 'Used for marshalling the network address changed event to the foreground thread - End Class - - ''' - ''' Temporary class used to provide WebClient with a timeout property. - ''' - ''' This class will be deleted when Timeout is added to WebClient - Friend NotInheritable Class WebClientExtended - Inherits WebClient - - ''' - ''' Sets or indicates the timeout used by WebRequest used by WebClient - ''' - Public WriteOnly Property Timeout() As Integer - Set(value As Integer) - Debug.Assert(value > 0, "illegal value for timeout") - _timeout = value - End Set - End Property - - ''' - ''' Enables switching the server to non passive mode. - ''' - ''' We need this in order for the progress UI on a download to work - Public WriteOnly Property UseNonPassiveFtp() As Boolean - Set(value As Boolean) - _useNonPassiveFtp = value - End Set - End Property - - ''' - ''' Makes sure that the timeout value for WebRequests (used for all Download and Upload methods) is set - ''' to the Timeout value - ''' - ''' - Protected Overrides Function GetWebRequest(address As Uri) As WebRequest - Dim request As WebRequest = MyBase.GetWebRequest(address) - - Debug.Assert(request IsNot Nothing, "Unable to get WebRequest from base class") - If request IsNot Nothing Then - request.Timeout = _timeout - If _useNonPassiveFtp Then - Dim ftpRequest As FtpWebRequest = TryCast(request, FtpWebRequest) - If ftpRequest IsNot Nothing Then - ftpRequest.UsePassive = False - End If - End If - - Dim httpRequest As HttpWebRequest = TryCast(request, HttpWebRequest) - If httpRequest IsNot Nothing Then - httpRequest.AllowAutoRedirect = False - End If - - End If - - Return request - End Function - -#Disable Warning BC41004 ' First statement of this 'Sub New' should be an explicit call to 'MyBase.New' or 'MyClass.New' because the constructor in the base class is marked obsolete - Friend Sub New() - End Sub -#Enable Warning BC41004 ' First statement of this 'Sub New' should be an explicit call to 'MyBase.New' or 'MyClass.New' because the constructor in the base class is marked obsolete - - ' The Timeout value to be used by WebClient's WebRequest for Downloading or Uploading a file - Private _timeout As Integer = 100000 - - ' Flag used to indicate whether or not we should use passive mode when ftp downloading - Private _useNonPassiveFtp As Boolean - End Class - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/ServerComputer.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/ServerComputer.vb deleted file mode 100644 index 063073676b0..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/ServerComputer.vb +++ /dev/null @@ -1,107 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - -Imports Microsoft.VisualBasic.MyServices - -Namespace Microsoft.VisualBasic.Devices - - ''' - ''' A RAD object representing the server 'computer' for the web/Windows Services - ''' that serves as a discovery mechanism for finding principle abstractions in - ''' the system that you can code against - ''' - Public Class ServerComputer - - 'NOTE: The .Net design guidelines state that access to Instance members does not have to be thread-safe. Access to Shared members does have to be thread-safe. - 'Since My.Computer creates the instance of Computer in a thread-safe way, access to the Computer will necessarily be thread-safe. - 'There is nothing to prevent a user from passing our computer object across threads or creating their own instance and then getting into trouble. - 'But that is completely consistent with the rest of the FX design. It is MY.* that is thread safe and leads to best practice access to these objects. - 'If you dim them up yourself, you are responsible for managing the threading. - - ''' - ''' Returns the Clock object which contains the LocalTime and GMTTime. - ''' - Public ReadOnly Property Clock() As Clock - Get - If s_clock IsNot Nothing Then Return s_clock - s_clock = New Clock - Return s_clock - End Get - End Property - - ''' - ''' Gets the object representing the file system of the computer. - ''' - ''' A System.IO.FileSystem object. - ''' The instance returned by this property is lazy initialized and cached. - Public ReadOnly Property FileSystem() As FileSystemProxy - Get - If _fileIO Is Nothing Then - _fileIO = New FileSystemProxy - End If - Return _fileIO - End Get - End Property - - ''' - ''' Gets the object representing information about the computer's state - ''' - ''' A Microsoft.VisualBasic.MyServices.ComputerInfo object. - ''' The instance returned by this property is lazy initialized and cached. - Public ReadOnly Property Info() As ComputerInfo - Get - If _computerInfo Is Nothing Then - _computerInfo = New ComputerInfo - End If - Return _computerInfo - End Get - End Property - - ''' - ''' This property returns the Network object containing information about - ''' the network the machine is part of. - ''' - ''' An instance of the Network.Network class. - Public ReadOnly Property Network() As Network - Get - If _network IsNot Nothing Then Return _network - _network = New Network - Return _network - End Get - End Property - - ''' - ''' This property wraps the System.Environment.MachineName property - ''' in the .NET framework to return the name of the computer. - ''' - ''' A string containing the name of the computer. - Public ReadOnly Property Name() As String - Get - Return System.Environment.MachineName - End Get - End Property - - ''' - ''' Gets the Registry object, which can be used to read, set and - ''' enumerate keys and values in the system registry. - ''' - ''' An instance of the RegistryProxy object - Public ReadOnly Property Registry() As RegistryProxy - Get - If _registryInstance IsNot Nothing Then Return _registryInstance - _registryInstance = New RegistryProxy - Return _registryInstance - End Get - End Property - - Private _computerInfo As ComputerInfo 'Lazy initialized cache for ComputerInfo - Private _fileIO As FileSystemProxy 'Lazy initialized cache for the FileSystem. - Private _network As Network 'Lazy initialized cache for the Network class. - Private _registryInstance As RegistryProxy 'Lazy initialized cache for the Registry class - Private Shared s_clock As Clock 'Lazy initialized cache for the Clock class. SHARED because Clock behaves as a readonly singleton class - - End Class 'MyServerComputer -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/FileSystemUtils.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/FileSystemUtils.vb deleted file mode 100644 index 10357a7ae66..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/FileSystemUtils.vb +++ /dev/null @@ -1,154 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - -Imports System.Security - -Imports ExUtils = Microsoft.VisualBasic.CompilerServices.ExceptionUtils - -Namespace Microsoft.VisualBasic.CompilerServices - - ''' - ''' Internal utilities from Microsoft.VisualBasic.FileIO.FileSystem. - ''' - Friend NotInheritable Class FileSystemUtils - - ''' - ''' Normalize the path, but throw exception if the path ends with separator. - ''' - ''' The input path. - ''' The parameter name to include in the exception if one is raised. - ''' The normalized path. - Friend Shared Function NormalizeFilePath(Path As String, ParamName As String) As String - CheckFilePathTrailingSeparator(Path, ParamName) - Return NormalizePath(Path) - End Function - - ''' - ''' Get full path, get long format, and remove any pending separator. - ''' - ''' The path to be normalized. - ''' The normalized path. - ''' See IO.Path.GetFullPath for possible exceptions. - ''' Keep this function since we might change the implementation / behavior later. - Friend Shared Function NormalizePath(Path As String) As String - Return GetLongPath(RemoveEndingSeparator(IO.Path.GetFullPath(Path))) - End Function - - ''' - ''' Throw ArgumentException if the file path ends with a separator. - ''' - ''' The file path. - ''' The parameter name to include in ArgumentException. - Friend Shared Sub CheckFilePathTrailingSeparator(path As String, paramName As String) - If String.IsNullOrEmpty(path) Then ' Check for argument null - Throw ExUtils.GetArgumentNullException(paramName) - End If - If path.EndsWith(IO.Path.DirectorySeparatorChar, StringComparison.Ordinal) Or - path.EndsWith(IO.Path.AltDirectorySeparatorChar, StringComparison.Ordinal) Then - Throw ExUtils.GetArgumentExceptionWithArgName(paramName, SR.IO_FilePathException) - End If - End Sub - - ''' - ''' Returns the given path in long format (v.s 8.3 format) if the path exists. - ''' - ''' The path to resolve to long format. - ''' The given path in long format if the path exists. - ''' - ''' GetLongPathName is a PInvoke call and requires unmanaged code permission. - ''' Use DirectoryInfo.GetFiles and GetDirectories (which call FindFirstFile) so that we always have permission. - ''' - Private Shared Function GetLongPath(FullPath As String) As String - Debug.Assert(Not String.IsNullOrEmpty(FullPath) AndAlso IO.Path.IsPathRooted(FullPath), "Must be full path") - Try - ' If root path, return itself. UNC path do not recognize 8.3 format in root path, so this is fine. - If IsRoot(FullPath) Then - Return FullPath - End If - - ' DirectoryInfo.GetFiles and GetDirectories call FindFirstFile which resolves 8.3 path. - ' Get the DirectoryInfo (user must have code permission or access permission). - Dim DInfo As New IO.DirectoryInfo(FileIO.FileSystem.GetParentPath(FullPath)) - - If IO.File.Exists(FullPath) Then - Debug.Assert(DInfo.GetFiles(IO.Path.GetFileName(FullPath)).Length = 1, "Must found exactly 1") - Return DInfo.GetFiles(IO.Path.GetFileName(FullPath))(0).FullName - ElseIf IO.Directory.Exists(FullPath) Then - Debug.Assert(DInfo.GetDirectories(IO.Path.GetFileName(FullPath)).Length = 1, - "Must found exactly 1") - Return DInfo.GetDirectories(IO.Path.GetFileName(FullPath))(0).FullName - Else - Return FullPath ' Path does not exist, cannot resolve. - End If - Catch ex As Exception - ' Ignore these type of exceptions and return FullPath. These type of exceptions should either be caught by calling functions - ' or indicate that caller does not have enough permission and should get back the 8.3 path. - If TypeOf ex Is ArgumentException OrElse - TypeOf ex Is ArgumentNullException OrElse - TypeOf ex Is IO.PathTooLongException OrElse - TypeOf ex Is NotSupportedException OrElse - TypeOf ex Is IO.DirectoryNotFoundException OrElse - TypeOf ex Is SecurityException OrElse - TypeOf ex Is UnauthorizedAccessException Then - - Debug.Assert(Not (TypeOf ex Is ArgumentException OrElse - TypeOf ex Is ArgumentNullException OrElse - TypeOf ex Is IO.PathTooLongException OrElse - TypeOf ex Is NotSupportedException), "These exceptions should be caught above") - - Return FullPath - Else - Throw - End If - End Try - End Function - - ''' - ''' Checks if the full path is a root path. - ''' - ''' The path to check. - ''' True if FullPath is a root path, False otherwise. - ''' - ''' IO.Path.GetPathRoot: C: -> C:, C:\ -> C:\, \\machine\share -> \\machine\share, - ''' BUT \\machine\share\ -> \\machine\share (No separator here). - ''' Therefore, remove any separators at the end to have correct result. - ''' - Private Shared Function IsRoot(Path As String) As Boolean - ' This function accepts a relative path since GetParentPath will call this, - ' and GetParentPath accept relative paths. - If Not IO.Path.IsPathRooted(Path) Then - Return False - End If - - Path = Path.TrimEnd(IO.Path.DirectorySeparatorChar, IO.Path.AltDirectorySeparatorChar) - Return String.Equals(Path, IO.Path.GetPathRoot(Path), - StringComparison.OrdinalIgnoreCase) - End Function - - ''' - ''' Removes all directory separators at the end of a path. - ''' - ''' a full or relative path. - ''' If Path is a root path, the same value. Otherwise, removes any directory separators at the end. - ''' We decided not to return path with separators at the end. - Private Shared Function RemoveEndingSeparator(Path As String) As String - If IO.Path.IsPathRooted(Path) Then - ' If the path is rooted, attempt to check if it is a root path. - ' Note: IO.Path.GetPathRoot: C: -> C:, C:\ -> C:\, \\myshare\mydir -> \\myshare\mydir - ' BUT \\myshare\mydir\ -> \\myshare\mydir!!! This function will remove the ending separator of - ' \\myshare\mydir\ as well. Do not use IsRoot here. - If Path.Equals(IO.Path.GetPathRoot(Path), StringComparison.OrdinalIgnoreCase) Then - Return Path - End If - End If - - ' Otherwise, remove all separators at the end. - Return Path.TrimEnd(IO.Path.DirectorySeparatorChar, IO.Path.AltDirectorySeparatorChar) - End Function - - End Class - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/Hosting.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/Hosting.vb deleted file mode 100644 index 50af821b5cd..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/Hosting.vb +++ /dev/null @@ -1,33 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Namespace Microsoft.VisualBasic.CompilerServices - - - Public Interface IVbHost - Function GetParentWindow() As System.Windows.Forms.IWin32Window - Function GetWindowTitle() As String - End Interface - - - Public NotInheritable Class HostServices - -#Disable Warning IDE0032 ' Use auto property, Justification:= - Private Shared s_host As IVbHost -#Enable Warning IDE0032 ' Use auto property - - Public Shared Property VBHost() As IVbHost - Get - Return s_host - End Get - - Set(Value As IVbHost) - s_host = Value - End Set - End Property - - End Class - -End Namespace - - diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/NativeMethods.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/NativeMethods.vb deleted file mode 100644 index 7c9780356c0..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/NativeMethods.vb +++ /dev/null @@ -1,147 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - -Imports System.Runtime.InteropServices -Imports System.Text - -Namespace Microsoft.VisualBasic.CompilerServices - - - Friend NotInheritable Class NativeMethods - - - Friend Declare Auto Function _ - WaitForInputIdle _ - Lib "user32" (Process As NativeTypes.LateInitSafeHandleZeroOrMinusOneIsInvalid, Milliseconds As Integer) As Integer - - - Friend Declare Function _ - GetWindow _ - Lib "user32" (hwnd As IntPtr, wFlag As Integer) As IntPtr - - - Friend Declare Function _ - GetDesktopWindow _ - Lib "user32" () As IntPtr - -#Disable Warning CA1838 ' Avoid 'StringBuilder' parameters for P/Invokes - - Friend Shared Function GetWindowText(hWnd As IntPtr, lpString As StringBuilder, nMaxCount As Integer) As Integer -#Enable Warning CA1838 ' Avoid 'StringBuilder' parameters for P/Invokes - End Function - - - Friend Declare Function _ - AttachThreadInput _ - Lib "user32" (idAttach As Integer, idAttachTo As Integer, fAttach As Integer) As Integer - - - Friend Declare Function _ - SetForegroundWindow _ - Lib "user32" (hwnd As IntPtr) As Boolean - - - Friend Declare Function _ - SetFocus _ - Lib "user32" (hwnd As IntPtr) As IntPtr - - - Friend Declare Auto Function _ - FindWindow _ - Lib "user32" (lpClassName As String, lpWindowName As String) As IntPtr - - - Friend Declare Function _ - CloseHandle _ - Lib "kernel32" (hObject As IntPtr) As Integer - - - Friend Declare Function _ - WaitForSingleObject _ - Lib "kernel32" (hHandle As NativeTypes.LateInitSafeHandleZeroOrMinusOneIsInvalid, dwMilliseconds As Integer) As Integer - - - Friend Shared Sub GetStartupInfo(<[In](), Out()> lpStartupInfo As NativeTypes.STARTUPINFO) - End Sub - - - Friend Shared Function CreateProcess( - lpApplicationName As String, - lpCommandLine As String, - lpProcessAttributes As NativeTypes.SECURITY_ATTRIBUTES, - lpThreadAttributes As NativeTypes.SECURITY_ATTRIBUTES, - bInheritHandles As Boolean, - dwCreationFlags As Integer, - lpEnvironment As IntPtr, - lpCurrentDirectory As String, - lpStartupInfo As NativeTypes.STARTUPINFO, - lpProcessInformation As NativeTypes.PROCESS_INFORMATION) As Integer - End Function - -#Disable Warning IDE0049 ' Simplify Names, Justification:= -#Disable Warning IDE1006 ' Naming Styles, Justification:= - ''' - ''' Contains information about the current state of both physical and virtual memory, including extended memory. - ''' - - Friend Structure MEMORYSTATUSEX - 'typedef struct _MEMORYSTATUSEX { - ' DWORD dwLength; Size of the structure. Must set before calling GlobalMemoryStatusEx. - ' DWORD dwMemoryLoad; Number between 0 and 100 on current memory utilization. - ' DWORDLONG ullTotalPhys; Total size of physical memory. - ' DWORDLONG ullAvailPhys; Total size of available physical memory. - ' DWORDLONG ullTotalPageFile; Size of committed memory limit. - ' DWORDLONG ullAvailPageFile; Size of available memory to committed (ullTotalPageFile max). - ' DWORDLONG ullTotalVirtual; Total size of user potion of virtual address space of calling process. - ' DWORDLONG ullAvailVirtual; Total size of unreserved and uncommitted memory in virtual address space. - ' DWORDLONG ullAvailExtendedVirtual; Total size of unreserved and uncommitted memory in extended portion of virtual address. - '} MEMORYSTATUSEX, *LPMEMORYSTATUSEX; - - Friend dwLength As UInt32 - Friend dwMemoryLoad As UInt32 - Friend ullTotalPhys As UInt64 - Friend ullAvailPhys As UInt64 - Friend ullTotalPageFile As UInt64 - Friend ullAvailPageFile As UInt64 - Friend ullTotalVirtual As UInt64 - Friend ullAvailVirtual As UInt64 - Friend ullAvailExtendedVirtual As UInt64 -#Enable Warning IDE1006 ' Naming Styles - - Friend Sub Init() - dwLength = CType(Marshal.SizeOf(GetType(MEMORYSTATUSEX)), UInt32) - End Sub - End Structure -#Enable Warning IDE0049 ' Simplify Names - - ''' - ''' Obtains information about the system's current usage of both physical and virtual memory. - ''' - ''' Pointer to a MEMORYSTATUSEX structure. - ''' True if the function succeeds. Otherwise, False. - - Friend Shared Function GlobalMemoryStatusEx(ByRef lpBuffer As MEMORYSTATUSEX) As Boolean - End Function - - ''' - ''' Adding a private constructor to prevent the compiler from generating a default constructor. - ''' - Private Sub New() - End Sub - - End Class - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/NativeTypes.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/NativeTypes.vb deleted file mode 100644 index f5986f5564b..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/NativeTypes.vb +++ /dev/null @@ -1,178 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On - -Imports System.Runtime.InteropServices -Imports Microsoft.Win32.SafeHandles - -Namespace Microsoft.VisualBasic.CompilerServices - - - Friend NotInheritable Class NativeTypes - -#Disable Warning CA1812 ' Supress warning as this is a type used in PInvoke and shouldn't be changed. - - Friend NotInheritable Class SECURITY_ATTRIBUTES -#Enable Warning CA1812 - Implements IDisposable - - Friend Sub New() - nLength = Marshal.SizeOf(GetType(SECURITY_ATTRIBUTES)) - End Sub - - Public nLength As Integer - Public lpSecurityDescriptor As IntPtr - Public bInheritHandle As Boolean - - Public Overloads Sub Dispose() Implements IDisposable.Dispose - If lpSecurityDescriptor <> IntPtr.Zero Then - UnsafeNativeMethods.LocalFree(lpSecurityDescriptor) - lpSecurityDescriptor = IntPtr.Zero - End If - GC.SuppressFinalize(Me) - End Sub - - Protected Overrides Sub Finalize() - Dispose() - MyBase.Finalize() - End Sub - End Class - - ''' - ''' Inherits SafeHandleZeroOrMinusOneIsInvalid, with additional InitialSetHandle method. - ''' This is required because call to constructor of SafeHandle is not allowed in constrained region. - ''' - Friend NotInheritable Class LateInitSafeHandleZeroOrMinusOneIsInvalid - Inherits SafeHandleZeroOrMinusOneIsInvalid - - Friend Sub New() - MyBase.New(True) - End Sub - - Friend Sub InitialSetHandle(h As IntPtr) - Debug.Assert(MyBase.IsInvalid, "Safe handle should only be set once.") - MyBase.SetHandle(h) - End Sub - - Protected Overrides Function ReleaseHandle() As Boolean - Return NativeMethods.CloseHandle(handle) <> 0 - End Function - End Class - - ''' - ''' Represent Win32 PROCESS_INFORMATION structure. IMPORTANT: Copy the handles to a SafeHandle before use them. - ''' - ''' - ''' The handles in PROCESS_INFORMATION are initialized in unmanaged function. - ''' We can't use SafeHandle here because Interop doesn't support [out] SafeHandles in structure / classes yet. - ''' This class makes no attempt to free the handles. To use the handle, first copy it to a SafeHandle class - ''' (using LateInitSafeHandleZeroOrMinusOneIsInvalid.InitialSetHandle) to correctly use and dispose the handle. - ''' - - Friend NotInheritable Class PROCESS_INFORMATION - Public hProcess As IntPtr = IntPtr.Zero - Public hThread As IntPtr = IntPtr.Zero - Public dwProcessId As Integer - Public dwThreadId As Integer - - Friend Sub New() - End Sub - End Class - - ''' - ''' Important! This class should be used where the API being called has allocated the strings. That is why lpReserved, etc. are declared as IntPtrs instead - ''' of Strings - so that the marshaling layer won't release the memory. This caused us problems in the shell() functions. We would call GetStartupInfo() - ''' which doesn't expect the memory for the strings to be freed. But because the strings were previously defined as type String, the marshaller would - ''' and we got memory corruption problems detectable while running AppVerifier. - ''' If you use this structure with an API like CreateProcess() then you are supplying the strings so you'll need another version of this class that defines lpReserved, etc. - ''' as String so that the memory will get cleaned up. - ''' - - Friend NotInheritable Class STARTUPINFO - Implements IDisposable - - Public cb As Integer - Public lpReserved As IntPtr = IntPtr.Zero 'not string - see summary - Public lpDesktop As IntPtr = IntPtr.Zero 'not string - see summary - Public lpTitle As IntPtr = IntPtr.Zero 'not string - see summary - Public dwX As Integer - Public dwY As Integer - Public dwXSize As Integer - Public dwYSize As Integer - Public dwXCountChars As Integer - Public dwYCountChars As Integer - Public dwFillAttribute As Integer - Public dwFlags As Integer - Public wShowWindow As Short - Public cbReserved2 As Short - Public lpReserved2 As IntPtr = IntPtr.Zero - Public hStdInput As IntPtr = IntPtr.Zero - Public hStdOutput As IntPtr = IntPtr.Zero - Public hStdError As IntPtr = IntPtr.Zero - - Friend Sub New() - End Sub - - Private _hasBeenDisposed As Boolean ' To detect redundant calls. Default initialize = False. - - Protected Overrides Sub Finalize() - Dispose(False) - End Sub - - ' IDisposable - Private Sub Dispose(disposing As Boolean) - If Not _hasBeenDisposed Then - If disposing Then - _hasBeenDisposed = True - - Const STARTF_USESTDHANDLES As Integer = 256 'Defined in windows.h - If (dwFlags And STARTF_USESTDHANDLES) <> 0 Then - If hStdInput <> IntPtr.Zero AndAlso hStdInput <> s_invalidHandle Then - NativeMethods.CloseHandle(hStdInput) - hStdInput = s_invalidHandle - End If - - If hStdOutput <> IntPtr.Zero AndAlso hStdOutput <> s_invalidHandle Then - NativeMethods.CloseHandle(hStdOutput) - hStdOutput = s_invalidHandle - End If - - If hStdError <> IntPtr.Zero AndAlso hStdError <> s_invalidHandle Then - NativeMethods.CloseHandle(hStdError) - hStdError = s_invalidHandle - End If - End If 'Me.dwFlags and STARTF_USESTDHANDLES - - End If - End If - End Sub - - ' This code correctly implements the disposable pattern. - Friend Sub Dispose() Implements IDisposable.Dispose - ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above. - Dispose(True) - GC.SuppressFinalize(Me) - End Sub - End Class - - ' Handle Values - Friend Shared ReadOnly s_invalidHandle As IntPtr = New IntPtr(-1) - - ' GetWindow() Constants - Friend Const GW_HWNDFIRST As Integer = 0 - Friend Const GW_HWNDLAST As Integer = 1 - Friend Const GW_HWNDNEXT As Integer = 2 - Friend Const GW_HWNDPREV As Integer = 3 - Friend Const GW_OWNER As Integer = 4 - Friend Const GW_CHILD As Integer = 5 - Friend Const GW_MAX As Integer = 5 - - Friend Const STARTF_USESHOWWINDOW As Integer = 1 - - Friend Const NORMAL_PRIORITY_CLASS As Integer = &H20 - - End Class - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/SafeNativeMethods.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/SafeNativeMethods.vb deleted file mode 100644 index e9445f00f5e..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/SafeNativeMethods.vb +++ /dev/null @@ -1,33 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Runtime.InteropServices - -Namespace Microsoft.VisualBasic.CompilerServices - - - - Friend NotInheritable Class _ - SafeNativeMethods - - Friend Declare Function _ - IsWindowEnabled _ - Lib "user32" (hwnd As IntPtr) As Boolean - - Friend Declare Function _ - IsWindowVisible _ - Lib "user32" (hwnd As IntPtr) As Boolean - - Friend Declare Function _ - GetWindowThreadProcessId _ - Lib "user32" (hwnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer - - ''' - ''' Adding a private constructor to prevent the compiler from generating a default constructor. - ''' - Private Sub New() - End Sub - End Class - -End Namespace - diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/UnsafeNativeMethods.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/UnsafeNativeMethods.vb deleted file mode 100644 index c1eee7c5e2f..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/UnsafeNativeMethods.vb +++ /dev/null @@ -1,50 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Runtime.InteropServices - -Namespace Microsoft.VisualBasic.CompilerServices - - - Friend NotInheritable Class UnsafeNativeMethods - - ''' - ''' Gets the state of the specified key on the keyboard when the function - ''' is called. - ''' - ''' Integer representing the key in question. - ''' - ''' The high order byte is 1 if the key is down. The low order byte is one - ''' if the key is toggled on (i.e. for keys like CapsLock) - ''' - - Friend Shared Function GetKeyState(KeyCode As Integer) As Short - End Function - - ''' - ''' Frees memory allocated from the local heap. i.e. frees memory allocated - ''' by LocalAlloc or LocalReAlloc. - ''' - - Friend Shared Function LocalFree(LocalHandle As IntPtr) As IntPtr - End Function - - ''' - ''' Used to determine how much free space is on a disk - ''' - ''' Path including drive we're getting information about - ''' The amount of free space available to the current user - ''' The total amount of space on the disk relative to the current user - ''' The amount of free spave on the disk. - ''' True if function succeeds in getting info otherwise False - - Friend Shared Function GetDiskFreeSpaceEx(Directory As String, ByRef UserSpaceFree As Long, ByRef TotalUserSpace As Long, ByRef TotalFreeSpace As Long) As Boolean - End Function - - ''' - ''' Adding a private constructor to prevent the compiler from generating a default constructor. - ''' - Private Sub New() - End Sub - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/VBInputBox.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/VBInputBox.vb deleted file mode 100644 index 62fb8bbb7e2..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Helpers/VBInputBox.vb +++ /dev/null @@ -1,131 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.ComponentModel -Imports System.Drawing -Imports System.Globalization -Imports System.Windows.Forms - -Namespace Microsoft.VisualBasic.CompilerServices - - Friend NotInheritable Class VBInputBox - Inherits Form - -#Disable Warning IDE1006 ' Naming Styles, Justification:= - Private ReadOnly components As Container - Private TextBox As TextBox - Private Label As Label - Private OKButton As Button - Private MyCancelButton As Button -#Enable Warning IDE1006 ' Naming Styles - Public Output As String = "" - - 'This constructor needed to be able to show the designer at design-time. - Friend Sub New() - MyBase.New() - InitializeComponent() - End Sub - - Friend Sub New(Prompt As String, Title As String, DefaultResponse As String, XPos As Integer, YPos As Integer) - MyBase.New() - InitializeComponent() - InitializeInputBox(Prompt, Title, DefaultResponse, XPos, YPos) - End Sub - - Protected Overloads Overrides Sub Dispose(disposing As Boolean) - If disposing Then - components?.Dispose() - End If - MyBase.Dispose(disposing) - End Sub - - Private Sub InitializeComponent() - Dim resources As ComponentResourceManager = New ComponentResourceManager(GetType(VBInputBox)) - OKButton = New Button - MyCancelButton = New Button - TextBox = New TextBox - Label = New Label - SuspendLayout() - ' - 'OKButton - ' - resources.ApplyResources(OKButton, "OKButton", CultureInfo.CurrentUICulture) - OKButton.Name = "OKButton" - ' - 'MyCancelButton - ' - MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel - resources.ApplyResources(MyCancelButton, "MyCancelButton", CultureInfo.CurrentUICulture) - MyCancelButton.Name = "MyCancelButton" - ' - 'TextBox - ' - resources.ApplyResources(TextBox, "TextBox", CultureInfo.CurrentUICulture) - TextBox.Name = "TextBox" - ' - 'Label - ' - resources.ApplyResources(Label, "Label", CultureInfo.CurrentUICulture) - Label.Name = "Label" - ' - 'VBInputBox - ' - AcceptButton = OKButton - resources.ApplyResources(Me, "$this", CultureInfo.CurrentUICulture) - CancelButton = MyCancelButton - Controls.Add(TextBox) - Controls.Add(Label) - Controls.Add(OKButton) - Controls.Add(MyCancelButton) - FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog - MaximizeBox = False - MinimizeBox = False - Name = "VBInputBox" - ResumeLayout(False) - PerformLayout() - - End Sub - - 'Initialize labels etc from the args passed in to InputBox() - Private Sub InitializeInputBox(Prompt As String, Title As String, DefaultResponse As String, XPos As Integer, YPos As Integer) - Text = Title - Label.Text = Prompt - TextBox.Text = DefaultResponse - AddHandler OKButton.Click, AddressOf OKButton_Click - AddHandler MyCancelButton.Click, AddressOf MyCancelButton_Click - - 'Re-size the dialog if the prompt is too large - Dim LabelGraphics As Graphics = Label.CreateGraphics - Dim LabelSizeNeeded As SizeF = LabelGraphics.MeasureString(Prompt, Label.Font, Label.Width) - LabelGraphics.Dispose() - If LabelSizeNeeded.Height > Label.Height Then - 'The current label size is not large enough to accommodate the prompt. We need - ' to expand the label and the dialog, and move the textbox to make room. - Dim DialogHeightChange As Integer = CInt(LabelSizeNeeded.Height) - Label.Height - Label.Height += DialogHeightChange - TextBox.Top += DialogHeightChange - Height += DialogHeightChange - End If - - 'Position the form - If (XPos = -1) AndAlso (YPos = -1) Then - StartPosition = FormStartPosition.CenterScreen - Else - If (XPos = -1) Then XPos = 600 - If (YPos = -1) Then YPos = 350 - StartPosition = FormStartPosition.Manual - DesktopLocation = New Point(XPos, YPos) - End If - End Sub - - Private Sub OKButton_Click(sender As Object, e As EventArgs) - Output = TextBox.Text - Close() - End Sub - - Private Sub MyCancelButton_Click(sender As Object, e As EventArgs) - Close() - End Sub - End Class - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Interaction.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Interaction.vb deleted file mode 100644 index 8d958ecc515..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Interaction.vb +++ /dev/null @@ -1,418 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Runtime.InteropServices -Imports System.Security -Imports System.Text -Imports System.Threading -Imports System.Windows.Forms -Imports Microsoft.VisualBasic.CompilerServices -Imports Microsoft.VisualBasic.CompilerServices.ExceptionUtils -Imports Microsoft.VisualBasic.CompilerServices.Utils - -Namespace Microsoft.VisualBasic - - ' Helper methods invoked through reflection from Microsoft.VisualBasic.Interaction in Microsoft.VisualBasic.Core.dll. - ' Do not change this API without also updating that dependent module. - Friend Module _Interaction - - Public Function Shell(PathName As String, Style As AppWinStyle, Wait As Boolean, Timeout As Integer) As Integer - Dim StartupInfo As New NativeTypes.STARTUPINFO - Dim ProcessInfo As New NativeTypes.PROCESS_INFORMATION - Dim ok As Integer - Dim safeProcessHandle As New NativeTypes.LateInitSafeHandleZeroOrMinusOneIsInvalid() - Dim safeThreadHandle As New NativeTypes.LateInitSafeHandleZeroOrMinusOneIsInvalid() - Dim ErrorCode As Integer = 0 - - If (PathName Is Nothing) Then - Throw New NullReferenceException(GetResourceString(SR.Argument_InvalidNullValue1, "Pathname")) - End If - - If (Style < 0 OrElse Style > 9) Then - Throw New ArgumentException(GetResourceString(SR.Argument_InvalidValue1, "Style")) - End If - - NativeMethods.GetStartupInfo(StartupInfo) - Try - StartupInfo.dwFlags = NativeTypes.STARTF_USESHOWWINDOW ' we want to specify the initial window style (minimized, etc) so set this bit. - StartupInfo.wShowWindow = Style - - 'We have to have unmanaged permissions to do this, so asking for path permissions would be redundant - 'Note: We are using the StartupInfo (defined in NativeTypes.StartupInfo) in CreateProcess() even though this version - 'of the StartupInfo type uses IntPtr instead of String because GetStartupInfo() above requires that version so we don't - 'free the string fields since the API manages it instead. But its OK here because we are just passing along the memory - 'that GetStartupInfo() allocated along to CreateProcess() which just reads the string fields. - - ok = NativeMethods.CreateProcess(Nothing, PathName, Nothing, Nothing, False, NativeTypes.NORMAL_PRIORITY_CLASS, Nothing, Nothing, StartupInfo, ProcessInfo) - If ok = 0 Then - ErrorCode = Marshal.GetLastWin32Error() - End If - If ProcessInfo.hProcess <> IntPtr.Zero AndAlso ProcessInfo.hProcess <> NativeTypes.s_invalidHandle Then - safeProcessHandle.InitialSetHandle(ProcessInfo.hProcess) - End If - If ProcessInfo.hThread <> IntPtr.Zero AndAlso ProcessInfo.hThread <> NativeTypes.s_invalidHandle Then - safeThreadHandle.InitialSetHandle(ProcessInfo.hThread) - End If - - Try - If (ok <> 0) Then - If Wait Then - ' Is infinite wait okay here ? - ' This is okay since this is marked as requiring the HostPermission with ExternalProcessMgmt rights - ok = NativeMethods.WaitForSingleObject(safeProcessHandle, Timeout) - - If ok = 0 Then 'succeeded - 'Process ran to completion - Shell = 0 - Else - 'Wait timed out - Shell = ProcessInfo.dwProcessId - End If - Else - NativeMethods.WaitForInputIdle(safeProcessHandle, 10000) - Shell = ProcessInfo.dwProcessId - End If - Else - 'Check for a win32 error access denied. If it is, make and throw the exception. - 'If not, throw FileNotFound - Const ERROR_ACCESS_DENIED As Integer = 5 - If ErrorCode = ERROR_ACCESS_DENIED Then - Throw VbMakeException(vbErrors.PermissionDenied) - End If - - Throw VbMakeException(vbErrors.FileNotFound) - End If - Finally - safeProcessHandle.Close() ' Close the process handle will not cause the process to stop. - safeThreadHandle.Close() - End Try - Finally - StartupInfo.Dispose() - End Try - End Function - - Public Sub AppActivateByProcessId(ProcessId As Integer) - 'As an optimization, we will only check the UI permission once we actually know we found the app to activate - we'll do that in AppActivateHelper - - Dim ProcessIdOwningWindow As Integer - 'Note, a process can have multiple windows. What we want to do is dig through to find one - 'that we can actually activate. So first ignore all the ones that are not visible and don't support mouse - 'or keyboard input - Dim WindowHandle As IntPtr = NativeMethods.GetWindow(NativeMethods.GetDesktopWindow(), NativeTypes.GW_CHILD) - - Do While (IntPtr.op_Inequality(WindowHandle, IntPtr.Zero)) - SafeNativeMethods.GetWindowThreadProcessId(WindowHandle, ProcessIdOwningWindow) - If (ProcessIdOwningWindow = ProcessId) AndAlso SafeNativeMethods.IsWindowEnabled(WindowHandle) AndAlso SafeNativeMethods.IsWindowVisible(WindowHandle) Then - Exit Do 'We found a window belonging to the desired process that we can actually activate and will support user input - End If - - 'keep rummaging through windows looking for one that belongs to the process we are after - WindowHandle = NativeMethods.GetWindow(WindowHandle, NativeTypes.GW_HWNDNEXT) - Loop - - 'If we didn't find a window during the pass above, try the less desirable route of finding any window that belongs to the process - If IntPtr.op_Equality(WindowHandle, IntPtr.Zero) Then - WindowHandle = NativeMethods.GetWindow(NativeMethods.GetDesktopWindow(), NativeTypes.GW_CHILD) - - Do While IntPtr.op_Inequality(WindowHandle, IntPtr.Zero) - SafeNativeMethods.GetWindowThreadProcessId(WindowHandle, ProcessIdOwningWindow) - If (ProcessIdOwningWindow = ProcessId) Then - Exit Do - End If - - 'keep rummaging through windows looking for one that belongs to the process we are after - WindowHandle = NativeMethods.GetWindow(WindowHandle, NativeTypes.GW_HWNDNEXT) - Loop - End If - - If IntPtr.op_Equality(WindowHandle, IntPtr.Zero) Then 'we never found a window belonging to the desired process - Throw New ArgumentException(GetResourceString(SR.ProcessNotFound, CStr(ProcessId))) - Else - AppActivateHelper(WindowHandle, CStr(ProcessId)) - End If - End Sub - - Public Sub AppActivateByTitle(Title As String) - 'As an optimization, we will only check the UI permission once we actually know we found the app to activate - we'll do that in AppActivateHelper - Dim WindowHandle As IntPtr = NativeMethods.FindWindow(Nothing, Title) 'see if we can find the window using an exact match on the title - Const MAX_TITLE_LENGTH As Integer = 511 - - ' if no match, search through all parent windows - If IntPtr.op_Equality(WindowHandle, IntPtr.Zero) Then - Dim AppTitle As String - ' Old implementation uses MAX_TITLE_LENGTH characters, INCLUDING NULL character. - ' Interop code will extend string builder to handle NULL character. - Dim AppTitleBuilder As New StringBuilder(MAX_TITLE_LENGTH) - Dim AppTitleLength As Integer - Dim TitleLength As Integer = Len(Title) - - 'Loop through all children of the desktop - WindowHandle = NativeMethods.GetWindow(NativeMethods.GetDesktopWindow(), NativeTypes.GW_CHILD) - Do While IntPtr.op_Inequality(WindowHandle, IntPtr.Zero) - ' get the window caption and test for a left-aligned substring - AppTitleLength = NativeMethods.GetWindowText(WindowHandle, AppTitleBuilder, AppTitleBuilder.Capacity) - AppTitle = AppTitleBuilder.ToString() - - If AppTitleLength >= TitleLength Then - If String.Compare(AppTitle, 0, Title, 0, TitleLength, StringComparison.OrdinalIgnoreCase) = 0 Then - Exit Do 'found one - End If - End If - - 'keep looking - WindowHandle = NativeMethods.GetWindow(WindowHandle, NativeTypes.GW_HWNDNEXT) - Loop - - If IntPtr.op_Equality(WindowHandle, IntPtr.Zero) Then - ' We didn't find it so try right aligned - WindowHandle = NativeMethods.GetWindow(NativeMethods.GetDesktopWindow(), NativeTypes.GW_CHILD) - - Do While IntPtr.op_Inequality(WindowHandle, IntPtr.Zero) - ' get the window caption and test for a right-aligned substring - AppTitleLength = NativeMethods.GetWindowText(WindowHandle, AppTitleBuilder, AppTitleBuilder.Capacity) - AppTitle = AppTitleBuilder.ToString() - - If AppTitleLength >= TitleLength Then - If String.Compare(Right(AppTitle, TitleLength), 0, Title, 0, TitleLength, StringComparison.OrdinalIgnoreCase) = 0 Then - Exit Do 'found a match - End If - End If - - 'keep looking - WindowHandle = NativeMethods.GetWindow(WindowHandle, NativeTypes.GW_HWNDNEXT) - Loop - End If - End If - - If IntPtr.op_Equality(WindowHandle, IntPtr.Zero) Then 'no match - Throw New ArgumentException(GetResourceString(SR.ProcessNotFound, Title)) - Else - AppActivateHelper(WindowHandle, Title) - End If - End Sub - - Private Sub AppActivateHelper(hwndApp As IntPtr, ProcessId As String) - ' if no window with name (full or truncated) or task id, return an error - ' if the window is not enabled or not visible, get the first window owned by it that is not enabled or not visible - Dim hwndOwned As IntPtr - If (Not SafeNativeMethods.IsWindowEnabled(hwndApp) OrElse Not SafeNativeMethods.IsWindowVisible(hwndApp)) Then - ' scan to the next window until failure - hwndOwned = NativeMethods.GetWindow(hwndApp, NativeTypes.GW_HWNDFIRST) - Do While IntPtr.op_Inequality(hwndOwned, IntPtr.Zero) - If IntPtr.op_Equality(NativeMethods.GetWindow(hwndOwned, NativeTypes.GW_OWNER), hwndApp) Then - If (Not SafeNativeMethods.IsWindowEnabled(hwndOwned) OrElse Not SafeNativeMethods.IsWindowVisible(hwndOwned)) Then - hwndApp = hwndOwned - hwndOwned = NativeMethods.GetWindow(hwndApp, NativeTypes.GW_HWNDFIRST) - Else - Exit Do - End If - End If - hwndOwned = NativeMethods.GetWindow(hwndOwned, NativeTypes.GW_HWNDNEXT) - Loop - - ' if scan failed, return an error - If IntPtr.op_Equality(hwndOwned, IntPtr.Zero) Then - Throw New ArgumentException(GetResourceString(SR.ProcessNotFound, ProcessId)) - End If - - ' set active window to the owned one - hwndApp = hwndOwned - End If - - ' SetActiveWindow on Win32 only activates the Window - it does - ' not bring to to the foreground unless the window belongs to - ' the current thread. NativeMethods.SetForegroundWindow() activates the - ' window, moves it to the foreground, and bumps the priority - ' of the thread which owns the window. - - Dim dwDummy As Integer ' dummy arg for SafeNativeMethods.GetWindowThreadProcessId - - ' Attach ourselves to the window we want to set focus to - NativeMethods.AttachThreadInput(0, SafeNativeMethods.GetWindowThreadProcessId(hwndApp, dwDummy), 1) - ' Make it foreground and give it focus, this will occur - ' synchronously because we are attached. - NativeMethods.SetForegroundWindow(hwndApp) - NativeMethods.SetFocus(hwndApp) - ' Unattached ourselves from the window - NativeMethods.AttachThreadInput(0, SafeNativeMethods.GetWindowThreadProcessId(hwndApp, dwDummy), 0) - End Sub - - Private NotInheritable Class InputBoxHandler - Private ReadOnly _prompt As String - Private ReadOnly _title As String - Private ReadOnly _defaultResponse As String - Private ReadOnly _xPos As Integer - Private ReadOnly _yPos As Integer - Private _result As String - Private ReadOnly _parentWindow As IWin32Window - Private _exception As Exception - - Sub New(Prompt As String, Title As String, DefaultResponse As String, XPos As Integer, YPos As Integer, ParentWindow As IWin32Window) - _prompt = Prompt - _title = Title - _defaultResponse = DefaultResponse - _xPos = XPos - _yPos = YPos - _parentWindow = ParentWindow - End Sub - - Public Sub StartHere() - Try - _result = InternalInputBox(_prompt, _title, _defaultResponse, _xPos, _yPos, _parentWindow) - Catch ex As Exception - _exception = ex - End Try - End Sub - - Public ReadOnly Property Result() As String - Get - Return _result - End Get - End Property - - Friend ReadOnly Property Exception As Exception - Get - Return _exception - End Get - End Property - End Class - - Public Function InputBox(Prompt As String, Title As String, DefaultResponse As String, XPos As Integer, YPos As Integer) As String - Dim vbhost As IVbHost - Dim ParentWindow As IWin32Window = Nothing - - vbhost = CompilerServices.HostServices.VBHost - If vbhost IsNot Nothing Then 'If we are hosted then we want to use the host as the parent window. If no parent window that's fine. - ParentWindow = vbhost.GetParentWindow() - End If - - If String.IsNullOrEmpty(Title) Then - If vbhost Is Nothing Then - Title = GetTitleFromAssembly(System.Reflection.Assembly.GetCallingAssembly()) - Else - Title = vbhost.GetWindowTitle() - End If - End If - - 'Threading state can only be set once, and will most often be already set - 'but set to STA and check if it isn't STA, then we need to start another thread - 'to display the InputBox - If System.Threading.Thread.CurrentThread.GetApartmentState() <> Threading.ApartmentState.STA Then - Dim InputHandler As New InputBoxHandler(Prompt, Title, DefaultResponse, XPos, YPos, ParentWindow) - Dim thread As New Thread(New ThreadStart(AddressOf InputHandler.StartHere)) - thread.Start() - thread.Join() - - If InputHandler.Exception IsNot Nothing Then - Throw InputHandler.Exception - End If - - Return InputHandler.Result - Else - Return InternalInputBox(Prompt, Title, DefaultResponse, XPos, YPos, ParentWindow) - End If - End Function - - Private Function GetTitleFromAssembly(CallingAssembly As Reflection.Assembly) As String - - Dim Title As String - - 'Get the Assembly name of the calling assembly - 'Assembly.GetName requires PathDiscovery permission so we try this first - 'and if it throws we catch the security exception and parse the name - 'from the full assembly name - Try - Title = CallingAssembly.GetName().Name - Catch ex As SecurityException - Dim FullName As String = CallingAssembly.FullName - - 'Find the text up to the first comma. Note, this fails if the assembly has - 'a comma in its name - Dim FirstCommaLocation As Integer = FullName.IndexOf(","c) - If FirstCommaLocation >= 0 Then - Title = FullName.Substring(0, FirstCommaLocation) - Else - 'The name is not in the format we're expecting so return an empty string - Title = "" - End If - End Try - - Return Title - - End Function - - Private Function InternalInputBox(Prompt As String, Title As String, DefaultResponse As String, XPos As Integer, YPos As Integer, ParentWindow As IWin32Window) As String - Dim Box As VBInputBox = New VBInputBox(Prompt, Title, DefaultResponse, XPos, YPos) - Box.ShowDialog(ParentWindow) - - InternalInputBox = Box.Output - Box.Dispose() - End Function - - Public Function MsgBox(Prompt As Object, Buttons As MsgBoxStyle, Title As Object) As MsgBoxResult - Dim sPrompt As String = Nothing - Dim sTitle As String - Dim vbhost As IVbHost - Dim ParentWindow As IWin32Window = Nothing - - vbhost = CompilerServices.HostServices.VBHost - If vbhost IsNot Nothing Then - ParentWindow = vbhost.GetParentWindow() - End If - - 'Only allow legal button combinations to be set, one choice from each group - 'These bit constants are defined in System.Windows.Forms.MessageBox - 'Low-order 4 bits (0x000f), legal values: 0, 1, 2, 3, 4, 5 - ' next 4 bits (0x00f0), legal values: 0, &H10, &H20, &H30, &H40 - ' next 4 bits (0x0f00), legal values: 0, &H100, &H200 - If ((Buttons And &HFI) > MsgBoxStyle.RetryCancel) OrElse ((Buttons And &HF0I) > MsgBoxStyle.Information) _ - OrElse ((Buttons And &HF00I) > MsgBoxStyle.DefaultButton3) Then - Buttons = MsgBoxStyle.OkOnly - End If - - Try - If Prompt IsNot Nothing Then - sPrompt = DirectCast(Conversions.ChangeType(Prompt, GetType(String)), String) - End If - Catch ex As StackOverflowException - Throw - Catch ex As OutOfMemoryException - Throw - Catch ex As ThreadAbortException - Throw - Catch - Throw New ArgumentException(GetResourceString(SR.Argument_InvalidValueType2, "Prompt", "String")) - End Try - - Try - If Title Is Nothing Then - If vbhost Is Nothing Then - sTitle = GetTitleFromAssembly(System.Reflection.Assembly.GetCallingAssembly()) - Else - sTitle = vbhost.GetWindowTitle() - End If - Else - sTitle = CStr(Title) 'allows the title to be an expression, e.g. msgbox(prompt, Title:=1+5) - End If - Catch ex As StackOverflowException - Throw - Catch ex As OutOfMemoryException - Throw - Catch ex As ThreadAbortException - Throw - Catch - Throw New ArgumentException(GetResourceString(SR.Argument_InvalidValueType2, "Title", "String")) - End Try - - Return CType(System.Windows.Forms.MessageBox.Show(ParentWindow, sPrompt, sTitle, - CType(Buttons And &HF, MessageBoxButtons), - CType(Buttons And &HF0, MessageBoxIcon), - CType(Buttons And &HF00, MessageBoxDefaultButton), - CType(Buttons And &HFFFFF000, MessageBoxOptions)), - MsgBoxResult) - End Function - - End Module - -End Namespace - diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Logging/FileLogTraceListener.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Logging/FileLogTraceListener.vb deleted file mode 100644 index 8413e3e3bbd..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Logging/FileLogTraceListener.vb +++ /dev/null @@ -1,1265 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On - -Imports System.ComponentModel -Imports System.Globalization -Imports System.IO -Imports System.Text -Imports System.Windows.Forms -Imports Microsoft.VisualBasic.CompilerServices -Imports Microsoft.VisualBasic.CompilerServices.ExceptionUtils -Imports Microsoft.VisualBasic.CompilerServices.Utils - -Namespace Microsoft.VisualBasic.Logging - - ''' - ''' Options for the location of a log's directory - ''' - Public Enum LogFileLocation As Integer - ' Changes to this enum must be reflected in ValidateLogfileLocationEnumValue() - TempDirectory - LocalUserApplicationDirectory - CommonApplicationDirectory - ExecutableDirectory - Custom - End Enum - - ''' - ''' Options for the date stamp in the name of a log file - ''' - Public Enum LogFileCreationScheduleOption As Integer - None '(default) - Daily 'YYYY-MM-DD for today - Weekly 'YYYY-MM-DD for first day of this week - End Enum - - ''' - ''' Options for behavior when resources are exhausted - ''' - Public Enum DiskSpaceExhaustedOption As Integer - ThrowException - DiscardMessages - End Enum - - ''' - ''' Class for logging to a text file - ''' - ''' - ''' TraceListener is ComVisible(False), Microsoft.VisualBasic.dll is ComVisible(True). - ''' Therefore, mark FileLogTraceListener as ComVisible(False). - ''' - - Public Class FileLogTraceListener - Inherits TraceListener - - ''' - ''' Creates a FileLogTraceListener with the passed in name - ''' - ''' The name of the listener - Public Sub New(name As String) - MyBase.New(name) - End Sub - - ''' - ''' Creates a FileLogTraceListener with default name - ''' - Public Sub New() - Me.New(DEFAULT_NAME) - End Sub - - ''' - ''' Indicates the log's directory - ''' - ''' An enum which can indicate one of several logical locations for the log - Public Property Location() As LogFileLocation - Get - If Not _propertiesSet(LOCATION_INDEX) Then - If Attributes.ContainsKey(KEY_LOCATION) Then - Dim converter As TypeConverter = TypeDescriptor.GetConverter(GetType(LogFileLocation)) - Me.Location = DirectCast(converter.ConvertFromInvariantString(Attributes(KEY_LOCATION)), LogFileLocation) - End If - End If - Return _location - End Get - Set(value As LogFileLocation) - ValidateLogFileLocationEnumValue(value, NameOf(value)) - - ' If the location is changing we need to close the current file - If _location <> value Then - CloseCurrentStream() - End If - _location = value - _propertiesSet(LOCATION_INDEX) = True - End Set - End Property - - ''' - ''' Indicates whether or not the stream should be flushed after every write - ''' - ''' True if the stream should be flushed after every write, otherwise False - Public Property AutoFlush() As Boolean - Get - If Not _propertiesSet(AUTOFLUSH_INDEX) Then - If Attributes.ContainsKey(KEY_AUTOFLUSH) Then - Me.AutoFlush = Convert.ToBoolean(Attributes(KEY_AUTOFLUSH), CultureInfo.InvariantCulture) - End If - End If - - Return _autoFlush - End Get - Set(value As Boolean) - DemandWritePermission() - _autoFlush = value - _propertiesSet(AUTOFLUSH_INDEX) = True - End Set - End Property - - ''' - ''' Indicates whether or not the host name of the logging machine should - ''' be included in the output. - ''' - ''' True if the HostId should be included, otherwise False - Public Property IncludeHostName() As Boolean - Get - If Not _propertiesSet(INCLUDEHOSTNAME_INDEX) Then - If Attributes.ContainsKey(KEY_INCLUDEHOSTNAME) Then - Me.IncludeHostName = Convert.ToBoolean(Attributes(KEY_INCLUDEHOSTNAME), CultureInfo.InvariantCulture) - End If - End If - Return _includeHostName - End Get - Set(value As Boolean) - DemandWritePermission() - _includeHostName = value - _propertiesSet(INCLUDEHOSTNAME_INDEX) = True - End Set - End Property - - ''' - ''' Indicates whether or not the file should be appended to or overwritten - ''' - ''' True if the file should be appended to, otherwise False - Public Property Append() As Boolean - Get - If Not _propertiesSet(APPEND_INDEX) Then - If Attributes.ContainsKey(KEY_APPEND) Then - Me.Append = Convert.ToBoolean(Attributes(KEY_APPEND), CultureInfo.InvariantCulture) - End If - End If - - Return _append - End Get - Set(value As Boolean) - - DemandWritePermission() - - ' If this property is changing, we need to close the current file - If value <> _append Then - CloseCurrentStream() - End If - _append = value - _propertiesSet(APPEND_INDEX) = True - End Set - End Property - - ''' - ''' Indicates what to do when the size of the log trespasses on the MaxFileSize - ''' or the ReserveDiskSpace set by the user - ''' - ''' An enum indicating the desired behavior (do nothing, throw) - Public Property DiskSpaceExhaustedBehavior() As DiskSpaceExhaustedOption - Get - If Not _propertiesSet(DISKSPACEEXHAUSTEDBEHAVIOR_INDEX) Then - If Attributes.ContainsKey(KEY_DISKSPACEEXHAUSTEDBEHAVIOR) Then - Dim converter As TypeConverter = TypeDescriptor.GetConverter(GetType(DiskSpaceExhaustedOption)) - Me.DiskSpaceExhaustedBehavior = DirectCast(converter.ConvertFromInvariantString(Attributes(KEY_DISKSPACEEXHAUSTEDBEHAVIOR)), DiskSpaceExhaustedOption) - End If - End If - Return _diskSpaceExhaustedBehavior - End Get - Set(value As DiskSpaceExhaustedOption) - DemandWritePermission() - ValidateDiskSpaceExhaustedOptionEnumValue(value, NameOf(value)) - _diskSpaceExhaustedBehavior = value - _propertiesSet(DISKSPACEEXHAUSTEDBEHAVIOR_INDEX) = True - End Set - End Property - - ''' - ''' The name of the log file not including DateStamp, file number, Path or extension - ''' - ''' The name of the log file - Public Property BaseFileName() As String - Get - If Not _propertiesSet(BASEFILENAME_INDEX) Then - If Attributes.ContainsKey(KEY_BASEFILENAME) Then - Me.BaseFileName = Attributes(KEY_BASEFILENAME) - End If - End If - Return _baseFileName - End Get - Set(value As String) - If String.IsNullOrEmpty(value) Then - Throw GetArgumentNullException("value", SR.ApplicationLogBaseNameNull) - End If - - ' Test the file name. This will throw if the name is invalid. - Path.GetFullPath(value) - - If Not String.Equals(value, _baseFileName, StringComparison.OrdinalIgnoreCase) Then - CloseCurrentStream() - _baseFileName = value - End If - - _propertiesSet(BASEFILENAME_INDEX) = True - End Set - End Property - - ''' - ''' The full name and path of the actual log file including DateStamp and file number - ''' - ''' The full name and path - ''' Calling this method will open the log file if it's not already open - Public ReadOnly Property FullLogFileName() As String - Get - ' The only way to reliably know the file name is to open the file. If we - ' don't have a stream, get one (this will open the file) - EnsureStreamIsOpen() - - ' We shouldn't use fields for demands so we use a local variable - Dim returnPath As String = _fullFileName - - Return returnPath - End Get - End Property - - ''' - ''' Indicates what Date to stamp the log file with (none, first day of week, day) - ''' - ''' An enum indicating how to stamp the file - Public Property LogFileCreationSchedule() As LogFileCreationScheduleOption - Get - If Not _propertiesSet(LOGFILECREATIONSCHEDULE_INDEX) Then - If Attributes.ContainsKey(KEY_LOGFILECREATIONSCHEDULE) Then - Dim converter As TypeConverter = TypeDescriptor.GetConverter(GetType(LogFileCreationScheduleOption)) - Me.LogFileCreationSchedule = DirectCast(converter.ConvertFromInvariantString(Attributes(KEY_LOGFILECREATIONSCHEDULE)), LogFileCreationScheduleOption) - End If - End If - Return _logFileDateStamp - End Get - Set(value As LogFileCreationScheduleOption) - ValidateLogFileCreationScheduleOptionEnumValue(value, NameOf(value)) - - If value <> _logFileDateStamp Then - CloseCurrentStream() - _logFileDateStamp = value - End If - - _propertiesSet(LOGFILECREATIONSCHEDULE_INDEX) = True - End Set - End Property - - ''' - ''' The maximum size in bytes the log file is allowed to grow to - ''' - ''' The maximum size - Public Property MaxFileSize() As Long - Get - If Not _propertiesSet(MAXFILESIZE_INDEX) Then - If Attributes.ContainsKey(KEY_MAXFILESIZE) Then - Me.MaxFileSize = Convert.ToInt64(Attributes(KEY_MAXFILESIZE), CultureInfo.InvariantCulture) - End If - End If - Return _maxFileSize - End Get - Set(value As Long) - DemandWritePermission() - If value < MIN_FILE_SIZE Then - Throw GetArgumentExceptionWithArgName("value", SR.ApplicationLogNumberTooSmall, "MaxFileSize") - End If - _maxFileSize = value - _propertiesSet(MAXFILESIZE_INDEX) = True - End Set - End Property - - ''' - ''' The amount of disk space, in bytes, that must be available after a write - ''' - ''' The reserved disk space - Public Property ReserveDiskSpace() As Long - Get - If Not _propertiesSet(RESERVEDISKSPACE_INDEX) Then - If Attributes.ContainsKey(KEY_RESERVEDISKSPACE) Then - Me.ReserveDiskSpace = Convert.ToInt64(Attributes(KEY_RESERVEDISKSPACE), CultureInfo.InvariantCulture) - End If - End If - Return _reserveDiskSpace - End Get - Set(value As Long) - DemandWritePermission() - If value < 0 Then - Throw GetArgumentExceptionWithArgName("value", SR.ApplicationLog_NegativeNumber, "ReserveDiskSpace") - End If - _reserveDiskSpace = value - _propertiesSet(RESERVEDISKSPACE_INDEX) = True - End Set - End Property - - ''' - ''' The delimiter to be used to delimit fields in a line of output - ''' - ''' The delimiter - Public Property Delimiter() As String - Get - If Not _propertiesSet(DELIMITER_INDEX) Then - If Attributes.ContainsKey(KEY_DELIMITER) Then - Me.Delimiter = Attributes(KEY_DELIMITER) - End If - End If - Return _delimiter - End Get - Set(value As String) - _delimiter = value - _propertiesSet(DELIMITER_INDEX) = True - End Set - End Property - - ''' - ''' The encoding to try when opening a file. - ''' - ''' The encoding - ''' - ''' If Append is true then this value will be trumped by the actual encoding value - ''' of the file - ''' - Public Property Encoding() As Encoding - Get - If Not _propertiesSet(ENCODING_INDEX) Then - If Attributes.ContainsKey(KEY_ENCODING) Then - Me.Encoding = System.Text.Encoding.GetEncoding(Attributes(KEY_ENCODING)) - End If - End If - Return _encoding - End Get - Set(value As Encoding) - If value Is Nothing Then - Throw GetArgumentNullException("value") - End If - _encoding = value - _propertiesSet(ENCODING_INDEX) = True - End Set - End Property - - ''' - ''' The directory to be used if Location is set to Custom - ''' - ''' The name of the directory - ''' This will throw if the path cannot be resolved - Public Property CustomLocation() As String - Get - If Not _propertiesSet(CUSTOMLOCATION_INDEX) Then - If Attributes.ContainsKey(KEY_CUSTOMLOCATION) Then - Me.CustomLocation = Attributes(KEY_CUSTOMLOCATION) - End If - End If - - Dim fileName As String = Path.GetFullPath(_customLocation) - Return fileName - End Get - Set(value As String) - - ' Validate the path - Dim tempPath As String = Path.GetFullPath(value) - - If Not Directory.Exists(tempPath) Then - Directory.CreateDirectory(tempPath) - End If - - ' If we're using custom location and the value is changing we need to - ' close the stream - If Me.Location = LogFileLocation.Custom And Not String.Equals(tempPath, _customLocation, StringComparison.OrdinalIgnoreCase) Then - CloseCurrentStream() - End If - - ' Since the user is setting a custom path, set Location to custom - Location = LogFileLocation.Custom - - _customLocation = tempPath - _propertiesSet(CUSTOMLOCATION_INDEX) = True - - End Set - End Property - - ''' - ''' Writes the message to the log - ''' - ''' The message to be written - Public Overloads Overrides Sub Write(message As String) - - ' Use Try block to attempt to close stream if an exception is thrown - Try - HandleDateChange() - - ' Check resources - Dim NewEntrySize As Long = Encoding.GetByteCount(message) - - If ResourcesAvailable(NewEntrySize) Then - ListenerStream.Write(message) - If AutoFlush Then - ListenerStream.Flush() - End If - End If - Catch - CloseCurrentStream() - Throw - End Try - - End Sub - - ''' - ''' Writes the message to the log as a line - ''' - ''' The message to be written - Public Overloads Overrides Sub WriteLine(message As String) - - ' Use Try block to attempt to close stream if an exception is thrown - Try - HandleDateChange() - - ' Check resources - Dim NewEntrySize As Long = Encoding.GetByteCount(message & vbCrLf) - - If ResourcesAvailable(NewEntrySize) Then - ListenerStream.WriteLine(message) - If AutoFlush Then - ListenerStream.Flush() - End If - End If - Catch - CloseCurrentStream() - Throw - End Try - End Sub - - ''' - ''' Event fired by TraceSourceListener resulting in writing to the log - ''' - ''' Cache of information - ''' The name of the TraceSourceListener - ''' The eventType of the message - ''' The id of the message - ''' The message - Public Overrides Sub TraceEvent(eventCache As TraceEventCache, source As String, eventType As TraceEventType, id As Integer, message As String) - - If Filter IsNot Nothing Then - If Not Filter.ShouldTrace(eventCache, source, eventType, id, message, Nothing, Nothing, Nothing) Then - Return - End If - End If - Dim outBuilder As New StringBuilder - - ' Add fields that always appear (source, eventType, id, message) - ' source - outBuilder.Append(source & Delimiter) - - ' eventType - outBuilder.Append([Enum].GetName(GetType(TraceEventType), eventType) & Delimiter) - - ' id - outBuilder.Append(id.ToString(CultureInfo.InvariantCulture) & Delimiter) - - ' message - outBuilder.Append(message) - - ' Add optional fields - ' Callstack - If (Me.TraceOutputOptions And TraceOptions.Callstack) = TraceOptions.Callstack Then - outBuilder.Append(Delimiter & eventCache.Callstack) - End If - - ' LogicalOperationStack - If (Me.TraceOutputOptions And TraceOptions.LogicalOperationStack) = TraceOptions.LogicalOperationStack Then - outBuilder.Append(Delimiter & StackToString(eventCache.LogicalOperationStack)) - End If - - ' DateTime - If (Me.TraceOutputOptions And TraceOptions.DateTime) = TraceOptions.DateTime Then - ' Add DateTime. Time will be in GMT. - outBuilder.Append(Delimiter & eventCache.DateTime.ToString("u", CultureInfo.InvariantCulture)) - End If - - ' ProcessId - If (Me.TraceOutputOptions And TraceOptions.ProcessId) = TraceOptions.ProcessId Then - outBuilder.Append(Delimiter & eventCache.ProcessId.ToString(CultureInfo.InvariantCulture)) - End If - - ' ThreadId - If (Me.TraceOutputOptions And TraceOptions.ThreadId) = TraceOptions.ThreadId Then - outBuilder.Append(Delimiter & eventCache.ThreadId) - End If - - ' Timestamp - If (Me.TraceOutputOptions And TraceOptions.Timestamp) = TraceOptions.Timestamp Then - outBuilder.Append(Delimiter & eventCache.Timestamp.ToString(CultureInfo.InvariantCulture)) - End If - - ' HostName - If IncludeHostName Then - outBuilder.Append(Delimiter & HostName) - End If - - WriteLine(outBuilder.ToString()) - - End Sub - - ''' - ''' Event fired by TraceSourceListener resulting in writing to the log - ''' - ''' Cache of information - ''' The name of the TraceSourceListener - ''' The eventType of the message - ''' The id of the message - ''' A string with placeholders that serves as a format for the message - ''' The values for the placeholders in format - Public Overrides Sub TraceEvent(eventCache As TraceEventCache, source As String, eventType As TraceEventType, id As Integer, format As String, ParamArray args() As Object) - - ' Create the message - Dim message As String - If args IsNot Nothing Then - message = String.Format(CultureInfo.InvariantCulture, format, args) - Else - message = format - End If - - TraceEvent(eventCache, source, eventType, id, message) - End Sub - - ''' - ''' Method of the base class we override to keep message format consistent - ''' - ''' Cache of information - ''' The name of the TraceSourceListener - ''' The eventType of the message - ''' The id of the message - ''' An object containing the message to be logged - Public Overrides Sub TraceData(eventCache As TraceEventCache, source As String, eventType As TraceEventType, id As Integer, data As Object) - - Dim message As String = "" - If data IsNot Nothing Then - message = data.ToString() - End If - - TraceEvent(eventCache, source, eventType, id, message) - End Sub - - ''' - ''' Method of the base class we override to keep message format consistent - ''' - ''' Cache of information - ''' The name of the TraceSourceListener - ''' The eventType of the message - ''' The id of the message - ''' A list of objects making up the message to be logged - Public Overrides Sub TraceData(eventCache As TraceEventCache, source As String, eventType As TraceEventType, id As Integer, ParamArray data As Object()) - - Dim messageBuilder As New StringBuilder() - If data IsNot Nothing Then - Dim bound As Integer = data.Length - 1 - For i As Integer = 0 To bound - messageBuilder.Append(data(i).ToString()) - If i <> bound Then - messageBuilder.Append(Delimiter) - End If - Next i - End If - - TraceEvent(eventCache, source, eventType, id, messageBuilder.ToString()) - End Sub - - ''' - ''' Flushes the underlying stream - ''' - Public Overrides Sub Flush() - _stream?.Flush() - End Sub - - ''' - ''' Closes the underlying stream - ''' - Public Overrides Sub Close() - Dispose(True) - End Sub - - ''' - ''' Gets a list of all the attributes recognized by the this listener. Trying to use an item not in this list - ''' in a config file will cause a configuration exception - ''' - ''' An array of attribute names - Protected Overrides Function GetSupportedAttributes() As String() - Return _supportedAttributes - End Function - - ''' - ''' Makes sure stream is flushed - ''' - ''' - Protected Overrides Sub Dispose(disposing As Boolean) - If disposing Then - CloseCurrentStream() - End If - End Sub - - ''' - ''' Gets the log file name under the current configuration. - ''' - ''' The log file name - ''' - ''' Includes the full path and the DateStamp, but does not include the - ''' file number or the extension. - ''' - Private ReadOnly Property LogFileName() As String - Get - Dim basePath As String - - ' Get the directory - Select Case Location - Case LogFileLocation.CommonApplicationDirectory - basePath = Application.CommonAppDataPath - Case LogFileLocation.ExecutableDirectory - basePath = Path.GetDirectoryName(Application.ExecutablePath) - Case LogFileLocation.LocalUserApplicationDirectory - basePath = Application.UserAppDataPath - Case LogFileLocation.TempDirectory - basePath = Path.GetTempPath() - Case LogFileLocation.Custom - If String.IsNullOrEmpty(CustomLocation) Then - basePath = Application.UserAppDataPath - Else - basePath = CustomLocation - End If - Case Else - Debug.Fail("Unrecognized location") - basePath = Application.UserAppDataPath - End Select - - ' Add the base name - Dim fileName As String = BaseFileName - - ' Add DateTime Stamp - Select Case LogFileCreationSchedule - Case LogFileCreationScheduleOption.Daily - fileName += "-" & Now.Date.ToString(DATE_FORMAT, CultureInfo.InvariantCulture) - Case LogFileCreationScheduleOption.Weekly - ' Get first day of week - _firstDayOfWeek = Now.AddDays(-Now.DayOfWeek) - fileName += "-" & _firstDayOfWeek.Date.ToString(DATE_FORMAT, CultureInfo.InvariantCulture) - Case LogFileCreationScheduleOption.None - Case Else - Debug.Fail("Unrecognized LogFileCreationSchedule") - End Select - - Return Path.Combine(basePath, fileName) - End Get - End Property - - ''' - ''' Gets the stream to use for writing to the log - ''' - ''' The stream - Private ReadOnly Property ListenerStream() As ReferencedStream - Get - EnsureStreamIsOpen() - - Debug.Assert(_stream IsNot Nothing, "Unable to get stream") - Return _stream - End Get - End Property - - ''' - ''' Gets or creates the stream used for writing to the log - ''' - ''' The stream - Private Function GetStream() As ReferencedStream - - ' Check the hash table to see if this file is already opened by another - ' FileLogTraceListener in the same process - Dim i As Integer = 0 - Dim refStream As ReferencedStream = Nothing - Dim BaseStreamName As String = Path.GetFullPath(LogFileName & FILE_EXTENSION) - - While refStream Is Nothing AndAlso i < MAX_OPEN_ATTEMPTS - ' This should only be true if processes outside our process have - ' MAX_OPEN_ATTEMPTS files open using the naming schema (file-1.log, file-2.log ... file-MAX_OPEN_ATTEMPTS.log) - - Dim fileName As String - If i = 0 Then - fileName = Path.GetFullPath(LogFileName & FILE_EXTENSION) - Else - fileName = Path.GetFullPath(LogFileName & "-" & i.ToString(CultureInfo.InvariantCulture) & FILE_EXTENSION) - End If - - Dim caseInsensitiveKey As String = fileName.ToUpper(CultureInfo.InvariantCulture) - SyncLock s_streams - - Dim value As ReferencedStream = Nothing - If s_streams.TryGetValue(caseInsensitiveKey, value) Then - refStream = value - If Not refStream.IsInUse Then - ' This means that the referenced stream has somehow entered an invalid state so remove it - Debug.Fail("Referenced stream is in invalid state") - s_streams.Remove(caseInsensitiveKey) - refStream = Nothing - Else - If Append Then - refStream.AddReference() - _fullFileName = fileName - Return refStream - Else - ' The user wants to overwrite, so we need to open a new stream - i += 1 - refStream = Nothing - Continue While - End If - End If - End If - - ' Try to open the file - Dim fileEncoding As Encoding = Encoding - Try - If Append Then - ' Try to get the file's actual encoding. If we get it, that trumps - ' the user specified value - fileEncoding = GetFileEncoding(fileName) - If fileEncoding Is Nothing Then - fileEncoding = Encoding - End If - End If - - Dim baseStreamWriter As New StreamWriter(fileName, Append, fileEncoding) - refStream = New ReferencedStream(baseStreamWriter) - refStream.AddReference() - s_streams.Add(caseInsensitiveKey, refStream) - _fullFileName = fileName - Return refStream - Catch ex As IOException - End Try - - i += 1 - End SyncLock - End While - 'If we fall out the loop, we have failed to obtain a valid stream name. This occurs if there are files on your system - 'ranging from BaseStreamName0..BaseStreamName{integer.MaxValue} which is pretty unlikely but hey. - Throw GetInvalidOperationException(SR.ApplicationLog_ExhaustedPossibleStreamNames, BaseStreamName) - End Function - - ''' - ''' Makes sure we have an open stream - ''' - Private Sub EnsureStreamIsOpen() - If _stream Is Nothing Then - _stream = GetStream() - End If - End Sub - - ''' - ''' Closes the stream. - ''' - ''' This method should be safe to call whether or not there is a stream - Private Sub CloseCurrentStream() - If _stream IsNot Nothing Then - SyncLock s_streams - _stream.CloseStream() - If Not _stream.IsInUse Then - s_streams.Remove(_fullFileName.ToUpper(CultureInfo.InvariantCulture)) - End If - _stream = Nothing - End SyncLock - End If - End Sub - - ''' - ''' Indicates whether or not the current date has changed to new day - ''' - ''' True if the date has changed, otherwise False - Private Function DayChanged() As Boolean - Return _day.Date <> Now.Date - End Function - - ''' - ''' Indicates whether or not the date has changed to a new week - ''' - ''' True if the date has changed, otherwise False - Private Function WeekChanged() As Boolean - Return _firstDayOfWeek.Date <> GetFirstDayOfWeek(Now.Date) - End Function - - ''' - ''' Utility to get the date of the first day of the week from the passed in date - ''' - ''' The date being checked - Private Shared Function GetFirstDayOfWeek(checkDate As Date) As Date - Return checkDate.AddDays(-checkDate.DayOfWeek).Date - End Function - - ''' - ''' Checks for date changes and carries out appropriate actions - ''' - ''' - ''' If the user has selected a DateStamp option then a change of - ''' date means we need to open a new file. - ''' - Private Sub HandleDateChange() - If Me.LogFileCreationSchedule = LogFileCreationScheduleOption.Daily Then - If DayChanged() Then - CloseCurrentStream() - End If - ElseIf Me.LogFileCreationSchedule = LogFileCreationScheduleOption.Weekly Then - If WeekChanged() Then - CloseCurrentStream() - End If - End If - End Sub - - ''' - ''' Checks the size of the current log plus the new entry and the free disk space against - ''' the user's limits. - ''' - ''' The size of what's about to be written to the file - ''' True if the limits aren't trespassed, otherwise False - ''' This method is not 100% accurate if AutoFlush is False - Private Function ResourcesAvailable(newEntrySize As Long) As Boolean - - If ListenerStream.FileSize + newEntrySize > MaxFileSize Then - If Me.DiskSpaceExhaustedBehavior = DiskSpaceExhaustedOption.ThrowException Then - Throw New InvalidOperationException(GetResourceString(SR.ApplicationLog_FileExceedsMaximumSize)) - End If - Return False - End If - - If GetFreeDiskSpace() - newEntrySize < ReserveDiskSpace Then - If Me.DiskSpaceExhaustedBehavior = DiskSpaceExhaustedOption.ThrowException Then - Throw New InvalidOperationException(GetResourceString(SR.ApplicationLog_ReservedSpaceEncroached)) - End If - Return False - End If - - Return True - End Function - - ''' - ''' Returns the total amount of free disk space available to the current user - ''' - ''' The total amount, in bytes, of free disk space available to the current user - ''' Throws an exception if API fails - Private Function GetFreeDiskSpace() As Long - Dim PathName As String = Path.GetPathRoot(Path.GetFullPath(FullLogFileName)) - - 'Initialize FreeUserSpace so we can determine if its value is changed by the API call - Dim FreeUserSpace As Long = -1 - Dim TotalUserSpace As Long - Dim TotalFreeSpace As Long - - If UnsafeNativeMethods.GetDiskFreeSpaceEx(PathName, FreeUserSpace, TotalUserSpace, TotalFreeSpace) Then - If FreeUserSpace > -1 Then - Return FreeUserSpace - End If - End If - - Throw GetWin32Exception(SR.ApplicationLog_FreeSpaceError) - End Function - - ''' - ''' Opens a file and attempts to determine the file's encoding - ''' - ''' The encoding or Nothing - Private Function GetFileEncoding(fileName As String) As Encoding - - If File.Exists(fileName) Then - Dim Reader As StreamReader = Nothing - Try - - 'Attempt to determine the encoding of the file. The call to Reader.ReadLine - 'will change the current encoding of Reader to that of the file. - Reader = New StreamReader(fileName, Encoding, True) - - 'Ignore 0 length file - If Reader.BaseStream.Length > 0 Then - Reader.ReadLine() - - Return Reader.CurrentEncoding - End If - Finally - Reader?.Close() - End Try - End If - - Return Nothing - End Function - - ''' - ''' Gets the host name - ''' - ''' The host name - ''' We use the machine name because we can get that even if not hooked up to a network - Private ReadOnly Property HostName() As String - Get - If String.IsNullOrEmpty(_hostName) Then - ' Use the machine name - _hostName = System.Environment.MachineName - End If - Return _hostName - End Get - End Property - - ''' - ''' Demands a FileIO write permission. - ''' - ''' This method should be called by public API that doesn't map to TraceListener. - ''' This ensures these API cannot be used to circumvent CAS - ''' - Private Sub DemandWritePermission() - Debug.Assert(Not String.IsNullOrWhiteSpace(Path.GetDirectoryName(LogFileName)), "The log directory shouldn't be empty.") - Dim fileName As String = Path.GetDirectoryName(LogFileName) - End Sub - - ''' - ''' Validates that the value being passed as an LogFileLocation enum is a legal value - ''' - ''' - Private Shared Sub ValidateLogFileLocationEnumValue(value As LogFileLocation, paramName As String) - If value < LogFileLocation.TempDirectory OrElse value > LogFileLocation.Custom Then - Throw New InvalidEnumArgumentException(paramName, DirectCast(value, Integer), GetType(LogFileLocation)) - End If - End Sub - - ''' - ''' Validates that the value being passed as an DiskSpaceExhaustedOption enum is a legal value - ''' - ''' - Private Shared Sub ValidateDiskSpaceExhaustedOptionEnumValue(value As DiskSpaceExhaustedOption, paramName As String) - If value < DiskSpaceExhaustedOption.ThrowException OrElse value > DiskSpaceExhaustedOption.DiscardMessages Then - Throw New InvalidEnumArgumentException(paramName, DirectCast(value, Integer), GetType(DiskSpaceExhaustedOption)) - End If - End Sub - - ''' - ''' Validates that the value being passed as an LogFileCreationScheduleOption enum is a legal value - ''' - ''' - Private Shared Sub ValidateLogFileCreationScheduleOptionEnumValue(value As LogFileCreationScheduleOption, paramName As String) - If value < LogFileCreationScheduleOption.None OrElse value > LogFileCreationScheduleOption.Weekly Then - Throw New InvalidEnumArgumentException(paramName, DirectCast(value, Integer), GetType(LogFileCreationScheduleOption)) - End If - End Sub - - ''' - ''' Convert a stack into a string - ''' - ''' - ''' Returns the stack as a .csv string - Private Shared Function StackToString(stack As Stack) As String - Debug.Assert(stack IsNot Nothing, "Stack wasn't created.") - - Dim length As Integer = STACK_DELIMITER.Length - Dim sb As New StringBuilder() - - For Each obj As Object In stack - sb.Append(obj.ToString() & STACK_DELIMITER) - Next - - ' Escape the quotes - sb.Replace("""", """""") - - ' Remove trailing delimiter - If sb.Length >= length Then - sb.Remove(sb.Length - length, length) - End If - - Return """" & sb.ToString() & """" - - End Function - - ' Indicates the location of the log's directory - Private _location As LogFileLocation = LogFileLocation.LocalUserApplicationDirectory - - ' Indicates whether or not to flush after every write - Private _autoFlush As Boolean - - ' Indicates whether to append to or overwrite the log file - Private _append As Boolean = True - - ' Indicates whether or not to include the host id in the output - Private _includeHostName As Boolean - - ' Indicates what behavior should take place when a resource level has been passed - Private _diskSpaceExhaustedBehavior As DiskSpaceExhaustedOption = DiskSpaceExhaustedOption.DiscardMessages - - ' Stores the name of the file minus the path, date stamp, and file number - Private _baseFileName As String = Path.GetFileNameWithoutExtension(Application.ExecutablePath) - - ' Indicate which date stamp should be used in the log file name - Private _logFileDateStamp As LogFileCreationScheduleOption = LogFileCreationScheduleOption.None - - ' The maximum size of the log file - Private _maxFileSize As Long = 5000000L - - ' The amount of free disk space there needs to be on the drive of the log file - Private _reserveDiskSpace As Long = 10000000L - - ' The delimiter to be used to separate fields in a line of output - Private _delimiter As String = vbTab - - ' The encoding of the log file - Private _encoding As Encoding = System.Text.Encoding.UTF8 - - ' The full name and path of the log file - Private _fullFileName As String - - ' Directory to be used for the log file if Location is set to Custom - Private _customLocation As String = Application.UserAppDataPath - - ' Reference counted stream used for writing to the log file - Private _stream As ReferencedStream - - Private ReadOnly _day As Date = Now.Date - - Private _firstDayOfWeek As Date = GetFirstDayOfWeek(Now.Date) - - Private _hostName As String - - ' Indicates whether or not properties have been set - ' Note: Properties that use m_PropertiesSet to track whether or not - ' they've been set should always be set through the property setter and not - ' by directly changing the corresponding private field. - Private ReadOnly _propertiesSet As New BitArray(PROPERTY_COUNT, False) - - ' Table of all of the files opened by any FileLogTraceListener in the current process - Private Shared ReadOnly s_streams As New Dictionary(Of String, ReferencedStream) - - ' A list of supported attributes - Private ReadOnly _supportedAttributes() As String = New String() {KEY_APPEND, KEY_APPEND_PASCAL, KEY_AUTOFLUSH, KEY_AUTOFLUSH_PASCAL, KEY_AUTOFLUSH_CAMEL, - KEY_BASEFILENAME, KEY_BASEFILENAME_PASCAL, KEY_BASEFILENAME_CAMEL, KEY_BASEFILENAME_PASCAL_ALT, KEY_BASEFILENAME_CAMEL_ALT, - KEY_CUSTOMLOCATION, KEY_CUSTOMLOCATION_PASCAL, KEY_CUSTOMLOCATION_CAMEL, KEY_DELIMITER, KEY_DELIMITER_PASCAL, - KEY_DISKSPACEEXHAUSTEDBEHAVIOR, KEY_DISKSPACEEXHAUSTEDBEHAVIOR_PASCAL, KEY_DISKSPACEEXHAUSTEDBEHAVIOR_CAMEL, - KEY_ENCODING, KEY_ENCODING_PASCAL, KEY_INCLUDEHOSTNAME, KEY_INCLUDEHOSTNAME_PASCAL, KEY_INCLUDEHOSTNAME_CAMEL, KEY_LOCATION, KEY_LOCATION_PASCAL, - KEY_LOGFILECREATIONSCHEDULE, KEY_LOGFILECREATIONSCHEDULE_PASCAL, KEY_LOGFILECREATIONSCHEDULE_CAMEL, - KEY_MAXFILESIZE, KEY_MAXFILESIZE_PASCAL, KEY_MAXFILESIZE_CAMEL, KEY_RESERVEDISKSPACE, KEY_RESERVEDISKSPACE_PASCAL, KEY_RESERVEDISKSPACE_CAMEL} - - ' Identifies properties in the BitArray - Private Const PROPERTY_COUNT As Integer = 12 - Private Const APPEND_INDEX As Integer = 0 - Private Const AUTOFLUSH_INDEX As Integer = 1 - Private Const BASEFILENAME_INDEX As Integer = 2 - Private Const CUSTOMLOCATION_INDEX As Integer = 3 - Private Const DELIMITER_INDEX As Integer = 4 - Private Const DISKSPACEEXHAUSTEDBEHAVIOR_INDEX As Integer = 5 - Private Const ENCODING_INDEX As Integer = 6 - Private Const INCLUDEHOSTNAME_INDEX As Integer = 7 - Private Const LOCATION_INDEX As Integer = 8 - Private Const LOGFILECREATIONSCHEDULE_INDEX As Integer = 9 - Private Const MAXFILESIZE_INDEX As Integer = 10 - Private Const RESERVEDISKSPACE_INDEX As Integer = 11 - - Private Const DATE_FORMAT As String = "yyyy-MM-dd" - Private Const FILE_EXTENSION As String = ".log" - Private Const MAX_OPEN_ATTEMPTS As Integer = Integer.MaxValue - - ' Name to be used when parameterless constructor is called - Private Const DEFAULT_NAME As String = "FileLogTraceListener" - - ' The minimum setting allowed for maximum file size - Private Const MIN_FILE_SIZE As Integer = 1000 - - ' Attribute keys used to access properties set in the config file - Private Const KEY_APPEND As String = "append" - Private Const KEY_APPEND_PASCAL As String = "Append" - - Private Const KEY_AUTOFLUSH As String = "autoflush" - Private Const KEY_AUTOFLUSH_PASCAL As String = "AutoFlush" - Private Const KEY_AUTOFLUSH_CAMEL As String = "autoFlush" - - Private Const KEY_BASEFILENAME As String = "basefilename" - Private Const KEY_BASEFILENAME_PASCAL As String = "BaseFilename" - Private Const KEY_BASEFILENAME_CAMEL As String = "baseFilename" - Private Const KEY_BASEFILENAME_PASCAL_ALT As String = "BaseFileName" - Private Const KEY_BASEFILENAME_CAMEL_ALT As String = "baseFileName" - - Private Const KEY_CUSTOMLOCATION As String = "customlocation" - Private Const KEY_CUSTOMLOCATION_PASCAL As String = "CustomLocation" - Private Const KEY_CUSTOMLOCATION_CAMEL As String = "customLocation" - - Private Const KEY_DELIMITER As String = "delimiter" - Private Const KEY_DELIMITER_PASCAL As String = "Delimiter" - - Private Const KEY_DISKSPACEEXHAUSTEDBEHAVIOR As String = "diskspaceexhaustedbehavior" - Private Const KEY_DISKSPACEEXHAUSTEDBEHAVIOR_PASCAL As String = "DiskSpaceExhaustedBehavior" - Private Const KEY_DISKSPACEEXHAUSTEDBEHAVIOR_CAMEL As String = "diskSpaceExhaustedBehavior" - - Private Const KEY_ENCODING As String = "encoding" - Private Const KEY_ENCODING_PASCAL As String = "Encoding" - - Private Const KEY_INCLUDEHOSTNAME As String = "includehostname" - Private Const KEY_INCLUDEHOSTNAME_PASCAL As String = "IncludeHostName" - Private Const KEY_INCLUDEHOSTNAME_CAMEL As String = "includeHostName" - - Private Const KEY_LOCATION As String = "location" - Private Const KEY_LOCATION_PASCAL As String = "Location" - - Private Const KEY_LOGFILECREATIONSCHEDULE As String = "logfilecreationschedule" - Private Const KEY_LOGFILECREATIONSCHEDULE_PASCAL As String = "LogFileCreationSchedule" - Private Const KEY_LOGFILECREATIONSCHEDULE_CAMEL As String = "logFileCreationSchedule" - - Private Const KEY_MAXFILESIZE As String = "maxfilesize" - Private Const KEY_MAXFILESIZE_PASCAL As String = "MaxFileSize" - Private Const KEY_MAXFILESIZE_CAMEL As String = "maxFileSize" - - Private Const KEY_RESERVEDISKSPACE As String = "reservediskspace" - Private Const KEY_RESERVEDISKSPACE_PASCAL As String = "ReserveDiskSpace" - Private Const KEY_RESERVEDISKSPACE_CAMEL As String = "reserveDiskSpace" - - ' Delimiter used when converting a stack to a string - Private Const STACK_DELIMITER As String = ", " - - ''' - ''' Wraps a StreamWriter and keeps a reference count. This enables multiple - ''' FileLogTraceListeners on multiple threads to access the same file. - ''' - Friend NotInheritable Class ReferencedStream - Implements IDisposable - - ''' - ''' Creates a new referenced stream - ''' - ''' The stream that does the actual writing - Friend Sub New(stream As StreamWriter) - _stream = stream - End Sub - - ''' - ''' Writes a message to the stream - ''' - ''' The message to write - Friend Sub Write(message As String) - SyncLock _syncObject - _stream.Write(message) - End SyncLock - End Sub - - ''' - ''' Writes a message to the stream as a line - ''' - ''' The message to write - Friend Sub WriteLine(message As String) - SyncLock _syncObject - _stream.WriteLine(message) - End SyncLock - End Sub - - ''' - ''' Increments the reference count for the stream - ''' - Friend Sub AddReference() - SyncLock _syncObject - _referenceCount += 1 - End SyncLock - End Sub - - ''' - ''' Flushes the stream - ''' - Friend Sub Flush() - SyncLock _syncObject - _stream.Flush() - End SyncLock - End Sub - - ''' - ''' Decrements the reference count to the stream and closes the stream if the reference count - ''' is zero - ''' - Friend Sub CloseStream() - SyncLock _syncObject - Try - _referenceCount -= 1 - _stream.Flush() - Debug.Assert(_referenceCount >= 0, "Ref count is below 0") - Finally - If _referenceCount <= 0 Then - _stream.Close() - _stream = Nothing - End If - End Try - End SyncLock - End Sub - - ''' - ''' Indicates whether or not the stream is still in use by a FileLogTraceListener - ''' - ''' True if the stream is being used, otherwise False - Friend ReadOnly Property IsInUse() As Boolean - Get - Return _stream IsNot Nothing - End Get - End Property - - ''' - ''' The size of the log file - ''' - ''' The size - Friend ReadOnly Property FileSize() As Long - Get - Return _stream.BaseStream.Length - End Get - End Property - - ''' - ''' Ensures the stream is closed (flushed) no matter how we are closed - ''' - ''' Indicates who called dispose - Private Overloads Sub Dispose(disposing As Boolean) - If disposing Then - If Not _disposed Then - _stream?.Close() - _disposed = True - End If - End If - End Sub - - ''' - ''' Standard implementation of IDisposable - ''' - Public Overloads Sub Dispose() Implements IDisposable.Dispose - ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above. - Dispose(True) - GC.SuppressFinalize(Me) - End Sub - - ''' - ''' Ensures stream is closed at GC - ''' - Protected Overrides Sub Finalize() - ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above. - Dispose(False) - MyBase.Finalize() - End Sub - - ' The stream that does the writing - Private _stream As StreamWriter - - ' The number of FileLogTraceListeners using the stream - Private _referenceCount As Integer - - ' Used for synchronizing writing and reference counting - Private ReadOnly _syncObject As Object = New Object - - ' Indicates whether or not the object has been disposed - Private _disposed As Boolean - - End Class 'ReferencedStream - - End Class 'FileLogTraceListener - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Logging/Log.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Logging/Log.vb deleted file mode 100644 index 49ea2c047d3..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Logging/Log.vb +++ /dev/null @@ -1,240 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On - -Imports System.Collections.Specialized -Imports System.ComponentModel -Imports System.Text -Imports Microsoft.VisualBasic.CompilerServices.ExceptionUtils - -Namespace Microsoft.VisualBasic.Logging - - ''' - ''' Enables logging to configured TraceListeners - ''' - Public Class Log - - ''' - ''' Creates a Log and the underlying TraceSource based on the platform - ''' - ''' Right now we only support WinApp as an application platform - Public Sub New() - ' Set trace source for platform. Right now we only support WinApp - _traceSource = New DefaultTraceSource(WINAPP_SOURCE_NAME) - If Not _traceSource.HasBeenConfigured Then - InitializeWithDefaultsSinceNoConfigExists() - End If - ' Make sure to flush the log when the application closes - AddHandler System.AppDomain.CurrentDomain.ProcessExit, AddressOf CloseOnProcessExit - End Sub - - ''' - ''' Creates a Log and the underlying TraceSource based on the passed in name - ''' - ''' The name of the TraceSource to be created - Public Sub New(name As String) - _traceSource = New DefaultTraceSource(name) - If Not _traceSource.HasBeenConfigured Then - InitializeWithDefaultsSinceNoConfigExists() - End If - End Sub - - ''' - ''' Has the TraceSource fire a TraceEvent for all of its listeners - ''' - ''' The message to be logged - Public Sub WriteEntry(message As String) - WriteEntry(message, TraceEventType.Information, TraceEventTypeToId(TraceEventType.Information)) - End Sub - - ''' - ''' Has the TraceSource fire a TraceEvent for all of its listeners - ''' - ''' The message to be logged - ''' The type of message (error, info, etc...) - Public Sub WriteEntry(message As String, severity As TraceEventType) - WriteEntry(message, severity, TraceEventTypeToId(severity)) - End Sub - - ''' - ''' Has the TraceSource fire a TraceEvent for all of its listeners - ''' - ''' The message to be logged - ''' The type of message (error, info, etc...) - ''' An id for the message (used for correlation) - Public Sub WriteEntry(message As String, severity As TraceEventType, id As Integer) - If message Is Nothing Then - message = "" - End If - _traceSource.TraceEvent(severity, id, message) - End Sub - - ''' - ''' Has the TraceSource fire a TraceEvent for all listeners using information in an exception to form the message - ''' - ''' The exception being logged - Public Sub WriteException(ex As Exception) - WriteException(ex, TraceEventType.Error, "", TraceEventTypeToId(TraceEventType.Error)) - End Sub - - ''' - ''' Has the TraceSource fire a TraceEvent for all listeners using information in an exception to form the message - ''' and appending additional info - ''' - ''' The exception being logged - ''' The type of message (error, info, etc...) - ''' Extra information to append to the message - Public Sub WriteException(ex As Exception, severity As TraceEventType, additionalInfo As String) - WriteException(ex, severity, additionalInfo, TraceEventTypeToId(severity)) - End Sub - - ''' - ''' Has the TraceSource fire a TraceEvent for all listeners using information in an exception to form the message - ''' and appending additional info - ''' - ''' The exception being logged - ''' The type of message (error, info, etc...) - ''' Extra information to append to the message - ''' An id for the message (used for correlation) - Public Sub WriteException(ex As Exception, severity As TraceEventType, additionalInfo As String, id As Integer) - - If ex Is Nothing Then - Throw GetArgumentNullException("ex") - End If - - Dim builder As New StringBuilder() - builder.Append(ex.Message) - - If Not String.IsNullOrEmpty(additionalInfo) Then - builder.Append(" "c) - builder.Append(additionalInfo) - End If - - _traceSource.TraceEvent(severity, id, builder.ToString()) - - End Sub - - ''' - ''' Gives access to the log's underlying TraceSource - ''' - ''' The log's underlying TraceSource - - Public ReadOnly Property TraceSource() As TraceSource - Get - Return _traceSource 'Note, this is a downcast from the DefaultTraceSource class we are using - End Get - End Property - - ''' - ''' Returns the file log trace listener we create for the Log - ''' - ''' The file log trace listener - Public ReadOnly Property DefaultFileLogWriter() As FileLogTraceListener - Get - Return CType(TraceSource.Listeners(DEFAULT_FILE_LOG_TRACE_LISTENER_NAME), FileLogTraceListener) - End Get - End Property - - ''' - ''' Encapsulates a System.Diagnostics.TraceSource. The value add is that it knows if it was initialized - ''' using a config file or not. - ''' - Friend NotInheritable Class DefaultTraceSource - Inherits TraceSource - - ''' - ''' TraceSource has other constructors, this is the only one we care about for this internal class - ''' - ''' - Sub New(name As String) - MyBase.New(name) - End Sub - - ''' - ''' Tells us whether this TraceSource found a config file to configure itself from - ''' - ''' True - The TraceSource was configured from a config file - Public ReadOnly Property HasBeenConfigured() As Boolean - Get - ' This forces initialization of the attributes list - If _listenerAttributes Is Nothing Then - _listenerAttributes = Attributes - End If - - ' TODO: This is a tempory fix, which will break configuring logging via file for the time being. See: https://github.com/dotnet/winforms/pull/7590 - Return False - End Get - End Property - - Private _listenerAttributes As StringDictionary - - End Class - - ''' - ''' When there is no config file to configure the trace source, this function is called in order to - ''' configure the trace source according to the defaults they would have had in a default AppConfig - ''' - Protected Friend Overridable Sub InitializeWithDefaultsSinceNoConfigExists() - 'By default, you get a file log listener that picks everything from level Information on up. - _traceSource.Listeners.Add(New FileLogTraceListener(DEFAULT_FILE_LOG_TRACE_LISTENER_NAME)) - _traceSource.Switch.Level = SourceLevels.Information - End Sub - - ''' - ''' Make sure we flush the log on exit - ''' - Private Sub CloseOnProcessExit(sender As Object, e As EventArgs) - RemoveHandler System.AppDomain.CurrentDomain.ProcessExit, AddressOf CloseOnProcessExit - TraceSource.Close() - End Sub - - ''' - ''' Adds the default id values - ''' - ''' Fix FxCop violation InitializeReferenceTypeStaticFieldsInline - Private Shared Function InitializeIDHash() As Dictionary(Of TraceEventType, Integer) - Dim result As New Dictionary(Of TraceEventType, Integer)(10) - - ' Populate table with the fx pre defined ids - With result - .Add(TraceEventType.Information, 0) - .Add(TraceEventType.Warning, 1) - .Add(TraceEventType.Error, 2) - .Add(TraceEventType.Critical, 3) - .Add(TraceEventType.Start, 4) - .Add(TraceEventType.Stop, 5) - .Add(TraceEventType.Suspend, 6) - .Add(TraceEventType.Resume, 7) - .Add(TraceEventType.Verbose, 8) - .Add(TraceEventType.Transfer, 9) - End With - - Return result - End Function - - ''' - ''' Converts a TraceEventType to an Id - ''' - ''' - ''' The Id - Private Shared Function TraceEventTypeToId(traceEventValue As TraceEventType) As Integer - Dim Id As Integer = 0 - s_idHash.TryGetValue(traceEventValue, Id) - Return Id - End Function - - ' The underlying TraceSource for the log - Private ReadOnly _traceSource As DefaultTraceSource - - ' A table of default id values - Private Shared ReadOnly s_idHash As Dictionary(Of TraceEventType, Integer) = InitializeIDHash() - - ' Names of TraceSources - Private Const WINAPP_SOURCE_NAME As String = "DefaultSource" - Private Const DEFAULT_FILE_LOG_TRACE_LISTENER_NAME As String = "FileLog" 'taken from appconfig - - End Class - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/ClipboardProxy.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/ClipboardProxy.vb deleted file mode 100644 index b60616852ca..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/ClipboardProxy.vb +++ /dev/null @@ -1,214 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On - -Imports System.Collections.Specialized -Imports System.ComponentModel -Imports System.Drawing -Imports System.IO -Imports System.Windows.Forms - -Namespace Microsoft.VisualBasic.MyServices - - ''' - ''' A class that wraps System.Windows.Forms.Clipboard so that - ''' a clipboard can be instanced. - ''' - - Public Class ClipboardProxy - - ''' - ''' Only Allows instantiation of the class - ''' - Friend Sub New() - End Sub - - ''' - ''' Gets text from the clipboard - ''' - ''' The text as a String - Public Function GetText() As String - Return Clipboard.GetText() - End Function - - ''' - ''' Gets text from the clipboard saved in the passed in format - ''' - ''' The type of text to get - ''' The text as a String - Public Function GetText(format As System.Windows.Forms.TextDataFormat) As String - Return Clipboard.GetText(format) - End Function - - ''' - ''' Indicates whether or not text is available on the clipboard - ''' - ''' True if text is available, otherwise False - Public Function ContainsText() As Boolean - Return Clipboard.ContainsText - End Function - - ''' - ''' Indicates whether or not text is available on the clipboard in - ''' the passed in format - ''' - ''' The type of text being checked for - ''' True if text is available, otherwise False - Public Function ContainsText(format As System.Windows.Forms.TextDataFormat) As Boolean - Return Clipboard.ContainsText(format) - End Function - - ''' - ''' Saves the passed in String to the clipboard - ''' - ''' The String to save - Public Sub SetText(text As String) - Clipboard.SetText(text) - End Sub - - ''' - ''' Saves the passed in String to the clipboard in the passed in format - ''' - ''' The String to save - ''' The format in which to save the String - Public Sub SetText(text As String, format As System.Windows.Forms.TextDataFormat) - Clipboard.SetText(text, format) - End Sub - - ''' - ''' Gets an Image from the clipboard - ''' - ''' The image - Public Function GetImage() As Image - Return Clipboard.GetImage() - End Function - - ''' - ''' Indicate whether or not an image has been saved to the clipboard - ''' - ''' True if an image is available, otherwise False - Public Function ContainsImage() As Boolean - Return Clipboard.ContainsImage() - End Function - - ''' - ''' Saves the passed in image to the clipboard - ''' - ''' The image to be saved - Public Sub SetImage(image As Image) - Clipboard.SetImage(image) - End Sub - - ''' - ''' Gets an audio stream from the clipboard - ''' - ''' The audio stream as a Stream - Public Function GetAudioStream() As Stream - Return Clipboard.GetAudioStream() - End Function - - ''' - ''' Indicates whether or not there's an audio stream saved to the clipboard - ''' - ''' True if an audio stream is available, otherwise False - Public Function ContainsAudio() As Boolean - Return Clipboard.ContainsAudio() - End Function - - ''' - ''' Saves the passed in audio byte array to the clipboard - ''' - ''' The byte array to be saved - Public Sub SetAudio(audioBytes As Byte()) - Clipboard.SetAudio(audioBytes) - End Sub - - ''' - ''' Saves the passed in audio stream to the clipboard - ''' - ''' The stream to be saved - Public Sub SetAudio(audioStream As Stream) - Clipboard.SetAudio(audioStream) - End Sub - - ''' - ''' Gets a file drop list from the clipboard - ''' - ''' The list of file paths as a StringCollection - Public Function GetFileDropList() As StringCollection - Return Clipboard.GetFileDropList() - End Function - - ''' - ''' Indicates whether or not a file drop list has been saved to the clipboard - ''' - ''' True if a file drop list is available, otherwise False - Public Function ContainsFileDropList() As Boolean - Return Clipboard.ContainsFileDropList() - End Function - - ''' - ''' Saves the passed in file drop list to the clipboard - ''' - ''' The file drop list as a StringCollection - Public Sub SetFileDropList(filePaths As StringCollection) - Clipboard.SetFileDropList(filePaths) - End Sub - - ''' - ''' Gets data from the clipboard that's been saved in the passed in format. - ''' - ''' The type of data being sought - ''' The data - Public Function GetData(format As String) As Object - Return Clipboard.GetData(format) - End Function - - ''' - ''' Indicates whether or not there is data on the clipboard in the passed in format - ''' - ''' - ''' True if there's data in the passed in format, otherwise False - Public Function ContainsData(format As String) As Boolean - Return Clipboard.ContainsData(format) - End Function - - ''' - ''' Saves the passed in data to the clipboard in the passed in format - ''' - ''' The format in which to save the data - ''' The data to be saved - Public Sub SetData(format As String, data As Object) - Clipboard.SetData(format, data) - End Sub - - ''' - ''' Removes everything from the clipboard - ''' - Public Sub Clear() - Clipboard.Clear() - End Sub - - ''' - ''' Gets a Data Object from the clipboard. - ''' - ''' The data object - ''' This gives the ability to save an object in multiple formats - - Public Function GetDataObject() As System.Windows.Forms.IDataObject - Return Clipboard.GetDataObject() - End Function - - ''' - ''' Saves a DataObject to the clipboard - ''' - ''' The data object to be saved - ''' This gives the ability to save an object in multiple formats - - Public Sub SetDataObject(data As System.Windows.Forms.DataObject) - Clipboard.SetDataObject(data) - End Sub - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/FileSystemProxy.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/FileSystemProxy.vb deleted file mode 100644 index b4a14a98322..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/FileSystemProxy.vb +++ /dev/null @@ -1,281 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Strict On -Option Explicit On - -Imports System.Collections.ObjectModel -Imports System.ComponentModel -Imports System.Text -Imports Microsoft.VisualBasic.FileIO - -Namespace Microsoft.VisualBasic.MyServices - - ''' - ''' An extremely thin wrapper around Microsoft.VisualBasic.FileIO.FileSystem to expose the type through My. - ''' - - Public Class FileSystemProxy - - Public ReadOnly Property Drives() As ReadOnlyCollection(Of IO.DriveInfo) - Get - Return FileIO.FileSystem.Drives - End Get - End Property - - Public ReadOnly Property SpecialDirectories() As SpecialDirectoriesProxy - Get - If _specialDirectoriesProxy Is Nothing Then - _specialDirectoriesProxy = New SpecialDirectoriesProxy - End If - Return _specialDirectoriesProxy - End Get - End Property - - Public Property CurrentDirectory() As String - Get - Return FileIO.FileSystem.CurrentDirectory - End Get - Set(value As String) - FileIO.FileSystem.CurrentDirectory = value - End Set - End Property - - Public Function DirectoryExists(directory As String) As Boolean - Return FileIO.FileSystem.DirectoryExists(directory) - End Function - - Public Function FileExists(file As String) As Boolean - Return FileIO.FileSystem.FileExists(file) - End Function - - Public Sub CreateDirectory(directory As String) - FileIO.FileSystem.CreateDirectory(directory) - End Sub - - Public Function GetDirectoryInfo(directory As String) As IO.DirectoryInfo - Return FileIO.FileSystem.GetDirectoryInfo(directory) - End Function - - Public Function GetFileInfo(file As String) As IO.FileInfo - Return FileIO.FileSystem.GetFileInfo(file) - End Function - - Public Function GetDriveInfo(drive As String) As IO.DriveInfo - Return FileIO.FileSystem.GetDriveInfo(drive) - End Function - - Public Function GetFiles(directory As String) As ReadOnlyCollection(Of String) - Return FileIO.FileSystem.GetFiles(directory) - End Function - - Public Function GetFiles(directory As String, searchType As SearchOption, - ParamArray wildcards() As String) As ReadOnlyCollection(Of String) - - Return FileIO.FileSystem.GetFiles(directory, searchType, wildcards) - End Function - - Public Function GetDirectories(directory As String) As ReadOnlyCollection(Of String) - Return FileIO.FileSystem.GetDirectories(directory) - End Function - - Public Function GetDirectories(directory As String, searchType As SearchOption, - ParamArray wildcards() As String) As ReadOnlyCollection(Of String) - - Return FileIO.FileSystem.GetDirectories(directory, searchType, wildcards) - End Function - - Public Function FindInFiles(directory As String, - containsText As String, ignoreCase As Boolean, searchType As SearchOption) As ReadOnlyCollection(Of String) - - Return FileIO.FileSystem.FindInFiles(directory, containsText, ignoreCase, searchType) - End Function - - Public Function FindInFiles(directory As String, containsText As String, ignoreCase As Boolean, - searchType As SearchOption, ParamArray fileWildcards() As String) As ReadOnlyCollection(Of String) - - Return FileIO.FileSystem.FindInFiles(directory, containsText, ignoreCase, searchType, fileWildcards) - End Function - - Public Function GetParentPath(path As String) As String - Return FileIO.FileSystem.GetParentPath(path) - End Function - - Public Function CombinePath(baseDirectory As String, relativePath As String) As String - Return FileIO.FileSystem.CombinePath(baseDirectory, relativePath) - End Function - - Public Function GetName(path As String) As String - Return FileIO.FileSystem.GetName(path) - End Function - - Public Function GetTempFileName() As String - Return FileIO.FileSystem.GetTempFileName() - End Function - - Public Function ReadAllText(file As String) As String - Return FileIO.FileSystem.ReadAllText(file) - End Function - - Public Function ReadAllText(file As String, encoding As Encoding) As String - Return FileIO.FileSystem.ReadAllText(file, encoding) - End Function - - Public Function ReadAllBytes(file As String) As Byte() - Return FileIO.FileSystem.ReadAllBytes(file) - End Function - - Public Sub WriteAllText(file As String, text As String, append As Boolean) - FileIO.FileSystem.WriteAllText(file, text, append) - End Sub - - Public Sub WriteAllText(file As String, text As String, append As Boolean, - encoding As Encoding) - - FileIO.FileSystem.WriteAllText(file, text, append, encoding) - End Sub - - Public Sub WriteAllBytes(file As String, data() As Byte, append As Boolean) - FileIO.FileSystem.WriteAllBytes(file, data, append) - End Sub - - Public Sub CopyFile(sourceFileName As String, destinationFileName As String) - FileIO.FileSystem.CopyFile(sourceFileName, destinationFileName) - End Sub - - Public Sub CopyFile(sourceFileName As String, destinationFileName As String, overwrite As Boolean) - FileIO.FileSystem.CopyFile(sourceFileName, destinationFileName, overwrite) - End Sub - - Public Sub CopyFile(sourceFileName As String, destinationFileName As String, showUI As UIOption) - FileIO.FileSystem.CopyFile(sourceFileName, destinationFileName, showUI) - End Sub - - Public Sub CopyFile(sourceFileName As String, destinationFileName As String, showUI As UIOption, onUserCancel As UICancelOption) - FileIO.FileSystem.CopyFile(sourceFileName, destinationFileName, showUI, onUserCancel) - End Sub - - Public Sub MoveFile(sourceFileName As String, destinationFileName As String) - FileIO.FileSystem.MoveFile(sourceFileName, destinationFileName) - End Sub - - Public Sub MoveFile(sourceFileName As String, destinationFileName As String, overwrite As Boolean) - FileIO.FileSystem.MoveFile(sourceFileName, destinationFileName, overwrite) - End Sub - - Public Sub MoveFile(sourceFileName As String, destinationFileName As String, showUI As UIOption) - FileIO.FileSystem.MoveFile(sourceFileName, destinationFileName, showUI) - End Sub - - Public Sub MoveFile(sourceFileName As String, destinationFileName As String, showUI As UIOption, onUserCancel As UICancelOption) - FileIO.FileSystem.MoveFile(sourceFileName, destinationFileName, showUI, onUserCancel) - End Sub - - Public Sub CopyDirectory(sourceDirectoryName As String, destinationDirectoryName As String) - FileIO.FileSystem.CopyDirectory(sourceDirectoryName, destinationDirectoryName) - End Sub - - Public Sub CopyDirectory(sourceDirectoryName As String, destinationDirectoryName As String, overwrite As Boolean) - FileIO.FileSystem.CopyDirectory(sourceDirectoryName, destinationDirectoryName, overwrite) - End Sub - - Public Sub CopyDirectory(sourceDirectoryName As String, destinationDirectoryName As String, showUI As UIOption) - FileIO.FileSystem.CopyDirectory(sourceDirectoryName, destinationDirectoryName, showUI) - End Sub - - Public Sub CopyDirectory(sourceDirectoryName As String, destinationDirectoryName As String, showUI As UIOption, onUserCancel As UICancelOption) - FileIO.FileSystem.CopyDirectory(sourceDirectoryName, destinationDirectoryName, showUI, onUserCancel) - End Sub - - Public Sub MoveDirectory(sourceDirectoryName As String, destinationDirectoryName As String) - FileIO.FileSystem.MoveDirectory(sourceDirectoryName, destinationDirectoryName) - End Sub - - Public Sub MoveDirectory(sourceDirectoryName As String, destinationDirectoryName As String, overwrite As Boolean) - FileIO.FileSystem.MoveDirectory(sourceDirectoryName, destinationDirectoryName, overwrite) - End Sub - - Public Sub MoveDirectory(sourceDirectoryName As String, destinationDirectoryName As String, showUI As UIOption) - FileIO.FileSystem.MoveDirectory(sourceDirectoryName, destinationDirectoryName, showUI) - End Sub - - Public Sub MoveDirectory(sourceDirectoryName As String, destinationDirectoryName As String, showUI As UIOption, onUserCancel As UICancelOption) - FileIO.FileSystem.MoveDirectory(sourceDirectoryName, destinationDirectoryName, showUI, onUserCancel) - End Sub - - Public Sub DeleteFile(file As String) - FileIO.FileSystem.DeleteFile(file) - End Sub - - Public Sub DeleteFile(file As String, showUI As UIOption, recycle As RecycleOption) - FileIO.FileSystem.DeleteFile(file, showUI, recycle) - End Sub - - Public Sub DeleteFile(file As String, showUI As UIOption, recycle As RecycleOption, - onUserCancel As UICancelOption) - - FileIO.FileSystem.DeleteFile(file, showUI, recycle, onUserCancel) - End Sub - - Public Sub DeleteDirectory(directory As String, onDirectoryNotEmpty As DeleteDirectoryOption) - FileIO.FileSystem.DeleteDirectory(directory, onDirectoryNotEmpty) - End Sub - - Public Sub DeleteDirectory(directory As String, showUI As UIOption, recycle As RecycleOption) - - FileIO.FileSystem.DeleteDirectory(directory, showUI, recycle) - End Sub - - Public Sub DeleteDirectory(directory As String, - showUI As UIOption, recycle As RecycleOption, onUserCancel As UICancelOption) - - FileIO.FileSystem.DeleteDirectory(directory, showUI, recycle, onUserCancel) - End Sub - - Public Sub RenameFile(file As String, newName As String) - FileIO.FileSystem.RenameFile(file, newName) - End Sub - - Public Sub RenameDirectory(directory As String, newName As String) - FileIO.FileSystem.RenameDirectory(directory, newName) - End Sub - - Public Function OpenTextFieldParser(file As String) As TextFieldParser - Return FileIO.FileSystem.OpenTextFieldParser(file) - End Function - - Public Function OpenTextFieldParser(file As String, ParamArray delimiters As String()) As TextFieldParser - Return FileIO.FileSystem.OpenTextFieldParser(file, delimiters) - End Function - - Public Function OpenTextFieldParser(file As String, ParamArray fieldWidths As Integer()) As TextFieldParser - Return FileIO.FileSystem.OpenTextFieldParser(file, fieldWidths) - End Function - - Public Function OpenTextFileReader(file As String) As IO.StreamReader - Return FileIO.FileSystem.OpenTextFileReader(file) - End Function - - Public Function OpenTextFileReader(file As String, encoding As Encoding) As IO.StreamReader - Return FileIO.FileSystem.OpenTextFileReader(file, encoding) - End Function - - Public Function OpenTextFileWriter(file As String, append As Boolean) As IO.StreamWriter - Return FileIO.FileSystem.OpenTextFileWriter(file, append) - End Function - - Public Function OpenTextFileWriter(file As String, append As Boolean, - encoding As Encoding) As IO.StreamWriter - - Return FileIO.FileSystem.OpenTextFileWriter(file, append, encoding) - End Function - - ''' - ''' Proxy class can only created by internal classes. - ''' - Friend Sub New() - End Sub - - Private _specialDirectoriesProxy As SpecialDirectoriesProxy - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/ContextValue.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/ContextValue.vb deleted file mode 100644 index 8963ff68ccd..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/ContextValue.vb +++ /dev/null @@ -1,55 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On - -Imports System.Threading - -Namespace Microsoft.VisualBasic.MyServices.Internal - - ''' - ''' Stores an object in a context appropriate for the environment we are - ''' running in (web/windows) - ''' - ''' - ''' - ''' "Thread appropriate" means that if we are running on ASP.Net the object will be stored in the - ''' context of the current request (meaning the object is stored per request on the web). - ''' Note that an instance of this class can only be associated - ''' with the one item to be stored/retrieved at a time. - ''' - - Public Class ContextValue(Of T) - Public Sub New() - _contextKey = System.Guid.NewGuid.ToString - End Sub - - ''' - ''' Get the object from the correct thread-appropriate location - ''' - Public Property Value() As T 'No SyncLocks required because we are operating upon instance data and the object is not shared across threads - Get - Dim dictionary As IDictionary = GetDictionary() - Return DirectCast(dictionary(_contextKey), T) 'Note, IDictionary(key) can return Nothing and that's OK - End Get - Set(value As T) - Dim dictionary As IDictionary = GetDictionary() - dictionary(_contextKey) = value - End Set - End Property - - Private Shared Function GetDictionary() As IDictionary - If s_threadLocal Is Nothing Then - Interlocked.CompareExchange(s_threadLocal, New ThreadLocal(Of IDictionary)(Function() New Dictionary(Of String, T)), Nothing) - End If - Return s_threadLocal.Value - End Function - - Private ReadOnly _contextKey As String 'An item is stored in the dictionary by a GUID which this string maintains - - Private Shared s_threadLocal As ThreadLocal(Of IDictionary) - - End Class 'ContextValue - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/ProgressDialog.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/ProgressDialog.vb deleted file mode 100644 index c7b97f8f532..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/ProgressDialog.vb +++ /dev/null @@ -1,277 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On - -Imports System.Drawing -Imports System.Globalization -Imports System.Threading -Imports System.Windows.Forms - -Namespace Microsoft.VisualBasic.MyServices.Internal - - ''' - ''' A dialog that shows progress used for Network.Download and Network.Upload - ''' - Friend NotInheritable Class ProgressDialog - Inherits Form - - ''' - ''' Event raised when user cancels the dialog or closes it before the operation is completed - ''' - Public Event UserHitCancel() - - ''' - ''' Constructor - ''' - Friend Sub New() - MyBase.New() - InitializeComponent() - End Sub - - ''' - ''' Increments the progress bar by the passed in amount - ''' - ''' The amount to increment the bar - ''' - ''' This method should never be called directly. It should be called with - ''' an InvokeBegin by a secondary thread. - ''' - Public Sub Increment(incrementAmount As Integer) - ProgressBarWork.Increment(incrementAmount) - End Sub - - ''' - ''' Closes the Progress Dialog - ''' - ''' - ''' This method should never be called directly. It should be called with - ''' an InvokeBegin by a secondary thread. - ''' - Public Sub CloseDialog() - _closeDialogInvoked = True - Close() - End Sub - - ''' - ''' Displays the progress dialog modally - ''' - ''' This method should be called on the main thread after the worker thread has been started - Public Sub ShowProgressDialog() - Try - If Not _closing Then - ShowDialog() - End If - Finally - FormClosableSemaphore.Set() - End Try - End Sub - - ''' - ''' Sets the text of the label (usually something like Copying x to y) - ''' - ''' The value to set the label to - ''' This should only be called on the main thread before showing the dialog - Public Property LabelText() As String - Get - Return LabelInfo.Text - End Get - Set(Value As String) - LabelInfo.Text = Value - End Set - End Property - - ''' - ''' Used to set or get the semaphore which signals when the dialog - ''' is in a closable state. - ''' - ''' The ManualResetEvent - Public ReadOnly Property FormClosableSemaphore() As ManualResetEvent - Get - Return _formClosableSemaphore - End Get - End Property - - ''' - ''' Inform the dialog that CloseDialog will soon be called - ''' - ''' - ''' This method should be called directly from the secondary thread. We want - ''' to indicate we're closing as soon as we can so w don't show the dialog when we - ''' don't need to (when the work is finished before we can show the dialog) - ''' - Public Sub IndicateClosing() - _closing = True - End Sub - - ''' - ''' Indicated if the user has clicked the cancel button - ''' - ''' True if the user has canceled, otherwise False - ''' - ''' The secondary thread checks this property directly. If it's True, the thread - ''' breaks out of its loop. - ''' - Public ReadOnly Property UserCanceledTheDialog() As Boolean - Get - Return _canceled - End Get - End Property - - ''' - ''' This enables a dialog with a close button, sizable borders, and no icon - ''' - Protected Overrides ReadOnly Property CreateParams() As CreateParams - Get - Dim cp As CreateParams = MyBase.CreateParams - cp.Style = cp.Style Or WS_THICKFRAME - Return cp - End Get - End Property - - ''' - ''' Handles user clicking Cancel. Sets a flag read by secondary thread. - ''' - ''' The cancel button - ''' Arguments - Private Sub ButtonCloseDialog_Click(sender As Object, e As EventArgs) Handles ButtonCloseDialog.Click - ButtonCloseDialog.Enabled = False - _canceled = True - RaiseEvent UserHitCancel() - End Sub - - ''' - ''' Indicates the form is closing - ''' - ''' - ''' - ''' - ''' We listen for this event since we want to make closing the dialog before it's - ''' finished behave the same as a cancel - ''' - Private Sub ProgressDialog_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing - If e.CloseReason = CloseReason.UserClosing And Not _closeDialogInvoked Then - ' If the progress bar isn't finished and the user hasn't already canceled - If ProgressBarWork.Value < 100 And Not _canceled Then - ' Cancel the Close since we want the dialog to be closed from a call from the - ' secondary thread - e.Cancel = True - - ' Indicate the user has canceled. We'll actually close the dialog from WebClientCopy - _canceled = True - RaiseEvent UserHitCancel() - End If - End If - End Sub - - ''' - ''' Ensure the label resizes with the dialog - ''' - ''' - ''' - ''' - ''' Since the label has AutoSize set to True we have to set the maximum size so the label - ''' will grow down rather than off the dialog. As the size of the dialog changes, the maximum - ''' size needs to be adjusted. - ''' - Private Sub ProgressDialog_Resize(sender As Object, e As EventArgs) Handles Me.Resize - LabelInfo.MaximumSize = New Size(ClientSize.Width - BORDER_SIZE, 0) - End Sub - - ''' - ''' Exits the monitor when we're activated - ''' - ''' Dialog - ''' Arguments - Private Sub ProgressDialog_Activated(sender As Object, e As EventArgs) Handles Me.Shown - _formClosableSemaphore.Set() - End Sub - - ' Indicates whether or not the dialog is closing - Private _closing As Boolean - - ' Indicates whether or not the user has canceled the copy - Private _canceled As Boolean - - ' Used to signal when the dialog is in a closable state. The dialog is in a closable - ' state when it has been activated or when it has been flagged to be closed before - ' ShowDialog has been called - Private _formClosableSemaphore As ManualResetEvent = New ManualResetEvent(False) - - ' Indicates CloseDialog has been called - Private _closeDialogInvoked As Boolean - - ' Constant used to get re-sizable dialog with border style set to fixed dialog. - Private Const WS_THICKFRAME As Integer = &H40000 - - ' Border area for label (10 pixels on each side) - Private Const BORDER_SIZE As Integer = 20 - -#Region " Windows Form Designer generated code " - - 'Form overrides dispose to clean up the component list. - Protected Overloads Overrides Sub Dispose(disposing As Boolean) - If disposing Then - _components?.Dispose() - If _formClosableSemaphore IsNot Nothing Then - _formClosableSemaphore.Dispose() - _formClosableSemaphore = Nothing - End If - End If - MyBase.Dispose(disposing) - End Sub - Friend WithEvents LabelInfo As Label - Friend WithEvents ProgressBarWork As ProgressBar - Friend WithEvents ButtonCloseDialog As Button - - 'Required by the Windows Form Designer - Private ReadOnly _components As System.ComponentModel.IContainer - - 'NOTE: The following procedure is required by the Windows Form Designer - 'It can be modified using the Windows Form Designer. - 'Do not modify it using the code editor. - - Private Sub InitializeComponent() - Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(ProgressDialog)) - LabelInfo = New Label - ProgressBarWork = New ProgressBar - ButtonCloseDialog = New Button - SuspendLayout() - ' - 'LabelInfo - ' - resources.ApplyResources(LabelInfo, "LabelInfo", CultureInfo.CurrentUICulture) - LabelInfo.MaximumSize = New Size(300, 0) - LabelInfo.Name = "LabelInfo" - ' - 'ProgressBarWork - ' - resources.ApplyResources(ProgressBarWork, "ProgressBarWork", CultureInfo.CurrentUICulture) - ProgressBarWork.Name = "ProgressBarWork" - ' - 'ButtonCloseDialog - ' - resources.ApplyResources(ButtonCloseDialog, "ButtonCloseDialog", CultureInfo.CurrentUICulture) - ButtonCloseDialog.Name = "ButtonCloseDialog" - ' - 'ProgressDialog - ' - resources.ApplyResources(Me, "$this", CultureInfo.CurrentUICulture) - Controls.Add(ButtonCloseDialog) - Controls.Add(ProgressBarWork) - Controls.Add(LabelInfo) - FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog - MaximizeBox = False - MinimizeBox = False - Name = "ProgressDialog" - ShowInTaskbar = False - ResumeLayout(False) - PerformLayout() - - End Sub - -#End Region - - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/WebClientCopy.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/WebClientCopy.vb deleted file mode 100644 index 539204e84a8..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/WebClientCopy.vb +++ /dev/null @@ -1,212 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Option Explicit On -Option Strict On - -Imports System.IO -Imports System.Net -Imports System.Windows.Forms - -Namespace Microsoft.VisualBasic.MyServices.Internal - - ''' - ''' Class that controls the thread that does the actual work of downloading or uploading. - ''' - Friend NotInheritable Class WebClientCopy - - ''' - ''' Creates an instance of a WebClientCopy, used to download or upload a file - ''' - ''' The WebClient used to do the downloading or uploading - ''' UI for indicating progress - Public Sub New(client As WebClient, dialog As ProgressDialog) - - Debug.Assert(client IsNot Nothing, "No WebClient") - - m_WebClient = client - m_ProgressDialog = dialog - - End Sub - - ''' - ''' Downloads a file - ''' - ''' The source for the file - ''' The path and name where the file is saved - Public Sub DownloadFile(address As Uri, destinationFileName As String) - Debug.Assert(m_WebClient IsNot Nothing, "No WebClient") - Debug.Assert(address IsNot Nothing, "No address") - Debug.Assert((Not String.IsNullOrWhiteSpace(destinationFileName)) AndAlso Directory.Exists(Path.GetDirectoryName(Path.GetFullPath(destinationFileName))), "Invalid path") - - ' If we have a dialog we need to set up an async download - If m_ProgressDialog IsNot Nothing Then - m_WebClient.DownloadFileAsync(address, destinationFileName) - m_ProgressDialog.ShowProgressDialog() 'returns when the download sequence is over, whether due to success, error, or being canceled - Else - m_WebClient.DownloadFile(address, destinationFileName) - End If - - 'Now that we are back on the main thread, throw the exception we encountered if the user didn't cancel. - If _exceptionEncounteredDuringFileTransfer IsNot Nothing Then - If m_ProgressDialog Is Nothing OrElse Not m_ProgressDialog.UserCanceledTheDialog Then - Throw _exceptionEncounteredDuringFileTransfer - End If - End If - - End Sub - - ''' - ''' Uploads a file - ''' - ''' The name and path of the source file - ''' The address to which the file is uploaded - Public Sub UploadFile(sourceFileName As String, address As Uri) - Debug.Assert(m_WebClient IsNot Nothing, "No WebClient") - Debug.Assert(address IsNot Nothing, "No address") - Debug.Assert((Not String.IsNullOrWhiteSpace(sourceFileName)) AndAlso File.Exists(sourceFileName), "Invalid file") - - ' If we have a dialog we need to set up an async download - If m_ProgressDialog IsNot Nothing Then - m_WebClient.UploadFileAsync(address, sourceFileName) - m_ProgressDialog.ShowProgressDialog() 'returns when the download sequence is over, whether due to success, error, or being canceled - Else - m_WebClient.UploadFile(address, sourceFileName) - End If - - 'Now that we are back on the main thread, throw the exception we encountered if the user didn't cancel. - If _exceptionEncounteredDuringFileTransfer IsNot Nothing Then - If m_ProgressDialog Is Nothing OrElse Not m_ProgressDialog.UserCanceledTheDialog Then - Throw _exceptionEncounteredDuringFileTransfer - End If - End If - End Sub - - ''' - ''' Notifies the progress dialog to increment the progress bar - ''' - ''' The percentage of bytes read - Private Sub InvokeIncrement(progressPercentage As Integer) - ' Don't invoke unless dialog is up and running - If m_ProgressDialog IsNot Nothing Then - If m_ProgressDialog.IsHandleCreated Then - - ' For performance, don't invoke if increment is 0 - Dim increment As Integer = progressPercentage - _percentage - _percentage = progressPercentage - If increment > 0 Then - m_ProgressDialog.BeginInvoke(New DoIncrement(AddressOf m_ProgressDialog.Increment), increment) - End If - - End If - End If - End Sub - - ''' - ''' Posts a message to close the progress dialog - ''' - Private Sub CloseProgressDialog() - ' Don't invoke unless dialog is up and running - If m_ProgressDialog IsNot Nothing Then - m_ProgressDialog.IndicateClosing() - - If m_ProgressDialog.IsHandleCreated Then - m_ProgressDialog.BeginInvoke(New MethodInvoker(AddressOf m_ProgressDialog.CloseDialog)) - Else - ' Ensure dialog is closed. If we get here it means the file was copied before the handle for - ' the progress dialog was created. - m_ProgressDialog.Close() - End If - End If - End Sub - - ''' - ''' Handles the WebClient's DownloadFileCompleted event - ''' - ''' - ''' - Private Sub m_WebClient_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles m_WebClient.DownloadFileCompleted - Try - ' If the download was interrupted by an exception, keep track of the exception, which we'll throw from the main thread - If e.Error IsNot Nothing Then - _exceptionEncounteredDuringFileTransfer = e.Error - End If - - If Not e.Cancelled AndAlso e.Error Is Nothing Then - InvokeIncrement(100) - End If - Finally - 'We don't close the dialog until we receive the WebClient.DownloadFileCompleted event - CloseProgressDialog() - End Try - End Sub - - ''' - ''' Handles event WebClient fires whenever progress of download changes - ''' - ''' - ''' - Private Sub m_WebClient_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) Handles m_WebClient.DownloadProgressChanged - InvokeIncrement(e.ProgressPercentage) - End Sub - - ''' - ''' Handles the WebClient's UploadFileCompleted event - ''' - ''' - ''' - Private Sub m_WebClient_UploadFileCompleted(sender As Object, e As UploadFileCompletedEventArgs) Handles m_WebClient.UploadFileCompleted - - ' If the upload was interrupted by an exception, keep track of the exception, which we'll throw from the main thread - Try - If e.Error IsNot Nothing Then - _exceptionEncounteredDuringFileTransfer = e.Error - End If - If Not e.Cancelled AndAlso e.Error Is Nothing Then - InvokeIncrement(100) - End If - Finally - 'We don't close the dialog until we receive the WebClient.DownloadFileCompleted event - CloseProgressDialog() - End Try - End Sub - - ''' - ''' Handles event WebClient fires whenever progress of upload changes - ''' - ''' - ''' - Private Sub m_WebClient_UploadProgressChanged(sender As Object, e As UploadProgressChangedEventArgs) Handles m_WebClient.UploadProgressChanged - Dim increment As Long = (e.BytesSent * 100) \ e.TotalBytesToSend - InvokeIncrement(CInt(increment)) - End Sub - - ''' - ''' If the user clicks cancel on the Progress dialog, we need to cancel - ''' the current async file transfer operation - ''' - ''' - ''' Note that we don't want to close the progress dialog here. Wait until - ''' the actual file transfer cancel event comes through and do it there. - ''' - Private Sub m_ProgressDialog_UserCancelledEvent() Handles m_ProgressDialog.UserHitCancel - m_WebClient.CancelAsync() 'cancel the upload/download transfer. We'll close the ProgressDialog as soon as the WebClient cancels the xfer. - End Sub - - ' The WebClient performs the downloading or uploading operations for us - Private WithEvents m_WebClient As WebClient - - ' Dialog shown if user wants to see progress UI. Allows the user to cancel the file transfer. - Private WithEvents m_ProgressDialog As ProgressDialog - - 'Keeps track of the error that happened during upload/download so we can throw it once we can guarantee we are back on the main thread - Private _exceptionEncounteredDuringFileTransfer As Exception - - ' Used for invoking ProgressDialog.Increment - Private Delegate Sub DoIncrement(Increment As Integer) - - ' The percentage of the operation completed - Private _percentage As Integer - - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/RegistryProxy.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/RegistryProxy.vb deleted file mode 100644 index e981b1c5316..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/RegistryProxy.vb +++ /dev/null @@ -1,75 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.ComponentModel -Imports Microsoft.Win32 - -Namespace Microsoft.VisualBasic.MyServices - - ''' - ''' An extremely thin wrapper around Microsoft.Win32.Registry to expose the type through My. - ''' - - Public Class RegistryProxy - - Public ReadOnly Property CurrentUser() As RegistryKey - Get - Return Registry.CurrentUser - End Get - End Property - - Public ReadOnly Property LocalMachine() As RegistryKey - Get - Return Registry.LocalMachine - End Get - End Property - - Public ReadOnly Property ClassesRoot() As RegistryKey - Get - Return Registry.ClassesRoot - End Get - End Property - - Public ReadOnly Property Users() As RegistryKey - Get - Return Registry.Users - End Get - End Property - - Public ReadOnly Property PerformanceData() As RegistryKey - Get - Return Registry.PerformanceData - End Get - End Property - - Public ReadOnly Property CurrentConfig() As RegistryKey - Get - Return Registry.CurrentConfig - End Get - End Property - - Public Function GetValue(keyName As String, valueName As String, - defaultValue As Object) As Object - - Return Registry.GetValue(keyName, valueName, defaultValue) - End Function - - Public Sub SetValue(keyName As String, valueName As String, value As Object) - Registry.SetValue(keyName, valueName, value) - End Sub - - Public Sub SetValue(keyName As String, valueName As String, value As Object, - valueKind As RegistryValueKind) - - Registry.SetValue(keyName, valueName, value, valueKind) - End Sub - - ''' - ''' Proxy class can only created by internal classes. - ''' - Friend Sub New() - End Sub - - End Class -End Namespace - diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/SpecialDirectoriesProxy.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/SpecialDirectoriesProxy.vb deleted file mode 100644 index a28c07a16b3..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/SpecialDirectoriesProxy.vb +++ /dev/null @@ -1,77 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.ComponentModel -Imports Microsoft.VisualBasic.FileIO - -Namespace Microsoft.VisualBasic.MyServices - - ''' - ''' An extremely thin wrapper around Microsoft.VisualBasic.FileIO.SpecialDirectories to expose the type through My. - ''' - - Public Class SpecialDirectoriesProxy - - Public ReadOnly Property MyDocuments() As String - Get - Return SpecialDirectories.MyDocuments - End Get - End Property - - Public ReadOnly Property MyMusic() As String - Get - Return SpecialDirectories.MyMusic - End Get - End Property - - Public ReadOnly Property MyPictures() As String - Get - Return SpecialDirectories.MyPictures - End Get - End Property - - Public ReadOnly Property Desktop() As String - Get - Return SpecialDirectories.Desktop - End Get - End Property - - Public ReadOnly Property Programs() As String - Get - Return SpecialDirectories.Programs - End Get - End Property - - Public ReadOnly Property ProgramFiles() As String - Get - Return SpecialDirectories.ProgramFiles - End Get - End Property - - Public ReadOnly Property Temp() As String - Get - Return SpecialDirectories.Temp - End Get - End Property - - Public ReadOnly Property CurrentUserApplicationData() As String - Get - Return SpecialDirectories.CurrentUserApplicationData - End Get - End Property - - Public ReadOnly Property AllUsersApplicationData() As String - Get - Return SpecialDirectories.AllUsersApplicationData - End Get - End Property - - ''' - ''' Proxy class can only created by internal classes. - ''' - Friend Sub New() - End Sub - - End Class - -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/PublicAPI.Shipped.txt b/src/Microsoft.VisualBasic.Forms/src/PublicAPI.Shipped.txt deleted file mode 100644 index 0e4c9c9b678..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/PublicAPI.Shipped.txt +++ /dev/null @@ -1,380 +0,0 @@ -Microsoft.VisualBasic.ApplicationServices.ApplicationBase -Microsoft.VisualBasic.ApplicationServices.ApplicationBase.ChangeCulture(cultureName As String) -> Void -Microsoft.VisualBasic.ApplicationServices.ApplicationBase.ChangeUICulture(cultureName As String) -> Void -Microsoft.VisualBasic.ApplicationServices.ApplicationBase.Culture() -> System.Globalization.CultureInfo -Microsoft.VisualBasic.ApplicationServices.ApplicationBase.GetEnvironmentVariable(name As String) -> String -Microsoft.VisualBasic.ApplicationServices.ApplicationBase.Info() -> Microsoft.VisualBasic.ApplicationServices.AssemblyInfo -Microsoft.VisualBasic.ApplicationServices.ApplicationBase.Log() -> Microsoft.VisualBasic.Logging.Log -Microsoft.VisualBasic.ApplicationServices.ApplicationBase.New() -> Void -Microsoft.VisualBasic.ApplicationServices.ApplicationBase.UICulture() -> System.Globalization.CultureInfo -Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs -Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.Font() -> System.Drawing.Font -Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.Font(AutoPropertyValue As System.Drawing.Font) -> Void -Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.HighDpiMode() -> System.Windows.Forms.HighDpiMode -Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.HighDpiMode(AutoPropertyValue As System.Windows.Forms.HighDpiMode) -> Void -Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.MinimumSplashScreenDisplayTime() -> Integer -Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.MinimumSplashScreenDisplayTime(AutoPropertyValue As Integer) -> Void -Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventHandler -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.AssemblyName() -> String -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.CompanyName() -> String -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.Copyright() -> String -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.Description() -> String -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.DirectoryPath() -> String -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.LoadedAssemblies() -> System.Collections.ObjectModel.ReadOnlyCollection(Of System.Reflection.Assembly) -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.New(currentAssembly As System.Reflection.Assembly) -> Void -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.ProductName() -> String -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.StackTrace() -> String -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.Title() -> String -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.Trademark() -> String -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.Version() -> System.Version -Microsoft.VisualBasic.ApplicationServices.AssemblyInfo.WorkingSet() -> Long -Microsoft.VisualBasic.ApplicationServices.AuthenticationMode -Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.ApplicationDefined = 1 -> Microsoft.VisualBasic.ApplicationServices.AuthenticationMode -Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows = 0 -> Microsoft.VisualBasic.ApplicationServices.AuthenticationMode -Microsoft.VisualBasic.ApplicationServices.CantStartSingleInstanceException -Microsoft.VisualBasic.ApplicationServices.CantStartSingleInstanceException.New() -> Void -Microsoft.VisualBasic.ApplicationServices.CantStartSingleInstanceException.New(info As System.Runtime.Serialization.SerializationInfo, context As System.Runtime.Serialization.StreamingContext) -> Void -Microsoft.VisualBasic.ApplicationServices.CantStartSingleInstanceException.New(message As String) -> Void -Microsoft.VisualBasic.ApplicationServices.CantStartSingleInstanceException.New(message As String, inner As System.Exception) -> Void -Microsoft.VisualBasic.ApplicationServices.ConsoleApplicationBase -Microsoft.VisualBasic.ApplicationServices.ConsoleApplicationBase.CommandLineArgs() -> System.Collections.ObjectModel.ReadOnlyCollection(Of String) -Microsoft.VisualBasic.ApplicationServices.ConsoleApplicationBase.InternalCommandLine(value As System.Collections.ObjectModel.ReadOnlyCollection(Of String)) -> Void -Microsoft.VisualBasic.ApplicationServices.ConsoleApplicationBase.New() -> Void -Microsoft.VisualBasic.ApplicationServices.NoStartupFormException -Microsoft.VisualBasic.ApplicationServices.NoStartupFormException.New() -> Void -Microsoft.VisualBasic.ApplicationServices.NoStartupFormException.New(info As System.Runtime.Serialization.SerializationInfo, context As System.Runtime.Serialization.StreamingContext) -> Void -Microsoft.VisualBasic.ApplicationServices.NoStartupFormException.New(message As String) -> Void -Microsoft.VisualBasic.ApplicationServices.NoStartupFormException.New(message As String, inner As System.Exception) -> Void -Microsoft.VisualBasic.ApplicationServices.ShutdownEventHandler -Microsoft.VisualBasic.ApplicationServices.ShutdownMode -Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterAllFormsClose = 1 -> Microsoft.VisualBasic.ApplicationServices.ShutdownMode -Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses = 0 -> Microsoft.VisualBasic.ApplicationServices.ShutdownMode -Microsoft.VisualBasic.ApplicationServices.StartupEventArgs -Microsoft.VisualBasic.ApplicationServices.StartupEventArgs.CommandLine() -> System.Collections.ObjectModel.ReadOnlyCollection(Of String) -Microsoft.VisualBasic.ApplicationServices.StartupEventArgs.New(args As System.Collections.ObjectModel.ReadOnlyCollection(Of String)) -> Void -Microsoft.VisualBasic.ApplicationServices.StartupEventHandler -Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs -Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs.BringToForeground() -> Boolean -Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs.BringToForeground(AutoPropertyValue As Boolean) -> Void -Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs.CommandLine() -> System.Collections.ObjectModel.ReadOnlyCollection(Of String) -Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs.New(args As System.Collections.ObjectModel.ReadOnlyCollection(Of String), bringToForegroundFlag As Boolean) -> Void -Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventHandler -Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs -Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs.ExitApplication() -> Boolean -Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs.ExitApplication(AutoPropertyValue As Boolean) -> Void -Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs.New(exitApplication As Boolean, exception As System.Exception) -> Void -Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventHandler -Microsoft.VisualBasic.ApplicationServices.User -Microsoft.VisualBasic.ApplicationServices.User.CurrentPrincipal() -> System.Security.Principal.IPrincipal -Microsoft.VisualBasic.ApplicationServices.User.CurrentPrincipal(value As System.Security.Principal.IPrincipal) -> Void -Microsoft.VisualBasic.ApplicationServices.User.IsAuthenticated() -> Boolean -Microsoft.VisualBasic.ApplicationServices.User.IsInRole(role As String) -> Boolean -Microsoft.VisualBasic.ApplicationServices.User.Name() -> String -Microsoft.VisualBasic.ApplicationServices.User.New() -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.ApplicationContext() -> System.Windows.Forms.ApplicationContext -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.ApplyApplicationDefaults -> Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventHandler -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoEvents() -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.EnableVisualStyles() -> Boolean -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.EnableVisualStyles(value As Boolean) -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.HideSplashScreen() -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.HighDpiMode() -> System.Windows.Forms.HighDpiMode -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.HighDpiMode(value As System.Windows.Forms.HighDpiMode) -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.IsSingleInstance() -> Boolean -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.IsSingleInstance(value As Boolean) -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.MainForm() -> System.Windows.Forms.Form -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.MainForm(value As System.Windows.Forms.Form) -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.MinimumSplashScreenDisplayTime() -> Integer -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.MinimumSplashScreenDisplayTime(value As Integer) -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.NetworkAvailabilityChanged -> Microsoft.VisualBasic.Devices.NetworkAvailableEventHandler -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.New() -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.New(authenticationMode As Microsoft.VisualBasic.ApplicationServices.AuthenticationMode) -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OpenForms() -> System.Windows.Forms.FormCollection -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(commandLine As String()) -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.SaveMySettingsOnExit() -> Boolean -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.SaveMySettingsOnExit(value As Boolean) -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.ShowSplashScreen() -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Shutdown -> Microsoft.VisualBasic.ApplicationServices.ShutdownEventHandler -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.ShutdownStyle() -> Microsoft.VisualBasic.ApplicationServices.ShutdownMode -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.ShutdownStyle(value As Microsoft.VisualBasic.ApplicationServices.ShutdownMode) -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.SplashScreen() -> System.Windows.Forms.Form -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.SplashScreen(value As System.Windows.Forms.Form) -> Void -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Startup -> Microsoft.VisualBasic.ApplicationServices.StartupEventHandler -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.StartupNextInstance -> Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventHandler -Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.UnhandledException -> Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventHandler -Microsoft.VisualBasic.AudioPlayMode -Microsoft.VisualBasic.AudioPlayMode.Background = 1 -> Microsoft.VisualBasic.AudioPlayMode -Microsoft.VisualBasic.AudioPlayMode.BackgroundLoop = 2 -> Microsoft.VisualBasic.AudioPlayMode -Microsoft.VisualBasic.AudioPlayMode.WaitToComplete = 0 -> Microsoft.VisualBasic.AudioPlayMode -Microsoft.VisualBasic.CompilerServices.HostServices -Microsoft.VisualBasic.CompilerServices.HostServices.New() -> Void -Microsoft.VisualBasic.CompilerServices.IVbHost -Microsoft.VisualBasic.CompilerServices.IVbHost.GetParentWindow() -> System.Windows.Forms.IWin32Window -Microsoft.VisualBasic.CompilerServices.IVbHost.GetWindowTitle() -> String -Microsoft.VisualBasic.Devices.Audio -Microsoft.VisualBasic.Devices.Audio.New() -> Void -Microsoft.VisualBasic.Devices.Audio.Play(data As Byte(), playMode As Microsoft.VisualBasic.AudioPlayMode) -> Void -Microsoft.VisualBasic.Devices.Audio.Play(location As String) -> Void -Microsoft.VisualBasic.Devices.Audio.Play(location As String, playMode As Microsoft.VisualBasic.AudioPlayMode) -> Void -Microsoft.VisualBasic.Devices.Audio.Play(stream As System.IO.Stream, playMode As Microsoft.VisualBasic.AudioPlayMode) -> Void -Microsoft.VisualBasic.Devices.Audio.PlaySystemSound(systemSound As System.Media.SystemSound) -> Void -Microsoft.VisualBasic.Devices.Audio.Stop() -> Void -Microsoft.VisualBasic.Devices.Clock -Microsoft.VisualBasic.Devices.Clock.GmtTime() -> Date -Microsoft.VisualBasic.Devices.Clock.LocalTime() -> Date -Microsoft.VisualBasic.Devices.Clock.New() -> Void -Microsoft.VisualBasic.Devices.Clock.TickCount() -> Integer -Microsoft.VisualBasic.Devices.Computer -Microsoft.VisualBasic.Devices.Computer.Audio() -> Microsoft.VisualBasic.Devices.Audio -Microsoft.VisualBasic.Devices.Computer.Clipboard() -> Microsoft.VisualBasic.MyServices.ClipboardProxy -Microsoft.VisualBasic.Devices.Computer.Keyboard() -> Microsoft.VisualBasic.Devices.Keyboard -Microsoft.VisualBasic.Devices.Computer.Mouse() -> Microsoft.VisualBasic.Devices.Mouse -Microsoft.VisualBasic.Devices.Computer.New() -> Void -Microsoft.VisualBasic.Devices.Computer.Screen() -> System.Windows.Forms.Screen -Microsoft.VisualBasic.Devices.ComputerInfo -Microsoft.VisualBasic.Devices.ComputerInfo.AvailablePhysicalMemory() -> ULong -Microsoft.VisualBasic.Devices.ComputerInfo.AvailableVirtualMemory() -> ULong -Microsoft.VisualBasic.Devices.ComputerInfo.InstalledUICulture() -> System.Globalization.CultureInfo -Microsoft.VisualBasic.Devices.ComputerInfo.New() -> Void -Microsoft.VisualBasic.Devices.ComputerInfo.OSFullName() -> String -Microsoft.VisualBasic.Devices.ComputerInfo.OSPlatform() -> String -Microsoft.VisualBasic.Devices.ComputerInfo.OSVersion() -> String -Microsoft.VisualBasic.Devices.ComputerInfo.TotalPhysicalMemory() -> ULong -Microsoft.VisualBasic.Devices.ComputerInfo.TotalVirtualMemory() -> ULong -Microsoft.VisualBasic.Devices.Keyboard -Microsoft.VisualBasic.Devices.Keyboard.AltKeyDown() -> Boolean -Microsoft.VisualBasic.Devices.Keyboard.CapsLock() -> Boolean -Microsoft.VisualBasic.Devices.Keyboard.CtrlKeyDown() -> Boolean -Microsoft.VisualBasic.Devices.Keyboard.New() -> Void -Microsoft.VisualBasic.Devices.Keyboard.NumLock() -> Boolean -Microsoft.VisualBasic.Devices.Keyboard.ScrollLock() -> Boolean -Microsoft.VisualBasic.Devices.Keyboard.SendKeys(keys As String) -> Void -Microsoft.VisualBasic.Devices.Keyboard.SendKeys(keys As String, wait As Boolean) -> Void -Microsoft.VisualBasic.Devices.Keyboard.ShiftKeyDown() -> Boolean -Microsoft.VisualBasic.Devices.Mouse -Microsoft.VisualBasic.Devices.Mouse.ButtonsSwapped() -> Boolean -Microsoft.VisualBasic.Devices.Mouse.New() -> Void -Microsoft.VisualBasic.Devices.Mouse.WheelExists() -> Boolean -Microsoft.VisualBasic.Devices.Mouse.WheelScrollLines() -> Integer -Microsoft.VisualBasic.Devices.Network -Microsoft.VisualBasic.Devices.Network.DownloadFile(address As String, destinationFileName As String) -> Void -Microsoft.VisualBasic.Devices.Network.DownloadFile(address As String, destinationFileName As String, userName As String, password As String) -> Void -Microsoft.VisualBasic.Devices.Network.DownloadFile(address As String, destinationFileName As String, userName As String, password As String, showUI As Boolean, connectionTimeout As Integer, overwrite As Boolean) -> Void -Microsoft.VisualBasic.Devices.Network.DownloadFile(address As String, destinationFileName As String, userName As String, password As String, showUI As Boolean, connectionTimeout As Integer, overwrite As Boolean, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.Devices.Network.DownloadFile(address As System.Uri, destinationFileName As String) -> Void -Microsoft.VisualBasic.Devices.Network.DownloadFile(address As System.Uri, destinationFileName As String, networkCredentials As System.Net.ICredentials, showUI As Boolean, connectionTimeout As Integer, overwrite As Boolean) -> Void -Microsoft.VisualBasic.Devices.Network.DownloadFile(address As System.Uri, destinationFileName As String, networkCredentials As System.Net.ICredentials, showUI As Boolean, connectionTimeout As Integer, overwrite As Boolean, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.Devices.Network.DownloadFile(address As System.Uri, destinationFileName As String, userName As String, password As String) -> Void -Microsoft.VisualBasic.Devices.Network.DownloadFile(address As System.Uri, destinationFileName As String, userName As String, password As String, showUI As Boolean, connectionTimeout As Integer, overwrite As Boolean) -> Void -Microsoft.VisualBasic.Devices.Network.DownloadFile(address As System.Uri, destinationFileName As String, userName As String, password As String, showUI As Boolean, connectionTimeout As Integer, overwrite As Boolean, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.Devices.Network.IsAvailable() -> Boolean -Microsoft.VisualBasic.Devices.Network.NetworkAvailabilityChanged -> Microsoft.VisualBasic.Devices.NetworkAvailableEventHandler -Microsoft.VisualBasic.Devices.Network.New() -> Void -Microsoft.VisualBasic.Devices.Network.Ping(address As System.Uri) -> Boolean -Microsoft.VisualBasic.Devices.Network.Ping(address As System.Uri, timeout As Integer) -> Boolean -Microsoft.VisualBasic.Devices.Network.Ping(hostNameOrAddress As String) -> Boolean -Microsoft.VisualBasic.Devices.Network.Ping(hostNameOrAddress As String, timeout As Integer) -> Boolean -Microsoft.VisualBasic.Devices.Network.UploadFile(sourceFileName As String, address As String) -> Void -Microsoft.VisualBasic.Devices.Network.UploadFile(sourceFileName As String, address As String, userName As String, password As String) -> Void -Microsoft.VisualBasic.Devices.Network.UploadFile(sourceFileName As String, address As String, userName As String, password As String, showUI As Boolean, connectionTimeout As Integer) -> Void -Microsoft.VisualBasic.Devices.Network.UploadFile(sourceFileName As String, address As String, userName As String, password As String, showUI As Boolean, connectionTimeout As Integer, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.Devices.Network.UploadFile(sourceFileName As String, address As System.Uri) -> Void -Microsoft.VisualBasic.Devices.Network.UploadFile(sourceFileName As String, address As System.Uri, networkCredentials As System.Net.ICredentials, showUI As Boolean, connectionTimeout As Integer) -> Void -Microsoft.VisualBasic.Devices.Network.UploadFile(sourceFileName As String, address As System.Uri, networkCredentials As System.Net.ICredentials, showUI As Boolean, connectionTimeout As Integer, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.Devices.Network.UploadFile(sourceFileName As String, address As System.Uri, userName As String, password As String) -> Void -Microsoft.VisualBasic.Devices.Network.UploadFile(sourceFileName As String, address As System.Uri, userName As String, password As String, showUI As Boolean, connectionTimeout As Integer) -> Void -Microsoft.VisualBasic.Devices.Network.UploadFile(sourceFileName As String, address As System.Uri, userName As String, password As String, showUI As Boolean, connectionTimeout As Integer, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.Devices.NetworkAvailableEventArgs -Microsoft.VisualBasic.Devices.NetworkAvailableEventArgs.IsNetworkAvailable() -> Boolean -Microsoft.VisualBasic.Devices.NetworkAvailableEventArgs.New(networkAvailable As Boolean) -> Void -Microsoft.VisualBasic.Devices.NetworkAvailableEventHandler -Microsoft.VisualBasic.Devices.ServerComputer -Microsoft.VisualBasic.Devices.ServerComputer.Clock() -> Microsoft.VisualBasic.Devices.Clock -Microsoft.VisualBasic.Devices.ServerComputer.FileSystem() -> Microsoft.VisualBasic.MyServices.FileSystemProxy -Microsoft.VisualBasic.Devices.ServerComputer.Info() -> Microsoft.VisualBasic.Devices.ComputerInfo -Microsoft.VisualBasic.Devices.ServerComputer.Name() -> String -Microsoft.VisualBasic.Devices.ServerComputer.Network() -> Microsoft.VisualBasic.Devices.Network -Microsoft.VisualBasic.Devices.ServerComputer.New() -> Void -Microsoft.VisualBasic.Devices.ServerComputer.Registry() -> Microsoft.VisualBasic.MyServices.RegistryProxy -Microsoft.VisualBasic.Logging.DiskSpaceExhaustedOption -Microsoft.VisualBasic.Logging.DiskSpaceExhaustedOption.DiscardMessages = 1 -> Microsoft.VisualBasic.Logging.DiskSpaceExhaustedOption -Microsoft.VisualBasic.Logging.DiskSpaceExhaustedOption.ThrowException = 0 -> Microsoft.VisualBasic.Logging.DiskSpaceExhaustedOption -Microsoft.VisualBasic.Logging.FileLogTraceListener -Microsoft.VisualBasic.Logging.FileLogTraceListener.Append() -> Boolean -Microsoft.VisualBasic.Logging.FileLogTraceListener.Append(value As Boolean) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.AutoFlush() -> Boolean -Microsoft.VisualBasic.Logging.FileLogTraceListener.AutoFlush(value As Boolean) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.BaseFileName() -> String -Microsoft.VisualBasic.Logging.FileLogTraceListener.BaseFileName(value As String) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.CustomLocation() -> String -Microsoft.VisualBasic.Logging.FileLogTraceListener.CustomLocation(value As String) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.Delimiter() -> String -Microsoft.VisualBasic.Logging.FileLogTraceListener.Delimiter(value As String) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.DiskSpaceExhaustedBehavior() -> Microsoft.VisualBasic.Logging.DiskSpaceExhaustedOption -Microsoft.VisualBasic.Logging.FileLogTraceListener.DiskSpaceExhaustedBehavior(value As Microsoft.VisualBasic.Logging.DiskSpaceExhaustedOption) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.Encoding() -> System.Text.Encoding -Microsoft.VisualBasic.Logging.FileLogTraceListener.Encoding(value As System.Text.Encoding) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.FullLogFileName() -> String -Microsoft.VisualBasic.Logging.FileLogTraceListener.IncludeHostName() -> Boolean -Microsoft.VisualBasic.Logging.FileLogTraceListener.IncludeHostName(value As Boolean) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.Location() -> Microsoft.VisualBasic.Logging.LogFileLocation -Microsoft.VisualBasic.Logging.FileLogTraceListener.Location(value As Microsoft.VisualBasic.Logging.LogFileLocation) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.LogFileCreationSchedule() -> Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption -Microsoft.VisualBasic.Logging.FileLogTraceListener.LogFileCreationSchedule(value As Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.MaxFileSize() -> Long -Microsoft.VisualBasic.Logging.FileLogTraceListener.MaxFileSize(value As Long) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.New() -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.New(name As String) -> Void -Microsoft.VisualBasic.Logging.FileLogTraceListener.ReserveDiskSpace() -> Long -Microsoft.VisualBasic.Logging.FileLogTraceListener.ReserveDiskSpace(value As Long) -> Void -Microsoft.VisualBasic.Logging.Log -Microsoft.VisualBasic.Logging.Log.DefaultFileLogWriter() -> Microsoft.VisualBasic.Logging.FileLogTraceListener -Microsoft.VisualBasic.Logging.Log.New() -> Void -Microsoft.VisualBasic.Logging.Log.New(name As String) -> Void -Microsoft.VisualBasic.Logging.Log.TraceSource() -> System.Diagnostics.TraceSource -Microsoft.VisualBasic.Logging.Log.WriteEntry(message As String) -> Void -Microsoft.VisualBasic.Logging.Log.WriteEntry(message As String, severity As System.Diagnostics.TraceEventType) -> Void -Microsoft.VisualBasic.Logging.Log.WriteEntry(message As String, severity As System.Diagnostics.TraceEventType, id As Integer) -> Void -Microsoft.VisualBasic.Logging.Log.WriteException(ex As System.Exception) -> Void -Microsoft.VisualBasic.Logging.Log.WriteException(ex As System.Exception, severity As System.Diagnostics.TraceEventType, additionalInfo As String) -> Void -Microsoft.VisualBasic.Logging.Log.WriteException(ex As System.Exception, severity As System.Diagnostics.TraceEventType, additionalInfo As String, id As Integer) -> Void -Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption -Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption.Daily = 1 -> Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption -Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption.None = 0 -> Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption -Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption.Weekly = 2 -> Microsoft.VisualBasic.Logging.LogFileCreationScheduleOption -Microsoft.VisualBasic.Logging.LogFileLocation -Microsoft.VisualBasic.Logging.LogFileLocation.CommonApplicationDirectory = 2 -> Microsoft.VisualBasic.Logging.LogFileLocation -Microsoft.VisualBasic.Logging.LogFileLocation.Custom = 4 -> Microsoft.VisualBasic.Logging.LogFileLocation -Microsoft.VisualBasic.Logging.LogFileLocation.ExecutableDirectory = 3 -> Microsoft.VisualBasic.Logging.LogFileLocation -Microsoft.VisualBasic.Logging.LogFileLocation.LocalUserApplicationDirectory = 1 -> Microsoft.VisualBasic.Logging.LogFileLocation -Microsoft.VisualBasic.Logging.LogFileLocation.TempDirectory = 0 -> Microsoft.VisualBasic.Logging.LogFileLocation -Microsoft.VisualBasic.MyServices.ClipboardProxy -Microsoft.VisualBasic.MyServices.ClipboardProxy.Clear() -> Void -Microsoft.VisualBasic.MyServices.ClipboardProxy.ContainsAudio() -> Boolean -Microsoft.VisualBasic.MyServices.ClipboardProxy.ContainsData(format As String) -> Boolean -Microsoft.VisualBasic.MyServices.ClipboardProxy.ContainsFileDropList() -> Boolean -Microsoft.VisualBasic.MyServices.ClipboardProxy.ContainsImage() -> Boolean -Microsoft.VisualBasic.MyServices.ClipboardProxy.ContainsText() -> Boolean -Microsoft.VisualBasic.MyServices.ClipboardProxy.ContainsText(format As System.Windows.Forms.TextDataFormat) -> Boolean -Microsoft.VisualBasic.MyServices.ClipboardProxy.GetAudioStream() -> System.IO.Stream -Microsoft.VisualBasic.MyServices.ClipboardProxy.GetData(format As String) -> Object -Microsoft.VisualBasic.MyServices.ClipboardProxy.GetDataObject() -> System.Windows.Forms.IDataObject -Microsoft.VisualBasic.MyServices.ClipboardProxy.GetFileDropList() -> System.Collections.Specialized.StringCollection -Microsoft.VisualBasic.MyServices.ClipboardProxy.GetImage() -> System.Drawing.Image -Microsoft.VisualBasic.MyServices.ClipboardProxy.GetText() -> String -Microsoft.VisualBasic.MyServices.ClipboardProxy.GetText(format As System.Windows.Forms.TextDataFormat) -> String -Microsoft.VisualBasic.MyServices.ClipboardProxy.SetAudio(audioBytes As Byte()) -> Void -Microsoft.VisualBasic.MyServices.ClipboardProxy.SetAudio(audioStream As System.IO.Stream) -> Void -Microsoft.VisualBasic.MyServices.ClipboardProxy.SetData(format As String, data As Object) -> Void -Microsoft.VisualBasic.MyServices.ClipboardProxy.SetDataObject(data As System.Windows.Forms.DataObject) -> Void -Microsoft.VisualBasic.MyServices.ClipboardProxy.SetFileDropList(filePaths As System.Collections.Specialized.StringCollection) -> Void -Microsoft.VisualBasic.MyServices.ClipboardProxy.SetImage(image As System.Drawing.Image) -> Void -Microsoft.VisualBasic.MyServices.ClipboardProxy.SetText(text As String) -> Void -Microsoft.VisualBasic.MyServices.ClipboardProxy.SetText(text As String, format As System.Windows.Forms.TextDataFormat) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy -Microsoft.VisualBasic.MyServices.FileSystemProxy.CombinePath(baseDirectory As String, relativePath As String) -> String -Microsoft.VisualBasic.MyServices.FileSystemProxy.CopyDirectory(sourceDirectoryName As String, destinationDirectoryName As String) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.CopyDirectory(sourceDirectoryName As String, destinationDirectoryName As String, overwrite As Boolean) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.CopyDirectory(sourceDirectoryName As String, destinationDirectoryName As String, showUI As Microsoft.VisualBasic.FileIO.UIOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.CopyDirectory(sourceDirectoryName As String, destinationDirectoryName As String, showUI As Microsoft.VisualBasic.FileIO.UIOption, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.CopyFile(sourceFileName As String, destinationFileName As String) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.CopyFile(sourceFileName As String, destinationFileName As String, overwrite As Boolean) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.CopyFile(sourceFileName As String, destinationFileName As String, showUI As Microsoft.VisualBasic.FileIO.UIOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.CopyFile(sourceFileName As String, destinationFileName As String, showUI As Microsoft.VisualBasic.FileIO.UIOption, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.CreateDirectory(directory As String) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.CurrentDirectory() -> String -Microsoft.VisualBasic.MyServices.FileSystemProxy.CurrentDirectory(value As String) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.DeleteDirectory(directory As String, onDirectoryNotEmpty As Microsoft.VisualBasic.FileIO.DeleteDirectoryOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.DeleteDirectory(directory As String, showUI As Microsoft.VisualBasic.FileIO.UIOption, recycle As Microsoft.VisualBasic.FileIO.RecycleOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.DeleteDirectory(directory As String, showUI As Microsoft.VisualBasic.FileIO.UIOption, recycle As Microsoft.VisualBasic.FileIO.RecycleOption, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.DeleteFile(file As String) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.DeleteFile(file As String, showUI As Microsoft.VisualBasic.FileIO.UIOption, recycle As Microsoft.VisualBasic.FileIO.RecycleOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.DeleteFile(file As String, showUI As Microsoft.VisualBasic.FileIO.UIOption, recycle As Microsoft.VisualBasic.FileIO.RecycleOption, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.DirectoryExists(directory As String) -> Boolean -Microsoft.VisualBasic.MyServices.FileSystemProxy.Drives() -> System.Collections.ObjectModel.ReadOnlyCollection(Of System.IO.DriveInfo) -Microsoft.VisualBasic.MyServices.FileSystemProxy.FileExists(file As String) -> Boolean -Microsoft.VisualBasic.MyServices.FileSystemProxy.FindInFiles(directory As String, containsText As String, ignoreCase As Boolean, searchType As Microsoft.VisualBasic.FileIO.SearchOption) -> System.Collections.ObjectModel.ReadOnlyCollection(Of String) -Microsoft.VisualBasic.MyServices.FileSystemProxy.FindInFiles(directory As String, containsText As String, ignoreCase As Boolean, searchType As Microsoft.VisualBasic.FileIO.SearchOption, ParamArray fileWildcards As String()) -> System.Collections.ObjectModel.ReadOnlyCollection(Of String) -Microsoft.VisualBasic.MyServices.FileSystemProxy.GetDirectories(directory As String) -> System.Collections.ObjectModel.ReadOnlyCollection(Of String) -Microsoft.VisualBasic.MyServices.FileSystemProxy.GetDirectories(directory As String, searchType As Microsoft.VisualBasic.FileIO.SearchOption, ParamArray wildcards As String()) -> System.Collections.ObjectModel.ReadOnlyCollection(Of String) -Microsoft.VisualBasic.MyServices.FileSystemProxy.GetDirectoryInfo(directory As String) -> System.IO.DirectoryInfo -Microsoft.VisualBasic.MyServices.FileSystemProxy.GetDriveInfo(drive As String) -> System.IO.DriveInfo -Microsoft.VisualBasic.MyServices.FileSystemProxy.GetFileInfo(file As String) -> System.IO.FileInfo -Microsoft.VisualBasic.MyServices.FileSystemProxy.GetFiles(directory As String) -> System.Collections.ObjectModel.ReadOnlyCollection(Of String) -Microsoft.VisualBasic.MyServices.FileSystemProxy.GetFiles(directory As String, searchType As Microsoft.VisualBasic.FileIO.SearchOption, ParamArray wildcards As String()) -> System.Collections.ObjectModel.ReadOnlyCollection(Of String) -Microsoft.VisualBasic.MyServices.FileSystemProxy.GetName(path As String) -> String -Microsoft.VisualBasic.MyServices.FileSystemProxy.GetParentPath(path As String) -> String -Microsoft.VisualBasic.MyServices.FileSystemProxy.GetTempFileName() -> String -Microsoft.VisualBasic.MyServices.FileSystemProxy.MoveDirectory(sourceDirectoryName As String, destinationDirectoryName As String) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.MoveDirectory(sourceDirectoryName As String, destinationDirectoryName As String, overwrite As Boolean) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.MoveDirectory(sourceDirectoryName As String, destinationDirectoryName As String, showUI As Microsoft.VisualBasic.FileIO.UIOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.MoveDirectory(sourceDirectoryName As String, destinationDirectoryName As String, showUI As Microsoft.VisualBasic.FileIO.UIOption, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.MoveFile(sourceFileName As String, destinationFileName As String) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.MoveFile(sourceFileName As String, destinationFileName As String, overwrite As Boolean) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.MoveFile(sourceFileName As String, destinationFileName As String, showUI As Microsoft.VisualBasic.FileIO.UIOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.MoveFile(sourceFileName As String, destinationFileName As String, showUI As Microsoft.VisualBasic.FileIO.UIOption, onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.OpenTextFieldParser(file As String) -> Microsoft.VisualBasic.FileIO.TextFieldParser -Microsoft.VisualBasic.MyServices.FileSystemProxy.OpenTextFieldParser(file As String, ParamArray delimiters As String()) -> Microsoft.VisualBasic.FileIO.TextFieldParser -Microsoft.VisualBasic.MyServices.FileSystemProxy.OpenTextFieldParser(file As String, ParamArray fieldWidths As Integer()) -> Microsoft.VisualBasic.FileIO.TextFieldParser -Microsoft.VisualBasic.MyServices.FileSystemProxy.OpenTextFileReader(file As String) -> System.IO.StreamReader -Microsoft.VisualBasic.MyServices.FileSystemProxy.OpenTextFileReader(file As String, encoding As System.Text.Encoding) -> System.IO.StreamReader -Microsoft.VisualBasic.MyServices.FileSystemProxy.OpenTextFileWriter(file As String, append As Boolean) -> System.IO.StreamWriter -Microsoft.VisualBasic.MyServices.FileSystemProxy.OpenTextFileWriter(file As String, append As Boolean, encoding As System.Text.Encoding) -> System.IO.StreamWriter -Microsoft.VisualBasic.MyServices.FileSystemProxy.ReadAllBytes(file As String) -> Byte() -Microsoft.VisualBasic.MyServices.FileSystemProxy.ReadAllText(file As String) -> String -Microsoft.VisualBasic.MyServices.FileSystemProxy.ReadAllText(file As String, encoding As System.Text.Encoding) -> String -Microsoft.VisualBasic.MyServices.FileSystemProxy.RenameDirectory(directory As String, newName As String) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.RenameFile(file As String, newName As String) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.SpecialDirectories() -> Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy -Microsoft.VisualBasic.MyServices.FileSystemProxy.WriteAllBytes(file As String, data As Byte(), append As Boolean) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.WriteAllText(file As String, text As String, append As Boolean) -> Void -Microsoft.VisualBasic.MyServices.FileSystemProxy.WriteAllText(file As String, text As String, append As Boolean, encoding As System.Text.Encoding) -> Void -Microsoft.VisualBasic.MyServices.Internal.ContextValue(Of T) -Microsoft.VisualBasic.MyServices.Internal.ContextValue(Of T).New() -> Void -Microsoft.VisualBasic.MyServices.Internal.ContextValue(Of T).Value() -> T -Microsoft.VisualBasic.MyServices.Internal.ContextValue(Of T).Value(value As T) -> Void -Microsoft.VisualBasic.MyServices.RegistryProxy -Microsoft.VisualBasic.MyServices.RegistryProxy.ClassesRoot() -> Microsoft.Win32.RegistryKey -Microsoft.VisualBasic.MyServices.RegistryProxy.CurrentConfig() -> Microsoft.Win32.RegistryKey -Microsoft.VisualBasic.MyServices.RegistryProxy.CurrentUser() -> Microsoft.Win32.RegistryKey -Microsoft.VisualBasic.MyServices.RegistryProxy.GetValue(keyName As String, valueName As String, defaultValue As Object) -> Object -Microsoft.VisualBasic.MyServices.RegistryProxy.LocalMachine() -> Microsoft.Win32.RegistryKey -Microsoft.VisualBasic.MyServices.RegistryProxy.PerformanceData() -> Microsoft.Win32.RegistryKey -Microsoft.VisualBasic.MyServices.RegistryProxy.SetValue(keyName As String, valueName As String, value As Object) -> Void -Microsoft.VisualBasic.MyServices.RegistryProxy.SetValue(keyName As String, valueName As String, value As Object, valueKind As Microsoft.Win32.RegistryValueKind) -> Void -Microsoft.VisualBasic.MyServices.RegistryProxy.Users() -> Microsoft.Win32.RegistryKey -Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy -Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy.AllUsersApplicationData() -> String -Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy.CurrentUserApplicationData() -> String -Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy.Desktop() -> String -Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy.MyDocuments() -> String -Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy.MyMusic() -> String -Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy.MyPictures() -> String -Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy.ProgramFiles() -> String -Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy.Programs() -> String -Microsoft.VisualBasic.MyServices.SpecialDirectoriesProxy.Temp() -> String -Overridable Microsoft.VisualBasic.ApplicationServices.User.InternalPrincipal() -> System.Security.Principal.IPrincipal -Overridable Microsoft.VisualBasic.ApplicationServices.User.InternalPrincipal(value As System.Security.Principal.IPrincipal) -> Void -Overridable Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnCreateMainForm() -> Void -Overridable Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnCreateSplashScreen() -> Void -Overridable Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnInitialize(commandLineArgs As System.Collections.ObjectModel.ReadOnlyCollection(Of String)) -> Boolean -Overridable Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() -> Void -Overridable Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnShutdown() -> Void -Overridable Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnStartup(eventArgs As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) -> Boolean -Overridable Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnStartupNextInstance(eventArgs As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) -> Void -Overridable Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnUnhandledException(e As Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) -> Boolean -Overridable Microsoft.VisualBasic.Logging.Log.InitializeWithDefaultsSinceNoConfigExists() -> Void -Overrides Microsoft.VisualBasic.Logging.FileLogTraceListener.Close() -> Void -Overrides Microsoft.VisualBasic.Logging.FileLogTraceListener.Dispose(disposing As Boolean) -> Void -Overrides Microsoft.VisualBasic.Logging.FileLogTraceListener.Flush() -> Void -Overrides Microsoft.VisualBasic.Logging.FileLogTraceListener.GetSupportedAttributes() -> String() -Overrides Microsoft.VisualBasic.Logging.FileLogTraceListener.TraceData(eventCache As System.Diagnostics.TraceEventCache, source As String, eventType As System.Diagnostics.TraceEventType, id As Integer, data As Object) -> Void -Overrides Microsoft.VisualBasic.Logging.FileLogTraceListener.TraceData(eventCache As System.Diagnostics.TraceEventCache, source As String, eventType As System.Diagnostics.TraceEventType, id As Integer, ParamArray data As Object()) -> Void -Overrides Microsoft.VisualBasic.Logging.FileLogTraceListener.TraceEvent(eventCache As System.Diagnostics.TraceEventCache, source As String, eventType As System.Diagnostics.TraceEventType, id As Integer, format As String, ParamArray args As Object()) -> Void -Overrides Microsoft.VisualBasic.Logging.FileLogTraceListener.TraceEvent(eventCache As System.Diagnostics.TraceEventCache, source As String, eventType As System.Diagnostics.TraceEventType, id As Integer, message As String) -> Void -Overrides Microsoft.VisualBasic.Logging.FileLogTraceListener.Write(message As String) -> Void -Overrides Microsoft.VisualBasic.Logging.FileLogTraceListener.WriteLine(message As String) -> Void -Shared Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.UseCompatibleTextRendering() -> Boolean -Shared Microsoft.VisualBasic.CompilerServices.HostServices.VBHost() -> Microsoft.VisualBasic.CompilerServices.IVbHost -Shared Microsoft.VisualBasic.CompilerServices.HostServices.VBHost(Value As Microsoft.VisualBasic.CompilerServices.IVbHost) -> Void diff --git a/src/Microsoft.VisualBasic.Forms/src/PublicAPI.Unshipped.txt b/src/Microsoft.VisualBasic.Forms/src/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/VBInputBox.resx b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/VBInputBox.resx deleted file mode 100644 index 09f45adb611..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/VBInputBox.resx +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Assembly - - - - - 290, 12 - - - - 60, 22 - - - - - 2 - - - - OK - - - OKButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - Assembly - - - - 290, 40 - - - - 60, 22 - - - - 3 - - - - Cancel - - - MyCancelButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - Assembly - - - - 10, 90 - - - - 335, 20 - - - - 0 - - - - TextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - Assembly - - - - 10, 10 - - - - 250, 70 - - - - 1 - - - - Label - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - - 5, 13 - - - - 353, 120 - - - - VBInputBox - - - System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - # - - - # - - diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.cs.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.cs.xlf deleted file mode 100644 index 1595dc80b9b..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.cs.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - Počet - - - - # - Počet - - - - Cancel - Storno - - - - OK - OK - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.de.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.de.xlf deleted file mode 100644 index 09475693772..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.de.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - Abbrechen - - - - OK - OK - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.es.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.es.xlf deleted file mode 100644 index e3e0a82d4f4..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.es.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - Cancelar - - - - OK - Aceptar - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.fr.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.fr.xlf deleted file mode 100644 index 68325a22abf..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.fr.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - Annuler - - - - OK - OK - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.it.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.it.xlf deleted file mode 100644 index 6a1faa9c4a0..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.it.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - Annulla - - - - OK - OK - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.ja.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.ja.xlf deleted file mode 100644 index 443ddf1b5dd..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.ja.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - キャンセル - - - - OK - OK - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.ko.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.ko.xlf deleted file mode 100644 index db627da614c..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.ko.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - 취소 - - - - OK - 확인 - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.pl.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.pl.xlf deleted file mode 100644 index 844f80b32c1..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.pl.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - Anuluj - - - - OK - OK - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.pt-BR.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.pt-BR.xlf deleted file mode 100644 index 49bd9d75d52..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.pt-BR.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - Cancelar - - - - OK - OK - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.ru.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.ru.xlf deleted file mode 100644 index 2b53f680dda..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.ru.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - - - - - # - - - - - Cancel - Отмена - - - - OK - ОК - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.tr.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.tr.xlf deleted file mode 100644 index 86996f05dae..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.tr.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - İptal - - - - OK - Tamam - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.zh-Hans.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.zh-Hans.xlf deleted file mode 100644 index 5de0b4812e9..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.zh-Hans.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - 取消 - - - - OK - 确定 - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.zh-Hant.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.zh-Hant.xlf deleted file mode 100644 index 401c9857792..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/CompilerServices/xlf/VBInputBox.zh-Hant.xlf +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - # - # - - - - # - # - - - - Cancel - 取消 - - - - OK - 確定 - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/ProgressDialog.resx b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/ProgressDialog.resx deleted file mode 100644 index f7a3ca9ebda..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/ProgressDialog.resx +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Top, Left, Right - - - - True - - - - 10, 23 - - - 350, 39 - - - 0 - - - Progress Dialog - - - LabelInfo - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - Top, Left, Right - - - 10, 78 - - - 268, 12 - - - 1 - - - ProgressBarWork - - - System.Windows.Forms.ProgressBar, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Top, Right - - - True - - - 286, 78 - - - 2 - - - &Cancel - - - ButtonCloseDialog - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - 5, 13 - - - 373, 109 - - - ProgressDialog - - - ProgressDialog - - - System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.cs.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.cs.xlf deleted file mode 100644 index 913b35d1e16..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.cs.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - &Zrušit - - - - Progress Dialog - Dialogové okno průběhu - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.de.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.de.xlf deleted file mode 100644 index 4e598b49b87..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.de.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - Abbre&chen - - - - Progress Dialog - Fortschrittsdialogfeld - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.es.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.es.xlf deleted file mode 100644 index e57c421f31d..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.es.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - &Cancelar - - - - Progress Dialog - Cuadro de diálogo de progreso - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.fr.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.fr.xlf deleted file mode 100644 index a872b4dc181..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.fr.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - &Annuler - - - - Progress Dialog - Boîte de dialogue Avancement - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.it.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.it.xlf deleted file mode 100644 index df0031893e3..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.it.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - &Annulla - - - - Progress Dialog - Finestra di dialogo Stato - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.ja.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.ja.xlf deleted file mode 100644 index 14c63ad209b..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.ja.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - キャンセル(&C) - - - - Progress Dialog - 進行状況ダイアログ - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.ko.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.ko.xlf deleted file mode 100644 index 830107eee30..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.ko.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - 취소(&C) - - - - Progress Dialog - 진행률 대화 상자 - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.pl.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.pl.xlf deleted file mode 100644 index 7742cd3e772..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.pl.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - &Anuluj - - - - Progress Dialog - Okno dialogowe postępu - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.pt-BR.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.pt-BR.xlf deleted file mode 100644 index 57dca7cd4fd..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.pt-BR.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - &Cancelar - - - - Progress Dialog - Caixa de Diálogo de Progresso - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.ru.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.ru.xlf deleted file mode 100644 index 7f6918a0b35..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.ru.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - &Отмена - - - - Progress Dialog - Индикатор выполнения - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.tr.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.tr.xlf deleted file mode 100644 index d3797593724..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.tr.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - &İptal - - - - Progress Dialog - İlerleme İletişim Kutusu - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.zh-Hans.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.zh-Hans.xlf deleted file mode 100644 index 02995022f7a..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.zh-Hans.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - 取消(&C) - - - - Progress Dialog - 进度对话框 - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.zh-Hant.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.zh-Hant.xlf deleted file mode 100644 index 8024e79328a..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/Microsoft/VisualBasic/MyServices/Internal/xlf/ProgressDialog.zh-Hant.xlf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - ProgressDialog - ProgressDialog - - - - &Cancel - 取消(&C) - - - - Progress Dialog - 進度對話方塊 - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/SR.resx b/src/Microsoft.VisualBasic.Forms/src/Resources/SR.resx deleted file mode 100644 index ff406c3aee6..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/SR.resx +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - File not found. - - - Permission denied. - - - Argument '{0}' is not a valid value. - - - Argument '{0}' cannot be converted to type '{1}'. - - - Argument '{0}' is Nothing. - - - Process '{0}' was not found. - - - No mouse is present. - - - No mouse wheel is present. - - - Could not complete operation since a file already exists in this path '{0}'. - - - Could not find file '{0}'. - - - The given file path ends with a directory separator character. - - - Argument cannot be Nothing. - - - Property {0} cannot be set to Nothing. - - - Cannot determine the amount of available disk space. - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - - - The value of {0} must be a positive number. - - - BaseFileName cannot be Nothing or an empty String. - - - The value of {0} must be greater than or equal to 1000. - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - - - The ConnectionTimeout must be greater than 0. - - - Unable to ping because a network connection is not available. - - - The address for UploadFile needs to include a file name. - - - destinationFileName needs to include a file name. - - - Downloading {0} - - - Uploading {0} - - - Downloading {0} to {1} - - - Uploading {0} to {1} - - - Could not obtain memory information due to internal error. - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - - - A startup form has not been specified. - - - This single-instance application could not connect to the original instance. - - - Splash screen and main form cannot be the same form. - - - Environment variable is not defined: '{0}'. - - diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.cs.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.cs.xlf deleted file mode 100644 index f737611c412..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.cs.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - Nebyl zadán formulář spuštění. - - - - This single-instance application could not connect to the original instance. - Tato aplikace s jedinou instancí se nemůže připojit k původní instanci. - - - - Splash screen and main form cannot be the same form. - Formulář úvodní obrazovky a hlavní formulář nemohou být stejné. - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName nemůže být prázdná hodnota (Nothing) nebo prázdný řetězec (String). - - - - The value of {0} must be greater than or equal to 1000. - Hodnota {0} musí být větší nebo rovna 1000. - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - Nelze získat datový proud pro protokol. Potenciální názvy souborů založené na {0} se již používají. - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - Nelze zapisovat do souboru protokolu, protože při zápisu by došlo k překročení hodnoty MaxFileSize. - - - - Cannot determine the amount of available disk space. - Nelze určit velikost dostupného místa na disku. - - - - The value of {0} must be a positive number. - Hodnota {0} musí být kladné číslo. - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - Nelze zapisovat do souboru protokolu, protože při zápisu by došlo ke snížení volného místa na disku určeného hodnotou ReservedSpace. - - - - Argument '{0}' is Nothing. - Argument {0} má hodnotu Nothing. - - - - Argument '{0}' is not a valid value. - Argument {0} nemá platnou hodnotu. - - - - Argument '{0}' cannot be converted to type '{1}'. - Argument {0} nelze převést na typ {1}. - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - Nelze získat úplný název operačního systému, protože došlo k vnitřní chybě. Pravděpodobnou příčinou je to, že v počítači není nainstalována služba WMI. - - - - Could not obtain memory information due to internal error. - Nelze získat informace o paměti, protože došlo k vnitřní chybě. - - - - Environment variable is not defined: '{0}'. - Není definována proměnná prostředí: {0}. - - - - Argument cannot be Nothing. - Argument nemůže být prázdná hodnota (Nothing). - - - - Property {0} cannot be set to Nothing. - Vlastnost {0} nemůže být nastavena na hodnotu Nothing. - - - - File not found. - Soubor se nepovedlo najít. - - - - Permission denied. - Oprávnění byla odepřena. - - - - Could not complete operation since a file already exists in this path '{0}'. - Nelze provést operaci, protože soubor již existuje v této cestě {0}. - - - - Could not find file '{0}'. - Soubor {0} nebyl nalezen. - - - - The given file path ends with a directory separator character. - Zadaná cesta k souboru končí znakem oddělovače adresářů. - - - - No mouse is present. - Není připojena myš. - - - - No mouse wheel is present. - Nebylo nalezeno kolečko myši. - - - - The ConnectionTimeout must be greater than 0. - Hodnota ConnectionTimeout musí být větší než 0. - - - - destinationFileName needs to include a file name. - destinationFileName musí obsahovat název souboru. - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - {0} není platná adresa vzdáleného souboru. Platná adresa musí obsahovat protokol, cestu a název k souboru. - - - - Unable to ping because a network connection is not available. - Nelze provést test pomocí příkazu ping, protože k dispozici není připojení k síti. - - - - The address for UploadFile needs to include a file name. - Adresa pro UploadFile musí zahrnovat název souboru. - - - - Process '{0}' was not found. - Proces {0} nebyl nalezen. - - - - Downloading {0} to {1} - Stahování {0} do {1} - - - - Downloading {0} - Stahuje se {0}. - - - - Uploading {0} to {1} - Ukládání {0} do {1} - - - - Uploading {0} - Ukládání {0} - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.de.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.de.xlf deleted file mode 100644 index e4e2a7e5e3e..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.de.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - Es wurde kein Startformular angegeben. - - - - This single-instance application could not connect to the original instance. - Diese Einzelinstanzanwendung konnte keine Verbindung zur ursprünglichen Instanz herstellen. - - - - Splash screen and main form cannot be the same form. - Das Formular für den Begrüßungsbildschirm und das Hauptformular dürfen nicht identisch sein. - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName kann nicht "Nothing" oder eine leere Zeichenfolge sein. - - - - The value of {0} must be greater than or equal to 1000. - Der Wert von {0} muss größer als oder gleich 1000 sein. - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - Für das Protokoll kann kein Stream abgerufen werden. Die auf {0} basierenden potenziellen Dateinamen werden bereits verwendet. - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - In der Protokolldatei kann nicht geschrieben werden, weil dies dazu führen würde, dass sie den MaxFileSize-Wert überschreitet. - - - - Cannot determine the amount of available disk space. - Der freie Speicherplatz auf dem Datenträger kann nicht bestimmt werden. - - - - The value of {0} must be a positive number. - Der Wert von {0} muss eine positive Zahl sein. - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - Die Protokolldatei kann nicht geschrieben werden, weil das Schreiben in dieser Datei dazu führen würde, dass der freie Speicherplatz auf dem Datenträger unter den ReservedSpace-Wert absinkt. - - - - Argument '{0}' is Nothing. - Das Argument {0} ist "Nothing". - - - - Argument '{0}' is not a valid value. - Das Argument {0} ist kein gültiger Wert. - - - - Argument '{0}' cannot be converted to type '{1}'. - Das Argument {0} kann nicht in den Typ {1} umgewandelt werden. - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - Interner Fehler. Der vollständige Betriebssystemname konnte nicht abgerufen werden. Mögliche Ursache: Auf dem aktuellen Computer ist keine WMI vorhanden. - - - - Could not obtain memory information due to internal error. - Interner Fehler. Die Speicherinformationen konnten nicht abgerufen werden. - - - - Environment variable is not defined: '{0}'. - Die Umgebungsvariable wurde nicht definiert: {0}. - - - - Argument cannot be Nothing. - Das Argument kann nicht "Nothing" sein. - - - - Property {0} cannot be set to Nothing. - Die Eigenschaft {0} kann nicht auf "Nothing" festgelegt werden. - - - - File not found. - Datei nicht gefunden. - - - - Permission denied. - Berechtigung verweigert. - - - - Could not complete operation since a file already exists in this path '{0}'. - Der Vorgang konnte nicht abgeschlossen werden, da bereits eine Datei im Pfad {0} vorhanden ist. - - - - Could not find file '{0}'. - Die Datei "{0}" konnte nicht gefunden werden. - - - - The given file path ends with a directory separator character. - Der angegebene Pfad endet mit einem Verzeichnistrennzeichen. - - - - No mouse is present. - Es ist keine Maus vorhanden. - - - - No mouse wheel is present. - Es ist kein Mausrad vorhanden. - - - - The ConnectionTimeout must be greater than 0. - Der Verbindungstimeout-Wert muss größer als 0 sein. - - - - destinationFileName needs to include a file name. - In destinationFileName muss ein Dateiname enthalten sein. - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - "{0}" ist keine gültige Remotedateiadresse. Eine gültige Adresse muss ein Protokoll, einen Pfad und einen Dateinamen enthalten. - - - - Unable to ping because a network connection is not available. - Pingfehler. Es ist keine Netzwerkverbindung verfügbar. - - - - The address for UploadFile needs to include a file name. - Die Adresse für UploadFile muss einen Dateinamen enthalten. - - - - Process '{0}' was not found. - Der Prozess {0} wurde nicht gefunden. - - - - Downloading {0} to {1} - {0} wird nach {1} heruntergeladen. - - - - Downloading {0} - {0} wird heruntergeladen - - - - Uploading {0} to {1} - {0} wird nach {1} hochgeladen. - - - - Uploading {0} - {0} wird hochgeladen - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.es.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.es.xlf deleted file mode 100644 index 006fe62ea7d..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.es.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - No se ha especificado un formulario de inicio. - - - - This single-instance application could not connect to the original instance. - Esta aplicación de una sola instancia no pudo conectar con la instancia original. - - - - Splash screen and main form cannot be the same form. - La pantalla de presentación y el formulario principal no pueden ser el mismo formulario. - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName no puede ser Nothing o un tipo String vacío. - - - - The value of {0} must be greater than or equal to 1000. - El valor de {0} debe ser mayor o igual que 1000. - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - No se pudo obtener una secuencia para el registro. Los nombres de archivo potenciales que se basan en {0} ya están en uso. - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - No se puede escribir en el archivo de registro porque se superaría el valor MaxFileSize. - - - - Cannot determine the amount of available disk space. - No se puede determinar la cantidad de espacio en disco disponible. - - - - The value of {0} must be a positive number. - El valor de {0} debe ser un número positivo. - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - No se puede escribir en el archivo de registro porque el espacio en disco disponible pasaría a ser inferior al valor ReservedSpace. - - - - Argument '{0}' is Nothing. - El argumento '{0}' tiene un valor Nothing. - - - - Argument '{0}' is not a valid value. - El argumento '{0}' es un valor no válido. - - - - Argument '{0}' cannot be converted to type '{1}'. - El argumento '{0}' no se puede convertir en el tipo '{1}'. - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - No se pudo obtener el nombre del sistema operativo completo debido a un error interno. La causa puede deberse a que WMI no existe en el equipo actual. - - - - Could not obtain memory information due to internal error. - No se pudo obtener la información de memoria debido a un error interno. - - - - Environment variable is not defined: '{0}'. - Variable de entorno no definida: '{0}'. - - - - Argument cannot be Nothing. - El argumento no puede ser Nothing. - - - - Property {0} cannot be set to Nothing. - La propiedad {0} no se puede establecer en Nothing. - - - - File not found. - No se encontró el archivo. - - - - Permission denied. - Permiso denegado. - - - - Could not complete operation since a file already exists in this path '{0}'. - No se pudo completar la operación porque ya existe un archivo en esta ruta de acceso '{0}'. - - - - Could not find file '{0}'. - No se pudo encontrar el archivo '{0}'. - - - - The given file path ends with a directory separator character. - La ruta de acceso de archivo dada termina con un carácter separador de directorio. - - - - No mouse is present. - No hay un mouse presente. - - - - No mouse wheel is present. - No hay rueda de mouse presente. - - - - The ConnectionTimeout must be greater than 0. - ConnectionTimeout debe ser mayor que 0. - - - - destinationFileName needs to include a file name. - Es necesario incluir un nombre de archivo en destinationFileName. - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - '{0}' no es una dirección de archivo remoto válida. Una dirección válida debe incluir un protocolo, una ruta de acceso y un nombre de archivo. - - - - Unable to ping because a network connection is not available. - No se puede ejecutar el comando ping porque no hay disponible ninguna conexión de red. - - - - The address for UploadFile needs to include a file name. - La dirección de UploadFile necesita incluir un nombre de archivo. - - - - Process '{0}' was not found. - No se encuentra el proceso '{0}'. - - - - Downloading {0} to {1} - Descargando {0} en {1} - - - - Downloading {0} - Descargando {0} - - - - Uploading {0} to {1} - Cargando {0} en {1} - - - - Uploading {0} - Cargando {0} - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.fr.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.fr.xlf deleted file mode 100644 index 3e06f665f6a..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.fr.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - Un formulaire de démarrage n'a pas été spécifié. - - - - This single-instance application could not connect to the original instance. - Impossible de connecter cette application à instance unique à l'instance d'origine. - - - - Splash screen and main form cannot be the same form. - L'écran de démarrage et le formulaire principal ne peuvent pas être le même formulaire. - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName ne peut pas être Nothing ou un String vide. - - - - The value of {0} must be greater than or equal to 1000. - La valeur de {0} doit être supérieure ou égale à 1 000. - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - Impossible d'obtenir un flux pour le journal. Des noms de fichiers éventuels fondés sur {0} sont déjà utilisés. - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - Impossible d'écrire dans le fichier journal, car cette opération entraînerait un dépassement de la valeur MaxFileSize. - - - - Cannot determine the amount of available disk space. - Impossible de déterminer la quantité d'espace disque disponible. - - - - The value of {0} must be a positive number. - La valeur de {0} doit être un nombre positif. - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - Impossible d'écrire dans le fichier journal, car la quantité d'espace disque libre deviendrait alors inférieure à la valeur ReservedSpace. - - - - Argument '{0}' is Nothing. - L'argument '{0}' a la valeur Nothing. - - - - Argument '{0}' is not a valid value. - L'argument '{0}' n'est pas une valeur valide. - - - - Argument '{0}' cannot be converted to type '{1}'. - L'argument '{0}' ne peut pas être converti en type '{1}'. - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - Impossible d'obtenir le nom complet du système d'exploitation en raison d'une erreur interne. Ceci peut être dû au fait que WMI est absent de l'ordinateur actuel. - - - - Could not obtain memory information due to internal error. - Impossible d'obtenir des informations sur la mémoire en raison d'une erreur interne. - - - - Environment variable is not defined: '{0}'. - Variable d'environnement non définie : '{0}'. - - - - Argument cannot be Nothing. - L'argument ne peut pas avoir la valeur Nothing. - - - - Property {0} cannot be set to Nothing. - La propriété {0} ne peut pas avoir la valeur Nothing. - - - - File not found. - Fichier introuvable. - - - - Permission denied. - Autorisation refusée. - - - - Could not complete operation since a file already exists in this path '{0}'. - Impossible d'achever l'opération, car un fichier figure déjà dans ce chemin d'accès '{0}'. - - - - Could not find file '{0}'. - Impossible de trouver le fichier '{0}'. - - - - The given file path ends with a directory separator character. - Le chemin d'accès de fichier spécifié se termine par un caractère de séparation de répertoire. - - - - No mouse is present. - Absence de souris. - - - - No mouse wheel is present. - Absence de roulette de souris. - - - - The ConnectionTimeout must be greater than 0. - Le ConnectionTimeout doit être supérieur à 0. - - - - destinationFileName needs to include a file name. - destinationFileName doit inclure un nom de fichier. - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - '{0}' n'est pas une adresse valide de fichier distant. Une adresse valide doit inclure un protocole, un chemin d'accès et un nom de fichier. - - - - Unable to ping because a network connection is not available. - Impossible d'exécuter la commande PING, car une connexion réseau n'est pas disponible. - - - - The address for UploadFile needs to include a file name. - L'adresse de UploadFile doit inclure un nom de fichier. - - - - Process '{0}' was not found. - Le processus '{0}' est introuvable. - - - - Downloading {0} to {1} - Téléchargement de {0} sur {1} - - - - Downloading {0} - Téléchargement de {0} - - - - Uploading {0} to {1} - Transfert de {0} sur {1} - - - - Uploading {0} - Chargement de {0} - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.it.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.it.xlf deleted file mode 100644 index cc73272c979..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.it.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - Non è stato specificato un form di avvio. - - - - This single-instance application could not connect to the original instance. - Impossibile connettere l'applicazione a istanza singola con l'istanza originale. - - - - Splash screen and main form cannot be the same form. - La schermata iniziale e il form principale non possono avere lo stesso formato. - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName non può essere Nothing o una stringa vuota. - - - - The value of {0} must be greater than or equal to 1000. - Il valore di {0} deve essere maggiore o uguale a 1000. - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - Impossibile ottenere un flusso per il log. I possibili nome di file basati su {0} sono già in uso. - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - Impossibile scrivere nel file di log. Verrebbe superato il valore MaxFileSize. - - - - Cannot determine the amount of available disk space. - Impossibile determinare la quantità di spazio libero su disco. - - - - The value of {0} must be a positive number. - Il valore di {0} deve essere un numero positivo. - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - Impossibile scrivere nel file di log. Lo spazio libero su disco risulterebbe inferiore al valore ReservedSpace. - - - - Argument '{0}' is Nothing. - L'argomento '{0}' è Nothing. - - - - Argument '{0}' is not a valid value. - L'argomento '{0}' non è un valore valido. - - - - Argument '{0}' cannot be converted to type '{1}'. - Impossibile convertire l'argomento '{0}' nel tipo '{1}'. - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - Errore interno. Impossibile ottenere il nome completo del sistema operativo. WMI potrebbe non essere presente sul computer in uso. - - - - Could not obtain memory information due to internal error. - Errore interno. Impossibile ottenere informazioni sulla memoria. - - - - Environment variable is not defined: '{0}'. - Variabile di ambiente non definita: '{0}'. - - - - Argument cannot be Nothing. - L'argomento non può essere Nothing. - - - - Property {0} cannot be set to Nothing. - La proprietà {0} non può essere impostata su Nothing. - - - - File not found. - Il file non è stato trovato. - - - - Permission denied. - Autorizzazione negata. - - - - Could not complete operation since a file already exists in this path '{0}'. - Impossibile completare l'operazione. Nel percorso '{0}' è già presente un file. - - - - Could not find file '{0}'. - Il file '{0}' non è stato trovato. - - - - The given file path ends with a directory separator character. - Il percorso di file fornito termina con un carattere di separatore di directory. - - - - No mouse is present. - Mouse non presente. - - - - No mouse wheel is present. - Rotellina del mouse non presente. - - - - The ConnectionTimeout must be greater than 0. - ConnectionTimeout deve essere maggiore di 0. - - - - destinationFileName needs to include a file name. - destinationFileName deve includere un nome file. - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - '{0}' non è un indirizzo di file remoto valido. Un indirizzo valido deve includere un protocollo, un percorso e un nome di file. - - - - Unable to ping because a network connection is not available. - Impossibile effettuare il ping. La connessione di rete non è disponibile. - - - - The address for UploadFile needs to include a file name. - L'indirizzo di UploadFile deve includere un nome file. - - - - Process '{0}' was not found. - Impossibile trovare il processo '{0}'. - - - - Downloading {0} to {1} - Download di {0} in {1} - - - - Downloading {0} - Download di {0} - - - - Uploading {0} to {1} - Upload di {0} in {1} - - - - Uploading {0} - Caricamento di {0} - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ja.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ja.xlf deleted file mode 100644 index d9c1b872741..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ja.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - スタートアップ フォームが指定されていません。 - - - - This single-instance application could not connect to the original instance. - この単一インスタンス アプリケーションは元のインスタンスに接続できませんでした。 - - - - Splash screen and main form cannot be the same form. - スプラッシュ スクリーンとメイン フォームは同じフォームであることはできません。 - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName は、Nothing または空文字列にできません。 - - - - The value of {0} must be greater than or equal to 1000. - {0} の値は 1000 以上でなければなりません。 - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - ログのストリームを取得できません。 {0} に基づく、可能性のあるファイル名は既に使用中です。 - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - 書き込みを行うと MaxFileSize 値を超えてしまうため、ログ ファイルに書き込めません。 - - - - Cannot determine the amount of available disk space. - 利用可能な空きディスク領域を確認できません。 - - - - The value of {0} must be a positive number. - {0} の値は正数でなければなりません。 - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - 書き込みを行うと、空きディスク領域が ReservedSpace 値よりも少なくなるため、ログ ファイルに書き込めません。 - - - - Argument '{0}' is Nothing. - 引数 '{0}' は Nothing です。 - - - - Argument '{0}' is not a valid value. - 引数 '{0}' は有効な値ではありません。 - - - - Argument '{0}' cannot be converted to type '{1}'. - 引数 '{0}' は型 '{1}' に変換できません。 - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - 内部エラーのため、完全なオペレーション システム名を取得できませんでした。現在のコンピューター上に WMI が存在していないことが原因と考えられます。 - - - - Could not obtain memory information due to internal error. - 内部エラーのため、メモリ情報を取得できませんでした。 - - - - Environment variable is not defined: '{0}'. - 環境変数は定義されていません: '{0}' - - - - Argument cannot be Nothing. - 引数には Nothing を使用できません。 - - - - Property {0} cannot be set to Nothing. - プロパティ {0} は Nothing に設定できません。 - - - - File not found. - ファイルが見つかりません。 - - - - Permission denied. - アクセス許可が拒否されました。 - - - - Could not complete operation since a file already exists in this path '{0}'. - ファイルがこのパス '{0}' 内に既に存在するため、操作を完了できませんでした。 - - - - Could not find file '{0}'. - ファイル '{0}' は見つかりませんでした。 - - - - The given file path ends with a directory separator character. - 指定されたファイル パスの終わりにはディレクトリの区切り記号が指定されています。 - - - - No mouse is present. - マウスが存在しません。 - - - - No mouse wheel is present. - マウスのホイールが存在しません。 - - - - The ConnectionTimeout must be greater than 0. - ConnectionTimeout は 0 より大きくなければなりません。 - - - - destinationFileName needs to include a file name. - destinationFileName はファイル名を含んでいなければなりません。 - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - '{0}' は無効なリモート ファイル アドレスです。有効なアドレスはプロトコル、パスおよびファイル名を含んでいなければなりません。 - - - - Unable to ping because a network connection is not available. - ネットワーク接続が利用できないため、ping を実行できません。 - - - - The address for UploadFile needs to include a file name. - UploadFile のアドレスにはファイル名が含まれていなければなりません。 - - - - Process '{0}' was not found. - プロセス '{0}' が見つかりませんでした。 - - - - Downloading {0} to {1} - {0} を {1} にダウンロードしています。 - - - - Downloading {0} - {0} をダウンロードしています - - - - Uploading {0} to {1} - {0} を {1} にアップロードしています。 - - - - Uploading {0} - {0} のアップロード中 - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ko.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ko.xlf deleted file mode 100644 index 5546130053f..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ko.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - 시작 폼이 지정되지 않았습니다. - - - - This single-instance application could not connect to the original instance. - 이 단일 인스턴스 응용 프로그램을 원본 인스턴스에 연결할 수 없습니다. - - - - Splash screen and main form cannot be the same form. - 시작 화면과 기본 폼은 같은 폼일 수 없습니다. - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName은 Nothing이나 빈 문자열일 수 없습니다. - - - - The value of {0} must be greater than or equal to 1000. - {0}의 값은 1000보다 크거나 같아야 합니다. - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - 로그의 스트림을 가져올 수 없습니다. {0}에 기반한 파일 이름이 이미 사용 중입니다. - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - MaxFileSize 값을 초과할 수 있기 때문에 로그 파일에 쓸 수 없습니다. - - - - Cannot determine the amount of available disk space. - 사용 가능한 디스크 공간을 확인할 수 없습니다. - - - - The value of {0} must be a positive number. - {0}의 값은 양수여야 합니다. - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - 사용 가능한 디스크 공간이 ReservedSpace 값 미만으로 줄어들 수 있기 때문에 로그 파일에 쓸 수 없습니다. - - - - Argument '{0}' is Nothing. - '{0}' 인수가 Nothing입니다. - - - - Argument '{0}' is not a valid value. - '{0}' 인수는 잘못된 값입니다. - - - - Argument '{0}' cannot be converted to type '{1}'. - '{0}' 인수를 '{1}' 형식으로 변환할 수 없습니다. - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - 내부 오류 때문에 작업 시스템의 전체 이름을 가져올 수 없습니다. 이 오류는 현재 컴퓨터에 WMI가 없기 때문에 발생할 수 있습니다. - - - - Could not obtain memory information due to internal error. - 내부 오류 때문에 메모리 정보를 가져올 수 없습니다. - - - - Environment variable is not defined: '{0}'. - 환경 변수가 정의되지 않았습니다. '{0}' - - - - Argument cannot be Nothing. - 인수는 Nothing일 수 없습니다. - - - - Property {0} cannot be set to Nothing. - {0} 속성을 Nothing으로 설정할 수 없습니다. - - - - File not found. - 파일을 찾을 수 없습니다. - - - - Permission denied. - 사용 권한이 거부되었습니다. - - - - Could not complete operation since a file already exists in this path '{0}'. - 파일이 이 '{0}' 경로에 이미 있기 때문에 작업을 완료할 수 없습니다. - - - - Could not find file '{0}'. - '{0}' 파일을 찾을 수 없습니다. - - - - The given file path ends with a directory separator character. - 지정한 파일 경로가 디렉터리 구분 문자로 끝납니다. - - - - No mouse is present. - 마우스가 없습니다. - - - - No mouse wheel is present. - 마우스 휠이 없습니다. - - - - The ConnectionTimeout must be greater than 0. - ConnectionTimeout은 0보다 커야 합니다. - - - - destinationFileName needs to include a file name. - destinationFileName에는 파일 이름이 포함되어야 합니다. - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - '{0}'은(는) 올바른 원격 파일 주소가 아닙니다. 올바른 주소에는 프로토콜, 경로 및 파일 이름이 포함되어야 합니다. - - - - Unable to ping because a network connection is not available. - 네트워크 연결을 사용할 수 없어 ping을 실행할 수 없습니다. - - - - The address for UploadFile needs to include a file name. - UploadFile의 주소에는 파일 이름이 포함되어야 합니다. - - - - Process '{0}' was not found. - 프로세스 '{0}'을(를) 찾을 수 없습니다. - - - - Downloading {0} to {1} - {0}을(를) {1}(으)로 다운로드하고 있습니다. - - - - Downloading {0} - {0}을(를) 다운로드하는 중 - - - - Uploading {0} to {1} - {0}을(를) {1}(으)로 업로드하고 있습니다. - - - - Uploading {0} - {0} 업로드 중 - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pl.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pl.xlf deleted file mode 100644 index 35284bb512e..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pl.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - Formularz początkowy nie został określony. - - - - This single-instance application could not connect to the original instance. - To pojedyncze wystąpienie aplikacji nie może połączyć się z wystąpieniem oryginalnym. - - - - Splash screen and main form cannot be the same form. - Ekran powitalny i ekran główny nie mogą być tym samym formularzem. - - - - BaseFileName cannot be Nothing or an empty String. - Parametr BaseFileName nie może mieć wartości Nothing ani nie może być pustym ciągiem. - - - - The value of {0} must be greater than or equal to 1000. - Wartość {0} musi być większa lub równa 1000. - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - Nie można uzyskać strumienia dla dziennika. Potencjalne nazwy plików oparte na {0} są już używane. - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - Nie można zapisać w pliku dziennika, ponieważ zapisanie może spowodować przekroczenie wartości MaxFileSize. - - - - Cannot determine the amount of available disk space. - Nie można określić ilości dostępnego miejsca na dysku. - - - - The value of {0} must be a positive number. - Wartość {0} musi być liczbą dodatnią. - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - Nie można zapisać w pliku dziennika, ponieważ zapisanie może spowodować zmniejszenie ilości wolnego miejsca na dysku poniżej wartości ReservedSpace. - - - - Argument '{0}' is Nothing. - Argument '{0}' ma wartość Nothing. - - - - Argument '{0}' is not a valid value. - Argument '{0}' nie ma prawidłowej wartości. - - - - Argument '{0}' cannot be converted to type '{1}'. - Nie można przekonwertować argumentu '{0}' na typ '{1}'. - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - Nie można uzyskać pełnej nazwy systemu operacyjnego z powodu błędu wewnętrznego. Przyczyną może być interfejs WMI nie istniejący na bieżącym komputerze. - - - - Could not obtain memory information due to internal error. - Nie można uzyskać informacji o pamięci z powodu błędu wewnętrznego. - - - - Environment variable is not defined: '{0}'. - Zmienna środowiskowa nie została zdefiniowana: '{0}'. - - - - Argument cannot be Nothing. - Argument nie może mieć wartości Nothing. - - - - Property {0} cannot be set to Nothing. - Właściwość {0} nie może być ustawiona na wartość Nothing. - - - - File not found. - Nie znaleziono pliku. - - - - Permission denied. - Odmowa uprawnień. - - - - Could not complete operation since a file already exists in this path '{0}'. - Nie można wykonać operacji, ponieważ plik już istnieje w tej ścieżce '{0}'. - - - - Could not find file '{0}'. - Nie można odnaleźć pliku '{0}'. - - - - The given file path ends with a directory separator character. - Podana ścieżka pliku kończy się znakiem separatora katalogu. - - - - No mouse is present. - Nie ma myszy. - - - - No mouse wheel is present. - Nie ma kółka myszy. - - - - The ConnectionTimeout must be greater than 0. - Wartość parametru ConnectionTimeout musi być większa niż 0. - - - - destinationFileName needs to include a file name. - Parametr destinationFileName musi zawierać nazwę pliku. - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - '{0}' nie jest prawidłowym adresem pliku zdalnego. prawidłowy adres powinien zawierać protokół, ścieżkę i nazwę pliku. - - - - Unable to ping because a network connection is not available. - Nie można użyć polecenia ping, ponieważ połączenie sieciowe jest niedostępne. - - - - The address for UploadFile needs to include a file name. - Adres parametru UploadFile musi zawierać nazwę pliku. - - - - Process '{0}' was not found. - Nie można odnaleźć procesu '{0}'. - - - - Downloading {0} to {1} - Pobieranie {0} do {1} - - - - Downloading {0} - Pobieranie {0} - - - - Uploading {0} to {1} - Przekazywanie {0} do {1} - - - - Uploading {0} - Przekazywanie: {0} - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pt-BR.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pt-BR.xlf deleted file mode 100644 index 1e1b8f1416f..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pt-BR.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - Não foi especificado um formulário de inicialização. - - - - This single-instance application could not connect to the original instance. - Este aplicativo de instância única não pôde se conectar à instância original. - - - - Splash screen and main form cannot be the same form. - Tela inicial e formulário principal não podem ser o mesmo formulário. - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName não pode ser Nothing ou uma cadeia de caracteres vazia. - - - - The value of {0} must be greater than or equal to 1000. - O valor de {0} deve ser maior ou igual a 1000. - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - Não é possível obter um fluxo para o log. Os possíveis nomes de arquivo baseados em {0} já estão em uso. - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - Não é possível gravar no arquivo de log porque isso faria com que o valor de MaxFileSize fosse excedido. - - - - Cannot determine the amount of available disk space. - Não é possível determinar a quantidade de espaço em disco disponível. - - - - The value of {0} must be a positive number. - O valor de {0} deve ser um número positivo. - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - Não é possível gravar no arquivo de log porque isso reduziria o espaço livre em disco abaixo do valor de ReservedSpace. - - - - Argument '{0}' is Nothing. - O argumento '{0}' é Nothing. - - - - Argument '{0}' is not a valid value. - O argumento '{0}' é um valor inválido. - - - - Argument '{0}' cannot be converted to type '{1}'. - O argumento '{0}' não pode ser convertido no tipo '{1}'. - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - Não foi possível obter o nome completo do sistema operacional devido a um erro interno. Possível causa: ausência de WMI na máquina atual. - - - - Could not obtain memory information due to internal error. - Não foi possível obter informações sobre memória devido a um erro interno. - - - - Environment variable is not defined: '{0}'. - Variável de ambiente não definida: '{0}'. - - - - Argument cannot be Nothing. - O argumento não pode ser Nothing. - - - - Property {0} cannot be set to Nothing. - A propriedade {0} não pode ser Nothing. - - - - File not found. - Arquivo não encontrado. - - - - Permission denied. - Permissão negada. - - - - Could not complete operation since a file already exists in this path '{0}'. - Não foi possível concluir a operação porque já existe um arquivo neste caminho '{0}'. - - - - Could not find file '{0}'. - Não foi possível encontrar o arquivo '{0}'. - - - - The given file path ends with a directory separator character. - O caminho de arquivo fornecido termina com um caractere separador de diretório. - - - - No mouse is present. - Nenhum mouse presente. - - - - No mouse wheel is present. - Nenhuma roda de mouse presente. - - - - The ConnectionTimeout must be greater than 0. - ConnectionTimeout deve ser maior que 0. - - - - destinationFileName needs to include a file name. - destinationFileName precisa incluir um nome de arquivo. - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - '{0}' não é um endereço de arquivo remoto válido. Um endereço válido deve incluir um protocolo, um caminho e um nome de arquivo. - - - - Unable to ping because a network connection is not available. - Não é possível executar ping porque a conexão com a rede não está disponível. - - - - The address for UploadFile needs to include a file name. - O endereço para UploadFile precisa incluir um nome de arquivo. - - - - Process '{0}' was not found. - O processo '{0}' não foi encontrado. - - - - Downloading {0} to {1} - Baixando {0} para {1} - - - - Downloading {0} - Baixando {0} - - - - Uploading {0} to {1} - Carregando {0} para {1} - - - - Uploading {0} - Carregando {0} - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ru.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ru.xlf deleted file mode 100644 index e400e684656..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ru.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - Форма запуска не указана. - - - - This single-instance application could not connect to the original instance. - Данное приложение, допускающее только один экземпляр, не может подключиться к первоначальному экземпляру. - - - - Splash screen and main form cannot be the same form. - Заставка и главная форма не могут быть одной и той же формой. - - - - BaseFileName cannot be Nothing or an empty String. - Параметр BaseFileName не может принимать значение Nothing или оставаться пустым. - - - - The value of {0} must be greater than or equal to 1000. - Значение {0} должно быть больше или равно 1000. - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - Невозможно получить поток для журнала. Потенциальные имена файлов, основанные на {0}, уже используются. - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - Невозможно произвести запись в файл журнала, это приведет к превышению значения MaxFileSize. - - - - Cannot determine the amount of available disk space. - Не удается определить объем свободного дискового пространства. - - - - The value of {0} must be a positive number. - Значение {0} должно быть положительным числом. - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - Невозможно произвести запись в файл журнала, на диске останется менее ReservedSpace. - - - - Argument '{0}' is Nothing. - Аргумент "{0}" имеет значение Nothing. - - - - Argument '{0}' is not a valid value. - Аргумент "{0}" не является допустимым значением. - - - - Argument '{0}' cannot be converted to type '{1}'. - Невозможно привести аргумент "{0}" к типу "{1}". - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - Не удается получить полное имя операционной системы из-за внутренней ошибки. Возможно, на данном компьютере отсутствует WMI. - - - - Could not obtain memory information due to internal error. - Невозможно получить информацию о памяти из-за внутренней ошибки. - - - - Environment variable is not defined: '{0}'. - Не задана переменная окружения: "{0}". - - - - Argument cannot be Nothing. - Аргумент не может принимать значение Nothing. - - - - Property {0} cannot be set to Nothing. - Свойству {0} нельзя присвоить значение Nothing. - - - - File not found. - Файл не найден. - - - - Permission denied. - В разрешении отказано. - - - - Could not complete operation since a file already exists in this path '{0}'. - Не удалось завершить операцию: файл "{0}" уже существует. - - - - Could not find file '{0}'. - Не удалось найти файл "{0}". - - - - The given file path ends with a directory separator character. - Данный путь к файлу заканчивается символом разделителя каталогов. - - - - No mouse is present. - Не обнаружена мышь. - - - - No mouse wheel is present. - Не обнаружено колесо мыши. - - - - The ConnectionTimeout must be greater than 0. - Значение ConnectionTimeout должно быть больше 0. - - - - destinationFileName needs to include a file name. - destinationFileName должен включать имя файла. - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - "{0}" является недопустимым адресом удаленного файла. Допустимый адрес должен включать протокол, путь и имя файла. - - - - Unable to ping because a network connection is not available. - Не удается отправить запрос отклика: отсутствует сетевое соединение. - - - - The address for UploadFile needs to include a file name. - Адрес UploadFile должен включать имя файла. - - - - Process '{0}' was not found. - Процесс "{0}" не найден. - - - - Downloading {0} to {1} - Скачивание {0} в {1} - - - - Downloading {0} - Загрузка {0} - - - - Uploading {0} to {1} - Загрузка {0} в {1} - - - - Uploading {0} - Идет отправка {0} - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.tr.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.tr.xlf deleted file mode 100644 index 751c15e6832..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.tr.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - Başlangıç formu belirtilmedi. - - - - This single-instance application could not connect to the original instance. - Bu tek örnekli uygulama özgün örneğe bağlanamadı. - - - - Splash screen and main form cannot be the same form. - Giriş ekranı ve ana form aynı form olamaz. - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName Nothing veya boş Dize olamaz. - - - - The value of {0} must be greater than or equal to 1000. - {0} değeri 1000'den büyük veya eşit olmalıdır. - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - Günlük için akış alınamıyor. {0} öğesini temel alan olası dosya adları zaten kullanılıyor. - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - Günlük dosyalarına yazılması MaxFileSize değerinin aşmasına neden olacağından günlük dosyasına yazılamıyor. - - - - Cannot determine the amount of available disk space. - Kullanılabilir disk alanı miktarı belirlenemiyor. - - - - The value of {0} must be a positive number. - {0} değeri artı sayı olmalıdır. - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - Günlük dosyasına yazmak boş dik alanını ReservedSpace değerinin altına düşüreceğinden günlük dosyasına yazılamıyor. - - - - Argument '{0}' is Nothing. - '{0}' bağımsız değişkeni Nothing olarak belirlenmiş. - - - - Argument '{0}' is not a valid value. - '{0}' bağımsız değişkeninin değeri geçerli değil. - - - - Argument '{0}' cannot be converted to type '{1}'. - '{0}' bağımsız değişkeni '{1}' türüne dönüştürülemez. - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - İç hata nedeniyle işletim sistemi tam adı alınamadı. Geçerli bilgisayarda WMI'nın olmaması buna neden olabilir. - - - - Could not obtain memory information due to internal error. - İç hata nedeniyle bellek bilgileri alınamadı. - - - - Environment variable is not defined: '{0}'. - Ortam değişkeni tanımlanmamış: '{0}'. - - - - Argument cannot be Nothing. - Bağımsız değişken Nothing olamaz. - - - - Property {0} cannot be set to Nothing. - {0} özelliği Nothing olarak ayarlanamaz. - - - - File not found. - Dosya bulunamadı. - - - - Permission denied. - İzin reddedildi. - - - - Could not complete operation since a file already exists in this path '{0}'. - Bu '{0}' yolunda zaten bir dosya olduğundan işlem tamamlanamadı. - - - - Could not find file '{0}'. - '{0}' adlı dosya bulunamadı. - - - - The given file path ends with a directory separator character. - Verilen dosya yolu bir dizinle veya ayırıcı karakterle sona eriyor. - - - - No mouse is present. - Fare yok. - - - - No mouse wheel is present. - Fare tekerleği yok. - - - - The ConnectionTimeout must be greater than 0. - ConnectionTimeout sıfırdan büyük olmalıdır. - - - - destinationFileName needs to include a file name. - destinationFileName öğesinin bir dosya adı içermesi gerekir. - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - '{0}' geçerli bir uzak dosya adresi değil. Geçerli adres bir protokol, yol ve dosya adı içermelidir. - - - - Unable to ping because a network connection is not available. - Kullanılabilir ağ bağlantısı olmadığından ping işlemi yapılamıyor. - - - - The address for UploadFile needs to include a file name. - UploadFile adresinin bir dosya adı içermesi gerekir. - - - - Process '{0}' was not found. - '{0}' işlemi bulunamadı. - - - - Downloading {0} to {1} - {0}, {1} konumuna indiriliyor - - - - Downloading {0} - {0} indiriliyor - - - - Uploading {0} to {1} - {0}, {1} konumuna yükleniyor - - - - Uploading {0} - {0} karşıya yükleniyor - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hans.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hans.xlf deleted file mode 100644 index af55164f9e7..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hans.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - 未指定启动窗体。 - - - - This single-instance application could not connect to the original instance. - 此单实例应用程序未能连接到原始实例。 - - - - Splash screen and main form cannot be the same form. - 初始屏幕和主窗体不能是同一个窗体。 - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName 不能为 Nothing 或空字符串。 - - - - The value of {0} must be greater than or equal to 1000. - {0} 的值必须大于或等于 1000。 - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - 无法获取日志的流。可能基于 {0} 的文件名已在使用中。 - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - 无法写入日志文件,原因是写入将导致日志文件超过 MaxFileSize 值。 - - - - Cannot determine the amount of available disk space. - 无法确定可用磁盘空间量。 - - - - The value of {0} must be a positive number. - {0} 的值必须是正数。 - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - 无法写入日志文件,因为写入日志文件会使可用磁盘空间低于 ReservedSpace 值。 - - - - Argument '{0}' is Nothing. - 参数“{0}”为 Nothing。 - - - - Argument '{0}' is not a valid value. - 参数“{0}”不是有效值。 - - - - Argument '{0}' cannot be converted to type '{1}'. - 参数“{0}”无法转换为类型“{1}”。 - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - 由于内部错误,未能获取完整的操作系统名称。这可能是由于当前计算机上不存在 WMI 造成的。 - - - - Could not obtain memory information due to internal error. - 由于内部错误,未能获取内存信息。 - - - - Environment variable is not defined: '{0}'. - 未定义环境变量:“{0}”。 - - - - Argument cannot be Nothing. - 参数不能为 Nothing。 - - - - Property {0} cannot be set to Nothing. - 属性 {0} 不能设置为 Nothing。 - - - - File not found. - 找不到文件。 - - - - Permission denied. - 权限被拒绝。 - - - - Could not complete operation since a file already exists in this path '{0}'. - 未能完成操作,因为此路径“{0}”中已存在文件。 - - - - Could not find file '{0}'. - 找不到文件“{0}”。 - - - - The given file path ends with a directory separator character. - 给定的文件路径以目录分隔符字符结尾。 - - - - No mouse is present. - 没有鼠标。 - - - - No mouse wheel is present. - 没有鼠标轮。 - - - - The ConnectionTimeout must be greater than 0. - ConnectionTimeout 必须大于 0。 - - - - destinationFileName needs to include a file name. - destinationFileName 需要包括文件名。 - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - “{0}”不是有效的远程文件地址。有效的地址应包括协议、路径和文件名。 - - - - Unable to ping because a network connection is not available. - 由于网络连接不可用,无法使用 ping 命令。 - - - - The address for UploadFile needs to include a file name. - UploadFile 的地址中需要包括文件名。 - - - - Process '{0}' was not found. - 未找到进程“{0}”。 - - - - Downloading {0} to {1} - 正在将 {0} 下载到 {1} - - - - Downloading {0} - 正在下载 {0} - - - - Uploading {0} to {1} - 正在将 {0} 上载到 {1} - - - - Uploading {0} - 正在上传 {0} - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hant.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hant.xlf deleted file mode 100644 index c3df5ab1fb7..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hant.xlf +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - A startup form has not been specified. - 尚未指定啟動表單。 - - - - This single-instance application could not connect to the original instance. - 此單一執行個體應用程式無法連接到原始執行個體。 - - - - Splash screen and main form cannot be the same form. - 啟動顯示畫面和主要表單不能是同樣的表單。 - - - - BaseFileName cannot be Nothing or an empty String. - BaseFileName 不能為 Nothing 或空字串。 - - - - The value of {0} must be greater than or equal to 1000. - {0} 的值必須大於或等於 1000。 - - - - Unable to obtain a stream for the log. Potential file names based on {0} are already in use. - 無法取得記錄檔的資料流。以 {0} 為主的檔名已經在使用中。 - - - - Unable to write to log file because writing to it would cause it to exceed the MaxFileSize value. - 無法寫入記錄檔,因為如果寫入,會使它超過 MaxFileSize 值。 - - - - Cannot determine the amount of available disk space. - 無法判斷可用磁碟空間量。 - - - - The value of {0} must be a positive number. - {0} 的值必須為正數。 - - - - Unable to write to log file because writing to it would reduce free disk space below ReservedSpace value. - 無法寫入記錄檔,因為如果寫入,可用磁碟空間會減少到 ReservedSpace 值以下。 - - - - Argument '{0}' is Nothing. - 引數 '{0}' 為 Nothing。 - - - - Argument '{0}' is not a valid value. - 引數 '{0}' 不是一個有效的值。 - - - - Argument '{0}' cannot be converted to type '{1}'. - 引數 '{0}' 無法轉換為類型 '{1}'。 - - - - Could not obtain full operation system name due to internal error. This might be caused by WMI not existing on the current machine. - 由於內部錯誤,無法取得完整作業系統名稱。這可能是因為目前電腦上沒有 WMI 存在所造成。 - - - - Could not obtain memory information due to internal error. - 由於內部錯誤,無法取得記憶體資訊。 - - - - Environment variable is not defined: '{0}'. - 環境變數未定義: '{0}'。 - - - - Argument cannot be Nothing. - 引數不能為 Nothing。 - - - - Property {0} cannot be set to Nothing. - 屬性 {0} 不能設定為 Nothing。 - - - - File not found. - 找不到檔案。 - - - - Permission denied. - 使用權限遭拒。 - - - - Could not complete operation since a file already exists in this path '{0}'. - 無法完成作業,因為檔案已經存在於此路徑 '{0}'。 - - - - Could not find file '{0}'. - 找不到檔案 '{0}'。 - - - - The given file path ends with a directory separator character. - 指定的檔案路徑以目錄分隔符號結束。 - - - - No mouse is present. - 滑鼠不存在。 - - - - No mouse wheel is present. - 滑鼠滾輪不存在。 - - - - The ConnectionTimeout must be greater than 0. - ConnectionTimeout 必須大於 0。 - - - - destinationFileName needs to include a file name. - destinationFileName 需要包含檔案名稱。 - - - - '{0}' is not a valid remote file address. A valid address should include a protocol, a path and a file name. - '{0}' 不是有效的遠端檔案位址。有效位址應該包含通訊協定、路徑和檔案名稱。 - - - - Unable to ping because a network connection is not available. - 無法 Ping,因為有一個網路連接無法使用。 - - - - The address for UploadFile needs to include a file name. - UploadFile 的位址必須包含檔名。 - - - - Process '{0}' was not found. - 找不到處理序 '{0}'。 - - - - Downloading {0} to {1} - 下載 {0} 至 {1} - - - - Downloading {0} - 正在下載 {0} - - - - Uploading {0} to {1} - 上傳 {0} 至 {1} - - - - Uploading {0} - 正在上傳 {0} - - - - - \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/Microsoft.VisualBasic.Forms.Tests.vbproj b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/Microsoft.VisualBasic.Forms.Tests.vbproj deleted file mode 100644 index 75a84335a78..00000000000 --- a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/Microsoft.VisualBasic.Forms.Tests.vbproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - $(TargetFramework) - $(TargetFramework)-windows7.0 - true - Microsoft.VisualBasic.Forms.Tests - latest - true - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/ControlTests.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/ControlTests.vb deleted file mode 100644 index b8df093183f..00000000000 --- a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/ControlTests.vb +++ /dev/null @@ -1,105 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Windows.Forms -Imports Xunit - -Namespace Microsoft.VisualBasic.Forms.Tests - Partial Public Class ControlTests - - - Public Sub Control_Invoke_Action_calls_correct_method() - Using _control As New Control - _control.CreateControl() - - Dim invoker As Action = AddressOf FaultingMethod - Dim exception = Assert.Throws(Of DivideByZeroException)( - Sub() _control.Invoke(invoker)) - - ' Expecting something Like the following. - ' The first frame must be the this method, followed by MarshaledInvoke at previous location. - ' - ' at Microsoft.VisualBasic.Forms.Tests.Microsoft.VisualBasic.Forms.Tests.ControlTests.FaultingMethod() in ...\winforms\src\Microsoft.VisualBasic.Forms\tests\UnitTests\ControlTests.vb:line 28 - ' at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6511 - ' at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6487 - ' at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6459 - ' at System.Windows.Forms.Control.InvokeMarshaledCallbacks() in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6563 - ' --- End of stack trace from previous location --- - ' at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6951 - ' at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6413 - ' at System.Windows.Forms.Control.Invoke(Delegate method) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6393 - ' at Microsoft.VisualBasic.Forms.Tests.Microsoft.VisualBasic.Forms.Tests.ControlTests._Closure$__1-1._Lambda$__0() in ...\winforms\src\Microsoft.VisualBasic.Forms\tests\UnitTests\ControlTests.vb:line 18 - - Assert.Contains(NameOf(FaultingMethod), exception.StackTrace) - Assert.Contains(" System.Windows.Forms.Control.Invoke(Action method) ", exception.StackTrace) - End Using - End Sub - - - Public Sub Control_Invoke_Delegate_MethodInvoker_calls_correct_method() - Using _control As New Control - _control.CreateControl() - - Dim invoker As New MethodInvoker(AddressOf FaultingMethod) - Dim exception = Assert.Throws(Of DivideByZeroException)( - Sub() _control.Invoke(invoker)) - - ' Expecting something Like the following. - ' The first frame must be the this method, followed by MarshaledInvoke at previous location. - ' - ' at Microsoft.VisualBasic.Forms.Tests.Microsoft.VisualBasic.Forms.Tests.ControlTests.FaultingMethod() in ...\winforms\src\Microsoft.VisualBasic.Forms\tests\UnitTests\ControlTests.vb:line 28 - ' at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6511 - ' at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6487 - ' at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6459 - ' at System.Windows.Forms.Control.InvokeMarshaledCallbacks() in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6563 - ' --- End of stack trace from previous location --- - ' at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6951 - ' at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6413 - ' at System.Windows.Forms.Control.Invoke(Delegate method) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6393 - ' at Microsoft.VisualBasic.Forms.Tests.Microsoft.VisualBasic.Forms.Tests.ControlTests._Closure$__1-1._Lambda$__0() in ...\winforms\src\Microsoft.VisualBasic.Forms\tests\UnitTests\ControlTests.vb:line 18 - - Assert.Contains(NameOf(FaultingMethod), exception.StackTrace) - Assert.Contains(" System.Windows.Forms.Control.Invoke(Delegate method) ", exception.StackTrace) - End Using - End Sub - - - Public Sub Control_Invoke_Func_calls_correct_method() - Using _control As New Control - _control.CreateControl() - - Dim invoker As Func(Of Integer, Integer) = AddressOf FaultingFunc - Dim exception = Assert.Throws(Of DivideByZeroException)( - Sub() - Dim result = _control.Invoke(Function() invoker(19)) - End Sub) - - ' Expecting something Like the following. - ' The first frame must be the this method, followed by MarshaledInvoke at previous location. - ' - ' at Microsoft.VisualBasic.Forms.Tests.Microsoft.VisualBasic.Forms.Tests.ControlTests.FaultingFunc(Int32 a) in ...\winforms\src\Microsoft.VisualBasic.Forms\tests\UnitTests\ControlTests.vb:line 144 - ' at Microsoft.VisualBasic.Forms.Tests.Microsoft.VisualBasic.Forms.Tests.ControlTests._Closure$__4-1._Lambda$__1() in ...\winforms\src\Microsoft.VisualBasic.Forms\tests\UnitTests\ControlTests.vb:line 112 - ' --- End of stack trace from previous location --- - ' at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6951 - ' at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6413 - ' at System.Windows.Forms.Control.Invoke[T](Func`1 method) in ...\winforms\src\System.Windows.Forms\src\System\Windows\Forms\Control.cs:line 6422 - ' at Microsoft.VisualBasic.Forms.Tests.Microsoft.VisualBasic.Forms.Tests.ControlTests._Closure$__4-1._Lambda$__0() in ...\winforms\src\Microsoft.VisualBasic.Forms\tests\UnitTests\ControlTests.vb:line 111 - ' at Xunit.Assert.RecordException(Action testCode) in C:\Dev\xunit\xunit\src\xunit.assert\Asserts\Record.cs:line 27 - - Assert.Contains(NameOf(FaultingFunc), exception.StackTrace) - Assert.Contains(" System.Windows.Forms.Control.Invoke[T](Func`1 method) ", exception.StackTrace) - End Using - End Sub - - Shared Sub FaultingMethod() - Throw New DivideByZeroException() - End Sub - - Shared Function FaultingFunc(a As Integer) As Integer - Return a \ 0 - End Function - - End Class - -End Namespace - diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/runtimeconfig.template.json b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/runtimeconfig.template.json deleted file mode 100644 index e460762026c..00000000000 --- a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/runtimeconfig.template.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "configProperties": { - "TestSwitch.LocalAppContext.DisableCaching": "true", - "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": "false" - } -} \ No newline at end of file diff --git a/src/Microsoft.VisualBasic/Directory.Build.props b/src/Microsoft.VisualBasic/Directory.Build.props deleted file mode 100644 index 4691d3cd770..00000000000 --- a/src/Microsoft.VisualBasic/Directory.Build.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - 10.1.0.0 - Microsoft - - diff --git a/src/Microsoft.VisualBasic/src/Microsoft.VisualBasic.Facade.csproj b/src/Microsoft.VisualBasic/src/Microsoft.VisualBasic.Facade.csproj deleted file mode 100644 index 2fca69fd6aa..00000000000 --- a/src/Microsoft.VisualBasic/src/Microsoft.VisualBasic.Facade.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - Microsoft.VisualBasic - - - - - - - - diff --git a/src/Microsoft.VisualBasic/tests/Directory.Build.targets b/src/Microsoft.VisualBasic/tests/Directory.Build.targets deleted file mode 100644 index 4cdd168b9a6..00000000000 --- a/src/Microsoft.VisualBasic/tests/Directory.Build.targets +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - diff --git a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/GlobalUsings.cs b/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/GlobalUsings.cs deleted file mode 100644 index 5abc35b2162..00000000000 --- a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/GlobalUsings.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -global using System.Diagnostics; -global using Xunit; diff --git a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/InteractionTests.cs b/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/InteractionTests.cs deleted file mode 100644 index cb4cb2065d2..00000000000 --- a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/InteractionTests.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms.IntegrationTests.Common; - -namespace Microsoft.VisualBasic.IntegrationTests; - -public class InteractionTests -{ - [Fact] - public void AppActivate_ProcessId() - { - Process process = StartTestProcess("Interaction.MsgBox"); - try - { - Interaction.AppActivate(process.Id); - } - catch (ArgumentException) - { - // Modal dialog may be closed automatically on build machine. - } - - EndProcess(process); - } - - [Fact] - public void AppActivate_Title_ArgumentException() - { - // Exception.ToString() called to verify message is constructed successfully. - _ = Assert.Throws(() => Interaction.AppActivate(GetUniqueName())).ToString(); - } - - [Fact] - public void InputBox() - { - Process process = StartTestProcess("Interaction.InputBox"); - EndProcess(process); - } - - [Fact] - public void InputBox_VbHost() - { - Process process = StartTestProcess("Interaction.InputBox_VbHost"); - EndProcess(process); - } - - [Fact] - public void VBInputBox_ShowDialog() - { - Process process = StartTestProcess("VBInputBox.ShowDialog"); - EndProcess(process); - Assert.True(process.HasExited); - Assert.NotEqual(2, process.ExitCode); - } - - [Fact] - public void MsgBox() - { - Process process = StartTestProcess("Interaction.MsgBox"); - try - { - TestHelpers.SendEnterKeyToProcess(process); - } - catch (ArgumentException) - { - // Modal dialog may be closed automatically on build machine. - } - - EndProcess(process); - } - - [Fact] - public void MsgBox_VbHost() - { - Process process = StartTestProcess("Interaction.MsgBox_VbHost"); - try - { - TestHelpers.SendEnterKeyToProcess(process); - } - catch (ArgumentException) - { - // Modal dialog may be closed automatically on build machine. - } - - EndProcess(process); - } - - [Fact] - public void Shell() - { - int processId = Interaction.Shell(_exePath); - Process process = Process.GetProcessById(processId); - process.Kill(); - process.WaitForExit(); - } - - [Fact] - public void Shell_NullReferenceException() - { - // Exception.ToString() called to verify message is constructed successfully. - _ = Assert.Throws(() => Interaction.Shell(null)).ToString(); - } - - [Fact] - public void Shell_FileNotFoundException() - { - var path = Path.Combine(Path.GetTempPath(), GetUniqueName()); - // Exception.ToString() called to verify message is constructed successfully. - _ = Assert.Throws(() => Interaction.Shell(path)).ToString(); - } - - private static readonly string _exePath = TestHelpers.GetExePath("VisualBasicRuntimeTest"); - - private static Process StartTestProcess(string arguments) - { - ProcessStartInfo startInfo = new() { FileName = _exePath, Arguments = arguments }; - return TestHelpers.StartProcess(startInfo); - } - - private static void EndProcess(Process process) - { - TestHelpers.EndProcess(process, 1000); - } - - private static string GetUniqueName() => Guid.NewGuid().ToString("D"); -} diff --git a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/Microsoft.VisualBasic.IntegrationTests.csproj b/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/Microsoft.VisualBasic.IntegrationTests.csproj deleted file mode 100644 index c0f023ecd50..00000000000 --- a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/Microsoft.VisualBasic.IntegrationTests.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - true - - - - - - - - - diff --git a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBaseTests.cs b/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBaseTests.cs deleted file mode 100644 index 194ffecfd7a..00000000000 --- a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBaseTests.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms.IntegrationTests.Common; -using Microsoft.VisualBasic.ApplicationServices; - -namespace Microsoft.VisualBasic.IntegrationTests; - -public class WindowsFormsApplicationBaseTests -{ - [Fact] - public void Run() - { - string exePath = TestHelpers.GetExePath("VisualBasicRuntimeTest"); - ProcessStartInfo startInfo = new() { FileName = exePath, Arguments = "WindowsFormsApplicationBase.Run" }; - Process process = TestHelpers.StartProcess(startInfo); - TestHelpers.EndProcess(process, timeout: 1000); - Assert.True(process.HasExited); - } - - [Fact] - public void RunSingleInstance() - { - string exePath = TestHelpers.GetExePath("VisualBasicRuntimeTest"); - Process process0 = TestHelpers.StartProcess(new ProcessStartInfo { FileName = exePath, Arguments = "WindowsFormsApplicationBase.RunSingleInstance0" }); - Process process1 = TestHelpers.StartProcess(new ProcessStartInfo { FileName = exePath, Arguments = "WindowsFormsApplicationBase.RunSingleInstance1" }); - TestHelpers.EndProcess(process0, timeout: 1000); - TestHelpers.EndProcess(process1, timeout: 1000); - Assert.True(process0.HasExited); - Assert.True(process1.HasExited); - } - - [Fact] - public void Run_NoStartupFormException() - { - WindowsFormsApplicationBase application = new(); - // Exception.ToString() called to verify message is constructed successfully. - _ = Assert.Throws(() => application.Run(Array.Empty())).ToString(); - } -} diff --git a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/Microsoft/VisualBasic/MyServices/Internal/ProgressDialogTests.cs b/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/Microsoft/VisualBasic/MyServices/Internal/ProgressDialogTests.cs deleted file mode 100644 index 3483da4641e..00000000000 --- a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/Microsoft/VisualBasic/MyServices/Internal/ProgressDialogTests.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms.IntegrationTests.Common; - -namespace Microsoft.VisualBasic.MyServices.Internal.Tests; - -public class ProgressDialogTests -{ - [Fact] - public void ShowProgressDialog() - { - string exePath = TestHelpers.GetExePath("VisualBasicRuntimeTest"); - ProcessStartInfo startInfo = new() { FileName = exePath, Arguments = "ProgressDialog.ShowProgressDialog" }; - Process process = TestHelpers.StartProcess(startInfo); - TestHelpers.EndProcess(process, timeout: 1000); - Assert.True(process.HasExited); - Assert.NotEqual(2, process.ExitCode); - } -} diff --git a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/runtimeconfig.template.json b/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/runtimeconfig.template.json deleted file mode 100644 index e460762026c..00000000000 --- a/src/Microsoft.VisualBasic/tests/IntegrationTests/Microsoft.VisualBasic.IntegrationTests/runtimeconfig.template.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "configProperties": { - "TestSwitch.LocalAppContext.DisableCaching": "true", - "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": "false" - } -} \ No newline at end of file diff --git a/src/Microsoft.VisualBasic/tests/IntegrationTests/VisualBasicRuntimeTest/Program.cs b/src/Microsoft.VisualBasic/tests/IntegrationTests/VisualBasicRuntimeTest/Program.cs deleted file mode 100644 index 2e299db7c69..00000000000 --- a/src/Microsoft.VisualBasic/tests/IntegrationTests/VisualBasicRuntimeTest/Program.cs +++ /dev/null @@ -1,194 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Reflection; -using System.Resources; -using System.Windows.Forms; -using Microsoft.VisualBasic; -using Microsoft.VisualBasic.ApplicationServices; -using Microsoft.VisualBasic.CompilerServices; - -namespace VisualBasicRuntimeTest; - -internal class Program -{ - [STAThread] - static void Main(string[] args) - { - try - { - if (args.Length != 1) - { - throw new ArgumentException(); - } - - switch (args[0]) - { - case "Interaction.InputBox": - Interaction_InputBox(useVbHost: false); - break; - case "Interaction.InputBox_VbHost": - Interaction_InputBox(useVbHost: true); - break; - case "Interaction.MsgBox": - Interaction_MsgBox(useVbHost: false); - break; - case "Interaction.MsgBox_VbHost": - Interaction_MsgBox(useVbHost: true); - break; - case "WindowsFormsApplicationBase.Run": - WindowsFormsApplicationBase_Run(isSingleInstance: false, isFirstInstance: true); - break; - case "WindowsFormsApplicationBase.RunSingleInstance0": - WindowsFormsApplicationBase_Run(isSingleInstance: true, isFirstInstance: true); - break; - case "WindowsFormsApplicationBase.RunSingleInstance1": - WindowsFormsApplicationBase_Run(isSingleInstance: true, isFirstInstance: false); - break; - case "ProgressDialog.ShowProgressDialog": - ProgressDialog_ShowProgressDialog(); - break; - case "VBInputBox.ShowDialog": - VBInputBox_ShowDialog(); - break; - default: - throw new ArgumentException(); - } - } - catch (Exception) - { - Environment.Exit(2); - } - } - - private static void Interaction_InputBox(bool useVbHost) - { - VbHost host = useVbHost ? new VbHost() : null; - HostServices.VBHost = host; - Interaction.InputBox(Prompt: "Prompt", Title: "Title"); - } - - private static void Interaction_MsgBox(bool useVbHost) - { - VbHost host = useVbHost ? new VbHost() : null; - HostServices.VBHost = host; - Interaction.MsgBox(Prompt: "Message", Buttons: MsgBoxStyle.OkCancel, Title: "Title"); - } - - private static void WindowsFormsApplicationBase_Run(bool isSingleInstance, bool isFirstInstance) - { - Form mainForm = new(); - WindowsApplication application = new(mainForm, isSingleInstance); - - bool valid = false; - bool loaded = false; - bool startUpNextInstance = false; - - application.StartupNextInstance += (object sender, StartupNextInstanceEventArgs e) => - { - startUpNextInstance = true; - if (!isFirstInstance) - { - mainForm.Close(); - } - }; - - mainForm.Load += (object sender, EventArgs e) => - { - loaded = true; - var forms = application.OpenForms; - valid = forms.Count == 1 && - forms[0] == mainForm && - application.ApplicationContext.MainForm == mainForm; - if (!valid) - { - mainForm.Close(); - } - }; - - application.Run(Array.Empty()); - - if (startUpNextInstance) - { - throw new InvalidOperationException(); - } - - if (!loaded && !isFirstInstance) - { - throw new InvalidOperationException(); - } - - if (!valid) - { - throw new InvalidOperationException(); - } - } - - private static void ProgressDialog_ShowProgressDialog() - { - Type dialogType = typeof(ApplicationBase).Assembly.GetType("Microsoft.VisualBasic.MyServices.Internal.ProgressDialog"); - var dialog = (Form)Activator.CreateInstance(dialogType, nonPublic: true); - - ResourceManager resources = new(dialogType); - var expectedValue = (Point)resources.GetObject("ProgressBarWork.Location"); - if (expectedValue == new Point(0, 0)) - { - throw new InvalidOperationException(); - } - - PropertyInfo controlProperty = dialogType.GetProperty("ProgressBarWork", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); - var control = (Control)controlProperty.GetValue(dialog); - Point actualValue = control.Location; - if (actualValue != expectedValue) - { - throw new InvalidOperationException(); - } - - MethodInfo showMethod = dialogType.GetMethod("ShowProgressDialog"); - showMethod.Invoke(dialog, null); - } - - private static void VBInputBox_ShowDialog() - { - Type formType = typeof(ApplicationBase).Assembly.GetType("Microsoft.VisualBasic.CompilerServices.VBInputBox"); - var form = (Form)Activator.CreateInstance(formType, nonPublic: true); - - ResourceManager resources = new(formType); - var expectedValue = (Point)resources.GetObject("TextBox.Location"); - if (expectedValue == new Point(0, 0)) - { - throw new InvalidOperationException(); - } - - FieldInfo controlField = formType.GetField("TextBox", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); - var control = (Control)controlField.GetValue(form); - Point actualValue = control.Location; - if (actualValue != expectedValue) - { - throw new InvalidOperationException(); - } - - form.ShowDialog(); - } - - private sealed class WindowsApplication : WindowsFormsApplicationBase - { - internal WindowsApplication(Form mainForm, bool isSingleInstance) - { - MainForm = mainForm; - IsSingleInstance = isSingleInstance; - } - } - - private static string GetUniqueName() => Guid.NewGuid().ToString("D"); - - private sealed class VbHost : IVbHost - { - private readonly string _title = GetUniqueName(); - - public IWin32Window GetParentWindow() => null; - - public string GetWindowTitle() => _title; - } -} diff --git a/src/Microsoft.VisualBasic/tests/IntegrationTests/VisualBasicRuntimeTest/VisualBasicRuntimeTest.csproj b/src/Microsoft.VisualBasic/tests/IntegrationTests/VisualBasicRuntimeTest/VisualBasicRuntimeTest.csproj deleted file mode 100644 index 8f3ddde355d..00000000000 --- a/src/Microsoft.VisualBasic/tests/IntegrationTests/VisualBasicRuntimeTest/VisualBasicRuntimeTest.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - Exe - - - - - - - diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/GlobalUsings.cs b/src/Microsoft.VisualBasic/tests/UnitTests/GlobalUsings.cs deleted file mode 100644 index 5abc35b2162..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/GlobalUsings.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -global using System.Diagnostics; -global using Xunit; diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft.VisualBasic.Tests.csproj b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft.VisualBasic.Tests.csproj deleted file mode 100644 index ac5c446edca..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft.VisualBasic.Tests.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - $(TargetFramework)-windows7.0 - true - true - true - - - - - - - - - - - - - - diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/ApplicationBaseTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/ApplicationBaseTests.cs deleted file mode 100644 index 87fbe88925c..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/ApplicationBaseTests.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.ApplicationServices.Tests; - -public class ApplicationBaseTests -{ - [Fact] - public void Culture() - { - var app = new ApplicationBase(); - var culture = app.Culture; - Assert.Equal(System.Threading.Thread.CurrentThread.CurrentCulture, culture); - try - { - app.ChangeCulture("en-US"); - Assert.Equal(System.Threading.Thread.CurrentThread.CurrentCulture, app.Culture); - Assert.Equal("en-US", app.Culture.Name); - } - finally - { - System.Threading.Thread.CurrentThread.CurrentCulture = culture; - } - } - - [Fact] - public void UICulture() - { - var app = new ApplicationBase(); - var culture = app.UICulture; - Assert.Equal(System.Threading.Thread.CurrentThread.CurrentUICulture, culture); - try - { - app.ChangeUICulture("en-US"); - Assert.Equal(System.Threading.Thread.CurrentThread.CurrentUICulture, app.UICulture); - Assert.Equal("en-US", app.UICulture.Name); - } - finally - { - System.Threading.Thread.CurrentThread.CurrentUICulture = culture; - } - } - - [Fact] - public void GetEnvironmentVariable() - { - var app = new ApplicationBase(); - foreach (var (key, value) in GetEnvironmentVariables()) - { - Assert.Equal(value, app.GetEnvironmentVariable(key)); - } - } - - [Fact] - public void GetEnvironmentVariable_ArgumentException() - { - var app = new ApplicationBase(); - var key = GetEnvironmentVariables().LastOrDefault().Item1 ?? ""; - var ex = Assert.Throws(() => app.GetEnvironmentVariable($"{key}z")); - _ = ex.ToString(); // ensure message can be formatted - } - - private static (string, string)[] GetEnvironmentVariables() - { - var pairs = new List<(string, string)>(); - var vars = Environment.GetEnvironmentVariables(); - foreach (var key in vars.Keys) - { - pairs.Add(((string)key, (string)vars[key])); - } - - return pairs.OrderBy(pair => pair.Item1).ToArray(); - } - - [Fact] - [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Different entry assembly")] - public void Info() - { - var app = new ApplicationBase(); - var assembly = System.Reflection.Assembly.GetEntryAssembly() ?? System.Reflection.Assembly.GetCallingAssembly(); - var assemblyName = assembly.GetName(); - Assert.Equal(assemblyName.Name, app.Info.AssemblyName); - Assert.Equal(assemblyName.Version, app.Info.Version); - } - - [Fact] - public void Log() - { - var app = new ApplicationBase(); - var log = app.Log; - _ = log.TraceSource; - _ = log.DefaultFileLogWriter; - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/AssemblyInfoTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/AssemblyInfoTests.cs deleted file mode 100644 index 133883b16c6..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/AssemblyInfoTests.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; - -namespace Microsoft.VisualBasic.ApplicationServices.Tests; - -public class AssemblyInfoTests -{ - [Fact] - public void Constructor_ArgumentNullException() - { - Assert.Throws(() => new AssemblyInfo(null)); - } - - [Theory] - [MemberData(nameof(AssemblyProperties_TestData))] - public void AssemblyProperties(System.Reflection.Assembly assembly) - { - var assemblyInfo = new AssemblyInfo(assembly); - var assemblyName = assembly.GetName(); - Assert.Equal(assemblyName.Name, assemblyInfo.AssemblyName); - Assert.Equal(System.IO.Path.GetDirectoryName(assembly.Location), assemblyInfo.DirectoryPath); - Assert.Equal(GetAttributeValue(assembly, attr => attr.Company), assemblyInfo.CompanyName); - Assert.Equal(GetAttributeValue(assembly, attr => attr.Copyright), assemblyInfo.Copyright); - Assert.Equal(GetAttributeValue(assembly, attr => attr.Description), assemblyInfo.Description); - Assert.Equal(GetAttributeValue(assembly, attr => attr.Product), assemblyInfo.ProductName); - Assert.Equal(GetAttributeValue(assembly, attr => attr.Title), assemblyInfo.Title); - Assert.Equal(GetAttributeValue(assembly, attr => attr.Trademark), assemblyInfo.Trademark); - Assert.Equal(assemblyName.Version, assemblyInfo.Version); - } - - public static IEnumerable AssemblyProperties_TestData() - { - yield return new object[] { typeof(object).Assembly }; - yield return new object[] { Assembly.GetExecutingAssembly() }; - } - - [Fact] - public void LoadedAssemblies() - { - var executingAssembly = Assembly.GetExecutingAssembly(); - var assemblyInfo = new AssemblyInfo(executingAssembly); - var loadedAssemblies = assemblyInfo.LoadedAssemblies; - Assert.Contains(executingAssembly, loadedAssemblies); - } - - [Fact] - public void StackTrace() - { - // Property is independent of the actual assembly. - var assemblyInfo = new AssemblyInfo(Assembly.GetExecutingAssembly()); - var stackTrace = assemblyInfo.StackTrace; - Assert.Contains(nameof(AssemblyInfoTests), stackTrace); - } - - [Fact] - public void WorkingSet() - { - // Property is independent of the actual assembly. - var assemblyInfo = new AssemblyInfo(Assembly.GetExecutingAssembly()); - var workingSet = assemblyInfo.WorkingSet; - Assert.True(workingSet > 0); - } - - private static string GetAttributeValue(System.Reflection.Assembly assembly, Func getAttributeValue) - where TAttribute : Attribute - { - var attribute = (TAttribute)assembly.GetCustomAttribute(typeof(TAttribute)); - return (attribute is null) ? "" : getAttributeValue(attribute); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/ConsoleApplicationBaseTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/ConsoleApplicationBaseTests.cs deleted file mode 100644 index 99e0922eecb..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/ConsoleApplicationBaseTests.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.ApplicationServices.Tests; - -public class ConsoleApplicationBaseTests -{ - [Fact] - public void CommandLineArgs() - { - var app = new ConsoleApplicationBase(); - var expected = System.Environment.GetCommandLineArgs().Skip(1).ToArray(); - Assert.Equal(expected, app.CommandLineArgs); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/SingleInstanceTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/SingleInstanceTests.cs deleted file mode 100644 index 5d19f76c2fd..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/SingleInstanceTests.cs +++ /dev/null @@ -1,374 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using System.IO.Pipes; -using System.Runtime.Serialization; -using System.Text; - -namespace Microsoft.VisualBasic.ApplicationServices.Tests; - -public class SingleInstanceTests -{ - private const int SendTimeout = 10000; - - private sealed class ReceivedArgs - { - private List _received = new(); - - internal void Add(string[] args) - { - _received.Add(args); - } - - internal ImmutableArray Freeze() - { - var received = _received; - Interlocked.CompareExchange(ref _received, null, received); - return received.ToImmutableArray(); - } - } - - private readonly dynamic _testAccessor = GetTestHelper(); - - private static dynamic GetTestHelper() - { - var assembly = typeof(Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase).Assembly; - var type = assembly.GetType("Microsoft.VisualBasic.ApplicationServices.SingleInstanceHelpers"); - return type.TestAccessor().Dynamic; - } - - private bool TryCreatePipeServer(string pipeName, out NamedPipeServerStream pipeServer) - { - return _testAccessor.TryCreatePipeServer(pipeName, out pipeServer); - } - - private Task WaitForClientConnectionsAsync(NamedPipeServerStream pipeServer, Action callback, CancellationToken cancellationToken = default) - { - return _testAccessor.WaitForClientConnectionsAsync(pipeServer, callback, cancellationToken); - } - - private Task SendSecondInstanceArgsAsync(string pipeName, string[] args, CancellationToken cancellationToken) - { - return _testAccessor.SendSecondInstanceArgsAsync(pipeName, args, cancellationToken); - } - - private bool SendSecondInstanceArgs(string pipeName, int timeout, string[] args) - { - var tokenSource = new CancellationTokenSource(); - tokenSource.CancelAfter(timeout); - try - { - var awaitable = SendSecondInstanceArgsAsync(pipeName, args, tokenSource.Token).ConfigureAwait(false); - awaitable.GetAwaiter().GetResult(); - } - catch (Exception) - { - return false; - } - - return true; - } - - private static string GetUniqueName() => Guid.NewGuid().ToString(); - - [Fact] - public void MultipleDistinctServers() - { - var pipeServers = new List(); - int n = 5; - try - { - for (int i = 0; i < n; i++) - { - Assert.True(TryCreatePipeServer(GetUniqueName(), out var pipeServer)); - Assert.NotNull(pipeServer); - pipeServers.Add(pipeServer); - } - } - finally - { - foreach (var pipeServer in pipeServers) - { - pipeServer.Dispose(); - } - } - } - - [Fact] - public void MultipleServers_Overlapping() - { - var pipeName = GetUniqueName(); - const int n = 10; - int completed = 0; - int created = 0; - var tasks = Enumerable.Range(0, n).Select(i => Task.Factory.StartNew(() => - { - Thread.Sleep(100); - if (TryCreatePipeServer(pipeName, out var pipeServer)) - { - Interlocked.Increment(ref created); - } - - using (pipeServer) - { - Thread.Sleep(10); - } - - Interlocked.Increment(ref completed); - }, cancellationToken: default, creationOptions: default, scheduler: TaskScheduler.Default)).ToArray(); - Task.WaitAll(tasks); - Assert.Equal(n, completed); - Assert.True(created >= 1); - } - - [Fact] - public void MultipleClients_Sequential() - { - var pipeName = GetUniqueName(); - Assert.True(TryCreatePipeServer(pipeName, out var pipeServer)); - using (pipeServer) - { - const int n = 5; - var sentArgs = Enumerable.Range(0, n).Select(i => Enumerable.Range(0, i).Select(i => i.ToString()).ToArray()).ToArray(); - var receivedArgs = new ReceivedArgs(); - WaitForClientConnectionsAsync(pipeServer, receivedArgs.Add); - for (int i = 0; i < n; i++) - { - Assert.True(SendSecondInstanceArgs(pipeName, SendTimeout, sentArgs[i])); - } - - FlushLastConnection(pipeName); - Assert.Equal(sentArgs, receivedArgs.Freeze()); - } - } - - [Fact] - public void MultipleClients_Overlapping() - { - var pipeName = GetUniqueName(); - Assert.True(TryCreatePipeServer(pipeName, out var pipeServer)); - using (pipeServer) - { - const int n = 5; - var sentArgs = Enumerable.Range(0, n).Select(i => Enumerable.Range(0, i).Select(i => i.ToString()).ToArray()).ToArray(); - var receivedArgs = new ReceivedArgs(); - WaitForClientConnectionsAsync(pipeServer, receivedArgs.Add); - var tasks = Enumerable.Range(0, n).Select(i => Task.Factory.StartNew(() => { Assert.True(SendSecondInstanceArgs(pipeName, SendTimeout, sentArgs[i])); }, cancellationToken: default, creationOptions: default, scheduler: TaskScheduler.Default)).ToArray(); - Task.WaitAll(tasks); - FlushLastConnection(pipeName); - var receivedSorted = receivedArgs.Freeze().Sort((x, y) => x.Length - y.Length); - Assert.Equal(sentArgs, receivedSorted); - } - } - - // Message that exceeds the buffer size in SingleInstanceHelpers.ReadArgsAsync. - [Fact] - public void ManyArgs() - { - var pipeName = GetUniqueName(); - Assert.True(TryCreatePipeServer(pipeName, out var pipeServer)); - using (pipeServer) - { - var expectedArgs = getStrings(20000).ToArray(); - var receivedArgs = new ReceivedArgs(); - WaitForClientConnectionsAsync(pipeServer, receivedArgs.Add); - Assert.True(SendSecondInstanceArgs(pipeName, SendTimeout, expectedArgs)); - FlushLastConnection(pipeName); - var actualArgs = receivedArgs.Freeze().Single(); - Assert.Equal(expectedArgs, actualArgs); - } - - static IEnumerable getStrings(int maxTotalLength) - { - var r = new Random(); - int n = 0; - while (n < maxTotalLength) - { - var str = getString(r); - n += str.Length; - yield return str; - } - } - - static string getString(Random r) - { - int n = r.Next(1000); - var builder = new StringBuilder(); - for (int i = 0; i < n; i++) - { - builder.Append((char)('a' + r.Next(26))); - } - - return builder.ToString(); - } - } - - [Fact] - public void ClientConnectionTimeout() - { - var pipeName = GetUniqueName(); - Assert.True(TryCreatePipeServer(pipeName, out var pipeServer)); - using (pipeServer) - { - var task = Task.Factory.StartNew(() => SendSecondInstanceArgs(pipeName, timeout: 300, Array.Empty()), cancellationToken: default, creationOptions: default, scheduler: TaskScheduler.Default); - bool result = task.Result; - Assert.False(result); - } - } - - // Corresponds to second instance crash sending incomplete args. - [Fact] - public void ClientConnectBeforeWaitForClientConnection() - { - var pipeName = GetUniqueName(); - Assert.True(TryCreatePipeServer(pipeName, out var pipeServer)); - using (pipeServer) - { - var receivedArgs = new ReceivedArgs(); - var task = Task.Factory.StartNew(() => SendSecondInstanceArgs(pipeName, SendTimeout, new[] { "1", "ABC" }), cancellationToken: default, creationOptions: default, scheduler: TaskScheduler.Default); - // Allow time for connection. - Thread.Sleep(100); - WaitForClientConnectionsAsync(pipeServer, receivedArgs.Add); - task.Wait(); - FlushLastConnection(pipeName); - Assert.Equal(new[] { new[] { "1", "ABC" } }, receivedArgs.Freeze()); - } - } - - // Send data other than string[]. - [Fact] - public void InvalidClientData() - { - var pipeName = GetUniqueName(); - Assert.True(TryCreatePipeServer(pipeName, out var pipeServer)); - using (pipeServer) - { - var receivedArgs = new ReceivedArgs(); - WaitForClientConnectionsAsync(pipeServer, receivedArgs.Add); - - sendData(pipeName, Array.Empty()); // valid - sendData(pipeName, (int)3); // invalid - sendData(pipeName, new[] { "ABC" }); // valid - sendData(pipeName, new int[] { 1, 2, 3 }); // invalid - sendData(pipeName, new[] { "", "" }); // valid - sendData(pipeName, new char[] { '1', '2', '3' }); // invalid - - FlushLastConnection(pipeName); - - Assert.Equal(new[] { Array.Empty(), new[] { "ABC" }, new[] { "", "" } }, receivedArgs.Freeze()); - } - - static void sendData(string pipeName, T obj) - { - var pipeClient = CreateClientConnection(pipeName, SendTimeout); - if (pipeClient is null) - { - return; - } - - using (pipeClient) - { - var serializer = new DataContractSerializer(typeof(T)); - serializer.WriteObject(pipeClient, obj); - } - } - } - - // Corresponds to second instance crash sending incomplete args. - [Fact] - public void CloseClientAfterClientConnect() - { - var pipeName = GetUniqueName(); - Assert.True(TryCreatePipeServer(pipeName, out var pipeServer)); - using (pipeServer) - { - var receivedArgs = new ReceivedArgs(); - WaitForClientConnectionsAsync(pipeServer, receivedArgs.Add); - - // Send valid args. - Assert.True(SendSecondInstanceArgs(pipeName, SendTimeout, Array.Empty())); - Assert.True(SendSecondInstanceArgs(pipeName, SendTimeout, new[] { "1", "ABC" })); - - // Send bad args: close client after connect. - closeAfterConnect(pipeName); - - // Send invalid args. - sendUnexpectedArgs(pipeName); - - // Send valid args. - Assert.True(SendSecondInstanceArgs(pipeName, SendTimeout, new[] { "DEF", "2" })); - - FlushLastConnection(pipeName); - - Assert.Equal(new[] { Array.Empty(), new[] { "1", "ABC" }, new[] { "DEF", "2" } }, receivedArgs.Freeze()); - } - - static void closeAfterConnect(string pipeName) - { - using var pipeClient = CreateClientConnection(pipeName, SendTimeout); - } - - static void sendUnexpectedArgs(string pipeName) - { - var pipeClient = CreateClientConnection(pipeName, SendTimeout); - if (pipeClient is null) - { - return; - } - - using (pipeClient) - { - pipeClient.Write(new byte[] { 1, 2, 3 }, 0, 3); - } - } - } - - // Corresponds to first instance closing while second instance is sending args. - [Fact] - public void CloseServerAfterClientConnect() - { - var pipeName = GetUniqueName(); - NamedPipeClientStream pipeClient = null; - try - { - var receivedArgs = new ReceivedArgs(); - Assert.True(TryCreatePipeServer(pipeName, out var pipeServer)); - using (pipeServer) - { - WaitForClientConnectionsAsync(pipeServer, receivedArgs.Add); - pipeClient = CreateClientConnection(pipeName, SendTimeout); - } - - Thread.Sleep(500); - Assert.Empty(receivedArgs.Freeze()); - } - finally - { - pipeClient?.Dispose(); - } - } - - // Ensure the previous client connection has been consumed completely by the - // server by creating an extra client connection that closes after connecting. - private static void FlushLastConnection(string pipeName) - { - using var _ = CreateClientConnection(pipeName, SendTimeout); - } - - private static NamedPipeClientStream CreateClientConnection(string pipeName, int timeout) - { - var pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.Out); - try - { - pipeClient.Connect(timeout); - } - catch (TimeoutException) - { - pipeClient.Dispose(); - return null; - } - - return pipeClient; - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/StartupEventArgsTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/StartupEventArgsTests.cs deleted file mode 100644 index 5cea119d70e..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/StartupEventArgsTests.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.ObjectModel; - -namespace Microsoft.VisualBasic.ApplicationServices.Tests; - -public class StartupEventArgsTests -{ - [Fact] - public void Ctor_ReadOnlyCollection() - { - var collection = new ReadOnlyCollection(new string[] { "a" }); - var args = new StartupEventArgs(collection); - Assert.Same(collection, args.CommandLine); - } - - [Fact] - public void Ctor_NullCommandLine_ThrowsArgumentNullException() - { - AssertExtensions.Throws("list", () => new StartupEventArgs(null)); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/StartupNextInstanceEventArgsTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/StartupNextInstanceEventArgsTests.cs deleted file mode 100644 index 833937e9d5f..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/StartupNextInstanceEventArgsTests.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.ObjectModel; - -namespace Microsoft.VisualBasic.ApplicationServices.Tests; - -public class StartupNextInstanceEventArgsTests -{ - [Theory] - [InlineData(true)] - [InlineData(false)] - public void Ctor_ReadOnlyCollection_Boolean(bool bringToForeground) - { - var collection = new ReadOnlyCollection(new string[] { "a" }); - var args = new StartupNextInstanceEventArgs(collection, bringToForeground); - Assert.Same(collection, args.CommandLine); - Assert.Equal(bringToForeground, args.BringToForeground); - } - - [Fact] - public void Ctor_NullCommandLine_ThrowsArgumentNullException() - { - AssertExtensions.Throws("list", () => new StartupNextInstanceEventArgs(null, bringToForegroundFlag: true)); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void BringToForeground_Set_GetReturnsExpected(bool value) - { - var collection = new ReadOnlyCollection(new string[] { "a" }); - var args = new StartupNextInstanceEventArgs(collection, bringToForegroundFlag: true) - { - BringToForeground = value - }; - Assert.Equal(value, args.BringToForeground); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/UnhandledExceptionEventArgsTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/UnhandledExceptionEventArgsTests.cs deleted file mode 100644 index 2ecd2d153c4..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/UnhandledExceptionEventArgsTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.ApplicationServices.Tests; - -public class UnhandledExceptionEventArgsTests -{ - public static IEnumerable Ctor_Bool_Exception_TestData() - { - yield return new object[] { true, null }; - yield return new object[] { false, new Exception() }; - } - - [Theory] - [MemberData(nameof(Ctor_Bool_Exception_TestData))] - public void Ctor_Bool_Exception(bool exitApplication, Exception exception) - { - var args = new UnhandledExceptionEventArgs(exitApplication, exception); - Assert.Same(exception, args.Exception); - Assert.Equal(exitApplication, args.ExitApplication); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void ExitApplication_Set_GetReturnsExpected(bool value) - { - var args = new UnhandledExceptionEventArgs(true, null); - args.ExitApplication = value; - Assert.Equal(value, args.ExitApplication); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/UserTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/UserTests.cs deleted file mode 100644 index bf143be283f..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/UserTests.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.ApplicationServices.Tests; - -public class UserTests -{ - [Fact] - public void Properties() - { - var user = new User(); - Assert.Equal(System.Threading.Thread.CurrentPrincipal, user.CurrentPrincipal); - if (user.CurrentPrincipal is not null) - { - Assert.Equal(System.Threading.Thread.CurrentPrincipal.Identity.Name, user.Name); - Assert.Equal(System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated, user.IsAuthenticated); - Assert.Equal(System.Threading.Thread.CurrentPrincipal.IsInRole("Guest"), user.IsInRole("Guest")); - } - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBaseTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBaseTests.cs deleted file mode 100644 index 368ded09eab..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBaseTests.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; -using System.Reflection.Emit; -using System.Runtime.InteropServices; - -namespace Microsoft.VisualBasic.ApplicationServices.Tests; - -public class WindowsFormsApplicationBaseTests -{ - private static string GetAppID(Assembly assembly) - { - var testAccessor = typeof(WindowsFormsApplicationBase).TestAccessor(); - return testAccessor.Dynamic.GetApplicationInstanceID(assembly); - } - - [Fact] - public void GetApplicationInstanceID() - { - var assembly = typeof(WindowsFormsApplicationBaseTests).Assembly; - var expectedId = assembly.ManifestModule.ModuleVersionId.ToString(); - Assert.Equal(expectedId, GetAppID(assembly)); - } - - private static string GetUniqueIDFromAssembly(string guid, Version version) - { - var attributeBuilder = new CustomAttributeBuilder( - typeof(GuidAttribute).GetConstructor(new[] { typeof(string) }), new[] { guid }); - var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly( - new AssemblyName(Guid.NewGuid().ToString()) { Version = version }, - AssemblyBuilderAccess.RunAndCollect, - new[] { attributeBuilder }); - assemblyBuilder.DefineDynamicModule(Guid.NewGuid().ToString()); - return GetAppID(assemblyBuilder); - } - - [Fact] - public void GetApplicationInstanceID_GuidAttribute() - { - var guid = Guid.NewGuid().ToString(); - Assert.Equal($"{guid}1.2", GetUniqueIDFromAssembly(guid, new Version(1, 2, 3, 4))); - } - - [Fact] - public void GetApplicationInstanceID_GuidAttributeNewVersion() - { - var guid = Guid.NewGuid().ToString(); - Assert.Equal($"{guid}0.0", GetUniqueIDFromAssembly(guid, new Version())); - } - - [Fact] - public void GetApplicationInstanceID_GuidAttributeNullVersion() - { - var guid = Guid.NewGuid().ToString(); - Assert.Equal($"{guid}0.0", GetUniqueIDFromAssembly(guid, version: null)); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/AudioTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/AudioTests.cs deleted file mode 100644 index 116a7efc5fb..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/AudioTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.Devices.Tests; - -public class AudioTests -{ - [Fact] - public void Play() - { - var location = Path.Combine(Path.GetTempPath(), GetUniqueName()); - var audio = new Audio(); - Assert.Throws(() => audio.Play(location)); - } - - // Not tested: - // Public Sub PlaySystemSound(ByVal systemSound As System.Media.SystemSound) - - [Fact] - public void Stop() - { - var audio = new Audio(); - audio.Stop(); - } - - private static string GetUniqueName() => Guid.NewGuid().ToString("D"); -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ClockTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ClockTests.cs deleted file mode 100644 index 6b2be555f59..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ClockTests.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.Devices.Tests; - -public class ClockTests -{ - [Fact] - public void LocalTime() - { - var clock = new Clock(); - - var before = clock.LocalTime; - System.Threading.Thread.Sleep(10); - - var now = DateTime.Now; - System.Threading.Thread.Sleep(10); - - var after = clock.LocalTime; - - Assert.True(before <= now); - Assert.True(now <= after); - } - - [Fact] - public void GmtTime() - { - var clock = new Clock(); - - var before = clock.GmtTime; - System.Threading.Thread.Sleep(10); - - var now = DateTime.UtcNow; - System.Threading.Thread.Sleep(10); - - var after = clock.GmtTime; - - Assert.True(before <= now); - Assert.True(now <= after); - } - - [Fact] - public void TickCount() - { - var clock = new Clock(); - - var before = clock.TickCount; - System.Threading.Thread.Sleep(10); - - var after = clock.TickCount; - Assert.True(before <= after); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ComputerInfoTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ComputerInfoTests.cs deleted file mode 100644 index 2b0d7cfd049..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ComputerInfoTests.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.Devices.Tests; - -public class ComputerInfoTests -{ - [Fact] - public void Properties() - { - var info = new ComputerInfo(); - Assert.Equal(System.Globalization.CultureInfo.InstalledUICulture, info.InstalledUICulture); - Assert.Equal(System.Environment.OSVersion.Platform.ToString(), info.OSPlatform); - Assert.Equal(System.Environment.OSVersion.Version.ToString(), info.OSVersion); - } - - [Fact] - public void Memory() - { - var info = new ComputerInfo(); - if (PlatformDetection.IsWindows) - { - Assert.NotEqual(0u, info.AvailablePhysicalMemory); - Assert.NotEqual(0u, info.AvailableVirtualMemory); - Assert.NotEqual(0u, info.TotalPhysicalMemory); - Assert.NotEqual(0u, info.TotalVirtualMemory); - } - else - { - Assert.Throws(() => info.AvailablePhysicalMemory); - Assert.Throws(() => info.AvailableVirtualMemory); - Assert.Throws(() => info.TotalPhysicalMemory); - Assert.Throws(() => info.TotalVirtualMemory); - } - } - - [Fact] - public void OSFullName() - { - var info = new ComputerInfo(); - var fullName = info.OSFullName; - Assert.False(string.IsNullOrEmpty(fullName)); - Assert.Equal(System.Runtime.InteropServices.RuntimeInformation.OSDescription, fullName); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ComputerTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ComputerTests.cs deleted file mode 100644 index f0614cb1758..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ComputerTests.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.Devices.Tests; - -public class ComputerTests -{ - [Fact] - public void Properties() - { - var computer = new Computer(); - - var audio = computer.Audio; - Assert.NotNull(audio); - Assert.Same(audio, computer.Audio); - - var clipboard = computer.Clipboard; - Assert.NotNull(clipboard); - Assert.Same(clipboard, computer.Clipboard); - - var keyboard = computer.Keyboard; - Assert.NotNull(keyboard); - Assert.Same(keyboard, computer.Keyboard); - - var mouse = computer.Mouse; - Assert.NotNull(mouse); - Assert.Same(mouse, computer.Mouse); - } - - [Fact] - public void Screen() - { - var computer = new Computer(); - Assert.Equal(System.Windows.Forms.Screen.PrimaryScreen, computer.Screen); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/KeyboardTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/KeyboardTests.cs deleted file mode 100644 index 6dde1beacef..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/KeyboardTests.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.Devices.Tests; - -public class KeyboardTests -{ - [Fact] - public void Properties() - { - var keyboard = new Keyboard(); - _ = keyboard.ShiftKeyDown; - _ = keyboard.AltKeyDown; - _ = keyboard.CtrlKeyDown; - _ = keyboard.CapsLock; - _ = keyboard.NumLock; - _ = keyboard.ScrollLock; - } - - // Not tested: - // Public Sub SendKeys(ByVal keys As String) - // Public Sub SendKeys(ByVal keys As String, ByVal wait As Boolean) -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/MouseTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/MouseTests.cs deleted file mode 100644 index 294c38cd441..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/MouseTests.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Microsoft.VisualBasic.Devices.Tests; - -public class MouseTests -{ - public static bool NoMousePresent => !SystemInformation.MousePresent; - - public static bool NoMouseWheelPresent => NoMousePresent || !SystemInformation.MouseWheelPresent; - - [ConditionalFact(typeof(SystemInformation), nameof(SystemInformation.MousePresent))] - public void Mouse_ButtonsSwapped_Get_ReturnsExpected() - { - var mouse = new Mouse(); - Assert.Equal(SystemInformation.MouseButtonsSwapped, mouse.ButtonsSwapped); - Assert.Equal(mouse.ButtonsSwapped, mouse.ButtonsSwapped); - } - - [ConditionalFact(nameof(NoMousePresent))] - public void Mouse_ButtonsSwapped_GetNoMousePresent_ThrowsInvalidOperationException() - { - if (NoMousePresent) - { - var mouse = new Mouse(); - Assert.Throws(() => mouse.ButtonsSwapped); - } - } - - [ConditionalFact(typeof(SystemInformation), nameof(SystemInformation.MousePresent))] - public void Mouse_WheelExists_Get_ReturnsExpected() - { - var mouse = new Mouse(); - Assert.Equal(SystemInformation.MouseWheelPresent, mouse.WheelExists); - Assert.Equal(mouse.WheelExists, mouse.WheelExists); - } - - [ConditionalFact(nameof(NoMousePresent))] - public void Mouse_WheelExists_GetNoMousePresent_ThrowsInvalidOperationException() - { - if (NoMousePresent) - { - var mouse = new Mouse(); - Assert.Throws(() => mouse.WheelExists); - } - } - - [ConditionalFact(typeof(SystemInformation), nameof(SystemInformation.MousePresent), nameof(SystemInformation.MouseWheelPresent))] - public void Mouse_WheelScrollLines_Get_ReturnsExpected() - { - if (SystemInformation.MouseWheelPresent) - { - var mouse = new Mouse(); - Assert.Equal(SystemInformation.MouseWheelScrollLines, mouse.WheelScrollLines); - Assert.Equal(mouse.WheelScrollLines, mouse.WheelScrollLines); - } - } - - [ConditionalFact(nameof(NoMouseWheelPresent))] - public void Mouse_WheelScrollLines_GetNoMouseWheelPresent_ThrowsInvalidOperationException() - { - if (NoMouseWheelPresent) - { - var mouse = new Mouse(); - Assert.Throws(() => mouse.WheelScrollLines); - } - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/NetworkAvailableEventArgsTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/NetworkAvailableEventArgsTests.cs deleted file mode 100644 index 57440a76fad..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/NetworkAvailableEventArgsTests.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.Devices.Tests; - -public class NetworkAvailableEventArgsTests -{ - [Theory] - [InlineData(true)] - [InlineData(false)] - public void Ctor_Bool(bool networkAvailable) - { - var args = new NetworkAvailableEventArgs(networkAvailable); - Assert.Equal(networkAvailable, args.IsNetworkAvailable); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/NetworkTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/NetworkTests.cs deleted file mode 100644 index 47879b54643..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/NetworkTests.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.Devices.Tests; - -public class NetworkTests -{ - [Fact] - public void IsAvailable() - { - var network = new Network(); - Assert.Equal(System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable(), network.IsAvailable); - } - - [Fact] - public void Ping() - { - var network = new Network(); - Assert.True(network.Ping("127.0.0.1")); - } - - // Not tested: - // Public Sub DownloadFile(...) [multiple overloads] - // Public Sub UploadFile(...) [multiple overloads] -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ServerComputerTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ServerComputerTests.cs deleted file mode 100644 index 8311b2561fd..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Devices/ServerComputerTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.Devices.Tests; - -public class ServerComputerTests -{ - [Fact] - public void Properties() - { - var computer = new ServerComputer(); - - Assert.Equal(System.Environment.MachineName, computer.Name); - - var clock = computer.Clock; - Assert.NotNull(clock); - Assert.Same(clock, computer.Clock); - - var fileSystem = computer.FileSystem; - Assert.NotNull(fileSystem); - Assert.Same(fileSystem, computer.FileSystem); - - var info = computer.Info; - Assert.NotNull(info); - Assert.Same(info, computer.Info); - - var network = computer.Network; - Assert.NotNull(network); - Assert.Same(network, computer.Network); - - var registry = computer.Registry; - Assert.NotNull(registry); - Assert.Same(registry, computer.Registry); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Logging/FileLogTraceListenerTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Logging/FileLogTraceListenerTests.cs deleted file mode 100644 index 54975475a41..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Logging/FileLogTraceListenerTests.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.Logging.Tests; - -public class FileLogTraceListenerTests : FileCleanupTestBase -{ - [Fact] - public void Properties() - { - var listener = new FileLogTraceListener(); - _ = listener.Location; - _ = listener.AutoFlush; - _ = listener.IncludeHostName; - _ = listener.Append; - _ = listener.DiskSpaceExhaustedBehavior; - _ = listener.BaseFileName; - _ = listener.FullLogFileName; - _ = listener.LogFileCreationSchedule; - _ = listener.MaxFileSize; - _ = listener.ReserveDiskSpace; - _ = listener.Delimiter; - _ = listener.Encoding; - _ = listener.CustomLocation; - } - - [Fact] - public void Write() - { - var cache = new TraceEventCache(); - var listener = new FileLogTraceListener(); - listener.Location = LogFileLocation.Custom; - listener.CustomLocation = GetTestFilePath(); - - listener.Write("Write"); - listener.WriteLine("WriteLine"); - listener.TraceEvent(eventCache: cache, source: "Source", eventType: TraceEventType.Warning, id: 3, message: "TraceEvent"); - listener.TraceData(eventCache: cache, source: "Source", eventType: TraceEventType.Error, id: 4, data: "TraceData"); - listener.Flush(); - listener.Close(); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Logging/LogTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Logging/LogTests.cs deleted file mode 100644 index b066f6e40c8..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/Logging/LogTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.Logging.Tests; - -public class LogTests : FileCleanupTestBase -{ - [Fact] - public void Properties() - { - var log = new Log(); - _ = log.TraceSource; - _ = log.DefaultFileLogWriter; - } - - [Fact] - public void Write() - { - var log = new Log(); - var listener = log.DefaultFileLogWriter; - listener.Location = LogFileLocation.Custom; - listener.CustomLocation = GetTestFilePath(); - - log.WriteEntry("WriteEntry"); - log.WriteEntry("WriteEntry", severity: System.Diagnostics.TraceEventType.Warning); - log.WriteEntry("WriteEntry", severity: System.Diagnostics.TraceEventType.Error, id: 3); - - log.WriteException(new System.ArgumentException()); - log.WriteException(new System.ArgumentException(), severity: System.Diagnostics.TraceEventType.Warning, additionalInfo: "AdditionalInfo"); - log.WriteException(new System.ArgumentException(), severity: System.Diagnostics.TraceEventType.Warning, additionalInfo: "AdditionalInfo", id: 6); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/ClipboardProxyTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/ClipboardProxyTests.cs deleted file mode 100644 index aa95e0afc5a..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/ClipboardProxyTests.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using Microsoft.VisualBasic.Devices; -using DataFormats = System.Windows.Forms.DataFormats; -using TextDataFormat = System.Windows.Forms.TextDataFormat; - -namespace Microsoft.VisualBasic.MyServices.Tests; - -public class ClipboardProxyTests -{ - [WinFormsFact] - public void Clear() - { - var clipboard = (new Computer()).Clipboard; - var text = GetUniqueText(); - clipboard.SetText(text); - Assert.True(System.Windows.Forms.Clipboard.ContainsText()); - clipboard.Clear(); - Assert.False(System.Windows.Forms.Clipboard.ContainsText()); - } - - [WinFormsFact] - public void Text() - { - var clipboard = (new Computer()).Clipboard; - var text = GetUniqueText(); - clipboard.SetText(text, TextDataFormat.UnicodeText); - Assert.Equal(System.Windows.Forms.Clipboard.ContainsText(), clipboard.ContainsText()); - Assert.Equal(System.Windows.Forms.Clipboard.GetText(), clipboard.GetText()); - Assert.Equal(System.Windows.Forms.Clipboard.GetText(TextDataFormat.UnicodeText), clipboard.GetText(TextDataFormat.UnicodeText)); - Assert.Equal(text, clipboard.GetText(TextDataFormat.UnicodeText)); - } - - [WinFormsFact] - public void Image() - { - var clipboard = (new Computer()).Clipboard; - var image = new Bitmap(2, 2); - Assert.Equal(System.Windows.Forms.Clipboard.ContainsImage(), clipboard.ContainsImage()); - Assert.Equal(System.Windows.Forms.Clipboard.GetImage(), clipboard.GetImage()); - clipboard.SetImage(image); - } - - [WinFormsFact] - public void Audio() - { - var clipboard = (new Computer()).Clipboard; - Assert.Equal(System.Windows.Forms.Clipboard.ContainsAudio(), clipboard.ContainsAudio()); - // Not tested: - // Public Function GetAudioStream() As Stream - // Public Sub SetAudio(ByVal audioBytes As Byte()) - // Public Sub SetAudio(ByVal audioStream As Stream) - } - - [WinFormsFact] - public void FileDropList() - { - var clipboard = (new Computer()).Clipboard; - Assert.Equal(System.Windows.Forms.Clipboard.ContainsFileDropList(), clipboard.ContainsFileDropList()); - // Not tested: - // Public Function GetFileDropList() As StringCollection - // Public Sub SetFileDropList(ByVal filePaths As StringCollection) - } - - [WinFormsFact] - public void Data() - { - var clipboard = (new Computer()).Clipboard; - object data = GetUniqueText(); - Assert.Equal(System.Windows.Forms.Clipboard.ContainsData(DataFormats.UnicodeText), clipboard.ContainsData(DataFormats.UnicodeText)); - Assert.Equal(System.Windows.Forms.Clipboard.GetData(DataFormats.UnicodeText), clipboard.GetData(DataFormats.UnicodeText)); - clipboard.SetData(DataFormats.UnicodeText, data); - } - - [WinFormsFact] - public void DataObject() - { - var clipboard = (new Computer()).Clipboard; - object data = GetUniqueText(); - Assert.Equal(System.Windows.Forms.Clipboard.GetDataObject().GetData(DataFormats.UnicodeText), clipboard.GetDataObject().GetData(DataFormats.UnicodeText)); - clipboard.SetDataObject(new System.Windows.Forms.DataObject(data)); - } - - private static string GetUniqueText() => Guid.NewGuid().ToString("D"); -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/FileSystemProxyTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/FileSystemProxyTests.cs deleted file mode 100644 index d288e9a57f1..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/FileSystemProxyTests.cs +++ /dev/null @@ -1,706 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.VisualBasic.FileIO; -using SearchOption = Microsoft.VisualBasic.FileIO.SearchOption; - -namespace Microsoft.VisualBasic.MyServices.Tests; - -// File tests cloned from Microsoft.VisualBasic.FileIO.Tests.FileSystemTests. -public class FileSystemProxyTests : FileCleanupTestBase -{ - private const string DestData = "xXy"; - private const string SourceData = "aAb"; - - private readonly FileSystemProxy _fileSystem = new Microsoft.VisualBasic.Devices.ServerComputer().FileSystem; - - private static bool HasExpectedData(string FileNameWithPath, string ExpectedData) - { - string actualData = System.IO.File.ReadAllText(FileNameWithPath); - return ExpectedData == actualData; - } - - private static void WriteFile(string FileName, string TestData) - { - System.IO.File.WriteAllText(FileName, TestData); - } - - [Fact] - public void CombinePathTest_BadBaseDirectory_RelativePath() - { - Assert.Throws(() => _fileSystem.CombinePath(null, "Test2")); - Assert.Throws(() => _fileSystem.CombinePath("", "Test2")); - } - - [Fact] - public void CombinePathTest_BaseDirectory_RelativePath() - { - var TestDirInfo = new System.IO.DirectoryInfo(TestDirectory); - var Root = TestDirInfo.Root.Name; - Assert.Equal(_fileSystem.CombinePath(Root, "Test2"), System.IO.Path.Combine(Root, "Test2")); - } - - [Fact] - public void CombinePathTest_RootDirectory_RelativePath() - { - Assert.Equal(_fileSystem.CombinePath(TestDirectory, null), TestDirectory); - Assert.Equal(_fileSystem.CombinePath(TestDirectory, ""), TestDirectory); - Assert.Equal(_fileSystem.CombinePath(TestDirectory, "Test"), System.IO.Path.Combine(TestDirectory, "Test")); - } - - [Fact] - public void CopyDirectory_SourceDirectoryName_DestinationDirectoryName() - { - var FullPathToSourceDirectory = System.IO.Path.Combine(TestDirectory, "SourceDirectory"); - System.IO.Directory.CreateDirectory(FullPathToSourceDirectory); - for (int i = 0; i < 6; i++) - { - CreateTestFile(SourceData, PathFromBase: "SourceDirectory", TestFileName: $"NewFile{i}"); - } - - var FullPathToTargetDirectory = System.IO.Path.Combine(TestDirectory, "TargetDirectory"); - _fileSystem.CopyDirectory(FullPathToSourceDirectory, FullPathToTargetDirectory); - Assert.Equal(System.IO.Directory.GetFiles(FullPathToSourceDirectory).Length, System.IO.Directory.GetFiles(FullPathToTargetDirectory).Length); - foreach (var CurrentFile in System.IO.Directory.GetFiles(FullPathToTargetDirectory)) - { - // Ensure copy transferred written data - Assert.True(HasExpectedData(CurrentFile, SourceData)); - } - - System.IO.Directory.Delete(FullPathToTargetDirectory, recursive: true); - System.IO.Directory.CreateDirectory(FullPathToTargetDirectory); - CreateTestFile(TestData: SourceData, PathFromBase: "TargetDirectory", TestFileName: $"NewFile0"); - Assert.Throws(() => _fileSystem.CopyDirectory(FullPathToSourceDirectory, FullPathToTargetDirectory)); - } - - [Fact] - public void CopyDirectory_SourceDirectoryName_DestinationDirectoryName_OverwriteFalse() - { - var FullPathToSourceDirectory = System.IO.Path.Combine(TestDirectory, "SourceDirectory"); - var FullPathToTargetDirectory = System.IO.Path.Combine(TestDirectory, "TargetDirectory"); - System.IO.Directory.CreateDirectory(FullPathToSourceDirectory); - for (int i = 0; i < 6; i++) - { - CreateTestFile(SourceData, PathFromBase: "SourceDirectory", TestFileName: $"NewFile{i}"); - } - - _fileSystem.CopyDirectory(FullPathToSourceDirectory, FullPathToTargetDirectory, overwrite: false); - Assert.Equal(System.IO.Directory.GetFiles(FullPathToSourceDirectory).Length, System.IO.Directory.GetFiles(FullPathToTargetDirectory).Length); - foreach (var CurrentFile in System.IO.Directory.GetFiles(FullPathToTargetDirectory)) - { - // Ensure copy transferred written data - Assert.True(HasExpectedData(CurrentFile, SourceData)); - } - - System.IO.Directory.Delete(FullPathToTargetDirectory, recursive: true); - System.IO.Directory.CreateDirectory(FullPathToTargetDirectory); - CreateTestFile(DestData, PathFromBase: "TargetDirectory", TestFileName: $"NewFile0"); - Assert.Throws(() => _fileSystem.CopyDirectory(FullPathToSourceDirectory, FullPathToTargetDirectory, overwrite: false)); - Assert.Equal(System.IO.Directory.GetFiles(FullPathToTargetDirectory).Length, System.IO.Directory.GetFiles(FullPathToSourceDirectory).Length); - foreach (var CurrentFile in System.IO.Directory.GetFiles(FullPathToTargetDirectory)) - { - Assert.True(HasExpectedData(CurrentFile, CurrentFile.EndsWith("0") ? DestData : SourceData)); - } - } - - [Fact] - public void CopyDirectory_SourceDirectoryName_DestinationDirectoryName_OverwriteTrue() - { - var FullPathToSourceDirectory = System.IO.Path.Combine(TestDirectory, "SourceDirectory"); - var FullPathToTargetDirectory = System.IO.Path.Combine(TestDirectory, "TargetDirectory"); - System.IO.Directory.CreateDirectory(FullPathToSourceDirectory); - System.IO.Directory.CreateDirectory(FullPathToTargetDirectory); - for (int i = 0; i < 6; i++) - { - CreateTestFile(SourceData, PathFromBase: "SourceDirectory", TestFileName: $"NewFile{i}"); - } - - _fileSystem.CopyDirectory(FullPathToSourceDirectory, FullPathToTargetDirectory, overwrite: true); - Assert.Equal(System.IO.Directory.GetFiles(FullPathToSourceDirectory).Length, System.IO.Directory.GetFiles(FullPathToTargetDirectory).Length); - foreach (var CurrentFile in System.IO.Directory.GetFiles(FullPathToTargetDirectory)) - { - // Ensure copy transferred written data - Assert.True(HasExpectedData(CurrentFile, SourceData)); - } - } - - [Fact] - public void CopyFile_FileSourceFileName_DestinationFileName() - { - var testFileSource = GetTestFilePath(); - var testFileDest = GetTestFilePath(); - - // Write and copy file - WriteFile(testFileSource, SourceData); - WriteFile(testFileDest, DestData); - Assert.Throws(() => _fileSystem.CopyFile(testFileSource, testFileDest)); - - // Ensure copy didn't overwrite existing data - Assert.True(HasExpectedData(testFileDest, DestData)); - - // Get a new destination name - testFileDest = GetTestFilePath(); - _fileSystem.CopyFile(testFileSource, testFileDest); - - // Ensure copy transferred written data - Assert.True(HasExpectedData(testFileDest, SourceData)); - } - - [Fact] - public void CopyFile_FileSourceFileName_DestinationFileName_OverwriteFalse() - { - var testFileSource = GetTestFilePath(); - var testFileDest = GetTestFilePath(); - - // Write and copy file - WriteFile(testFileSource, SourceData); - WriteFile(testFileDest, DestData); - Assert.Throws(() => _fileSystem.CopyFile(testFileSource, testFileDest, overwrite: false)); - - // Ensure copy didn't overwrite existing data - Assert.True(HasExpectedData(testFileDest, DestData)); - } - - [Fact] - public void CopyFile_FileSourceFileName_DestinationFileName_OverwriteTrue() - { - var testFileSource = GetTestFilePath(); - var testFileDest = GetTestFilePath(); - - // Write and copy file - WriteFile(testFileSource, SourceData); - WriteFile(testFileDest, DestData); - _fileSystem.CopyFile(testFileSource, testFileDest, overwrite: true); - - // Ensure copy transferred written data - Assert.True(HasExpectedData(testFileDest, SourceData)); - } - - [Fact] - public void CreateDirectory_Directory() - { - var FullPathToNewDirectory = System.IO.Path.Combine(TestDirectory, "NewDirectory"); - Assert.False(System.IO.Directory.Exists(FullPathToNewDirectory)); - _fileSystem.CreateDirectory(FullPathToNewDirectory); - Assert.True(System.IO.Directory.Exists(FullPathToNewDirectory)); - } - - [Fact] - public void CurrentDirectoryGet() - { - var CurrentDirectory = System.IO.Directory.GetCurrentDirectory(); - Assert.Equal(_fileSystem.CurrentDirectory, CurrentDirectory); - } - - [Fact] - public void CurrentDirectorySet() - { - var SavedCurrentDirectory = System.IO.Directory.GetCurrentDirectory(); - _fileSystem.CurrentDirectory = TestDirectory; - Assert.Equal(TestDirectory, _fileSystem.CurrentDirectory); - _fileSystem.CurrentDirectory = SavedCurrentDirectory; - Assert.Equal(_fileSystem.CurrentDirectory, SavedCurrentDirectory); - } - - [Fact] - public void DeleteDirectory_Directory_DeleteAllContents() - { - var FullPathToNewDirectory = System.IO.Path.Combine(TestDirectory, "NewDirectory"); - System.IO.Directory.CreateDirectory(FullPathToNewDirectory); - Assert.True(System.IO.Directory.Exists(FullPathToNewDirectory)); - var testFileSource = CreateTestFile(SourceData, PathFromBase: "NewDirectory", TestFileName: "TestFile"); - Assert.True(System.IO.File.Exists(testFileSource)); - _fileSystem.DeleteDirectory(FullPathToNewDirectory, DeleteDirectoryOption.DeleteAllContents); - Assert.False(System.IO.Directory.Exists(FullPathToNewDirectory)); - } - - [Fact] - public void DeleteDirectory_Directory_ThrowIfDirectoryNonEmpty() - { - var FullPathToNewDirectory = System.IO.Path.Combine(TestDirectory, "NewDirectory"); - _fileSystem.CreateDirectory(FullPathToNewDirectory); - Assert.True(System.IO.Directory.Exists(FullPathToNewDirectory)); - var testFileSource = CreateTestFile(SourceData, PathFromBase: "NewDirectory", TestFileName: "TestFile"); - - Assert.True(System.IO.File.Exists(testFileSource)); - Assert.Throws(() => _fileSystem.DeleteDirectory(FullPathToNewDirectory, DeleteDirectoryOption.ThrowIfDirectoryNonEmpty)); - Assert.True(System.IO.Directory.Exists(FullPathToNewDirectory)); - Assert.True(System.IO.File.Exists(testFileSource)); - } - - [Fact] - public void DeleteFile_File() - { - var testFileSource = CreateTestFile(SourceData, TestFileName: GetTestFileName()); - - Assert.True(System.IO.File.Exists(testFileSource)); - _fileSystem.DeleteFile(testFileSource); - Assert.False(System.IO.File.Exists(testFileSource)); - } - - [Fact] - public void DirectoryExists_Directory() - { - Assert.True(_fileSystem.DirectoryExists(TestDirectory)); - Assert.False(_fileSystem.DirectoryExists(System.IO.Path.Combine(TestDirectory, "NewDirectory"))); - } - - // Not tested: - // public System.Collections.ObjectModel.ReadOnlyCollection Drives { get { throw null; } } - - [Fact] - public void FileExists_File() - { - var testFileSource = CreateTestFile(SourceData, TestFileName: GetTestFileName()); - Assert.True(_fileSystem.FileExists(testFileSource)); - _fileSystem.FileExists(testFileSource); - System.IO.File.Delete(testFileSource); - Assert.False(_fileSystem.FileExists(testFileSource)); - } - - // Not tested: - // public System.Collections.ObjectModel.ReadOnlyCollection FindInFiles(string directory, string containsText, bool ignoreCase, FileIO.SearchOption searchType) { throw null; } - // public System.Collections.ObjectModel.ReadOnlyCollection FindInFiles(string directory, string containsText, bool ignoreCase, FileIO.SearchOption searchType, params string[] fileWildcards) { throw null; } - - [Fact] - public void GetDirectories_Directory() - { - var DirectoryList = _fileSystem.GetDirectories(TestDirectory); - Assert.Empty(DirectoryList); - for (int i = 0; i < 6; i++) - { - System.IO.Directory.CreateDirectory(System.IO.Path.Combine(TestDirectory, $"GetDirectories_DirectoryNewSubDirectory{i}")); - } - - DirectoryList = _fileSystem.GetDirectories(TestDirectory); - Assert.Equal(6, DirectoryList.Count); - for (int i = 0; i < 6; i++) - { - Assert.Contains(System.IO.Path.Combine(TestDirectory, $"GetDirectories_DirectoryNewSubDirectory{i}"), DirectoryList); - } - - System.IO.Directory.CreateDirectory(System.IO.Path.Combine(TestDirectory, $"GetDirectories_DirectoryNewSubDirectory0", $"NewSubSubDirectory")); - DirectoryList = _fileSystem.GetDirectories(TestDirectory); - Assert.Equal(6, DirectoryList.Count); - } - - [Fact] - public void GetDirectories_Directory_SearchOption() - { - var DirectoryList = _fileSystem.GetDirectories(TestDirectory, SearchOption.SearchTopLevelOnly); - Assert.Empty(DirectoryList); - for (int i = 0; i < 6; i++) - { - System.IO.Directory.CreateDirectory(System.IO.Path.Combine(TestDirectory, $"GetDirectories_Directory_SearchOptionNewSubDirectory{i}")); - } - - DirectoryList = _fileSystem.GetDirectories(TestDirectory, SearchOption.SearchTopLevelOnly); - Assert.Equal(6, DirectoryList.Count); - for (int i = 0; i < 6; i++) - { - Assert.Contains(System.IO.Path.Combine(TestDirectory, $"GetDirectories_Directory_SearchOptionNewSubDirectory{i}"), DirectoryList); - } - - System.IO.Directory.CreateDirectory(System.IO.Path.Combine(TestDirectory, $"GetDirectories_Directory_SearchOptionNewSubDirectory0", $"NewSubSubDirectory")); - DirectoryList = _fileSystem.GetDirectories(TestDirectory, SearchOption.SearchTopLevelOnly); - Assert.Equal(6, DirectoryList.Count); - DirectoryList = _fileSystem.GetDirectories(TestDirectory, SearchOption.SearchAllSubDirectories); - Assert.Equal(7, DirectoryList.Count); - } - - [Fact] - public void GetDirectories_Directory_SearchOption_Wildcards() - { - var DirectoryList = _fileSystem.GetDirectories(TestDirectory, SearchOption.SearchTopLevelOnly, "*"); - Assert.Empty(DirectoryList); - var CreatedDirectories = new List(); - for (int i = 0; i < 6; i++) - { - CreatedDirectories.Add(System.IO.Directory.CreateDirectory(System.IO.Path.Combine(TestDirectory, $"NewSubDirectory00{i}")).Name); - } - - DirectoryList = _fileSystem.GetDirectories(TestDirectory, SearchOption.SearchTopLevelOnly, "*000", "*001"); - Assert.Equal(2, DirectoryList.Count); - for (int i = 0; i < 2; i++) - { - var DirectoryName = System.IO.Path.Combine(TestDirectory, $"NewSubDirectory00{i}"); - Assert.Contains(DirectoryName, DirectoryList); - } - - System.IO.Directory.CreateDirectory(System.IO.Path.Combine(TestDirectory, $"NewSubDirectory000", $"NewSubSubDirectory000")); - DirectoryList = _fileSystem.GetDirectories(TestDirectory, SearchOption.SearchTopLevelOnly, "*000"); - Assert.Single(DirectoryList); - DirectoryList = _fileSystem.GetDirectories(TestDirectory, SearchOption.SearchAllSubDirectories, "*000"); - Assert.Equal(2, DirectoryList.Count); - } - - [Fact] - public void GetDirectoryInfo_Directory() - { - for (int i = 0; i < 6; i++) - { - System.IO.Directory.CreateDirectory(System.IO.Path.Combine(TestDirectory, $"NewSubDirectory{i}")); - } - - System.IO.Directory.CreateDirectory(System.IO.Path.Combine(TestDirectory, $"NewSubDirectory0", $"NewSubSubDirectory")); - var info = _fileSystem.GetDirectoryInfo(TestDirectory); - var infoFromIO = new System.IO.DirectoryInfo(TestDirectory); - Assert.Equal(info.CreationTime, infoFromIO.CreationTime); - Assert.Equal(info.Extension, infoFromIO.Extension); - Assert.Equal(info.FullName, TestDirectory); - Assert.Equal(info.LastAccessTime, infoFromIO.LastAccessTime); - Assert.Equal(info.Name, infoFromIO.Name); - Assert.Equal(info.Parent.ToString(), infoFromIO.Parent.ToString()); - Assert.Equal(info.Root.Name, infoFromIO.Root.Name); - } - - [Fact] - public void GetDriveInfo_Drive() - { - var Drives = System.IO.DriveInfo.GetDrives(); - Assert.True(Drives.Length > 0); - Assert.Equal(_fileSystem.GetDriveInfo(Drives[0].Name).Name, new System.IO.DriveInfo(Drives[0].Name).Name); - } - - [Fact] - public void GetFileInfo_File() - { - var TestFile = CreateTestFile(SourceData, TestFileName: GetTestFileName()); - - var FileInfoFromSystemIO = new System.IO.FileInfo(TestFile); - Assert.NotNull(FileInfoFromSystemIO); - - var info = _fileSystem.GetFileInfo(TestFile); - Assert.NotNull(info); - Assert.True(info.Exists); - Assert.Equal(info.Attributes, FileInfoFromSystemIO.Attributes); - Assert.Equal(info.CreationTime, FileInfoFromSystemIO.CreationTime); - Assert.True(info.CreationTime > DateTime.MinValue); - Assert.Equal(info.DirectoryName, FileInfoFromSystemIO.DirectoryName); - Assert.Equal(info.Extension, FileInfoFromSystemIO.Extension); - Assert.Equal(info.FullName, FileInfoFromSystemIO.FullName); - Assert.Equal(info.IsReadOnly, FileInfoFromSystemIO.IsReadOnly); - Assert.Equal(info.LastAccessTime, FileInfoFromSystemIO.LastAccessTime); - Assert.Equal(info.LastWriteTime, FileInfoFromSystemIO.LastWriteTime); - Assert.Equal(info.Length, FileInfoFromSystemIO.Length); - Assert.Equal(info.Name, FileInfoFromSystemIO.Name); - } - - [Fact] - public void GetFiles_Directory() - { - var FileList = _fileSystem.GetFiles(TestDirectory); - Assert.Empty(FileList); - for (int i = 0; i < 6; i++) - { - CreateTestFile(SourceData, PathFromBase: null, TestFileName: $"NewFile{i}"); - } - - FileList = _fileSystem.GetFiles(TestDirectory); - Assert.Equal(6, FileList.Count); - for (int i = 0; i < 6; i++) - { - Assert.Contains(System.IO.Path.Combine(TestDirectory, $"NewFile{i}"), FileList); - } - - System.IO.Directory.CreateDirectory(System.IO.Path.Combine(TestDirectory, "GetFiles_DirectoryNewSubDirectory")); - CreateTestFile(SourceData, PathFromBase: "GetFiles_DirectoryNewSubDirectory", TestFileName: "NewFile"); - FileList = _fileSystem.GetFiles(TestDirectory); - Assert.Equal(6, FileList.Count); - } - - [Fact] - public void GetFiles_Directory_SearchOption() - { - var NewSubDirectoryPath = System.IO.Path.Combine(TestDirectory, "GetFiles_Directory_SearchOptionNewSubDirectory"); - System.IO.Directory.CreateDirectory(NewSubDirectoryPath); - CreateTestFile(SourceData, PathFromBase: "GetFiles_Directory_SearchOptionNewSubDirectory", TestFileName: "NewFile"); - var FileList = _fileSystem.GetFiles(TestDirectory); - Assert.Empty(FileList); - for (int i = 0; i < 6; i++) - { - CreateTestFile(SourceData, PathFromBase: null, TestFileName: $"NewFile{i}"); - } - - FileList = _fileSystem.GetFiles(TestDirectory, SearchOption.SearchTopLevelOnly); - CreateTestFile(SourceData, PathFromBase: null, TestFileName: "NewFile"); - Assert.Equal(6, FileList.Count); - for (int i = 0; i < 6; i++) - { - Assert.Contains(System.IO.Path.Combine(TestDirectory, $"NewFile{i}"), FileList); - } - - FileList = _fileSystem.GetFiles(TestDirectory, SearchOption.SearchAllSubDirectories); - Assert.Equal(8, FileList.Count); - for (int i = 0; i < 7; i++) - { - Assert.True(System.IO.File.Exists(FileList[i])); - } - } - - [Fact] - public void GetFiles_Directory_SearchOption_Wildcards() - { - var FileList = _fileSystem.GetFiles(TestDirectory); - Assert.Empty(FileList); - var TestFileList = new List(); - for (int i = 0; i < 6; i++) - { - TestFileList.Add(CreateTestFile(SourceData, PathFromBase: null, TestFileName: $"NewFile{i}{(i % 2 == 0 ? ".vb" : ".cs")}")); - } - - FileList = _fileSystem.GetFiles(TestDirectory, SearchOption.SearchTopLevelOnly, "*.vb"); - Assert.Equal(3, FileList.Count); - for (int i = 0; i < 3; i++) - { - Assert.Contains(FileList[i], TestFileList); - } - - var NewSubDirectoryPath = System.IO.Path.Combine(TestDirectory, "GetFiles_Directory_SearchOption_WildcardsNewSubDirectory"); - System.IO.Directory.CreateDirectory(NewSubDirectoryPath); - TestFileList.Add(CreateTestFile(SourceData, PathFromBase: "GetFiles_Directory_SearchOption_WildcardsNewSubDirectory", TestFileName: "NewFile.cs")); - FileList = _fileSystem.GetFiles(TestDirectory, SearchOption.SearchAllSubDirectories, "*.cs"); - Assert.Contains(TestFileList[TestFileList.Count - 1], FileList); - Assert.Equal(4, FileList.Count); - } - - [Fact] - public void GetName_Path() - { - Assert.Equal(_fileSystem.GetName(TestDirectory), System.IO.Path.GetFileName(TestDirectory)); - } - - [Fact] - public void GetParentPath_Path() - { - Assert.Equal(_fileSystem.GetParentPath(TestDirectory), System.IO.Path.GetDirectoryName(TestDirectory)); - } - - [Fact] - public void GetTempFileName() - { - var TempFile = _fileSystem.GetTempFileName(); - Assert.True(System.IO.File.Exists(TempFile)); - Assert.Equal(0, (new System.IO.FileInfo(TempFile)).Length); - System.IO.File.Delete(TempFile); - } - - [Fact] - public void MoveDirectory_SourceDirectoryName_DestinationDirectoryName() - { - var FullPathToSourceDirectory = System.IO.Path.Combine(TestDirectory, "SourceDirectory"); - var FullPathToTargetDirectory = System.IO.Path.Combine(TestDirectory, "TargetDirectory"); - System.IO.Directory.CreateDirectory(FullPathToSourceDirectory); - for (int i = 0; i < 6; i++) - { - CreateTestFile(SourceData, PathFromBase: "SourceDirectory", TestFileName: $"NewFile{i}"); - } - - _fileSystem.MoveDirectory(FullPathToSourceDirectory, FullPathToTargetDirectory); - Assert.Equal(6, System.IO.Directory.GetFiles(FullPathToTargetDirectory).Length); - Assert.False(System.IO.Directory.Exists(FullPathToSourceDirectory)); - foreach (var CurrentFile in System.IO.Directory.GetFiles(FullPathToTargetDirectory)) - { - // Ensure move transferred written data - Assert.True(HasExpectedData(CurrentFile, SourceData)); - } - - System.IO.Directory.Move(FullPathToTargetDirectory, FullPathToSourceDirectory); - System.IO.Directory.CreateDirectory(FullPathToTargetDirectory); - CreateTestFile(SourceData, PathFromBase: "TargetDirectory", TestFileName: "NewFile0"); - Assert.Throws(() => _fileSystem.MoveDirectory(FullPathToSourceDirectory, FullPathToTargetDirectory)); - } - - [Fact] - public void MoveDirectory_SourceDirectoryName_DestinationDirectoryName_OverwriteFalse() - { - var FullPathToSourceDirectory = System.IO.Path.Combine(TestDirectory, "SourceDirectory"); - var FullPathToTargetDirectory = System.IO.Path.Combine(TestDirectory, "TargetDirectory"); - System.IO.Directory.CreateDirectory(FullPathToSourceDirectory); - for (int i = 0; i < 6; i++) - { - CreateTestFile(SourceData, PathFromBase: "SourceDirectory", TestFileName: $"NewFile{i}"); - } - - _fileSystem.MoveDirectory(FullPathToSourceDirectory, FullPathToTargetDirectory, overwrite: false); - Assert.Equal(6, System.IO.Directory.GetFiles(FullPathToTargetDirectory).Length); - Assert.False(System.IO.Directory.Exists(FullPathToSourceDirectory)); - foreach (var CurrentFile in System.IO.Directory.GetFiles(FullPathToTargetDirectory)) - { - // Ensure move transferred written data - Assert.True(HasExpectedData(CurrentFile, SourceData)); - } - - System.IO.Directory.Move(FullPathToTargetDirectory, FullPathToSourceDirectory); - System.IO.Directory.CreateDirectory(FullPathToTargetDirectory); - var NewFile0WithPath = CreateTestFile(DestData, PathFromBase: "TargetDirectory", TestFileName: "NewFile0"); - Assert.Throws(() => _fileSystem.MoveDirectory(FullPathToSourceDirectory, FullPathToTargetDirectory, overwrite: false)); - string[] RemainingSourceFilesWithPath = System.IO.Directory.GetFiles(FullPathToSourceDirectory); - // We couldn't move one file - Assert.Single(RemainingSourceFilesWithPath); - // Ensure the file left has correct data - Assert.True(HasExpectedData(RemainingSourceFilesWithPath[0], SourceData)); - - string[] DestinationFilesWithPath = System.IO.Directory.GetFiles(FullPathToTargetDirectory); - Assert.Equal(6, DestinationFilesWithPath.Length); - foreach (var CurrentFile in DestinationFilesWithPath) - { - Assert.True(HasExpectedData(CurrentFile, CurrentFile.EndsWith("0") ? DestData : SourceData)); - } - } - - [Fact] - public void MoveDirectory_SourceDirectoryName_DestinationDirectoryName_OverwriteTrue() - { - var FullPathToSourceDirectory = System.IO.Path.Combine(TestDirectory, "SourceDirectory"); - var FullPathToTargetDirectory = System.IO.Path.Combine(TestDirectory, "TargetDirectory"); - System.IO.Directory.CreateDirectory(FullPathToSourceDirectory); - System.IO.Directory.CreateDirectory(FullPathToTargetDirectory); - for (int i = 0; i < 6; i++) - { - CreateTestFile(SourceData, PathFromBase: "SourceDirectory", TestFileName: $"NewFile{i}"); - } - - _fileSystem.MoveDirectory(FullPathToSourceDirectory, FullPathToTargetDirectory, overwrite: true); - Assert.False(System.IO.Directory.Exists(FullPathToSourceDirectory)); - Assert.Equal(6, System.IO.Directory.GetFiles(FullPathToTargetDirectory).Length); - foreach (var CurrentFile in System.IO.Directory.GetFiles(FullPathToTargetDirectory)) - { - // Ensure copy transferred written data - Assert.True(HasExpectedData(CurrentFile, SourceData)); - } - } - - [Fact] - public void MoveFile_SourceFileName_DestinationFileName() - { - var SourceFileNameWithPath = CreateTestFile(SourceData, TestFileName: GetTestFileName()); - var DestinationFileNameWithPath = System.IO.Path.Combine(TestDirectory, "NewName"); - _fileSystem.MoveFile(SourceFileNameWithPath, DestinationFileNameWithPath); - Assert.False(System.IO.File.Exists(SourceFileNameWithPath)); - Assert.True(System.IO.File.Exists(DestinationFileNameWithPath)); - Assert.True(HasExpectedData(DestinationFileNameWithPath, SourceData)); - - SourceFileNameWithPath = DestinationFileNameWithPath; - DestinationFileNameWithPath = CreateTestFile(DestData, TestFileName: GetTestFileName()); - Assert.Throws(() => _fileSystem.MoveFile(SourceFileNameWithPath, DestinationFileNameWithPath)); - // Make sure we did not override existing file - Assert.True(HasExpectedData(DestinationFileNameWithPath, DestData)); - Assert.True(System.IO.File.Exists(SourceFileNameWithPath)); - } - - [Fact] - public void MoveFile_SourceFileName_DestinationFileName_OverwriteFalse() - { - var SourceFileNameWithPath = CreateTestFile(SourceData, TestFileName: GetTestFileName()); - var DestinationFileNameWithPath = System.IO.Path.Combine(TestDirectory, "NewName"); - _fileSystem.MoveFile(SourceFileNameWithPath, DestinationFileNameWithPath, overwrite: false); - Assert.False(System.IO.File.Exists(SourceFileNameWithPath)); - Assert.True(System.IO.File.Exists(DestinationFileNameWithPath)); - Assert.True(HasExpectedData(DestinationFileNameWithPath, SourceData)); - SourceFileNameWithPath = DestinationFileNameWithPath; - DestinationFileNameWithPath = CreateTestFile(DestData, TestFileName: GetTestFileName()); - Assert.Throws(() => _fileSystem.MoveFile(SourceFileNameWithPath, DestinationFileNameWithPath, overwrite: false)); - // Make sure we did not override existing file - Assert.True(HasExpectedData(DestinationFileNameWithPath, DestData)); - Assert.True(System.IO.File.Exists(SourceFileNameWithPath)); - } - - [Fact] - public void MoveFile_SourceFileName_DestinationFileName_OverwriteTrue() - { - var SourceFileNameWithPath = CreateTestFile(SourceData, TestFileName: GetTestFileName()); - var DestinationFileNameWithPath = System.IO.Path.Combine(TestDirectory, "NewName"); - _fileSystem.MoveFile(SourceFileNameWithPath, DestinationFileNameWithPath, overwrite: true); - Assert.False(System.IO.File.Exists(SourceFileNameWithPath)); - Assert.True(System.IO.File.Exists(DestinationFileNameWithPath)); - Assert.True(HasExpectedData(DestinationFileNameWithPath, SourceData)); - CreateTestFile(DestData, PathFromBase: null, TestFileName: (new System.IO.FileInfo(SourceFileNameWithPath)).Name); - _fileSystem.MoveFile(sourceFileName: DestinationFileNameWithPath, destinationFileName: SourceFileNameWithPath, overwrite: true); - Assert.True(System.IO.File.Exists(SourceFileNameWithPath)); - Assert.False(System.IO.File.Exists(DestinationFileNameWithPath)); - Assert.True(HasExpectedData(SourceFileNameWithPath, SourceData)); - } - - // Not tested: - // public Microsoft.VisualBasic.FileIO.TextFieldParser OpenTextFieldParser(string file) { throw null; } - // public Microsoft.VisualBasic.FileIO.TextFieldParser OpenTextFieldParser(string file, params int[] fieldWidths) { throw null; } - // public Microsoft.VisualBasic.FileIO.TextFieldParser OpenTextFieldParser(string file, params string[] delimiters) { throw null; } - // public System.IO.StreamReader OpenTextFileReader(string file) { throw null; } - // public System.IO.StreamReader OpenTextFileReader(string file, System.Text.Encoding encoding) { throw null; } - // public System.IO.StreamWriter OpenTextFileWriter(string file, bool append) { throw null; } - // public System.IO.StreamWriter OpenTextFileWriter(string file, bool append, System.Text.Encoding encoding) { throw null; } - // public byte[] ReadAllBytes(string file) { throw null; } - // public string ReadAllText(string file) { throw null; } - // public string ReadAllText(string file, System.Text.Encoding encoding) { throw null; } - - [Fact] - public void RenameDirectory_Directory_NewName() - { - // If directory does not point to an existing directory. - Assert.Throws(() => _fileSystem.RenameDirectory(System.IO.Path.Combine(TestDirectory, "DoesNotExistDirectory"), "NewDirectory")); - var OrigDirectoryWithPath = System.IO.Path.Combine(TestDirectory, "OriginalDirectory"); - System.IO.Directory.CreateDirectory(OrigDirectoryWithPath); - // If newName is null or Empty String. - Assert.Throws(() => _fileSystem.RenameDirectory(OrigDirectoryWithPath, "")); - var DirectoryNameWithPath = System.IO.Path.Combine(TestDirectory, "DoesNotExist"); - // If contains path information. - Assert.Throws(() => _fileSystem.RenameDirectory(OrigDirectoryWithPath, DirectoryNameWithPath)); - _fileSystem.RenameDirectory(OrigDirectoryWithPath, "NewFDirectory"); - var NewFDirectoryPath = System.IO.Path.Combine(TestDirectory, "NewFDirectory"); - Assert.True(System.IO.Directory.Exists(NewFDirectoryPath)); - Assert.False(System.IO.Directory.Exists(OrigDirectoryWithPath)); - // If directory points to a root directory or if there's an existing directory or an existing file with the same name. - System.IO.Directory.CreateDirectory(OrigDirectoryWithPath); - Assert.Throws(() => _fileSystem.RenameDirectory(NewFDirectoryPath, "OriginalDirectory")); - } - - [Fact] - public void RenameFile_File_NewName() - { - // If file does not point to an existing file. - Assert.Throws(() => _fileSystem.RenameFile(System.IO.Path.Combine(TestDirectory, "DoesNotExistFile"), "NewFile")); - var OrigFileWithPath = CreateTestFile(SourceData, TestFileName: GetTestFileName()); - var ExistingFileWithPath = CreateTestFile(DestData, TestFileName: GetTestFileName()); - // If newName is null or Empty String. - Assert.Throws(() => _fileSystem.RenameFile(OrigFileWithPath, "")); - // If contains path information. - Assert.Throws(() => _fileSystem.RenameFile(OrigFileWithPath, ExistingFileWithPath)); - _fileSystem.RenameFile(OrigFileWithPath, "NewFile"); - var NewFileWithPath = System.IO.Path.Combine(TestDirectory, "NewFile"); - Assert.True(System.IO.File.Exists(NewFileWithPath)); - Assert.False(System.IO.File.Exists(OrigFileWithPath)); - // If there's an existing directory or an existing file with the same name. - Assert.Throws(() => _fileSystem.RenameFile(NewFileWithPath, "NewFile")); - System.IO.Directory.CreateDirectory(System.IO.Path.Combine(TestDirectory, "NewFDirectory")); - Assert.Throws(() => _fileSystem.RenameFile(NewFileWithPath, "NewFDirectory")); - } - - [Fact] - public void SpecialDirectories() - { - var specialDirectories = _fileSystem.SpecialDirectories; - Assert.NotNull(specialDirectories); - Assert.Same(specialDirectories, _fileSystem.SpecialDirectories); - } - - // Not tested: - // public void WriteAllBytes(string file, byte[] data, bool append) { } - // public void WriteAllText(string file, string text, bool append) { } - // public void WriteAllText(string file, string text, bool append, System.Text.Encoding encoding) { } - - private string CreateTestFile(string TestData, string TestFileName, string PathFromBase = null) - { - Assert.False(String.IsNullOrEmpty(TestFileName)); - var TempFileNameWithPath = TestDirectory; - if (!string.IsNullOrEmpty(PathFromBase)) - { - TempFileNameWithPath = System.IO.Path.Combine(TempFileNameWithPath, PathFromBase); - } - - TempFileNameWithPath = System.IO.Path.Combine(TempFileNameWithPath, TestFileName); - Assert.False(System.IO.File.Exists(TempFileNameWithPath), $"File {TempFileNameWithPath} should not exist!"); - WriteFile(TempFileNameWithPath, TestData); - return TempFileNameWithPath; - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/Internal/ContextValueTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/Internal/ContextValueTests.cs deleted file mode 100644 index 1ecdfd27a7f..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/Internal/ContextValueTests.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.VisualBasic.MyServices.Internal.Tests; - -public class ContextValueTests -{ - [Fact] - public void NoValue() - { - Assert.Null((new ContextValue()).Value); - Assert.Throws(() => (new ContextValue()).Value); - } - - [Fact] - public void MultipleInstances() - { - var context1 = new ContextValue(); - context1.Value = 1; - var context2 = new ContextValue(); - context2.Value = 2; - Assert.Equal(1, context1.Value); - Assert.Equal(2, context2.Value); - } - - [Fact] - public void MultipleThreads() - { - var context = new ContextValue(); - context.Value = "Hello"; - var thread = new Thread(() => - { - Assert.Null(context.Value); - context.Value = "World"; - Assert.Equal("World", context.Value); - }); - thread.Start(); - thread.Join(); - Assert.Equal("Hello", context.Value); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/RegistryProxyTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/RegistryProxyTests.cs deleted file mode 100644 index 06713c81d60..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/RegistryProxyTests.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.VisualBasic.Devices; - -namespace Microsoft.VisualBasic.MyServices.Tests; - -public class RegistryProxyTests -{ - [Fact] - public void Properties() - { - var registry = (new ServerComputer()).Registry; - Assert.Equal(Microsoft.Win32.Registry.CurrentUser, registry.CurrentUser); - Assert.Equal(Microsoft.Win32.Registry.LocalMachine, registry.LocalMachine); - Assert.Equal(Microsoft.Win32.Registry.ClassesRoot, registry.ClassesRoot); - Assert.Equal(Microsoft.Win32.Registry.Users, registry.Users); - Assert.Equal(Microsoft.Win32.Registry.PerformanceData, registry.PerformanceData); - Assert.Equal(Microsoft.Win32.Registry.CurrentConfig, registry.CurrentConfig); - } - - [Fact] - public void GetValue_ArgumentException() - { - var keyName = GetUniqueName(); - var registry = (new ServerComputer()).Registry; - Assert.Throws(() => registry.GetValue(keyName, "", null)); - } - - [Fact] - public void SetValue_ArgumentException() - { - var keyName = GetUniqueName(); - var valueName = GetUniqueName(); - var registry = (new ServerComputer()).Registry; - Assert.Throws(() => registry.SetValue(keyName, valueName, "")); - Assert.Throws(() => registry.SetValue(keyName, valueName, "", Microsoft.Win32.RegistryValueKind.String)); - } - - private static string GetUniqueName() => Guid.NewGuid().ToString("D"); -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/SpecialDirectoriesProxyTests.cs b/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/SpecialDirectoriesProxyTests.cs deleted file mode 100644 index 5868f530c06..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/SpecialDirectoriesProxyTests.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.VisualBasic.Devices; - -namespace Microsoft.VisualBasic.MyServices.Tests; - -public class SpecialDirectoriesProxyTests -{ - [Fact] - public void Properties() - { - SpecialDirectoriesProxy specialDirectories = new ServerComputer().FileSystem.SpecialDirectories; - VerifySpecialDirectory(() => Microsoft.VisualBasic.FileIO.SpecialDirectories.AllUsersApplicationData, () => specialDirectories.AllUsersApplicationData); - VerifySpecialDirectory(() => Microsoft.VisualBasic.FileIO.SpecialDirectories.CurrentUserApplicationData, () => specialDirectories.CurrentUserApplicationData); - VerifySpecialDirectory(() => Microsoft.VisualBasic.FileIO.SpecialDirectories.Desktop, () => specialDirectories.Desktop); - VerifySpecialDirectory(() => Microsoft.VisualBasic.FileIO.SpecialDirectories.MyDocuments, () => specialDirectories.MyDocuments); - VerifySpecialDirectory(() => Microsoft.VisualBasic.FileIO.SpecialDirectories.MyMusic, () => specialDirectories.MyMusic); - VerifySpecialDirectory(() => Microsoft.VisualBasic.FileIO.SpecialDirectories.MyPictures, () => specialDirectories.MyPictures); - VerifySpecialDirectory(() => Microsoft.VisualBasic.FileIO.SpecialDirectories.Programs, () => specialDirectories.Programs); - VerifySpecialDirectory(() => Microsoft.VisualBasic.FileIO.SpecialDirectories.ProgramFiles, () => specialDirectories.ProgramFiles); - VerifySpecialDirectory(() => Microsoft.VisualBasic.FileIO.SpecialDirectories.Temp, () => specialDirectories.Temp); - } - - private static void VerifySpecialDirectory(Func getExpected, Func getActual) - { - string expected; - try - { - expected = getExpected(); - } - catch (Exception) - { - return; - } - - string actual = getActual(); - Assert.Equal(expected, actual); - } -} diff --git a/src/Microsoft.VisualBasic/tests/UnitTests/runtimeconfig.template.json b/src/Microsoft.VisualBasic/tests/UnitTests/runtimeconfig.template.json deleted file mode 100644 index e460762026c..00000000000 --- a/src/Microsoft.VisualBasic/tests/UnitTests/runtimeconfig.template.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "configProperties": { - "TestSwitch.LocalAppContext.DisableCaching": "true", - "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": "false" - } -} \ No newline at end of file diff --git a/src/System.Drawing.Common/src/AssemblyRef.cs b/src/System.Drawing.Common/src/AssemblyRef.cs index 0d07cb8bca4..c1640f412f2 100644 --- a/src/System.Drawing.Common/src/AssemblyRef.cs +++ b/src/System.Drawing.Common/src/AssemblyRef.cs @@ -5,7 +5,7 @@ internal static class FXAssembly { // NB: this must never-ever change to facilitate type-forwarding from // .NET Framework, if those are referenced in .NET project. - internal const string Version = "4.0.0.0"; + internal const string Version = "8.0.0.0"; } internal static class AssemblyRef diff --git a/src/System.Drawing.Common/src/CompatibilitySuppressions.xml b/src/System.Drawing.Common/src/CompatibilitySuppressions.xml index f182e5528b0..3ecaeb47651 100644 --- a/src/System.Drawing.Common/src/CompatibilitySuppressions.xml +++ b/src/System.Drawing.Common/src/CompatibilitySuppressions.xml @@ -97,4 +97,46 @@ lib/netstandard2.0/System.Drawing.Common.dll lib/net462/System.Drawing.Common.dll + + CP0015 + P:System.Drawing.Font.Name:[T:System.ComponentModel.EditorAttribute] + lib/netstandard2.0/System.Drawing.Common.dll + lib/net6.0/System.Drawing.Common.dll + + + CP0015 + T:System.Drawing.Bitmap:[T:System.ComponentModel.EditorAttribute] + lib/netstandard2.0/System.Drawing.Common.dll + lib/net6.0/System.Drawing.Common.dll + + + CP0015 + T:System.Drawing.ContentAlignment:[T:System.ComponentModel.EditorAttribute] + lib/netstandard2.0/System.Drawing.Common.dll + lib/net6.0/System.Drawing.Common.dll + + + CP0015 + T:System.Drawing.Font:[T:System.ComponentModel.EditorAttribute] + lib/netstandard2.0/System.Drawing.Common.dll + lib/net6.0/System.Drawing.Common.dll + + + CP0015 + T:System.Drawing.Icon:[T:System.ComponentModel.EditorAttribute] + lib/netstandard2.0/System.Drawing.Common.dll + lib/net6.0/System.Drawing.Common.dll + + + CP0015 + T:System.Drawing.Image:[T:System.ComponentModel.EditorAttribute] + lib/netstandard2.0/System.Drawing.Common.dll + lib/net6.0/System.Drawing.Common.dll + + + CP0015 + T:System.Drawing.Imaging.Metafile:[T:System.ComponentModel.EditorAttribute] + lib/netstandard2.0/System.Drawing.Common.dll + lib/net6.0/System.Drawing.Common.dll + \ No newline at end of file diff --git a/src/System.Drawing.Common/src/System.Drawing.Common.csproj b/src/System.Drawing.Common/src/System.Drawing.Common.csproj index 6aaf4860002..3e5b8e3921f 100644 --- a/src/System.Drawing.Common/src/System.Drawing.Common.csproj +++ b/src/System.Drawing.Common/src/System.Drawing.Common.csproj @@ -2,6 +2,7 @@ $(NetCurrent);$(NetPrevious);$(NetMinimum);netstandard2.0;$(NetFrameworkMinimum) + 8.0.0.0 true CS0618 false @@ -13,10 +14,15 @@ true true true + + - 7.0.0 + + true - $(NoWarn);IDE0090 + $(NoWarn);IDE0090;CS0672;SYSLIB0051 Provides access to GDI+ graphics functionality. Commonly Used Types: diff --git a/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs b/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs index 59775b95200..70444a5b638 100644 --- a/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs +++ b/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs @@ -20,6 +20,9 @@ internal static unsafe partial class Gdip { private const string LibraryName = "gdiplus.dll"; + //[LibraryImport(LibraryName)] + //public static extern bool TrackPopupMenuEx(HandleRef hmenu, int fuFlags, int x, int y, HandleRef hwnd, NativeMethods.TPMPARAMS tpm); + // Imported functions [LibraryImport(LibraryName)] private static partial int GdiplusStartup(out IntPtr token, in StartupInputEx input, out StartupOutput output); diff --git a/src/System.Drawing.Common/src/System/Drawing/NativeMethods.cs b/src/System.Drawing.Common/src/System/Drawing/NativeMethods.cs index d96eab2c4c1..1d2486c7647 100644 --- a/src/System.Drawing.Common/src/System/Drawing/NativeMethods.cs +++ b/src/System.Drawing.Common/src/System/Drawing/NativeMethods.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; diff --git a/src/System.Drawing.Common/src/System/Drawing/Printing/InvalidPrinterException.Core.cs b/src/System.Drawing.Common/src/System/Drawing/Printing/InvalidPrinterException.Core.cs index 18dfd00a6c6..d9f83511b3b 100644 --- a/src/System.Drawing.Common/src/System/Drawing/Printing/InvalidPrinterException.Core.cs +++ b/src/System.Drawing.Common/src/System/Drawing/Printing/InvalidPrinterException.Core.cs @@ -13,7 +13,7 @@ namespace System.Drawing.Printing; [Runtime.CompilerServices.TypeForwardedFrom(AssemblyRef.SystemDrawing)] public partial class InvalidPrinterException { -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER [Obsolete(DiagnosticId = "SYSLIB0051")] #endif protected InvalidPrinterException(SerializationInfo info, StreamingContext context) : base(info, context) @@ -21,7 +21,7 @@ protected InvalidPrinterException(SerializationInfo info, StreamingContext conte // Ignoring not deserializable input } -#if NET8_0_OR_GREATER +#if NET6_0_OR_GREATER [Obsolete(DiagnosticId = "SYSLIB0051")] #endif public override void GetObjectData(SerializationInfo info, StreamingContext context) diff --git a/src/System.Drawing.Common/src/System/Drawing/ScreenDC.cs b/src/System.Drawing.Common/src/System/Drawing/ScreenDC.cs index 5c28158d5e6..ad683c4e0c7 100644 --- a/src/System.Drawing.Common/src/System/Drawing/ScreenDC.cs +++ b/src/System.Drawing.Common/src/System/Drawing/ScreenDC.cs @@ -8,7 +8,7 @@ namespace System.Drawing; /// /// Simple wrapper to create a screen HDC within a using statement. /// -internal struct ScreenDC : IDisposable +public struct ScreenDC : IDisposable { private IntPtr _handle; diff --git a/src/System.Drawing.Common/tests/BitmapTests.cs b/src/System.Drawing.Common/tests/BitmapTests.cs deleted file mode 100644 index f429838ce85..00000000000 --- a/src/System.Drawing.Common/tests/BitmapTests.cs +++ /dev/null @@ -1,1746 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// (C) 2004 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004,2006-2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -using System.Drawing.Imaging; -using System.Runtime.InteropServices; -using Microsoft.DotNet.XUnitExtensions; - -namespace System.Drawing.Tests; - -public class BitmapTests : FileCleanupTestBase -{ - public static IEnumerable Ctor_FilePath_TestData() - { - yield return new object[] { "16x16_one_entry_4bit.ico", 16, 16, PixelFormat.Format32bppArgb, ImageFormat.Icon }; - yield return new object[] { "bitmap_173x183_indexed_8bit.bmp", 173, 183, PixelFormat.Format8bppIndexed, ImageFormat.Bmp }; - yield return new object[] { "16x16_nonindexed_24bit.png", 16, 16, PixelFormat.Format24bppRgb, ImageFormat.Png }; - } - - [Theory] - [MemberData(nameof(Ctor_FilePath_TestData))] - public void Ctor_FilePath(string filename, int width, int height, PixelFormat pixelFormat, ImageFormat rawFormat) - { - using (var bitmap = new Bitmap(Helpers.GetTestBitmapPath(filename))) - { - Assert.Equal(width, bitmap.Width); - Assert.Equal(height, bitmap.Height); - Assert.Equal(pixelFormat, bitmap.PixelFormat); - Assert.Equal(rawFormat, bitmap.RawFormat); - } - } - - [Theory] - [MemberData(nameof(Ctor_FilePath_TestData))] - public void Ctor_FilePath_UseIcm(string filename, int width, int height, PixelFormat pixelFormat, ImageFormat rawFormat) - { - foreach (bool useIcm in new bool[] { true, false }) - { - using (var bitmap = new Bitmap(Helpers.GetTestBitmapPath(filename), useIcm)) - { - Assert.Equal(width, bitmap.Width); - Assert.Equal(height, bitmap.Height); - Assert.Equal(pixelFormat, bitmap.PixelFormat); - Assert.Equal(rawFormat, bitmap.RawFormat); - } - } - } - - [Fact] - public void Ctor_NullFilePath_ThrowsArgumentNullException() - { - AssertExtensions.Throws("path", () => new Bitmap((string)null)); - AssertExtensions.Throws("path", () => new Bitmap((string)null, false)); - } - - [Theory] - [InlineData("", "path")] - [InlineData("\0", "path")] - [InlineData("NoSuchPath", null)] - public void Ctor_InvalidFilePath_ThrowsArgumentException(string filename, string paramName) - { - AssertExtensions.Throws(paramName, null, () => new Bitmap(filename)); - AssertExtensions.Throws(paramName, null, () => new Bitmap(filename, false)); - AssertExtensions.Throws(paramName, null, () => new Bitmap(filename, true)); - } - - [Fact] - public void Ctor_Type_ResourceName() - { - using (var bitmap = new Bitmap(typeof(BitmapTests), "bitmap_173x183_indexed_8bit.bmp")) - { - Assert.Equal(173, bitmap.Width); - Assert.Equal(183, bitmap.Height); - Assert.Equal(PixelFormat.Format8bppIndexed, bitmap.PixelFormat); - Assert.Equal(ImageFormat.Bmp, bitmap.RawFormat); - } - } - - [Fact] - public void Ctor_NullType_ThrowsArgumentNullException() - { - AssertExtensions.Throws("type", () => new Bitmap(null, "name")); - } - - [Theory] - [InlineData(typeof(Bitmap), "")] - [InlineData(typeof(Bitmap), "bitmap_173x183_indexed_8bit.bmp")] - [InlineData(typeof(BitmapTests), "bitmap_173x183_INDEXED_8bit.bmp")] - [InlineData(typeof(BitmapTests), "empty.file")] - public void Ctor_InvalidResource_ThrowsArgumentException(Type type, string resource) - { - AssertExtensions.Throws(null, () => new Bitmap(type, resource)); - } - - [Fact] - public void Ctor_InvalidResource_ThrowsArgumentNullException() - { - AssertExtensions.Throws("resource", null, () => new Bitmap(typeof(Bitmap), null)); - } - - [Theory] - [MemberData(nameof(Ctor_FilePath_TestData))] - public void Ctor_Stream(string filename, int width, int height, PixelFormat pixelFormat, ImageFormat rawFormat) - { - using (Stream stream = File.OpenRead(Helpers.GetTestBitmapPath(filename))) - using (var bitmap = new Bitmap(stream)) - { - Assert.Equal(width, bitmap.Width); - Assert.Equal(height, bitmap.Height); - Assert.Equal(pixelFormat, bitmap.PixelFormat); - Assert.Equal(rawFormat, bitmap.RawFormat); - } - } - - [Theory] - [MemberData(nameof(Ctor_FilePath_TestData))] - public void Ctor_Stream_UseIcm(string filename, int width, int height, PixelFormat pixelFormat, ImageFormat rawFormat) - { - foreach (bool useIcm in new bool[] { true, false }) - { - using (Stream stream = File.OpenRead(Helpers.GetTestBitmapPath(filename))) - using (var bitmap = new Bitmap(stream, useIcm)) - { - Assert.Equal(width, bitmap.Width); - Assert.Equal(height, bitmap.Height); - Assert.Equal(pixelFormat, bitmap.PixelFormat); - Assert.Equal(rawFormat, bitmap.RawFormat); - } - } - } - - [Fact] - public void Ctor_NullStream_ThrowsArgumentNullException() - { - AssertExtensions.Throws("stream", null, () => new Bitmap((Stream)null)); - AssertExtensions.Throws("stream", null, () => new Bitmap((Stream)null, false)); - } - - [Fact] - public void Ctor_InvalidBytesInStream_ThrowsArgumentException() - { - using (var stream = new MemoryStream(new byte[0])) - { - AssertExtensions.Throws(null, () => new Bitmap(stream)); - AssertExtensions.Throws(null, () => new Bitmap(stream, false)); - AssertExtensions.Throws(null, () => new Bitmap(stream, true)); - } - } - - [Theory] - [InlineData(10, 10)] - [InlineData(5, 15)] - public void Ctor_Width_Height(int width, int height) - { - using (var bitmap = new Bitmap(width, height)) - { - Assert.Equal(width, bitmap.Width); - Assert.Equal(height, bitmap.Height); - Assert.Equal(PixelFormat.Format32bppArgb, bitmap.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, bitmap.RawFormat); - } - } - - [Theory] - [InlineData(10, 10, PixelFormat.Format1bppIndexed)] - [InlineData(10, 10, PixelFormat.Format8bppIndexed)] - [InlineData(1, 1, PixelFormat.Format16bppArgb1555)] - [InlineData(1, 1, PixelFormat.Format16bppRgb555)] - [InlineData(1, 1, PixelFormat.Format16bppRgb565)] - [InlineData(1, 1, PixelFormat.Format16bppGrayScale)] - [InlineData(1, 1, PixelFormat.Format24bppRgb)] - [InlineData(1, 1, PixelFormat.Format32bppRgb)] - [InlineData(5, 15, PixelFormat.Format32bppArgb)] - [InlineData(1, 1, PixelFormat.Format32bppPArgb)] - [InlineData(10, 10, PixelFormat.Format48bppRgb)] - [InlineData(10, 10, PixelFormat.Format4bppIndexed)] - [InlineData(1, 1, PixelFormat.Format64bppArgb)] - [InlineData(1, 1, PixelFormat.Format64bppPArgb)] - public void Ctor_Width_Height_PixelFormat(int width, int height, PixelFormat pixelFormat) - { - using (var bitmap = new Bitmap(width, height, pixelFormat)) - { - Assert.Equal(width, bitmap.Width); - Assert.Equal(height, bitmap.Height); - Assert.Equal(pixelFormat, bitmap.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, bitmap.RawFormat); - } - } - - public static IEnumerable Ctor_Width_Height_Stride_PixelFormat_Scan0_TestData() - { - yield return new object[] { 10, 10, 0, PixelFormat.Format8bppIndexed, IntPtr.Zero }; - yield return new object[] { 5, 15, int.MaxValue, PixelFormat.Format32bppArgb, IntPtr.Zero }; - yield return new object[] { 5, 15, int.MinValue, PixelFormat.Format24bppRgb, IntPtr.Zero }; - yield return new object[] { 1, 1, 1, PixelFormat.Format1bppIndexed, IntPtr.Zero }; - } - - [Theory] - [MemberData(nameof(Ctor_Width_Height_Stride_PixelFormat_Scan0_TestData))] - public void Ctor_Width_Height_Stride_PixelFormat_Scan0(int width, int height, int stride, PixelFormat pixelFormat, IntPtr scan0) - { - using (var bitmap = new Bitmap(width, height, stride, pixelFormat, scan0)) - { - Assert.Equal(width, bitmap.Width); - Assert.Equal(height, bitmap.Height); - Assert.Equal(pixelFormat, bitmap.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, bitmap.RawFormat); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(ushort.MaxValue * 513)] - [InlineData(int.MaxValue)] - public void Ctor_InvalidWidth_ThrowsArgumentException(int width) - { - AssertExtensions.Throws(null, () => new Bitmap(width, 1)); - AssertExtensions.Throws(null, () => new Bitmap(width, 1, Graphics.FromImage(new Bitmap(1, 1)))); - AssertExtensions.Throws(null, () => new Bitmap(new Bitmap(1, 1), width, 1)); - AssertExtensions.Throws(null, () => new Bitmap(new Bitmap(1, 1), new Size(width, 1))); - AssertExtensions.Throws(null, () => new Bitmap(width, 1, PixelFormat.Format16bppArgb1555)); - AssertExtensions.Throws(null, () => new Bitmap(width, 1, 0, PixelFormat.Format16bppArgb1555, IntPtr.Zero)); - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(ushort.MaxValue * 513)] - [InlineData(int.MaxValue)] - public void Ctor_InvalidHeight_ThrowsArgumentException(int height) - { - AssertExtensions.Throws(null, () => new Bitmap(1, height)); - AssertExtensions.Throws(null, () => new Bitmap(1, height, Graphics.FromImage(new Bitmap(1, 1)))); - AssertExtensions.Throws(null, () => new Bitmap(new Bitmap(1, 1), 1, height)); - AssertExtensions.Throws(null, () => new Bitmap(new Bitmap(1, 1), new Size(1, height))); - AssertExtensions.Throws(null, () => new Bitmap(1, height, PixelFormat.Format16bppArgb1555)); - AssertExtensions.Throws(null, () => new Bitmap(1, height, 0, PixelFormat.Format16bppArgb1555, IntPtr.Zero)); - } - - [Theory] - [InlineData(PixelFormat.Undefined - 1)] - [InlineData(PixelFormat.Undefined)] - [InlineData(PixelFormat.Gdi - 1)] - [InlineData(PixelFormat.Max)] - [InlineData(PixelFormat.Indexed)] - [InlineData(PixelFormat.Gdi)] - [InlineData(PixelFormat.Alpha)] - [InlineData(PixelFormat.PAlpha)] - [InlineData(PixelFormat.Extended)] - [InlineData(PixelFormat.Canonical)] - public void Ctor_InvalidPixelFormat_ThrowsArgumentException(PixelFormat format) - { - AssertExtensions.Throws(null, () => new Bitmap(1, 1, format)); - AssertExtensions.Throws(null, () => new Bitmap(1, 1, 0, format, IntPtr.Zero)); - } - - [Fact] - public void Ctor_InvalidScan0_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new Bitmap(1, 1, 0, PixelFormat.Format16bppArgb1555, (IntPtr)10)); - } - - public static IEnumerable Image_TestData() - { - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format16bppRgb555), 1, 1 }; - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format16bppRgb565), 1, 1 }; - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format24bppRgb), 1, 1 }; - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format32bppArgb), 1, 1 }; - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format32bppPArgb), 1, 1 }; - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format48bppRgb), 1, 1 }; - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format64bppArgb), 1, 1 }; - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format64bppPArgb), 1, 1 }; - - yield return new object[] { new Bitmap(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico")), 16, 16 }; - yield return new object[] { new Bitmap(Helpers.GetTestBitmapPath("16x16_nonindexed_24bit.png")), 32, 48 }; - } - - [Theory] - [MemberData(nameof(Image_TestData))] - public void Ctor_Width_Height_Graphics(Bitmap image, int width, int height) - { - using (Graphics graphics = Graphics.FromImage(image)) - using (var bitmap = new Bitmap(width, height, graphics)) - { - Assert.Equal(width, bitmap.Width); - Assert.Equal(height, bitmap.Height); - Assert.Equal(PixelFormat.Format32bppPArgb, bitmap.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, bitmap.RawFormat); - } - } - - [Fact] - public void Ctor_NullGraphics_ThrowsArgumentNullException() - { - AssertExtensions.Throws("g", null, () => new Bitmap(1, 1, null)); - } - - [Fact] - public void Ctor_Image() - { - using (var image = new Bitmap(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"))) - using (var bitmap = new Bitmap(image)) - { - Assert.Equal(16, bitmap.Width); - Assert.Equal(16, bitmap.Height); - Assert.Equal(PixelFormat.Format32bppArgb, bitmap.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, bitmap.RawFormat); - } - } - - [Fact] - public void Ctor_NullImageWithoutSize_ThrowsNullReferenceException() - { - Assert.Throws(() => new Bitmap((Image)null)); - } - - [Theory] - [MemberData(nameof(Image_TestData))] - public void Ctor_Image_Width_Height(Image image, int width, int height) - { - using (var bitmap = new Bitmap(image, width, height)) - { - Assert.Equal(width, bitmap.Width); - Assert.Equal(height, bitmap.Height); - Assert.Equal(PixelFormat.Format32bppArgb, bitmap.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, bitmap.RawFormat); - } - } - - [Theory] - [MemberData(nameof(Image_TestData))] - public void Ctor_Size(Image image, int width, int height) - { - using (var bitmap = new Bitmap(image, new Size(width, height))) - { - Assert.Equal(width, bitmap.Width); - Assert.Equal(height, bitmap.Height); - Assert.Equal(PixelFormat.Format32bppArgb, bitmap.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, bitmap.RawFormat); - } - } - - [Fact] - public void Ctor_NullImageWithSize_ThrowsArgumentNullException() - { - AssertExtensions.Throws("original", "image", () => new Bitmap(null, new Size(1, 2))); - AssertExtensions.Throws("original", "image", () => new Bitmap(null, 1, 2)); - } - - [Fact] - public void Ctor_DisposedImage_ThrowsArgumentException() - { - var image = new Bitmap(1, 1); - image.Dispose(); - - AssertExtensions.Throws(null, () => new Bitmap(image)); - AssertExtensions.Throws(null, () => new Bitmap(image, 1, 1)); - AssertExtensions.Throws(null, () => new Bitmap(image, new Size(1, 1))); - } - - public static IEnumerable Clone_TestData() - { - yield return new object[] { new Bitmap(3, 3, PixelFormat.Format32bppArgb), new Rectangle(0, 0, 3, 3), PixelFormat.Format32bppArgb }; - yield return new object[] { new Bitmap(3, 3, PixelFormat.Format32bppArgb), new Rectangle(0, 0, 3, 3), PixelFormat.Format24bppRgb }; - yield return new object[] { new Bitmap(3, 3, PixelFormat.Format1bppIndexed), new Rectangle(1, 1, 1, 1), PixelFormat.Format64bppArgb }; - yield return new object[] { new Bitmap(3, 3, PixelFormat.Format64bppPArgb), new Rectangle(1, 1, 1, 1), PixelFormat.Format16bppRgb565 }; - } - - [Theory] - [MemberData(nameof(Clone_TestData))] - public void Clone_Rectangle_ReturnsExpected(Bitmap bitmap, Rectangle rectangle, PixelFormat targetFormat) - { - try - { - using (Bitmap clone = bitmap.Clone(rectangle, targetFormat)) - { - Assert.NotSame(bitmap, clone); - - Assert.Equal(rectangle.Width, clone.Width); - Assert.Equal(rectangle.Height, clone.Height); - Assert.Equal(targetFormat, clone.PixelFormat); - Assert.Equal(bitmap.RawFormat, clone.RawFormat); - - for (int x = 0; x < rectangle.Width; x++) - { - for (int y = 0; y < rectangle.Height; y++) - { - Color expectedColor = bitmap.GetPixel(rectangle.X + x, rectangle.Y + y); - if (Image.IsAlphaPixelFormat(targetFormat)) - { - Assert.Equal(expectedColor, clone.GetPixel(x, y)); - } - else - { - Assert.Equal(Color.FromArgb(255, expectedColor.R, expectedColor.G, expectedColor.B), clone.GetPixel(x, y)); - } - } - } - } - } - finally - { - bitmap.Dispose(); - } - } - - [Theory] - [MemberData(nameof(Clone_TestData))] - public void Clone_RectangleF_ReturnsExpected(Bitmap bitmap, Rectangle rectangle, PixelFormat format) - { - try - { - using (Bitmap clone = bitmap.Clone((RectangleF)rectangle, format)) - { - Assert.NotSame(bitmap, clone); - - Assert.Equal(rectangle.Width, clone.Width); - Assert.Equal(rectangle.Height, clone.Height); - Assert.Equal(format, clone.PixelFormat); - } - } - finally - { - bitmap.Dispose(); - } - } - - [Theory] - [InlineData(0, 1)] - [InlineData(1, 0)] - public void Clone_ZeroWidthOrHeightRect_ThrowsArgumentException(int width, int height) - { - using (var bitmap = new Bitmap(3, 3)) - { - AssertExtensions.Throws(null, () => bitmap.Clone(new Rectangle(0, 0, width, height), bitmap.PixelFormat)); - AssertExtensions.Throws(null, () => bitmap.Clone(new RectangleF(0, 0, width, height), bitmap.PixelFormat)); - } - } - - [Theory] - [InlineData(0, 0, 4, 1)] - [InlineData(0, 0, 1, 4)] - [InlineData(1, 0, 3, 1)] - [InlineData(0, 1, 1, 3)] - [InlineData(4, 1, 1, 1)] - [InlineData(1, 4, 1, 1)] - public void Clone_InvalidRect_ThrowsOutOfMemoryException(int x, int y, int width, int height) - { - using (var bitmap = new Bitmap(3, 3)) - { - Assert.Throws(() => bitmap.Clone(new Rectangle(x, y, width, height), bitmap.PixelFormat)); - Assert.Throws(() => bitmap.Clone(new RectangleF(x, y, width, height), bitmap.PixelFormat)); - } - } - - [Theory] - [InlineData(PixelFormat.Max)] - [InlineData(PixelFormat.Indexed)] - [InlineData(PixelFormat.Gdi)] - [InlineData(PixelFormat.Alpha)] - [InlineData(PixelFormat.PAlpha)] - [InlineData(PixelFormat.Extended)] - [InlineData(PixelFormat.Format16bppGrayScale)] - [InlineData(PixelFormat.Canonical)] - public void Clone_InvalidPixelFormat_ThrowsOutOfMemoryException(PixelFormat format) - { - using (var bitmap = new Bitmap(1, 1)) - { - Assert.Throws(() => bitmap.Clone(new Rectangle(0, 0, 1, 1), format)); - Assert.Throws(() => bitmap.Clone(new RectangleF(0, 0, 1, 1), format)); - } - } - - [Fact] - public void Clone_GrayscaleFormat_ThrowsOutOfMemoryException() - { - using (var bitmap = new Bitmap(1, 1, PixelFormat.Format16bppGrayScale)) - { - Assert.Throws(() => bitmap.Clone(new Rectangle(0, 0, 1, 1), PixelFormat.Format32bppArgb)); - Assert.Throws(() => bitmap.Clone(new RectangleF(0, 0, 1, 1), PixelFormat.Format32bppArgb)); - } - } - - [Fact] - public void Clone_ValidBitmap_Success() - { - using (var bitmap = new Bitmap(1, 1)) - using (Bitmap clone = Assert.IsType(bitmap.Clone())) - { - Assert.NotSame(bitmap, clone); - Assert.Equal(1, clone.Width); - Assert.Equal(1, clone.Height); - } - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.Clone()); - AssertExtensions.Throws(null, () => bitmap.Clone(new Rectangle(0, 0, 1, 1), PixelFormat.Format32bppArgb)); - AssertExtensions.Throws(null, () => bitmap.Clone(new RectangleF(0, 0, 1, 1), PixelFormat.Format32bppArgb)); - } - - [Fact] - public void GetFrameCount_NewBitmap_ReturnsZero() - { - using (var bitmap = new Bitmap(1, 1)) - { - Assert.Equal(1, bitmap.GetFrameCount(FrameDimension.Page)); - Assert.Equal(1, bitmap.GetFrameCount(FrameDimension.Resolution)); - Assert.Equal(1, bitmap.GetFrameCount(FrameDimension.Time)); - Assert.Equal(1, bitmap.GetFrameCount(new FrameDimension(Guid.Empty))); - } - } - - [Fact] - public void GetFrameCount_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.GetFrameCount(FrameDimension.Page)); - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(1)] - public void SelectActiveFrame_InvalidFrameIndex_ThrowsArgumentException(int index) - { - using (var bitmap = new Bitmap(1, 1)) - { - Assert.Equal(0, bitmap.SelectActiveFrame(FrameDimension.Page, index)); - Assert.Equal(0, bitmap.SelectActiveFrame(FrameDimension.Resolution, index)); - Assert.Equal(0, bitmap.SelectActiveFrame(FrameDimension.Time, index)); - Assert.Equal(0, bitmap.SelectActiveFrame(new FrameDimension(Guid.Empty), index)); - } - } - - [Fact] - public void SelectActiveFrame_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.SelectActiveFrame(FrameDimension.Page, 0)); - } - - public static IEnumerable GetPixel_TestData() - { - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format1bppIndexed), 0, 0, Color.FromArgb(0, 0, 0) }; - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format4bppIndexed), 0, 0, Color.FromArgb(0, 0, 0) }; - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format8bppIndexed), 0, 0, Color.FromArgb(0, 0, 0) }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), 0, 0, Color.FromArgb(0, 0, 0) }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), 99, 99, Color.FromArgb(0, 0, 0) }; - } - - [Theory] - [MemberData(nameof(GetPixel_TestData))] - public void GetPixel_ValidPixelFormat_Success(Bitmap bitmap, int x, int y, Color color) - { - try - { - Assert.Equal(color, bitmap.GetPixel(x, y)); - } - finally - { - bitmap.Dispose(); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(1)] - public void GetPixel_InvalidX_ThrowsArgumentOutOfRangeException(int x) - { - using (var bitmap = new Bitmap(1, 1)) - { - AssertExtensions.Throws("x", () => bitmap.GetPixel(x, 0)); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(1)] - public void GetPixel_InvalidY_ThrowsArgumentOutOfRangeException(int y) - { - using (var bitmap = new Bitmap(1, 1)) - { - AssertExtensions.Throws("y", () => bitmap.GetPixel(0, y)); - } - } - - [Fact] - public void GetPixel_GrayScalePixelFormat_ThrowsArgumentException() - { - using (var bitmap = new Bitmap(1, 1, PixelFormat.Format16bppGrayScale)) - { - AssertExtensions.Throws(null, () => bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void GetPixel_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.GetPixel(0, 0)); - } - - public static IEnumerable GetHbitmap_TestData() - { - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format32bppRgb), 1, 1 }; - yield return new object[] { new Bitmap(32, 32, PixelFormat.Format32bppArgb), 32, 32 }; - yield return new object[] { new Bitmap(512, 512, PixelFormat.Format16bppRgb555), 512, 512 }; - } - - [Theory] - [MemberData(nameof(GetHbitmap_TestData))] - public void GetHbitmap_FromHbitmap_ReturnsExpected(Bitmap bitmap, int width, int height) - { - IntPtr handle = bitmap.GetHbitmap(); - try - { - Assert.NotEqual(IntPtr.Zero, handle); - - using (Bitmap result = Image.FromHbitmap(handle)) - { - Assert.Equal(width, result.Width); - Assert.Equal(height, result.Height); - Assert.Equal(PixelFormat.Format32bppRgb, result.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, result.RawFormat); - } - } - finally - { - bitmap.Dispose(); - } - - // Hbitmap survives original bitmap disposal. - using (Bitmap result = Image.FromHbitmap(handle)) - { - Assert.Equal(width, result.Width); - Assert.Equal(height, result.Height); - Assert.Equal(PixelFormat.Format32bppRgb, result.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, result.RawFormat); - } - - // Hbitmap can be used multiple times. - using (Bitmap result = Image.FromHbitmap(handle)) - { - Assert.Equal(width, result.Width); - Assert.Equal(height, result.Height); - Assert.Equal(PixelFormat.Format32bppRgb, result.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, result.RawFormat); - } - } - - [Theory] - [InlineData(1, 1)] - [InlineData(short.MaxValue, 1)] - [InlineData(1, short.MaxValue)] - public void GetHbitmap_Grayscale_ThrowsArgumentException(int width, int height) - { - using (var bitmap = new Bitmap(width, height, PixelFormat.Format16bppGrayScale)) - { - AssertExtensions.Throws(null, () => bitmap.GetHbitmap()); - } - } - - [Fact] - public void GetHbitmap_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.GetHbitmap()); - } - - [Fact] - public void FromHbitmap_InvalidHandle_ThrowsExternalException() - { - Assert.Throws(() => Image.FromHbitmap(IntPtr.Zero)); - Assert.Throws(() => Image.FromHbitmap((IntPtr)10)); - } - - public static IEnumerable FromHicon_Icon_TestData() - { - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico")), 16, 16 }; - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("32x32_one_entry_4bit.ico")), 32, 32 }; - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("64x64_one_entry_8bit.ico")), 64, 64 }; - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("96x96_one_entry_8bit.ico")), 96, 96 }; - } - - [Theory] - [MemberData(nameof(FromHicon_Icon_TestData))] - public void FromHicon_IconHandle_ReturnsExpected(Icon icon, int width, int height) - { - IntPtr handle; - try - { - using (Bitmap bitmap = GetHicon_FromHicon_ReturnsExpected(icon.Handle, width, height)) - { - handle = bitmap.GetHicon(); - } - } - finally - { - icon.Dispose(); - } - - // Hicon survives bitmap and icon disposal. - GetHicon_FromHicon_ReturnsExpected(handle, width, height); - } - - public static IEnumerable FromHicon_TestData() - { - yield return new object[] { new Bitmap(1, 1, PixelFormat.Format32bppRgb).GetHicon(), 1, 1 }; - yield return new object[] { new Bitmap(32, 32, PixelFormat.Format32bppRgb).GetHicon(), 32, 32 }; - yield return new object[] { new Bitmap(512, 512, PixelFormat.Format16bppRgb555).GetHicon(), 512, 512 }; - } - - [Theory] - [MemberData(nameof(FromHicon_TestData))] - public Bitmap GetHicon_FromHicon_ReturnsExpected(IntPtr handle, int width, int height) - { - Assert.NotEqual(IntPtr.Zero, handle); - - Bitmap result = Bitmap.FromHicon(handle); - Assert.Equal(width, result.Width); - Assert.Equal(height, result.Height); - Assert.Equal(PixelFormat.Format32bppArgb, result.PixelFormat); - Assert.Equal(ImageFormat.MemoryBmp, result.RawFormat); - Assert.Equal(335888, result.Flags); - Assert.Empty(result.Palette.Entries); - - return result; - } - - [Fact] - public void GetHicon_Grayscale_ThrowsArgumentException() - { - using (var bitmap = new Bitmap(1, 1, PixelFormat.Format16bppGrayScale)) - { - AssertExtensions.Throws(null, () => bitmap.GetHicon()); - } - } - - [Fact] - public void GetHicon_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.GetHicon()); - } - - [Fact] - public void SaveWmfAsPngDoesntChangeImageBoundaries() - { - if (PlatformDetection.IsWindows7) - { - throw new SkipTestException("GDI+ 1.1 is not supported"); - } - - if (PlatformDetection.IsArmOrArm64Process) - { - // https://github.com/dotnet/winforms/issues/8817 - throw new SkipTestException("Arm precision"); - } - - string output = $"{GetTestFilePath()}.png"; - using Stream wmfStream = File.OpenRead(Helpers.GetTestBitmapPath("gdiwmfboundariesbug.wmf")); - using Image bitmapFromWmf = Image.FromStream(wmfStream); - bitmapFromWmf.Save(output, ImageFormat.Png); - - using Stream expectedPngStream = File.OpenRead(Helpers.GetTestBitmapPath("gdiwmfboundariesbug-output.png")); - using Image expectedPngBitmap = Image.FromStream(expectedPngStream); - - using Stream outputPngStream = File.OpenRead(output); - using Image outputPngBitmap = Image.FromStream(outputPngStream); - - Assert.Equal(expectedPngBitmap.HorizontalResolution, outputPngBitmap.HorizontalResolution); - Assert.Equal(expectedPngBitmap.VerticalResolution, outputPngBitmap.VerticalResolution); - Assert.Equal(expectedPngBitmap.Size, outputPngBitmap.Size); - Assert.Equal(expectedPngBitmap.PhysicalDimension, outputPngBitmap.PhysicalDimension); - Assert.Equal(expectedPngBitmap.PixelFormat, outputPngBitmap.PixelFormat); - } - - [Fact] - public void FromHicon_InvalidHandle_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => Bitmap.FromHicon(IntPtr.Zero)); - AssertExtensions.Throws(null, () => Bitmap.FromHicon((IntPtr)10)); - } - - [Fact] - public void FromHicon_1bppIcon_ThrowsArgumentException() - { - using (var icon = new Icon(Helpers.GetTestBitmapPath("48x48_one_entry_1bit.ico"))) - { - AssertExtensions.Throws(null, () => Bitmap.FromHicon(icon.Handle)); - } - } - - [Fact] - public void FromResource_InvalidHandle_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => Bitmap.FromResource(IntPtr.Zero, "Name")); - AssertExtensions.Throws(null, () => Bitmap.FromResource((IntPtr)10, "Name")); - } - - [Fact] - public void FromResource_InvalidBitmapName_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => Bitmap.FromResource(IntPtr.Zero, "Name")); - AssertExtensions.Throws(null, () => Bitmap.FromResource((IntPtr)10, "Name")); - } - - [Fact] - public void MakeTransparent_NoColorWithMatches_SetsMatchingPixelsToTransparent() - { - using (var bitmap = new Bitmap(10, 10)) - { - for (int x = 0; x < bitmap.Width; x++) - { - for (int y = 0; y < bitmap.Height; y++) - { - if (y % 2 == 0) - { - bitmap.SetPixel(x, y, Color.LightGray); - } - else - { - bitmap.SetPixel(x, y, Color.Red); - } - } - } - - bitmap.MakeTransparent(); - for (int x = 0; x < bitmap.Width; x++) - { - for (int y = 0; y < bitmap.Height; y++) - { - if (y % 2 == 0) - { - Assert.Equal(Color.FromArgb(255, 211, 211, 211), bitmap.GetPixel(x, y)); - } - else - { - Assert.Equal(Color.FromArgb(0, 0, 0, 0), bitmap.GetPixel(x, y)); - } - } - } - } - } - - [Fact] - public void MakeTransparent_CustomColorExists_SetsMatchingPixelsToTransparent() - { - using (var bitmap = new Bitmap(10, 10)) - { - for (int x = 0; x < bitmap.Width; x++) - { - for (int y = 0; y < bitmap.Height; y++) - { - if (y % 2 == 0) - { - bitmap.SetPixel(x, y, Color.Blue); - } - else - { - bitmap.SetPixel(x, y, Color.Red); - } - } - } - - bitmap.MakeTransparent(Color.Blue); - for (int x = 0; x < bitmap.Width; x++) - { - for (int y = 0; y < bitmap.Height; y++) - { - if (y % 2 == 0) - { - Assert.Equal(Color.FromArgb(0, 0, 0, 0), bitmap.GetPixel(x, y)); - } - else - { - Assert.Equal(Color.FromArgb(255, 255, 0, 0), bitmap.GetPixel(x, y)); - } - } - } - } - } - - [Fact] - public void MakeTransparent_CustomColorDoesntExist_DoesNothing() - { - using (var bitmap = new Bitmap(10, 10)) - { - for (int x = 0; x < bitmap.Width; x++) - { - for (int y = 0; y < bitmap.Height; y++) - { - bitmap.SetPixel(x, y, Color.Blue); - } - } - - bitmap.MakeTransparent(Color.Red); - for (int x = 0; x < bitmap.Width; x++) - { - for (int y = 0; y < bitmap.Height; y++) - { - Assert.Equal(Color.FromArgb(255, 0, 0, 255), bitmap.GetPixel(x, y)); - } - } - } - } - - [Fact] - public void MakeTransparent_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.MakeTransparent()); - AssertExtensions.Throws(null, () => bitmap.MakeTransparent(Color.Red)); - } - - [Fact] - public void MakeTransparent_GrayscalePixelFormat_ThrowsArgumentException() - { - using var bitmap = new Bitmap(1, 1, PixelFormat.Format16bppGrayScale); - AssertExtensions.Throws(null, () => bitmap.MakeTransparent()); - - if (PlatformDetection.IsWindows11OrHigher) - { - bitmap.MakeTransparent(Color.Red); - } - else - { - Assert.Throws(() => bitmap.MakeTransparent(Color.Red)); - } - } - - [Fact] - public void MakeTransparent_Icon_ThrowsInvalidOperationException() - { - using (var bitmap = new Bitmap(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"))) - { - Assert.Throws(() => bitmap.MakeTransparent(Color.Red)); - } - } - - public static IEnumerable SetPixel_TestData() - { - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), 0, 0, Color.FromArgb(255, 128, 128, 128) }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), 99, 99, Color.FromArgb(255, 128, 128, 128) }; - } - - [Theory] - [MemberData(nameof(SetPixel_TestData))] - public void SetPixel_ValidPixelFormat_Success(Bitmap bitmap, int x, int y, Color color) - { - bitmap.SetPixel(x, y, color); - Assert.Equal(color, bitmap.GetPixel(x, y)); - } - - [Theory] - [InlineData(PixelFormat.Format1bppIndexed)] - [InlineData(PixelFormat.Format4bppIndexed)] - [InlineData(PixelFormat.Format8bppIndexed)] - public void SetPixel_IndexedPixelFormat_ThrowsInvalidOperationException(PixelFormat format) - { - using (var bitmap = new Bitmap(1, 1, format)) - { - Assert.Throws(() => bitmap.SetPixel(0, 0, Color.Red)); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(1)] - public void SetPixel_InvalidX_ThrowsArgumentOutOfRangeException(int x) - { - using (var bitmap = new Bitmap(1, 1)) - { - AssertExtensions.Throws("x", () => bitmap.SetPixel(x, 0, Color.Red)); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(1)] - public void SetPixel_InvalidY_ThrowsArgumentOutOfRangeException(int y) - { - using (var bitmap = new Bitmap(1, 1)) - { - AssertExtensions.Throws("y", () => bitmap.SetPixel(0, y, Color.Red)); - } - } - - [Fact] - public void SetPixel_GrayScalePixelFormat_ThrowsArgumentException() - { - using (var bitmap = new Bitmap(1, 1, PixelFormat.Format16bppGrayScale)) - { - AssertExtensions.Throws(null, () => bitmap.SetPixel(0, 0, Color.Red)); - } - } - - [Fact] - public void SetPixel_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.SetPixel(0, 0, Color.Red)); - } - - [Theory] - [InlineData(1, 1)] - [InlineData(float.PositiveInfinity, float.PositiveInfinity)] - [InlineData(float.MaxValue, float.MaxValue)] - public void SetResolution_ValidDpi_Success(float xDpi, float yDpi) - { - using (var bitmap = new Bitmap(1, 1)) - { - bitmap.SetResolution(xDpi, yDpi); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(float.NaN)] - [InlineData(float.NegativeInfinity)] - public void SetResolution_InvalidXDpi_ThrowsArgumentException(float xDpi) - { - using (var bitmap = new Bitmap(1, 1)) - { - AssertExtensions.Throws(null, () => bitmap.SetResolution(xDpi, 1)); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(float.NaN)] - [InlineData(float.NegativeInfinity)] - public void SetResolution_InvalidYDpi_ThrowsArgumentException(float yDpi) - { - using (var bitmap = new Bitmap(1, 1)) - { - AssertExtensions.Throws(null, () => bitmap.SetResolution(1, yDpi)); - } - } - - [Fact] - public void SetResolution_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.SetResolution(1, 1)); - } - - public static IEnumerable LockBits_TestData() - { - Bitmap bitmap() => new(2, 2, PixelFormat.Format32bppArgb); - yield return new object[] { bitmap(), new Rectangle(0, 0, 2, 2), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb, 8, 1 }; - yield return new object[] { bitmap(), new Rectangle(0, 0, 2, 2), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb, 8, 3 }; - yield return new object[] { bitmap(), new Rectangle(0, 0, 2, 2), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb, 8, 2 }; - - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb, 400, 1 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, 400, 3 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb, 400, 2 }; - - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb, 300, 65537 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, 300, 65539 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb, 300, 65538 }; - - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format24bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb, 300, 1 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format24bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, 300, 3 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format24bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb, 300, 2 }; - - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format24bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb, 400, 65537 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format24bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, 400, 65539 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format24bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb, 400, 65538 }; - - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format8bppIndexed), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb, 300, 65537 }; - - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format8bppIndexed), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed, 100, 1 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format8bppIndexed), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, 100, 3 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format8bppIndexed), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed, 100, 2 }; - - - yield return new object[] { new Bitmap(184, 184, PixelFormat.Format1bppIndexed), new Rectangle(0, 0, 184, 184), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed, 24, 1 }; - yield return new object[] { new Bitmap(184, 184, PixelFormat.Format1bppIndexed), new Rectangle(0, 0, 184, 184), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed, 24, 3 }; - yield return new object[] { new Bitmap(184, 184, PixelFormat.Format1bppIndexed), new Rectangle(0, 0, 184, 184), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed, 24, 2 }; - - yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb, 8, 1 }; - yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb, 8, 3 }; - yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb, 8, 2 }; - - yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.ReadOnly - 1, PixelFormat.Format32bppArgb, 8, 0 }; - - yield return new object[] { bitmap(), new Rectangle(0, 0, 2, 2), ImageLockMode.WriteOnly, PixelFormat.Format16bppGrayScale, 4, 65538 }; - - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed, 100, 65537 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, 100, 65539 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed, 100, 65538 }; - - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format8bppIndexed), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, 300, 65539 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format8bppIndexed), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb, 300, 65538 }; - } - - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - [MemberData(nameof(LockBits_TestData))] - public void LockBits_Invoke_Success(Bitmap bitmap, Rectangle rectangle, ImageLockMode lockMode, PixelFormat pixelFormat, int expectedStride, int expectedReserved) - { - try - { - BitmapData data = bitmap.LockBits(rectangle, lockMode, pixelFormat); - Assert.Equal(pixelFormat, data.PixelFormat); - Assert.Equal(rectangle.Width, data.Width); - Assert.Equal(rectangle.Height, data.Height); - Assert.Equal(expectedStride, data.Stride); - - // "Reserved" is documented as "Reserved. Do not use.", so it's not clear whether we actually need to test this in any unit tests. - Assert.Equal(expectedReserved, data.Reserved); - - // Locking with 16bppGrayscale succeeds, but the data can't be unlocked. - if (pixelFormat == PixelFormat.Format16bppGrayScale) - { - AssertExtensions.Throws(null, () => bitmap.UnlockBits(data)); - } - else - { - bitmap.UnlockBits(data); - } - } - finally - { - bitmap.Dispose(); - } - } - - [Fact] - public void LockBits_NullBitmapData_ThrowsArgumentException() - { - using (var bitmap = new Bitmap(1, 1)) - { - AssertExtensions.Throws(null, () => bitmap.LockBits(Rectangle.Empty, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb, null)); - } - } - - [Theory] - [InlineData(-1, 0, 1, 1)] - [InlineData(2, 0, 1, 1)] - [InlineData(0, -1, 1, 1)] - [InlineData(0, 2, 1, 1)] - [InlineData(0, 0, -1, 1)] - [InlineData(0, 0, 3, 1)] - [InlineData(0, 0, 1, -1)] - [InlineData(0, 0, 1, 3)] - [InlineData(1, 0, 2, 1)] - [InlineData(1, 1, 1, 0)] - [InlineData(1, 1, 0, 1)] - public void LockBits_InvalidRect_ThrowsArgumentException(int x, int y, int width, int height) - { - using (var bitmap = new Bitmap(2, 2)) - { - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(x, y, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat)); - - var bitmapData = new BitmapData(); - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(x, y, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat, bitmapData)); - Assert.Equal(IntPtr.Zero, bitmapData.Scan0); - } - } - - [Theory] - [InlineData(PixelFormat.DontCare)] - [InlineData(PixelFormat.Max)] - [InlineData(PixelFormat.Indexed)] - [InlineData(PixelFormat.Gdi)] - [InlineData(PixelFormat.Alpha)] - [InlineData(PixelFormat.PAlpha)] - [InlineData(PixelFormat.Extended)] - [InlineData(PixelFormat.Canonical)] - public void LockBits_InvalidPixelFormat_ThrowsArgumentException(PixelFormat format) - { - using (var bitmap = new Bitmap(1, 1)) - { - foreach (ImageLockMode lockMode in Enum.GetValues(typeof(ImageLockMode))) - { - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(0, 0, 1, 1), lockMode, format)); - - var bitmapData = new BitmapData(); - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(0, 0, 1, 1), lockMode, format, bitmapData)); - Assert.Equal(IntPtr.Zero, bitmapData.Scan0); - } - } - } - - [Fact] - public void LockBits_ReadOnlyGrayscale_ThrowsArgumentException() - { - using (var bitmap = new Bitmap(1, 1)) - { - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format16bppGrayScale)); - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format16bppGrayScale, new BitmapData())); - - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format16bppGrayScale)); - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format16bppGrayScale, new BitmapData())); - - BitmapData data = bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.WriteOnly, PixelFormat.Format16bppGrayScale); - AssertExtensions.Throws(null, () => bitmap.UnlockBits(data)); - } - } - - [Theory] - [InlineData((ImageLockMode)(-1))] - [InlineData(ImageLockMode.UserInputBuffer + 1)] - [InlineData(ImageLockMode.UserInputBuffer)] - public void LockBits_InvalidLockMode_ThrowsArgumentException(ImageLockMode lockMode) - { - using (var bitmap = new Bitmap(1, 1)) - { - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(0, 0, 1, 1), lockMode, bitmap.PixelFormat)); - - var bitmapData = new BitmapData(); - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(0, 0, 1, 1), lockMode, bitmap.PixelFormat, bitmapData)); - Assert.Equal(IntPtr.Zero, bitmapData.Scan0); - } - } - - [Fact] - public void LockBits_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)); - - var bitmapData = new BitmapData(); - AssertExtensions.Throws(null, () => bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb, bitmapData)); - Assert.Equal(IntPtr.Zero, bitmapData.Scan0); - } - - [Fact] - public void LockBits_AlreadyLocked_ThrowsInvalidOperationException() - { - using (var bitmap = new Bitmap(1, 1)) - { - bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, bitmap.PixelFormat); - - Assert.Throws(() => bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, bitmap.PixelFormat)); - Assert.Throws(() => bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, bitmap.PixelFormat, new BitmapData())); - - Assert.Throws(() => bitmap.LockBits(new Rectangle(1, 1, 1, 1), ImageLockMode.ReadOnly, bitmap.PixelFormat)); - Assert.Throws(() => bitmap.LockBits(new Rectangle(1, 1, 1, 1), ImageLockMode.ReadOnly, bitmap.PixelFormat, new BitmapData())); - } - } - - [Theory] - [InlineData(0, -1)] - [InlineData(0, 2)] - [InlineData(1, 2)] - public void UnlockBits_InvalidHeightWidth_Nop(int offset, int invalidParameter) - { - using (var bitmap = new Bitmap(2, 2)) - { - BitmapData data = bitmap.LockBits(new Rectangle(offset, offset, 1, 1), ImageLockMode.ReadOnly, bitmap.PixelFormat); - data.Height = invalidParameter; - data.Width = invalidParameter; - - bitmap.UnlockBits(data); - } - } - - [Fact] - public void UnlockBits_Scan0Zero_Nop() - { - using (var bitmap = new Bitmap(1, 1)) - { - BitmapData data = bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, bitmap.PixelFormat); - data.Scan0 = IntPtr.Zero; - - bitmap.UnlockBits(data); - } - } - - [Theory] - [InlineData(PixelFormat.Indexed)] - [InlineData(PixelFormat.Gdi)] - public void UnlockBits_InvalidPixelFormat_Nop(PixelFormat format) - { - using (var bitmap = new Bitmap(1, 1)) - { - BitmapData data = bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, bitmap.PixelFormat); - data.PixelFormat = format; - - bitmap.UnlockBits(data); - } - } - - [Fact] - public void UnlockBits_NullBitmapData_ThrowsArgumentException() - { - using (var bitmap = new Bitmap(1, 1)) - { - AssertExtensions.Throws(null, () => bitmap.UnlockBits(null)); - } - } - - [Fact] - public void UnlockBits_NotLocked_ThrowsExternalException() - { - using (var bitmap = new Bitmap(1, 1)) - { - Assert.Throws(() => bitmap.UnlockBits(new BitmapData())); - } - } - - [Fact] - public void UnlockBits_AlreadyUnlocked_ThrowsExternalException() - { - using (var bitmap = new Bitmap(1, 1)) - { - BitmapData data = bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, bitmap.PixelFormat); - bitmap.UnlockBits(data); - - Assert.Throws(() => bitmap.UnlockBits(new BitmapData())); - } - } - - [Fact] - public void UnlockBits_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.UnlockBits(new BitmapData())); - } - - [Fact] - public void Size_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.Width); - AssertExtensions.Throws(null, () => bitmap.Height); - AssertExtensions.Throws(null, () => bitmap.Size); - } - - [Theory] - [InlineData(PixelFormat.Format16bppArgb1555)] - [InlineData(PixelFormat.Format16bppRgb555)] - [InlineData(PixelFormat.Format16bppRgb565)] - [InlineData(PixelFormat.Format32bppArgb)] - [InlineData(PixelFormat.Format32bppPArgb)] - [InlineData(PixelFormat.Format32bppRgb)] - [InlineData(PixelFormat.Format24bppRgb)] - public void CustomPixelFormat_GetPixels_ReturnsExpected(PixelFormat format) - { - bool alpha = Image.IsAlphaPixelFormat(format); - int size = Image.GetPixelFormatSize(format) / 8 * 2; - using (var bitmap = new Bitmap(2, 1, format)) - { - Color a = Color.FromArgb(128, 64, 32, 16); - Color b = Color.FromArgb(192, 96, 48, 24); - bitmap.SetPixel(0, 0, a); - bitmap.SetPixel(1, 0, b); - Color c = bitmap.GetPixel(0, 0); - Color d = bitmap.GetPixel(1, 0); - if (size == 4) - { - Assert.Equal(255, c.A); - Assert.Equal(66, c.R); - if (format == PixelFormat.Format16bppRgb565) - { - Assert.Equal(32, c.G); - } - else - { - Assert.Equal(33, c.G); - } - Assert.Equal(16, c.B); - - Assert.Equal(255, d.A); - Assert.Equal(99, d.R); - if (format == PixelFormat.Format16bppRgb565) - { - Assert.Equal(48, d.G); - } - else - { - Assert.Equal(49, d.G); - } - Assert.Equal(24, d.B); - } - else if (alpha) - { - if (format == PixelFormat.Format32bppPArgb) - { - Assert.Equal(a.A, c.A); - Assert.Equal(a.R - 1, c.R); - Assert.Equal(a.G - 1, c.G); - Assert.Equal(a.B - 1, c.B); - - Assert.Equal(b.A, d.A); - Assert.Equal(b.R - 1, d.R); - Assert.Equal(b.G - 1, d.G); - Assert.Equal(b.B - 1, d.B); - } - else - { - Assert.Equal(a, c); - Assert.Equal(b, d); - } - } - else - { - Assert.Equal(Color.FromArgb(255, 64, 32, 16), c); - Assert.Equal(Color.FromArgb(255, 96, 48, 24), d); - } - BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, 2, 1), ImageLockMode.ReadOnly, format); - try - { - byte[] data = new byte[size]; - Marshal.Copy(bitmapData.Scan0, data, 0, size); - if (format == PixelFormat.Format32bppPArgb) - { - Assert.Equal(Math.Ceiling((float)c.B * c.A / 255), data[0]); - Assert.Equal(Math.Ceiling((float)c.G * c.A / 255), data[1]); - Assert.Equal(Math.Ceiling((float)c.R * c.A / 255), data[2]); - Assert.Equal(c.A, data[3]); - Assert.Equal(Math.Ceiling((float)d.B * d.A / 255), data[4]); - Assert.Equal(Math.Ceiling((float)d.G * d.A / 255), data[5]); - Assert.Equal(Math.Ceiling((float)d.R * d.A / 255), data[6]); - Assert.Equal(d.A, data[7]); - } - else if (size == 4) - { - switch (format) - { - case PixelFormat.Format16bppRgb565: - Assert.Equal(2, data[0]); - Assert.Equal(65, data[1]); - Assert.Equal(131, data[2]); - Assert.Equal(97, data[3]); - break; - case PixelFormat.Format16bppArgb1555: - Assert.Equal(130, data[0]); - Assert.Equal(160, data[1]); - Assert.Equal(195, data[2]); - Assert.Equal(176, data[3]); - break; - case PixelFormat.Format16bppRgb555: - Assert.Equal(130, data[0]); - Assert.Equal(32, data[1]); - Assert.Equal(195, data[2]); - Assert.Equal(48, data[3]); - break; - } - } - else - { - int n = 0; - Assert.Equal(c.B, data[n++]); - Assert.Equal(c.G, data[n++]); - Assert.Equal(c.R, data[n++]); - if (size % 4 == 0) - { - if (format == PixelFormat.Format32bppRgb) - { - Assert.Equal(128, data[n++]); - } - else - { - Assert.Equal(c.A, data[n++]); - } - } - Assert.Equal(d.B, data[n++]); - Assert.Equal(d.G, data[n++]); - Assert.Equal(d.R, data[n++]); - if (size % 4 == 0) - { - if (format == PixelFormat.Format32bppRgb) - { - Assert.Equal(192, data[n++]); - } - else - { - Assert.Equal(d.A, data[n++]); - } - } - } - } - finally - { - bitmap.UnlockBits(bitmapData); - } - } - } - - public static IEnumerable Palette_TestData() - { - yield return new object[] { PixelFormat.Format1bppIndexed, new int[] { -16777216, -1 } }; - yield return new object[] { PixelFormat.Format4bppIndexed, new int[] { -16777216, -8388608, -16744448, -8355840, -16777088, -8388480, -16744320, -8355712, -4144960, -65536, -16711936, -256, -16776961, -65281, -16711681, -1, } }; - yield return new object[] { PixelFormat.Format8bppIndexed, new int[] { -16777216, -8388608, -16744448, -8355840, -16777088, -8388480, -16744320, -8355712, -4144960, -65536, -16711936, -256, -16776961, -65281, -16711681, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -16777216, -16777165, -16777114, -16777063, -16777012, -16776961, -16764160, -16764109, -16764058, -16764007, -16763956, -16763905, -16751104, -16751053, -16751002, -16750951, -16750900, -16750849, -16738048, -16737997, -16737946, -16737895, -16737844, -16737793, -16724992, -16724941, -16724890, -16724839, -16724788, -16724737, -16711936, -16711885, -16711834, -16711783, -16711732, -16711681, -13434880, -13434829, -13434778, -13434727, -13434676, -13434625, -13421824, -13421773, -13421722, -13421671, -13421620, -13421569, -13408768, -13408717, -13408666, -13408615, -13408564, -13408513, -13395712, -13395661, -13395610, -13395559, -13395508, -13395457, -13382656, -13382605, -13382554, -13382503, -13382452, -13382401, -13369600, -13369549, -13369498, -13369447, -13369396, -13369345, -10092544, -10092493, -10092442, -10092391, -10092340, -10092289, -10079488, -10079437, -10079386, -10079335, -10079284, -10079233, -10066432, -10066381, -10066330, -10066279, -10066228, -10066177, -10053376, -10053325, -10053274, -10053223, -10053172, -10053121, -10040320, -10040269, -10040218, -10040167, -10040116, -10040065, -10027264, -10027213, -10027162, -10027111, -10027060, -10027009, -6750208, -6750157, -6750106, -6750055, -6750004, -6749953, -6737152, -6737101, -6737050, -6736999, -6736948, -6736897, -6724096, -6724045, -6723994, -6723943, -6723892, -6723841, -6711040, -6710989, -6710938, -6710887, -6710836, -6710785, -6697984, -6697933, -6697882, -6697831, -6697780, -6697729, -6684928, -6684877, -6684826, -6684775, -6684724, -6684673, -3407872, -3407821, -3407770, -3407719, -3407668, -3407617, -3394816, -3394765, -3394714, -3394663, -3394612, -3394561, -3381760, -3381709, -3381658, -3381607, -3381556, -3381505, -3368704, -3368653, -3368602, -3368551, -3368500, -3368449, -3355648, -3355597, -3355546, -3355495, -3355444, -3355393, -3342592, -3342541, -3342490, -3342439, -3342388, -3342337, -65536, -65485, -65434, -65383, -65332, -65281, -52480, -52429, -52378, -52327, -52276, -52225, -39424, -39373, -39322, -39271, -39220, -39169, -26368, -26317, -26266, -26215, -26164, -26113, -13312, -13261, -13210, -13159, -13108, -13057, -256, -205, -154, -103, -52, -1 } }; - } - - [Theory] - [MemberData(nameof(Palette_TestData))] - public void Palette_Get_ReturnsExpected(PixelFormat pixelFormat, int[] expectedEntries) - { - using (var bitmap = new Bitmap(1, 1, pixelFormat)) - { - Assert.Equal(expectedEntries, bitmap.Palette.Entries.Select(c => c.ToArgb())); - } - } - - [Fact] - public void Palette_SetNull_ThrowsNullReferenceException() - { - using (var bitmap = new Bitmap(1, 1)) - { - Assert.Throws(() => bitmap.Palette = null); - } - } - - [Fact] - public void Palette_Disposed_ThrowsArgumentException() - { - var bitmap = new Bitmap(1, 1); - ColorPalette palette = bitmap.Palette; - bitmap.Dispose(); - - AssertExtensions.Throws(null, () => bitmap.Palette); - AssertExtensions.Throws(null, () => bitmap.Palette = palette); - AssertExtensions.Throws(null, () => bitmap.Size); - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void LockBits_Marshalling_Success() - { - Color red = Color.FromArgb(Color.Red.ToArgb()); - Color blue = Color.FromArgb(Color.Blue.ToArgb()); - - using (var bitmap = new Bitmap(1, 1, PixelFormat.Format32bppRgb)) - { - bitmap.SetPixel(0, 0, red); - Color pixelColor = bitmap.GetPixel(0, 0); - Assert.Equal(red, pixelColor); - - BitmapData data = bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); - try - { - int pixelValue = Marshal.ReadByte(data.Scan0, 0); - pixelValue |= Marshal.ReadByte(data.Scan0, 1) << 8; - pixelValue |= Marshal.ReadByte(data.Scan0, 2) << 16; - pixelValue |= Marshal.ReadByte(data.Scan0, 3) << 24; - - pixelColor = Color.FromArgb(pixelValue); - // Disregard alpha information in the test - pixelColor = Color.FromArgb(red.A, pixelColor.R, pixelColor.G, pixelColor.B); - Assert.Equal(red, pixelColor); - - // write blue but we're locked in read-only... - Marshal.WriteByte(data.Scan0, 0, blue.B); - Marshal.WriteByte(data.Scan0, 1, blue.G); - Marshal.WriteByte(data.Scan0, 2, blue.R); - Marshal.WriteByte(data.Scan0, 3, blue.A); - } - finally - { - bitmap.UnlockBits(data); - pixelColor = bitmap.GetPixel(0, 0); - // Disregard alpha information in the test - pixelColor = Color.FromArgb(red.A, pixelColor.R, pixelColor.G, pixelColor.B); - // ...so we still read red after unlocking - Assert.Equal(red, pixelColor); - } - - data = bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); - try - { - // write blue - Marshal.WriteByte(data.Scan0, 0, blue.B); - Marshal.WriteByte(data.Scan0, 1, blue.G); - Marshal.WriteByte(data.Scan0, 2, blue.R); - Marshal.WriteByte(data.Scan0, 3, blue.A); - } - finally - { - bitmap.UnlockBits(data); - pixelColor = bitmap.GetPixel(0, 0); - // Disregard alpha information in the test - pixelColor = Color.FromArgb(blue.A, pixelColor.R, pixelColor.G, pixelColor.B); - // read blue - Assert.Equal(blue, pixelColor); - } - } - - using (var bitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb)) - { - bitmap.SetPixel(0, 0, red); - - BitmapData data = bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - byte b = Marshal.ReadByte(data.Scan0, 0); - byte g = Marshal.ReadByte(data.Scan0, 1); - byte r = Marshal.ReadByte(data.Scan0, 2); - Assert.Equal(red, Color.FromArgb(red.A, r, g, b)); - // write blue but we're locked in read-only... - Marshal.WriteByte(data.Scan0, 0, blue.B); - Marshal.WriteByte(data.Scan0, 1, blue.G); - Marshal.WriteByte(data.Scan0, 2, blue.R); - } - finally - { - bitmap.UnlockBits(data); - // ...so we still read red after unlocking - Assert.Equal(red, bitmap.GetPixel(0, 0)); - } - - data = bitmap.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - try - { - // write blue - Marshal.WriteByte(data.Scan0, 0, blue.B); - Marshal.WriteByte(data.Scan0, 1, blue.G); - Marshal.WriteByte(data.Scan0, 2, blue.R); - } - finally - { - bitmap.UnlockBits(data); - // read blue - Assert.Equal(blue, bitmap.GetPixel(0, 0)); - } - } - } - - [Fact] - public void FromNonSeekableStream() - { - string path = GetTestFilePath(); - using (Bitmap bitmap = new Bitmap(100, 100)) - { - bitmap.Save(path, ImageFormat.Png); - } - - using (FileStream stream = new FileStream(path, FileMode.Open)) - { - using (Bitmap bitmap = new Bitmap(new TestStream(stream, canSeek: false))) - { - Assert.Equal(100, bitmap.Height); - Assert.Equal(100, bitmap.Width); - Assert.Equal(ImageFormat.Png, bitmap.RawFormat); - } - } - } - - [Theory] - [InlineData(true, false)] - [InlineData(false, false)] - [InlineData(false, true)] - public void SaveToRestrictiveStream(bool canRead, bool canSeek) - { - using (Stream backingStream = new MemoryStream()) - using (Stream restrictiveStream = new TestStream(backingStream, canRead, canSeek)) - { - using (Bitmap bitmap = new Bitmap(100, 100)) - { - bitmap.Save(restrictiveStream, ImageFormat.Png); - } - - backingStream.Position = 0; - - using (Bitmap bitmap = new Bitmap(backingStream)) - { - Assert.Equal(100, bitmap.Height); - Assert.Equal(100, bitmap.Width); - Assert.Equal(ImageFormat.Png, bitmap.RawFormat); - } - } - } - - private class TestStream : Stream - { - private Stream _stream; - private bool _canRead; - private bool _canSeek; - - public TestStream(Stream stream, bool canRead = true, bool canSeek = true) - { - _stream = stream; - _canRead = canRead; - _canSeek = canSeek; - } - - public override bool CanRead => _canRead && _stream.CanRead; - public override bool CanSeek => _canSeek && _stream.CanSeek; - public override bool CanWrite => _stream.CanWrite; - public override long Length => _stream.Length; - public override long Position - { - get => _stream.Position; - set => _stream.Position = _canSeek ? value : throw new NotSupportedException(); - } - public override void Flush() => _stream.Flush(); - public override int Read(byte[] buffer, int offset, int count) => _canRead ? _stream.Read(buffer, offset, count) : throw new NotSupportedException(); - public override long Seek(long offset, SeekOrigin origin) => _stream.Seek(offset, origin); - public override void SetLength(long value) => _stream.SetLength(value); - public override void Write(byte[] buffer, int offset, int count) => _stream.Write(buffer, offset, count); - } -} diff --git a/src/System.Drawing.Common/tests/BrushTests.cs b/src/System.Drawing.Common/tests/BrushTests.cs deleted file mode 100644 index 3c8903b53ab..00000000000 --- a/src/System.Drawing.Common/tests/BrushTests.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class BrushTests -{ - [Fact] - public void SetNativeBrush_Brush_Success() - { - using (var brush = new SubBrush()) - { - brush.PublicSetNativeBrush(10); - brush.PublicSetNativeBrush(IntPtr.Zero); - - brush.PublicSetNativeBrush(10); - brush.PublicSetNativeBrush(IntPtr.Zero); - } - } - - [Fact] - public void Dispose_NoSuchEntryPoint_SilentyCatchesException() - { - var brush = new SubBrush(); - brush.PublicSetNativeBrush(10); - brush.Dispose(); - } - - private class SubBrush : Brush - { - public override object Clone() => this; - public void PublicSetNativeBrush(nint brush) => SetNativeBrush(brush); - - protected override void Dispose(bool disposing) - { - // The pointers we're creating here are invalid and dangerous to dereference. - } - } -} diff --git a/src/System.Drawing.Common/tests/BrushesTests.cs b/src/System.Drawing.Common/tests/BrushesTests.cs deleted file mode 100644 index 5877acd8530..00000000000 --- a/src/System.Drawing.Common/tests/BrushesTests.cs +++ /dev/null @@ -1,176 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class BrushesTests -{ - public static IEnumerable Brushes_TestData() - { - yield return Brush(() => Brushes.AliceBlue, Color.AliceBlue); - yield return Brush(() => Brushes.AntiqueWhite, Color.AntiqueWhite); - yield return Brush(() => Brushes.Aqua, Color.Aqua); - yield return Brush(() => Brushes.Aquamarine, Color.Aquamarine); - yield return Brush(() => Brushes.Azure, Color.Azure); - yield return Brush(() => Brushes.Beige, Color.Beige); - yield return Brush(() => Brushes.Bisque, Color.Bisque); - yield return Brush(() => Brushes.Black, Color.Black); - yield return Brush(() => Brushes.BlanchedAlmond, Color.BlanchedAlmond); - yield return Brush(() => Brushes.Blue, Color.Blue); - yield return Brush(() => Brushes.BlueViolet, Color.BlueViolet); - yield return Brush(() => Brushes.Brown, Color.Brown); - yield return Brush(() => Brushes.BurlyWood, Color.BurlyWood); - yield return Brush(() => Brushes.CadetBlue, Color.CadetBlue); - yield return Brush(() => Brushes.Chartreuse, Color.Chartreuse); - yield return Brush(() => Brushes.Chocolate, Color.Chocolate); - yield return Brush(() => Brushes.Coral, Color.Coral); - yield return Brush(() => Brushes.CornflowerBlue, Color.CornflowerBlue); - yield return Brush(() => Brushes.Cornsilk, Color.Cornsilk); - yield return Brush(() => Brushes.Crimson, Color.Crimson); - yield return Brush(() => Brushes.Cyan, Color.Cyan); - yield return Brush(() => Brushes.DarkBlue, Color.DarkBlue); - yield return Brush(() => Brushes.DarkCyan, Color.DarkCyan); - yield return Brush(() => Brushes.DarkGoldenrod, Color.DarkGoldenrod); - yield return Brush(() => Brushes.DarkGray, Color.DarkGray); - yield return Brush(() => Brushes.DarkGreen, Color.DarkGreen); - yield return Brush(() => Brushes.DarkKhaki, Color.DarkKhaki); - yield return Brush(() => Brushes.DarkMagenta, Color.DarkMagenta); - yield return Brush(() => Brushes.DarkOliveGreen, Color.DarkOliveGreen); - yield return Brush(() => Brushes.DarkOrange, Color.DarkOrange); - yield return Brush(() => Brushes.DarkOrchid, Color.DarkOrchid); - yield return Brush(() => Brushes.DarkRed, Color.DarkRed); - yield return Brush(() => Brushes.DarkSalmon, Color.DarkSalmon); - yield return Brush(() => Brushes.DarkSeaGreen, Color.DarkSeaGreen); - yield return Brush(() => Brushes.DarkSlateBlue, Color.DarkSlateBlue); - yield return Brush(() => Brushes.DarkSlateGray, Color.DarkSlateGray); - yield return Brush(() => Brushes.DarkTurquoise, Color.DarkTurquoise); - yield return Brush(() => Brushes.DarkViolet, Color.DarkViolet); - yield return Brush(() => Brushes.DeepPink, Color.DeepPink); - yield return Brush(() => Brushes.DeepSkyBlue, Color.DeepSkyBlue); - yield return Brush(() => Brushes.DimGray, Color.DimGray); - yield return Brush(() => Brushes.DodgerBlue, Color.DodgerBlue); - yield return Brush(() => Brushes.Firebrick, Color.Firebrick); - yield return Brush(() => Brushes.FloralWhite, Color.FloralWhite); - yield return Brush(() => Brushes.ForestGreen, Color.ForestGreen); - yield return Brush(() => Brushes.Fuchsia, Color.Fuchsia); - yield return Brush(() => Brushes.Gainsboro, Color.Gainsboro); - yield return Brush(() => Brushes.GhostWhite, Color.GhostWhite); - yield return Brush(() => Brushes.Gold, Color.Gold); - yield return Brush(() => Brushes.Goldenrod, Color.Goldenrod); - yield return Brush(() => Brushes.Gray, Color.Gray); - yield return Brush(() => Brushes.Green, Color.Green); - yield return Brush(() => Brushes.GreenYellow, Color.GreenYellow); - yield return Brush(() => Brushes.Honeydew, Color.Honeydew); - yield return Brush(() => Brushes.HotPink, Color.HotPink); - yield return Brush(() => Brushes.IndianRed, Color.IndianRed); - yield return Brush(() => Brushes.Indigo, Color.Indigo); - yield return Brush(() => Brushes.Ivory, Color.Ivory); - yield return Brush(() => Brushes.Khaki, Color.Khaki); - yield return Brush(() => Brushes.Lavender, Color.Lavender); - yield return Brush(() => Brushes.LavenderBlush, Color.LavenderBlush); - yield return Brush(() => Brushes.LawnGreen, Color.LawnGreen); - yield return Brush(() => Brushes.LemonChiffon, Color.LemonChiffon); - yield return Brush(() => Brushes.LightBlue, Color.LightBlue); - yield return Brush(() => Brushes.LightCoral, Color.LightCoral); - yield return Brush(() => Brushes.LightCyan, Color.LightCyan); - yield return Brush(() => Brushes.LightGoldenrodYellow, Color.LightGoldenrodYellow); - yield return Brush(() => Brushes.LightGray, Color.LightGray); - yield return Brush(() => Brushes.LightGreen, Color.LightGreen); - yield return Brush(() => Brushes.LightPink, Color.LightPink); - yield return Brush(() => Brushes.LightSalmon, Color.LightSalmon); - yield return Brush(() => Brushes.LightSeaGreen, Color.LightSeaGreen); - yield return Brush(() => Brushes.LightSkyBlue, Color.LightSkyBlue); - yield return Brush(() => Brushes.LightSlateGray, Color.LightSlateGray); - yield return Brush(() => Brushes.LightSteelBlue, Color.LightSteelBlue); - yield return Brush(() => Brushes.LightYellow, Color.LightYellow); - yield return Brush(() => Brushes.Lime, Color.Lime); - yield return Brush(() => Brushes.LimeGreen, Color.LimeGreen); - yield return Brush(() => Brushes.Linen, Color.Linen); - yield return Brush(() => Brushes.Magenta, Color.Magenta); - yield return Brush(() => Brushes.Maroon, Color.Maroon); - yield return Brush(() => Brushes.MediumAquamarine, Color.MediumAquamarine); - yield return Brush(() => Brushes.MediumBlue, Color.MediumBlue); - yield return Brush(() => Brushes.MediumOrchid, Color.MediumOrchid); - yield return Brush(() => Brushes.MediumPurple, Color.MediumPurple); - yield return Brush(() => Brushes.MediumSeaGreen, Color.MediumSeaGreen); - yield return Brush(() => Brushes.MediumSlateBlue, Color.MediumSlateBlue); - yield return Brush(() => Brushes.MediumSpringGreen, Color.MediumSpringGreen); - yield return Brush(() => Brushes.MediumTurquoise, Color.MediumTurquoise); - yield return Brush(() => Brushes.MediumVioletRed, Color.MediumVioletRed); - yield return Brush(() => Brushes.MidnightBlue, Color.MidnightBlue); - yield return Brush(() => Brushes.MintCream, Color.MintCream); - yield return Brush(() => Brushes.MistyRose, Color.MistyRose); - yield return Brush(() => Brushes.Moccasin, Color.Moccasin); - yield return Brush(() => Brushes.NavajoWhite, Color.NavajoWhite); - yield return Brush(() => Brushes.Navy, Color.Navy); - yield return Brush(() => Brushes.OldLace, Color.OldLace); - yield return Brush(() => Brushes.Olive, Color.Olive); - yield return Brush(() => Brushes.OliveDrab, Color.OliveDrab); - yield return Brush(() => Brushes.Orange, Color.Orange); - yield return Brush(() => Brushes.OrangeRed, Color.OrangeRed); - yield return Brush(() => Brushes.Orchid, Color.Orchid); - yield return Brush(() => Brushes.PaleGoldenrod, Color.PaleGoldenrod); - yield return Brush(() => Brushes.PaleGreen, Color.PaleGreen); - yield return Brush(() => Brushes.PaleTurquoise, Color.PaleTurquoise); - yield return Brush(() => Brushes.PaleVioletRed, Color.PaleVioletRed); - yield return Brush(() => Brushes.PapayaWhip, Color.PapayaWhip); - yield return Brush(() => Brushes.PeachPuff, Color.PeachPuff); - yield return Brush(() => Brushes.Peru, Color.Peru); - yield return Brush(() => Brushes.Pink, Color.Pink); - yield return Brush(() => Brushes.Plum, Color.Plum); - yield return Brush(() => Brushes.PowderBlue, Color.PowderBlue); - yield return Brush(() => Brushes.Purple, Color.Purple); - yield return Brush(() => Brushes.Red, Color.Red); - yield return Brush(() => Brushes.RosyBrown, Color.RosyBrown); - yield return Brush(() => Brushes.RoyalBlue, Color.RoyalBlue); - yield return Brush(() => Brushes.SaddleBrown, Color.SaddleBrown); - yield return Brush(() => Brushes.Salmon, Color.Salmon); - yield return Brush(() => Brushes.SandyBrown, Color.SandyBrown); - yield return Brush(() => Brushes.SeaGreen, Color.SeaGreen); - yield return Brush(() => Brushes.SeaShell, Color.SeaShell); - yield return Brush(() => Brushes.Sienna, Color.Sienna); - yield return Brush(() => Brushes.Silver, Color.Silver); - yield return Brush(() => Brushes.SkyBlue, Color.SkyBlue); - yield return Brush(() => Brushes.SlateBlue, Color.SlateBlue); - yield return Brush(() => Brushes.SlateGray, Color.SlateGray); - yield return Brush(() => Brushes.Snow, Color.Snow); - yield return Brush(() => Brushes.SpringGreen, Color.SpringGreen); - yield return Brush(() => Brushes.SteelBlue, Color.SteelBlue); - yield return Brush(() => Brushes.Tan, Color.Tan); - yield return Brush(() => Brushes.Teal, Color.Teal); - yield return Brush(() => Brushes.Thistle, Color.Thistle); - yield return Brush(() => Brushes.Tomato, Color.Tomato); - yield return Brush(() => Brushes.Transparent, Color.Transparent); - yield return Brush(() => Brushes.Turquoise, Color.Turquoise); - yield return Brush(() => Brushes.Violet, Color.Violet); - yield return Brush(() => Brushes.Wheat, Color.Wheat); - yield return Brush(() => Brushes.White, Color.White); - yield return Brush(() => Brushes.WhiteSmoke, Color.WhiteSmoke); - yield return Brush(() => Brushes.Yellow, Color.Yellow); - yield return Brush(() => Brushes.YellowGreen, Color.YellowGreen); - } - - public static object[] Brush(Func getBrush, Color expectedColor) => new object[] { getBrush, expectedColor }; - - [Theory] - [MemberData(nameof(Brushes_TestData))] - public void Brushes_Get_ReturnsExpected(Func getBrush, Color expectedColor) - { - SolidBrush brush = Assert.IsType(getBrush()); - Assert.Equal(expectedColor, brush.Color); - - Assert.Same(brush, getBrush()); - - // Brushes are not immutable. - Color color = brush.Color; - try - { - brush.Color = Color.Red; - Assert.Equal(Color.Red, brush.Color); - } - finally - { - brush.Color = color; - } - } -} diff --git a/src/System.Drawing.Common/tests/BufferedGraphicsContextTests.cs b/src/System.Drawing.Common/tests/BufferedGraphicsContextTests.cs deleted file mode 100644 index facc4867a67..00000000000 --- a/src/System.Drawing.Common/tests/BufferedGraphicsContextTests.cs +++ /dev/null @@ -1,286 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -namespace System.Drawing.Tests; - -public class BufferedGraphicsContextTests -{ - [Fact] - public void Ctor_Default() - { - using (var context = new BufferedGraphicsContext()) - { - Assert.Equal(new Size(225, 96), context.MaximumBuffer); - } - } - - [Fact] - public void Allocate_ValidTargetGraphics_Success() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (BufferedGraphics bufferedGraphics = context.Allocate(graphics, Rectangle.Empty)) - { - Assert.NotNull(bufferedGraphics.Graphics); - - context.Invalidate(); - } - } - - [Fact] - public void Allocate_SmallRectWithTargetGraphics_Success() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (BufferedGraphics bufferedGraphics = context.Allocate(graphics, new Rectangle(0, 0, context.MaximumBuffer.Width - 1, context.MaximumBuffer.Height - 1))) - { - Assert.NotNull(bufferedGraphics.Graphics); - - context.Invalidate(); - } - } - - [Fact] - public void Allocate_LargeRectWithTargetGraphics_Success() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (BufferedGraphics bufferedGraphics = context.Allocate(graphics, new Rectangle(0, 0, context.MaximumBuffer.Width + 1, context.MaximumBuffer.Height + 1))) - { - Assert.NotNull(bufferedGraphics.Graphics); - - context.Invalidate(); - } - } - - [Fact] - public void Allocate_ValidTargetHdc_Success() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - try - { - IntPtr hdc = graphics.GetHdc(); - using (BufferedGraphics bufferedGraphics = context.Allocate(hdc, Rectangle.Empty)) - { - Assert.NotNull(bufferedGraphics.Graphics); - } - - context.Invalidate(); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void Allocate_SmallRectWithTargetHdc_Success() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - try - { - IntPtr hdc = graphics.GetHdc(); - using (BufferedGraphics bufferedGraphics = context.Allocate(hdc, new Rectangle(0, 0, context.MaximumBuffer.Width - 1, context.MaximumBuffer.Height - 1))) - { - Assert.NotNull(bufferedGraphics.Graphics); - } - - context.Invalidate(); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void Allocate_LargeRectWithTargetHdc_Success() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - try - { - IntPtr hdc = graphics.GetHdc(); - using (BufferedGraphics bufferedGraphics = context.Allocate(hdc, new Rectangle(0, 0, context.MaximumBuffer.Width + 1, context.MaximumBuffer.Height + 1))) - { - Assert.NotNull(bufferedGraphics.Graphics); - } - - context.Invalidate(); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void Allocate_InvalidHdc_ThrowsArgumentException() - { - using (var context = new BufferedGraphicsContext()) - { - AssertExtensions.Throws(null, () => context.Allocate((IntPtr)(-1), new Rectangle(0, 0, 10, 10))); - } - } - - [Fact] - public void Allocate_NullGraphicsZeroSize_Success() - { - using (var context = new BufferedGraphicsContext()) - using (BufferedGraphics graphics = context.Allocate(null, Rectangle.Empty)) - { - Assert.NotNull(graphics.Graphics); - } - } - - [Fact] - public void Allocate_NullGraphicsNonZeroSize_ThrowsArgumentNullException() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - { - Assert.Throws("hdc", () => context.Allocate(null, new Rectangle(0, 0, 10, 10))); - } - } - - [Fact] - public void Allocate_DisposedGraphics_ThrowsArgumentException() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - Rectangle largeRectangle = new Rectangle(0, 0, context.MaximumBuffer.Width + 1, context.MaximumBuffer.Height + 1); - AssertExtensions.Throws(null, () => context.Allocate(graphics, largeRectangle)); - AssertExtensions.Throws(null, () => context.Allocate(graphics, Rectangle.Empty)); - } - } - - [Fact] - public void Allocate_BusyGraphics_ThrowsInvalidOperationException() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - try - { - graphics.GetHdc(); - - Rectangle largeRectangle = new Rectangle(0, 0, context.MaximumBuffer.Width + 1, context.MaximumBuffer.Height + 1); - Assert.Throws(() => context.Allocate(graphics, largeRectangle)); - Assert.Throws(() => context.Allocate(graphics, Rectangle.Empty)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void Invalidate_CallMultipleTimes_Success() - { - using (var context = new BufferedGraphicsContext()) - { - context.Invalidate(); - context.Invalidate(); - } - } - - [Fact] - public void MaximumBuffer_SetValid_ReturnsExpected() - { - using (var context = new BufferedGraphicsContext()) - { - context.MaximumBuffer = new Size(10, 10); - Assert.Equal(new Size(10, 10), context.MaximumBuffer); - - context.MaximumBuffer = new Size(255, 255); - Assert.Equal(new Size(255, 255), context.MaximumBuffer); - } - } - - [Theory] - [InlineData(0)] - [InlineData(-1)] - public void MaximumBuffer_SetInvalidWidth_ThrowsArgumentException(int width) - { - using (var context = new BufferedGraphicsContext()) - { - AssertExtensions.Throws("value", null, () => context.MaximumBuffer = new Size(width, 1)); - } - } - - [Theory] - [InlineData(0)] - [InlineData(-1)] - public void MaximumBuffer_SetInvalidHeight_ThrowsArgumentException(int height) - { - using (var context = new BufferedGraphicsContext()) - { - AssertExtensions.Throws("value", null, () => context.MaximumBuffer = new Size(1, height)); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static void AllocateBufferedGraphicsContext() => new BufferedGraphicsContext(); - - - [Fact] - public void Finalize_Invoke_Success() - { - // This makes sure than finalization doesn't cause any errors or debug assertions. - AllocateBufferedGraphicsContext(); - - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - - [Fact] - public void Dispose_BusyAndValidated_ThrowsInvalidOperationException() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - using (context.Allocate(graphics, Rectangle.Empty)) - { - Assert.Throws(() => context.Dispose()); - } - } - } - - [Fact] - public void Dispose_BusyAndInvalidated_ThrowsInvalidOperationException() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - using (context.Allocate(graphics, Rectangle.Empty)) - { - context.Invalidate(); - Assert.Throws(() => context.Dispose()); - } - } - } -} diff --git a/src/System.Drawing.Common/tests/BufferedGraphicsManagerTests.cs b/src/System.Drawing.Common/tests/BufferedGraphicsManagerTests.cs deleted file mode 100644 index e0ff3567fc3..00000000000 --- a/src/System.Drawing.Common/tests/BufferedGraphicsManagerTests.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class BufferedGraphicsManagerTests -{ - [Fact] - public void Current_Get_ReturnsSameInstance() - { - Assert.Same(BufferedGraphicsManager.Current, BufferedGraphicsManager.Current); - Assert.NotNull(BufferedGraphicsManager.Current); - } -} diff --git a/src/System.Drawing.Common/tests/BufferedGraphicsTests.cs b/src/System.Drawing.Common/tests/BufferedGraphicsTests.cs deleted file mode 100644 index 650135f64d3..00000000000 --- a/src/System.Drawing.Common/tests/BufferedGraphicsTests.cs +++ /dev/null @@ -1,143 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class BufferedGraphicsTests -{ - [Fact] - public void Dispose_TempMultipleTimes_Success() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(3, 3)) - using (Graphics targetGraphics = Graphics.FromImage(image)) - { - BufferedGraphics graphics = context.Allocate(targetGraphics, new Rectangle(0, 0, 1, 1)); - Assert.NotNull(graphics.Graphics); - - graphics.Dispose(); - Assert.Null(graphics.Graphics); - - graphics.Dispose(); - } - } - - [Fact] - public void Dispose_ActualMultipleTimes_Success() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(3, 3)) - using (Graphics targetGraphics = Graphics.FromImage(image)) - { - BufferedGraphics graphics = context.Allocate(targetGraphics, new Rectangle(0, 0, context.MaximumBuffer.Width + 1, context.MaximumBuffer.Height + 1)); - Assert.NotNull(graphics.Graphics); - - graphics.Dispose(); - Assert.Null(graphics.Graphics); - - graphics.Dispose(); - } - } - - [Fact] - public void Render_ParameterlessWithTargetGraphics_Success() - { - Color color = Color.FromArgb(255, 0, 0, 0); - - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(3, 3)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new SolidBrush(Color.Red)) - { - graphics.FillRectangle(brush, new Rectangle(0, 0, 3, 3)); - - using (BufferedGraphics bufferedGraphics = context.Allocate(graphics, new Rectangle(0, 0, 3, 3))) - { - bufferedGraphics.Render(); - - Helpers.VerifyBitmap(image, new Color[][] - { - new Color[] { color, color, color }, - new Color[] { color, color, color }, - new Color[] { color, color, color } - }); - } - } - } - - [Fact] - public void Render_ParameterlessWithNullTargetGraphics_Success() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(3, 3)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new SolidBrush(Color.Red)) - { - graphics.FillRectangle(brush, new Rectangle(0, 0, 3, 3)); - try - { - IntPtr hdc = graphics.GetHdc(); - - using (BufferedGraphics bufferedGraphics = context.Allocate(hdc, new Rectangle(0, 0, 3, 3))) - { - bufferedGraphics.Render(); - } - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void Render_TargetGraphics_Success() - { - Color color = Color.FromArgb(255, 0, 0, 0); - - using (var context = new BufferedGraphicsContext()) - using (var originalImage = new Bitmap(3, 3)) - using (var targetImage = new Bitmap(3, 3)) - using (Graphics originalGraphics = Graphics.FromImage(originalImage)) - using (Graphics targetGraphics = Graphics.FromImage(targetImage)) - using (var brush = new SolidBrush(Color.Red)) - { - originalGraphics.FillRectangle(brush, new Rectangle(0, 0, 3, 3)); - - using (BufferedGraphics graphics = context.Allocate(originalGraphics, new Rectangle(0, 0, 3, 3))) - { - graphics.Render(targetGraphics); - - Helpers.VerifyBitmap(targetImage, new Color[][] - { - new Color[] { color, color, color }, - new Color[] { color, color, color }, - new Color[] { color, color, color } - }); - } - } - } - - [Fact] - public void Render_NullGraphics_Nop() - { - using (var context = new BufferedGraphicsContext()) - using (var image = new Bitmap(3, 3)) - using (Graphics graphics = Graphics.FromImage(image)) - using (BufferedGraphics bufferedGraphics = context.Allocate(graphics, new Rectangle(0, 0, 1, 1))) - { - bufferedGraphics.Render(null); - } - } - - [Fact] - public void Render_InvalidTargetDC_Nop() - { - using (var context = new BufferedGraphicsContext()) - using (BufferedGraphics graphics = context.Allocate(null, Rectangle.Empty)) - { - graphics.Render(IntPtr.Zero); - graphics.Render((IntPtr)(-1)); - } - } -} diff --git a/src/System.Drawing.Common/tests/CharacterRangeTests.cs b/src/System.Drawing.Common/tests/CharacterRangeTests.cs deleted file mode 100644 index 49fc8d408f4..00000000000 --- a/src/System.Drawing.Common/tests/CharacterRangeTests.cs +++ /dev/null @@ -1,88 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class CharacterRangeTests -{ - [Fact] - public void Ctor_Default() - { - var range = new CharacterRange(); - Assert.Equal(0, range.First); - Assert.Equal(0, range.Length); - } - - [Theory] - [InlineData(-1, -2)] - [InlineData(0, 0)] - [InlineData(1, 2)] - public void Ctor_Int_Int(int First, int Length) - { - var range = new CharacterRange(First, Length); - Assert.Equal(First, range.First); - Assert.Equal(Length, range.Length); - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(10)] - public void First_Set_GetReturnsExpected(int value) - { - var range = new CharacterRange - { - First = value - }; - Assert.Equal(value, range.First); - - // Set same. - range.First = value; - Assert.Equal(value, range.First); - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(10)] - public void Length_Set_GetReturnsExpected(int value) - { - var range = new CharacterRange - { - Length = value - }; - Assert.Equal(value, range.Length); - - // Set same. - range.Length = value; - Assert.Equal(value, range.Length); - } - - public static IEnumerable Equals_TestData() - { - yield return new object[] { new CharacterRange(1, 2), new CharacterRange(1, 2), true }; - yield return new object[] { new CharacterRange(1, 2), new CharacterRange(2, 2), false }; - yield return new object[] { new CharacterRange(1, 2), new CharacterRange(1, 1), false }; - yield return new object[] { new CharacterRange(1, 2), new object(), false }; - - // .NET Framework throws NullReferenceException. - if (!PlatformDetection.IsNetFramework) - { - yield return new object[] { new CharacterRange(1, 2), null, false }; - } - } - - [Theory] - [MemberData(nameof(Equals_TestData))] - public void Equals_Invoke_ReturnsExpected(CharacterRange range, object obj, bool expected) - { - Assert.Equal(expected, range.Equals(obj)); - if (obj is CharacterRange otherRange) - { - Assert.Equal(expected, range.Equals(otherRange)); - Assert.Equal(expected, range == otherRange); - Assert.Equal(!expected, range != otherRange); - Assert.Equal(expected, range.GetHashCode().Equals(otherRange.GetHashCode())); - } - } -} diff --git a/src/System.Drawing.Common/tests/ColorTranslatorTests.cs b/src/System.Drawing.Common/tests/ColorTranslatorTests.cs deleted file mode 100644 index 0d584ce3fe4..00000000000 --- a/src/System.Drawing.Common/tests/ColorTranslatorTests.cs +++ /dev/null @@ -1,261 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Globalization; - -namespace System.Drawing.Tests; - -public class ColorTranslatorTests -{ - public static IEnumerable<(int, Color)> SystemColors_TestData() - { - yield return (unchecked((int)0x8000000A), SystemColors.ActiveBorder); - yield return (unchecked((int)0x80000002), SystemColors.ActiveCaption); - yield return (unchecked((int)0x80000009), SystemColors.ActiveCaptionText); - yield return (unchecked((int)0x8000000C), SystemColors.AppWorkspace); - yield return (unchecked((int)0x8000000F), SystemColors.Control); - yield return (unchecked((int)0x80000010), SystemColors.ControlDark); - yield return (unchecked((int)0x80000015), SystemColors.ControlDarkDark); - yield return (unchecked((int)0x80000016), SystemColors.ControlLight); - yield return (unchecked((int)0x80000014), SystemColors.ControlLightLight); - yield return (unchecked((int)0x80000012), SystemColors.ControlText); - yield return (unchecked((int)0x80000001), SystemColors.Desktop); - yield return (unchecked((int)0x8000001B), SystemColors.GradientActiveCaption); - yield return (unchecked((int)0x8000001C), SystemColors.GradientInactiveCaption); - yield return (unchecked((int)0x80000011), SystemColors.GrayText); - yield return (unchecked((int)0x8000000D), SystemColors.Highlight); - yield return (unchecked((int)0x8000000E), SystemColors.HighlightText); - yield return (unchecked((int)0x8000001A), SystemColors.HotTrack); - yield return (unchecked((int)0x8000000B), SystemColors.InactiveBorder); - yield return (unchecked((int)0x80000003), SystemColors.InactiveCaption); - yield return (unchecked((int)0x80000013), SystemColors.InactiveCaptionText); - yield return (unchecked((int)0x80000018), SystemColors.Info); - yield return (unchecked((int)0x80000017), SystemColors.InfoText); - yield return (unchecked((int)0x80000004), SystemColors.Menu); - yield return (unchecked((int)0x8000001E), SystemColors.MenuBar); - yield return (unchecked((int)0x8000001D), SystemColors.MenuHighlight); - yield return (unchecked((int)0x80000007), SystemColors.MenuText); - yield return (unchecked((int)0x80000000), SystemColors.ScrollBar); - yield return (unchecked((int)0x80000005), SystemColors.Window); - yield return (unchecked((int)0x80000006), SystemColors.WindowFrame); - yield return (unchecked((int)0x80000008), SystemColors.WindowText); - } - - public static IEnumerable ToWin32Color_TestData() - { - yield return new object[] { new Color(), 0 }; - yield return new object[] { Color.Red, 255 }; - yield return new object[] { Color.White, 16777215 }; - yield return new object[] { Color.FromArgb(1, 2, 3), 197121 }; - } - - [Theory] - [MemberData(nameof(ToWin32Color_TestData))] - public void ToWin32Color_Color_ReturnsExpected(Color color, int expected) - { - Assert.Equal(expected, ColorTranslator.ToWin32(color)); - } - - public static IEnumerable FromOle_TestData() - { - yield return new object[] { int.MinValue, SystemColors.ScrollBar }; - yield return new object[] { -1, Color.White }; - yield return new object[] { 0, Color.Black }; - yield return new object[] { 197121, Color.FromArgb(1, 2, 3) }; - yield return new object[] { 16777215, Color.White }; - yield return new object[] { int.MaxValue, Color.White }; - yield return new object[] { unchecked((int)0x8000001F), Color.FromArgb(255, 31, 0, 0) }; - yield return new object[] { unchecked((int)0x80000019), Color.FromArgb(255, 25, 0, 0) }; - - foreach ((int oleColor, Color color) in SystemColors_TestData()) - { - yield return new object[] { oleColor, color }; - } - } - - [Theory] - [MemberData(nameof(FromOle_TestData))] - public void FromOle_Color_ReturnsExpected(int oleColor, Color color) - { - Assert.Equal(color, ColorTranslator.FromOle(oleColor)); - Assert.Equal(color, ColorTranslator.FromWin32(oleColor)); - } - - public static IEnumerable ToOle_TestData() - { - yield return new object[] { new Color(), 0 }; - yield return new object[] { Color.Red, 255 }; - yield return new object[] { Color.White, 16777215 }; - yield return new object[] { Color.FromArgb(1, 2, 3), 197121 }; - - foreach ((int oleColor, Color color) in SystemColors_TestData()) - { - yield return new object[] { color, oleColor }; - } - - - // These system colors are equivalent to Control, ControlLight and ControlDark. - yield return new object[] { SystemColors.ButtonFace, unchecked((int)0x8000000F) }; - yield return new object[] { SystemColors.ButtonHighlight, unchecked((int)0x80000014) }; - yield return new object[] { SystemColors.ButtonShadow, unchecked((int)0x80000010) }; - } - - [Theory] - [MemberData(nameof(ToOle_TestData))] - public void ToOle_Color_ReturnsExpected(Color color, int oleColor) - { - Assert.Equal(oleColor, ColorTranslator.ToOle(color)); - } - - public static IEnumerable<(string, Color)> HtmlColors_TestData() - { - yield return ("activeborder", SystemColors.ActiveBorder); - yield return ("activecaption", SystemColors.ActiveCaption); - yield return ("appworkspace", SystemColors.AppWorkspace); - yield return ("background", SystemColors.Desktop); - yield return ("buttonface", SystemColors.Control); - yield return ("buttonhighlight", SystemColors.ControlLightLight); - yield return ("buttonshadow", SystemColors.ControlDark); - yield return ("buttontext", SystemColors.ControlText); - yield return ("captiontext", SystemColors.ActiveCaptionText); - yield return ("graytext", SystemColors.GrayText); - yield return ("highlight", SystemColors.Highlight); - yield return ("highlighttext", SystemColors.HighlightText); - yield return ("inactiveborder", SystemColors.InactiveBorder); - yield return ("inactivecaption", SystemColors.InactiveCaption); - yield return ("inactivecaptiontext", SystemColors.InactiveCaptionText); - yield return ("infobackground", SystemColors.Info); - yield return ("infotext", SystemColors.InfoText); - yield return ("menu", SystemColors.Menu); - yield return ("menutext", SystemColors.MenuText); - yield return ("scrollbar", SystemColors.ScrollBar); - yield return ("window", SystemColors.Window); - yield return ("windowframe", SystemColors.WindowFrame); - yield return ("windowtext", SystemColors.WindowText); - yield return ("threeddarkshadow", SystemColors.ControlDarkDark); - - yield return ("LightGrey", Color.LightGray); - yield return ("Blue", Color.Blue); - yield return ("#1F2E3D", Color.FromArgb(31, 46, 61)); - } - - public static IEnumerable FromHtml_TestData() - { - yield return new object[] { null, Color.Empty }; - yield return new object[] { "", Color.Empty }; - yield return new object[] { " ", Color.Empty }; - yield return new object[] { "''", Color.FromName("") }; - yield return new object[] { "\"\"", Color.FromName("") }; - - yield return new object[] { "#1B3", Color.FromArgb(17, 187, 51) }; - yield return new object[] { " #1F2E3D ", Color.FromArgb(31, 46, 61) }; - - yield return new object[] { "ActiveBorder", SystemColors.ActiveBorder }; - yield return new object[] { "ACTIVEBORDER", SystemColors.ActiveBorder }; - yield return new object[] { " Blue ", Color.Blue }; - yield return new object[] { "'Blue'", Color.Blue }; - yield return new object[] { "\"Blue\"", Color.Blue }; - yield return new object[] { "'None'", Color.FromName("None") }; - yield return new object[] { "\"None\"", Color.FromName("None") }; - yield return new object[] { "255,0,0", Color.Red }; - - // Color(argb) - yield return new object[] { 498, Color.FromArgb(0, 0, 1, 242) }; - yield return new object[] { "&h1F2", Color.FromArgb(0, 0, 1, 242) }; - yield return new object[] { "&h1F2", Color.FromArgb(0, 0, 1, 242) }; - - // Color(red, green, blue) - yield return new object[] { "1, 0x2, &h3", Color.FromArgb(1, 2, 3) }; - - // Color(alpha, red, green, blue) - yield return new object[] { "1, 2, 0x3, &h4", Color.FromArgb(1, 2, 3, 4) }; - - foreach ((string htmlColor, Color color) in HtmlColors_TestData()) - { - yield return new object[] { htmlColor, color }; - } - - // Some of the SystemColors.Control colors don't roundtrip. - yield return new object[] { "threedface", SystemColors.Control }; - yield return new object[] { "threedhighlight", SystemColors.ControlLight }; - yield return new object[] { "threedlightshadow", SystemColors.ControlLightLight }; - } - - [Theory] - [MemberData(nameof(FromHtml_TestData))] - public void FromHtml_String_ReturnsExpected(string htmlColor, Color expected) - { - using (new ThreadCultureChange(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture)) - { - Assert.Equal(expected, ColorTranslator.FromHtml(htmlColor)); - } - } - - [Theory] - [InlineData("'")] - [InlineData("'\"")] - [InlineData("\"'")] - [InlineData("#")] - [InlineData(" #G12 ")] - [InlineData(" #G12345 ")] - [InlineData("#FFFFFFFFF")] - [InlineData("0x")] - [InlineData("0xFFFFFFFFF")] - [InlineData("0xG12")] - [InlineData("&h")] - [InlineData("&hG12")] - public void FromHtml_Invalid_Throws(string htmlColor) - { - using (new ThreadCultureChange(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture)) - { - Exception exception = AssertExtensions.Throws(() => ColorTranslator.FromHtml(htmlColor)); - if (exception is ArgumentException argumentException) - Assert.Equal("htmlColor", argumentException.ParamName); - } - } - - [Theory] - [InlineData("#G12", typeof(FormatException))] - [InlineData("#G12345", typeof(FormatException))] - [InlineData("1,2", typeof(ArgumentException))] - [InlineData("1,2,3,4,5", typeof(ArgumentException))] - [InlineData("-1,2,3", typeof(ArgumentException))] - [InlineData("256,2,3", typeof(ArgumentException))] - [InlineData("1,-1,3", typeof(ArgumentException))] - [InlineData("1,256,3", typeof(ArgumentException))] - [InlineData("1,2,-1", typeof(ArgumentException))] - [InlineData("1,2,256", typeof(ArgumentException))] - public void FromHtml_Invalid_Throw(string htmlColor, Type exception) - { - using (new ThreadCultureChange(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture)) - { - Assert.Throws(exception, () => ColorTranslator.FromHtml(htmlColor)); - } - } - - public static IEnumerable ToHtml_TestData() - { - yield return new object[] { Color.Empty, "" }; - - foreach ((string htmlColor, Color color) in HtmlColors_TestData()) - { - yield return new object[] { color, htmlColor }; - } - - // SystemColors.ControlLight don't roundtrip. - yield return new object[] { SystemColors.ControlLight, "buttonface" }; - yield return new object[] { SystemColors.GradientActiveCaption, "activecaption" }; - yield return new object[] { SystemColors.HotTrack, "highlight" }; - yield return new object[] { SystemColors.MenuHighlight, "highlighttext" }; - yield return new object[] { SystemColors.GradientInactiveCaption, "inactivecaption" }; - yield return new object[] { SystemColors.MenuBar, "menu" }; - yield return new object[] { SystemColors.ButtonShadow, "" }; - } - - [Theory] - [MemberData(nameof(ToHtml_TestData))] - public void ToHtml_Color_ReturnsExpected(Color color, string expected) - { - Assert.Equal(expected, ColorTranslator.ToHtml(color)); - } -} diff --git a/src/System.Drawing.Common/tests/Design/CategoryNameCollectionTests.cs b/src/System.Drawing.Common/tests/Design/CategoryNameCollectionTests.cs deleted file mode 100644 index fefaac368e8..00000000000 --- a/src/System.Drawing.Common/tests/Design/CategoryNameCollectionTests.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Design.Tests; - -public class CategoryNameCollectionTests -{ - [Fact] - public void Ctor_StringArray() - { - var value = new string[] { "1", "2", "3" }; - var collection = new CategoryNameCollection(value); - Assert.Equal(value, collection.Cast()); - } - - [Fact] - public void Ctor_CategoryNameCollection() - { - var value = new string[] { "1", "2", "3" }; - var sourceCollection = new CategoryNameCollection(value); - - var collection = new CategoryNameCollection(sourceCollection); - Assert.Equal(value, collection.Cast()); - } - - [Fact] - public void Indexer_Get_ReturnsExpected() - { - var value = new string[] { "1", "2", "3" }; - var sourceCollection = new CategoryNameCollection(value); - - for (int i = 0; i < sourceCollection.Count; i++) - { - string expectedValue = value[i]; - Assert.Equal(expectedValue, sourceCollection[i]); - Assert.True(sourceCollection.Contains(expectedValue)); - Assert.Equal(i, sourceCollection.IndexOf(expectedValue)); - } - } - - [Fact] - public void CopyTo_Valid_Success() - { - var value = new string[] { "1", "2", "3" }; - var sourceCollection = new CategoryNameCollection(value); - - var destination = new string[5]; - sourceCollection.CopyTo(destination, 1); - - Assert.Equal(new string[] { null, "1", "2", "3", null }, destination); - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/AdjustableArrowCapTests.cs b/src/System.Drawing.Common/tests/Drawing2D/AdjustableArrowCapTests.cs deleted file mode 100644 index 80741c4bed1..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/AdjustableArrowCapTests.cs +++ /dev/null @@ -1,135 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Drawing2D.Tests; - -public class AdjustableArrowCapTests -{ - public static IEnumerable Ctor_Float_Float_TestData() - { - yield return new object[] { 1f, 1f }; - yield return new object[] { 50f, 50f }; - yield return new object[] { float.MaxValue, float.MaxValue }; - // Nonsensical values -- but still permitted. - yield return new object[] { -1f, 1f }; - yield return new object[] { float.PositiveInfinity, 1f }; - yield return new object[] { float.NegativeInfinity, 1f }; - yield return new object[] { float.NaN, 1f }; - yield return new object[] { 0f, 1f }; - yield return new object[] { 0f, 0f }; - yield return new object[] { 1f, -1f }; - } - - [Theory] - [MemberData(nameof(Ctor_Float_Float_TestData))] - public void Ctor_Float_Float(float width, float height) - { - using (AdjustableArrowCap arrowCap = new AdjustableArrowCap(width, height)) - { - Assert.Equal(width, arrowCap.Width); - Assert.Equal(height, arrowCap.Height); - Assert.True(arrowCap.Filled); - } - } - - public static IEnumerable Ctor_Float_Float_Bool_TestData() - { - foreach (object[] data in Ctor_Float_Float_TestData()) - { - yield return new object[] { data[0], data[1], true }; - yield return new object[] { data[0], data[1], false }; - } - } - - [Theory] - [MemberData(nameof(Ctor_Float_Float_Bool_TestData))] - public void Ctor_Float_Float_Bool(float width, float height, bool filled) - { - using (AdjustableArrowCap arrowCap = new AdjustableArrowCap(width, height, filled)) - { - Assert.Equal(width, arrowCap.Width); - Assert.Equal(height, arrowCap.Height); - Assert.Equal(filled, arrowCap.Filled); - } - } - - public static IEnumerable Properties_TestData() - { - yield return new object[] { -1 }; - yield return new object[] { 0 }; - yield return new object[] { 10 }; - yield return new object[] { 5000 }; - yield return new object[] { float.MaxValue }; - yield return new object[] { float.PositiveInfinity }; - yield return new object[] { float.NegativeInfinity }; - yield return new object[] { float.NaN }; - } - - [Theory] - [MemberData(nameof(Properties_TestData))] - public void Width_Set_GetReturnsExpected(float width) - { - using (AdjustableArrowCap arrowCap = new AdjustableArrowCap(1, 1)) - { - arrowCap.Width = width; - Assert.Equal(width, arrowCap.Width); - } - } - - [Theory] - [MemberData(nameof(Properties_TestData))] - public void Height_Set_GetReturnsExpected(float height) - { - using (AdjustableArrowCap arrowCap = new AdjustableArrowCap(1, 1)) - { - arrowCap.Height = height; - Assert.Equal(height, arrowCap.Height); - } - } - - [Theory] - [MemberData(nameof(Properties_TestData))] - public void MiddleInset_Set_GetReturnsExpected(float middleInset) - { - using (AdjustableArrowCap arrowCap = new AdjustableArrowCap(1, 1)) - { - arrowCap.MiddleInset = middleInset; - Assert.Equal(middleInset, arrowCap.MiddleInset); - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void Filled_Set_GetReturnsExpected(bool filled) - { - using (AdjustableArrowCap arrowCap = new AdjustableArrowCap(1, 1)) - { - arrowCap.Filled = filled; - Assert.Equal(filled, arrowCap.Filled); - } - } - - [Fact] - public void Clone_Success() - { - using (AdjustableArrowCap arrowCap = new AdjustableArrowCap(1, 1)) - using (AdjustableArrowCap clone = Assert.IsType(arrowCap.Clone())) - { - Assert.NotSame(clone, arrowCap); - Assert.Equal(clone.Width, arrowCap.Width); - Assert.Equal(clone.Height, arrowCap.Height); - Assert.Equal(clone.MiddleInset, arrowCap.MiddleInset); - Assert.Equal(clone.Filled, arrowCap.Filled); - } - } - - [Fact] - public void BaseCap_ReturnsTriangle() - { - using (AdjustableArrowCap arrowCap = new AdjustableArrowCap(1, 1)) - { - Assert.Equal(LineCap.Triangle, arrowCap.BaseCap); - } - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/BlendTests.cs b/src/System.Drawing.Common/tests/Drawing2D/BlendTests.cs deleted file mode 100644 index 47aee4f5c19..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/BlendTests.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Drawing2D.Tests; - -public class BlendTests -{ - [Fact] - public void Ctor_Default() - { - var blend = new Blend(); - Assert.Equal(new float[1], blend.Factors); - Assert.Equal(new float[1], blend.Positions); - } - - [Theory] - [InlineData(0)] - [InlineData(2)] - public void Ctor_Count(int count) - { - var blend = new Blend(count); - Assert.Equal(new float[count], blend.Factors); - Assert.Equal(new float[count], blend.Positions); - } - - [Fact] - public void Ctor_InvalidCount_ThrowsOverflowException() - { - Assert.Throws(() => new Blend(-1)); - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotIntMaxValueArrayIndexSupported))] - public void Ctor_LargeCount_ThrowsOutOfMemoryException() - { - Assert.Throws(() => new Blend(int.MaxValue)); - } - - [Fact] - public void Factors_Set_GetReturnsExpected() - { - var blend = new Blend { Factors = null }; - Assert.Null(blend.Factors); - - blend.Factors = new float[10]; - Assert.Equal(new float[10], blend.Factors); - } - - [Fact] - public void Positions_Set_GetReturnsExpected() - { - var blend = new Blend { Positions = null }; - Assert.Null(blend.Positions); - - blend.Positions = new float[10]; - Assert.Equal(new float[10], blend.Positions); - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/ColorBlendTests.cs b/src/System.Drawing.Common/tests/Drawing2D/ColorBlendTests.cs deleted file mode 100644 index 9d7ec9d8a0c..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/ColorBlendTests.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Drawing2D.Tests; - -public class ColorBlendTests -{ - [Fact] - public void Ctor_Default() - { - var blend = new ColorBlend(); - Assert.Equal(new Color[1], blend.Colors); - Assert.Equal(new float[1], blend.Positions); - } - - [Theory] - [InlineData(0)] - [InlineData(2)] - public void Ctor_Count(int count) - { - var blend = new ColorBlend(count); - Assert.Equal(new Color[count], blend.Colors); - Assert.Equal(new float[count], blend.Positions); - } - - [Fact] - public void Ctor_InvalidCount_ThrowsOverflowException() - { - Assert.Throws(() => new ColorBlend(-1)); - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotIntMaxValueArrayIndexSupported))] - public void Ctor_LargeCount_ThrowsOutOfMemoryException() - { - Assert.Throws(() => new ColorBlend(int.MaxValue)); - } - - [Fact] - public void Colors_Set_GetReturnsExpected() - { - var blend = new ColorBlend { Colors = null }; - Assert.Null(blend.Colors); - - blend.Colors = new Color[10]; - Assert.Equal(new Color[10], blend.Colors); - } - - [Fact] - public void Positions_Set_GetReturnsExpected() - { - var blend = new ColorBlend { Positions = null }; - Assert.Null(blend.Positions); - - blend.Positions = new float[10]; - Assert.Equal(new float[10], blend.Positions); - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/CustomLineCapTests.cs b/src/System.Drawing.Common/tests/Drawing2D/CustomLineCapTests.cs deleted file mode 100644 index 9428f5aae9c..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/CustomLineCapTests.cs +++ /dev/null @@ -1,243 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Drawing2D.Tests; - -public class CustomLineCapTests -{ - public static IEnumerable Ctor_Path_Path_LineCap_Float_TestData() - { - yield return new object[] { new GraphicsPath(), null, LineCap.Flat, 0f, LineCap.Flat }; - yield return new object[] { new GraphicsPath(), null, LineCap.Square, 1f, LineCap.Square }; - yield return new object[] { new GraphicsPath(), null, LineCap.Round, -1f, LineCap.Round }; - yield return new object[] { new GraphicsPath(), null, LineCap.Triangle, float.MaxValue, LineCap.Triangle }; - // All of these "anchor" values yield a "Flat" LineCap. - yield return new object[] { new GraphicsPath(), null, LineCap.NoAnchor, 0f, LineCap.Flat }; - yield return new object[] { new GraphicsPath(), null, LineCap.SquareAnchor, 0f, LineCap.Flat }; - yield return new object[] { new GraphicsPath(), null, LineCap.DiamondAnchor, 0f, LineCap.Flat }; - yield return new object[] { new GraphicsPath(), null, LineCap.ArrowAnchor, 0f, LineCap.Flat }; - - // Boxy cap - GraphicsPath strokePath = new GraphicsPath(); - strokePath.AddRectangle(new Rectangle(0, 0, 10, 10)); - yield return new object[] { null, strokePath, LineCap.Square, 0f, LineCap.Square }; - - // Hook-shaped cap - strokePath = new GraphicsPath(); - strokePath.AddLine(new Point(0, 0), new Point(0, 5)); - strokePath.AddLine(new Point(0, 5), new Point(5, 1)); - strokePath.AddLine(new Point(5, 1), new Point(3, 1)); - yield return new object[] { null, strokePath, LineCap.Flat, 0f, LineCap.Flat }; - - // Fill path -- Must intercept the Y-axis. - GraphicsPath fillPath = new GraphicsPath(); - fillPath.AddLine(new Point(-5, -10), new Point(0, 10)); - fillPath.AddLine(new Point(0, 10), new Point(5, -10)); - fillPath.AddLine(new Point(5, -10), new Point(-5, -10)); - yield return new object[] { fillPath, null, LineCap.Flat, 0f, LineCap.Flat }; - } - - [Theory] - [MemberData(nameof(Ctor_Path_Path_LineCap_Float_TestData))] - public void Ctor_Path_Path_LineCap_Float(GraphicsPath fillPath, GraphicsPath strokePath, LineCap baseCap, float baseInset, LineCap expectedCap) - { - using (fillPath) - using (strokePath) - using (CustomLineCap customLineCap = new CustomLineCap(fillPath, strokePath, baseCap, baseInset)) - { - Assert.Equal(expectedCap, customLineCap.BaseCap); - Assert.Equal(baseInset, customLineCap.BaseInset); - Assert.Equal(LineJoin.Miter, customLineCap.StrokeJoin); - Assert.Equal(1f, customLineCap.WidthScale); - } - } - - [Theory] - // These values are outside the valid range of the LineCap enum. - [InlineData(LineCap.Flat - 1)] - [InlineData(LineCap.Custom + 1)] - public void Ctor_InvalidLineCap_ReturnsFlat(LineCap baseCap) - { - using (GraphicsPath fillPath = new GraphicsPath()) - using (GraphicsPath strokePath = new GraphicsPath()) - using (CustomLineCap customLineCap = new CustomLineCap(fillPath, strokePath, baseCap, 0f)) - { - Assert.Equal(LineCap.Flat, customLineCap.BaseCap); - } - } - - [Fact] - public void Ctor_FillPath_Incomplete_ThrowsArgumentException() - { - using (GraphicsPath fillPath = new GraphicsPath()) - { - fillPath.AddLine(new Point(0, -10), new Point(0, 10)); - AssertExtensions.Throws(null, () => new CustomLineCap(fillPath, null)); - } - } - - [Fact] - public void Ctor_FillPath_DoesNotCrossYAxis_ThrowsNotImplementedException() - { - // Closed fillPath, but does not cross the Y-axis. - using (GraphicsPath fillPath = new GraphicsPath()) - { - fillPath.AddLine(new Point(-5, 5), new Point(5, 5)); - fillPath.AddLine(new Point(5, 5), new Point(5, 1)); - fillPath.AddLine(new Point(5, 1), new Point(-5, 5)); - Assert.Throws(() => new CustomLineCap(fillPath, null)); - } - } - - [Theory] - [InlineData(LineCap.Square, LineCap.Square)] - [InlineData(LineCap.Round, LineCap.Round)] - [InlineData(LineCap.Triangle, LineCap.Triangle)] - public void SetThenGetStrokeCaps_Success(LineCap startCap, LineCap endCap) - { - using (GraphicsPath strokePath = new GraphicsPath()) - using (CustomLineCap customLineCap = new CustomLineCap(null, strokePath)) - { - customLineCap.SetStrokeCaps(startCap, endCap); - customLineCap.GetStrokeCaps(out LineCap retrievedStartCap, out LineCap retrievedEndCap); - - Assert.Equal(startCap, retrievedStartCap); - Assert.Equal(endCap, retrievedEndCap); - } - } - - [Theory] - [InlineData(LineCap.SquareAnchor, LineCap.SquareAnchor)] - [InlineData(LineCap.Custom, LineCap.Custom)] - [InlineData(LineCap.Square, LineCap.Custom)] - [InlineData(LineCap.Custom, LineCap.SquareAnchor)] - [InlineData(LineCap.Flat - 1, LineCap.Flat)] // Below valid enum range - [InlineData(LineCap.Custom + 1, LineCap.Flat)] // Above valid enum range - public void SetStrokeCaps_InvalidLineCap_ThrowsArgumentException(LineCap startCap, LineCap endCap) - { - using (GraphicsPath strokePath = new GraphicsPath()) - using (CustomLineCap customLineCap = new CustomLineCap(null, strokePath)) - { - AssertExtensions.Throws(null, () => customLineCap.SetStrokeCaps(startCap, endCap)); - - // start and end cap should be unchanged. - customLineCap.GetStrokeCaps(out LineCap retrievedStartCap, out LineCap retrievedEndCap); - Assert.Equal(LineCap.Flat, retrievedStartCap); - Assert.Equal(LineCap.Flat, retrievedEndCap); - } - } - - [Theory] - [InlineData(LineJoin.Miter)] // Default value - [InlineData(LineJoin.Bevel)] - [InlineData(LineJoin.Round)] - [InlineData(LineJoin.MiterClipped)] - // Invalid (non-enum) values are allowed. Their values are stored and returned unchanged. - [InlineData(LineJoin.Miter - 1)] - [InlineData(LineJoin.MiterClipped + 1)] - public void StrokeJoin_SetThenGet_Success(LineJoin lineJoin) - { - using (GraphicsPath strokePath = new GraphicsPath()) - using (CustomLineCap customLineCap = new CustomLineCap(null, strokePath)) - { - customLineCap.StrokeJoin = lineJoin; - Assert.Equal(lineJoin, customLineCap.StrokeJoin); - } - } - - [Theory] - [InlineData(LineCap.Flat)] // Default value - [InlineData(LineCap.Square)] - [InlineData(LineCap.Round)] - [InlineData(LineCap.Triangle)] - public void BaseCap_SetThenGet_Success(LineCap baseCap) - { - using (GraphicsPath strokePath = new GraphicsPath()) - using (CustomLineCap customLineCap = new CustomLineCap(null, strokePath)) - { - customLineCap.BaseCap = baseCap; - Assert.Equal(baseCap, customLineCap.BaseCap); - } - } - - [Theory] - [InlineData(LineCap.NoAnchor)] - [InlineData(LineCap.SquareAnchor)] - [InlineData(LineCap.RoundAnchor)] - [InlineData(LineCap.DiamondAnchor)] - [InlineData(LineCap.Custom)] - [InlineData(LineCap.Flat - 1)] - [InlineData(LineCap.Custom + 1)] - public void BaseCap_Set_InvalidLineCap_ThrowsArgumentException(LineCap baseCap) - { - using (GraphicsPath strokePath = new GraphicsPath()) - using (CustomLineCap customLineCap = new CustomLineCap(null, strokePath)) - { - AssertExtensions.Throws(null, () => customLineCap.BaseCap = baseCap); - Assert.Equal(LineCap.Flat, customLineCap.BaseCap); - } - } - - [Theory] - [InlineData(0f)] - [InlineData(1f)] - [InlineData(10f)] - [InlineData(10000f)] - [InlineData(-1f)] - [InlineData(-10f)] - [InlineData(-10000f)] - [InlineData(float.MaxValue)] - [InlineData(float.MinValue)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NegativeInfinity)] - [InlineData(float.NaN)] - public void BaseInset_SetThenGet_Success(float value) - { - using (GraphicsPath strokePath = new GraphicsPath()) - using (CustomLineCap customLineCap = new CustomLineCap(null, strokePath)) - { - customLineCap.BaseInset = value; - Assert.Equal(value, customLineCap.BaseInset); - } - } - - [Theory] - [InlineData(0f)] - [InlineData(1f)] - [InlineData(10f)] - [InlineData(10000f)] - [InlineData(-1f)] - [InlineData(-10f)] - [InlineData(-10000f)] - [InlineData(float.MaxValue)] - [InlineData(float.MinValue)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NegativeInfinity)] - [InlineData(float.NaN)] - public void WidthScale_SetThenGet_Success(float value) - { - using (GraphicsPath strokePath = new GraphicsPath()) - using (CustomLineCap customLineCap = new CustomLineCap(null, strokePath)) - { - customLineCap.WidthScale = value; - Assert.Equal(value, customLineCap.WidthScale); - } - } - - [Fact] - public void Disposed_MembersThrow() - { - using (GraphicsPath strokePath = new GraphicsPath()) - using (CustomLineCap customLineCap = new CustomLineCap(null, strokePath)) - { - customLineCap.Dispose(); - AssertExtensions.Throws(null, () => customLineCap.StrokeJoin); - AssertExtensions.Throws(null, () => customLineCap.BaseCap); - AssertExtensions.Throws(null, () => customLineCap.BaseInset); - AssertExtensions.Throws(null, () => customLineCap.WidthScale); - AssertExtensions.Throws(null, () => customLineCap.Clone()); - AssertExtensions.Throws(null, () => customLineCap.SetStrokeCaps(LineCap.Flat, LineCap.Flat)); - AssertExtensions.Throws(null, () => customLineCap.GetStrokeCaps(out LineCap startCap, out LineCap endCap)); - } - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs b/src/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs deleted file mode 100644 index 34850f23f65..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs +++ /dev/null @@ -1,420 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace System.Drawing.Drawing2D.Tests; - -public class GraphicsPathIteratorTests -{ - private readonly PointF[] _twoPoints = new PointF[2] { new PointF(1, 2), new PointF(20, 30) }; - - [Fact] - public void Ctor_Path_Success() - { - byte[] types = new byte[] { 0, 1 }; - - using (GraphicsPath gp = new GraphicsPath(_twoPoints, types)) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(2, gpi.Count); - } - } - - [Fact] - public void Ctor_EmptyPath_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(0, gpi.Count); - } - } - - [Fact] - public void Ctor_NullPath_Success() - { - using (GraphicsPathIterator gpi = new GraphicsPathIterator(null)) - { - Assert.Equal(0, gpi.Count); - } - } - - [Fact] - public void NextSubpath_PathFigureNotClosed_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - gp.AddLines(_twoPoints); - Assert.Equal(0, gpi.NextSubpath(gp, out bool isClosed)); - Assert.False(isClosed); - } - } - - [Fact] - public void NextSubpath_PathFigureClosed_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath(_twoPoints, new byte[] { 0, 129 })) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(2, gpi.NextSubpath(gp, out bool isClosed)); - Assert.True(isClosed); - } - } - - [Fact] - public void NextSubpath_NullPath_ReturnsExpected() - { - using (GraphicsPathIterator gpi = new GraphicsPathIterator(null)) - { - Assert.Equal(0, gpi.NextSubpath(null, out bool isClosed)); - Assert.False(isClosed); - } - } - - [Fact] - public void NextSubpath_FigureNotClosed_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - gp.AddLines(_twoPoints); - Assert.Equal(0, gpi.NextSubpath(out int startIndex, out int endIndex, out bool isClosed)); - Assert.False(isClosed); - Assert.Equal(0, startIndex); - Assert.Equal(0, endIndex); - } - } - - [Fact] - public void NextSubpath_FigureClosed_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath(_twoPoints, new byte[] { 0, 129 })) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(2, gpi.NextSubpath(out int startIndex, out int endIndex, out bool isClosed)); - Assert.True(isClosed); - Assert.Equal(0, startIndex); - Assert.Equal(1, endIndex); - } - } - - [Fact] - public void NextMarker_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath(_twoPoints, new byte[] { 0, 1 })) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(2, gpi.NextMarker(out int startIndex, out int endIndex)); - Assert.Equal(0, startIndex); - Assert.Equal(1, endIndex); - } - } - - [Fact] - public void NextMarker_Empty_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - gp.AddLines(_twoPoints); - Assert.Equal(0, gpi.NextMarker(out int startIndex, out int endIndex)); - Assert.Equal(0, startIndex); - Assert.Equal(0, endIndex); - } - } - - [Fact] - public void NextMarker_NullPath_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - gp.AddLines(_twoPoints); - Assert.Equal(0, gpi.NextMarker(null)); - } - } - - [Fact] - public void NextMarker_EmptyPath_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - gp.AddLines(_twoPoints); - Assert.Equal(0, gpi.NextMarker(gp)); - } - } - - [Fact] - public void NextMarker_Path_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath(_twoPoints, new byte[] { 0, 1 })) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(2, gpi.NextMarker(gp)); - } - } - - [Fact] - public void Count_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath(_twoPoints, new byte[] { 0, 1 })) - using (GraphicsPath gpEmpty = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - using (GraphicsPathIterator gpiEmpty = new GraphicsPathIterator(gpEmpty)) - using (GraphicsPathIterator gpiNull = new GraphicsPathIterator(null)) - { - Assert.Equal(2, gpi.Count); - Assert.Equal(0, gpiEmpty.Count); - Assert.Equal(0, gpiNull.Count); - } - } - - [Fact] - public void SubpathCount_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - using (GraphicsPathIterator gpiNull = new GraphicsPathIterator(null)) - { - Assert.Equal(0, gpi.SubpathCount); - Assert.Equal(0, gpiNull.SubpathCount); - - gp.AddLine(0, 1, 2, 3); - gp.SetMarkers(); - gp.StartFigure(); - gp.AddLine(20, 21, 22, 23); - gp.AddBezier(5, 6, 7, 8, 9, 10, 11, 12); - - using (GraphicsPathIterator gpiWithSubpaths = new GraphicsPathIterator(gp)) - { - Assert.Equal(2, gpiWithSubpaths.SubpathCount); - } - } - } - - [Fact] - public void HasCurve_ReturnsExpected() - { - Point[] points = new Point[] { new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(4, 4) }; - byte[] types = new byte[] { 0, 3, 3, 3 }; - - using (GraphicsPath gp = new GraphicsPath(points, types)) - using (GraphicsPath gpEmpty = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - using (GraphicsPathIterator gpiEmpty = new GraphicsPathIterator(gpEmpty)) - using (GraphicsPathIterator gpiNull = new GraphicsPathIterator(null)) - { - Assert.True(gpi.HasCurve()); - Assert.False(gpiEmpty.HasCurve()); - Assert.False(gpiNull.HasCurve()); - } - } - - [Fact] - public void Rewind_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath inner = new GraphicsPath()) - { - gp.AddLine(0, 1, 2, 3); - gp.SetMarkers(); - gp.StartFigure(); - gp.AddLine(20, 21, 22, 23); - gp.AddBezier(5, 6, 7, 8, 9, 10, 11, 12); - - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(2, gpi.SubpathCount); - Assert.Equal(2, gpi.NextMarker(gp)); - Assert.Equal(6, gpi.NextMarker(gp)); - Assert.Equal(0, gpi.NextMarker(gp)); - gpi.Rewind(); - Assert.Equal(8, gpi.NextMarker(gp)); - Assert.Equal(0, gpi.NextMarker(gp)); - } - } - } - - [Fact] - public void Enumerate_ZeroPoints_ReturnsExpected() - { - PointF[] points = new PointF[0]; - byte[] types = new byte[0]; - - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(0, gpi.Enumerate(ref points, ref types)); - Assert.Equal(0, points.Length); - Assert.Equal(0, types.Length); - } - } - - [Fact] - public void Enumerate_ReturnsExpected() - { - PointF[] points = new PointF[] { new PointF(1f, 1f), new PointF(2f, 2f), new PointF(3f, 3f), new PointF(4f, 4f) }; - byte[] types = new byte[] { 0, 3, 3, 3 }; - - PointF[] actualPoints = new PointF[4]; - byte[] actualTypes = new byte[4]; - - using (GraphicsPath gp = new GraphicsPath(points, types)) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(4, gpi.Enumerate(ref actualPoints, ref actualTypes)); - Assert.Equal(gp.PathPoints, actualPoints); - Assert.Equal(gp.PathTypes, actualTypes); - } - } - - public static IEnumerable PointsTypesLengthMismatch_TestData() - { - yield return new object[] { new PointF[1], new byte[2] }; - yield return new object[] { new PointF[2], new byte[1] }; - } - - [Theory] - [MemberData(nameof(PointsTypesLengthMismatch_TestData))] - public void Enumerate_PointsTypesMismatch_ThrowsArgumentException(PointF[] points, byte[] types) - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - AssertExtensions.Throws(null, () => gpi.Enumerate(ref points, ref types)); - } - } - - public static IEnumerable NullPointsTypes_TestData() - { - yield return new object[] { null, new byte[1] }; - yield return new object[] { new PointF[1], null }; - yield return new object[] { null, null }; - } - - [Theory] - [MemberData(nameof(NullPointsTypes_TestData))] - public void Enumerate_NullPointsTypes_ThrowsNullReferenceException(PointF[] points, byte[] types) - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Throws(() => gpi.Enumerate(ref points, ref types)); - } - } - - [Theory] - [MemberData(nameof(PointsTypesLengthMismatch_TestData))] - public void CopyData_PointsTypesMismatch_ThrowsArgumentException(PointF[] points, byte[] types) - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - AssertExtensions.Throws(null, () => gpi.CopyData(ref points, ref types, 0, points.Length)); - } - } - - [Theory] - [MemberData(nameof(NullPointsTypes_TestData))] - public void CopyData_NullPointsTypes_ThrowsNullReferenceException(PointF[] points, byte[] types) - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Throws(() => gpi.CopyData(ref points, ref types, 0, 1)); - } - } - - [Theory] - [InlineData(-1, 2)] - [InlineData(0, 3)] - public void CopyData_StartEndIndexesOutOfRange_ThrowsArgumentException(int startIndex, int endIndex) - { - PointF[] resultPoints = new PointF[0]; - byte[] resultTypes = new byte[0]; - - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - AssertExtensions.Throws(null, () => gpi.CopyData(ref resultPoints, ref resultTypes, startIndex, endIndex)); - } - } - - public static IEnumerable CopyData_StartEndIndexesOutOfRange_TestData() - { - yield return new object[] { new PointF[3], new byte[3], int.MinValue, 2 }; - yield return new object[] { new PointF[3], new byte[3], 0, int.MaxValue }; - yield return new object[] { new PointF[3], new byte[3], 2, 0 }; - } - - [Theory] - [MemberData(nameof(CopyData_StartEndIndexesOutOfRange_TestData))] - public void CopyData_StartEndIndexesOutOfRange_ReturnsExpected(PointF[] points, byte[] types, int startIndex, int endIndex) - { - PointF[] resultPoints = new PointF[points.Length]; - byte[] resultTypes = new byte[points.Length]; - - using (GraphicsPath gp = new GraphicsPath(points, types)) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(0, gpi.CopyData(ref resultPoints, ref resultTypes, startIndex, endIndex)); - } - } - - [Fact] - public void CopyData_EqualStartEndIndexes_ReturnsExpected() - { - PointF[] points = new PointF[] { new PointF(1f, 1f), new PointF(2f, 2f), new PointF(3f, 3f), new PointF(4f, 4f) }; - byte[] types = new byte[] { 0, 3, 3, 3 }; - - PointF[] actualPoints = new PointF[1]; - byte[] actualTypes = new byte[1]; - - using (GraphicsPath gp = new GraphicsPath(points, types)) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(1, gpi.CopyData(ref actualPoints, ref actualTypes, 0, 0)); - Assert.Equal(gp.PathPoints[0], actualPoints[0]); - Assert.Equal(gp.PathTypes[0], actualTypes[0]); - } - } - - [Fact] - public void CopyData_ReturnsExpected() - { - PointF[] points = new PointF[] { new PointF(1f, 1f), new PointF(2f, 2f), new PointF(3f, 3f), new PointF(4f, 4f) }; - byte[] types = new byte[] { 0, 3, 3, 3 }; - - PointF[] actualPoints = new PointF[3]; - byte[] actualTypes = new byte[3]; - - using (GraphicsPath gp = new GraphicsPath(points, types)) - using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) - { - Assert.Equal(3, gpi.CopyData(ref actualPoints, ref actualTypes, 0, 2)); - } - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/GraphicsPathTests.cs b/src/System.Drawing.Common/tests/Drawing2D/GraphicsPathTests.cs deleted file mode 100644 index a23b8e50829..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/GraphicsPathTests.cs +++ /dev/null @@ -1,2684 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace System.Drawing.Drawing2D.Tests; - -public class GraphicsPathTests -{ - private const float Pi4 = (float)(Math.PI / 4); - private const float Delta = 0.0003f; - - [Fact] - public void Ctor_Default_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - Assert.Equal(FillMode.Alternate, gp.FillMode); - AssertEmptyGraphicsPath(gp); - } - } - - [Fact] - public void Ctor_FillMode_Success() - { - using (GraphicsPath gpa = new GraphicsPath(FillMode.Alternate)) - using (GraphicsPath gpw = new GraphicsPath(FillMode.Winding)) - { - Assert.Equal(FillMode.Alternate, gpa.FillMode); - AssertEmptyGraphicsPath(gpa); - Assert.Equal(FillMode.Winding, gpw.FillMode); - AssertEmptyGraphicsPath(gpw); - } - } - - [Fact] - public void Ctor_SamePoints_Success() - { - byte[] types = new byte[6] { 0, 1, 1, 1, 1, 1 }; - Point[] points = new Point[] - { - new Point (1, 1), new Point (1, 1), new Point (1, 1), - new Point (1, 1), new Point (1, 1), new Point (1, 1), - }; - - PointF[] fPoints = new PointF[] - { - new PointF (1f, 1f), new PointF (1f, 1f), new PointF (1f, 1f), - new PointF (1f, 1f), new PointF (1f, 1f), new PointF (1f, 1f), - }; - - using (GraphicsPath gp = new GraphicsPath(points, types)) - using (GraphicsPath gpf = new GraphicsPath(fPoints, types)) - { - Assert.Equal(FillMode.Alternate, gp.FillMode); - Assert.Equal(6, gp.PointCount); - Assert.Equal(FillMode.Alternate, gpf.FillMode); - Assert.Equal(6, gpf.PointCount); - types[0] = 1; - Assert.Equal(FillMode.Alternate, gp.FillMode); - Assert.Equal(6, gp.PointCount); - Assert.Equal(FillMode.Alternate, gpf.FillMode); - Assert.Equal(6, gpf.PointCount); - } - } - - [Fact] - public void Ctor_PointsNull_ThrowsArgumentNullException() - { - AssertExtensions.Throws("pts", () => new GraphicsPath((Point[])null, new byte[1])); - } - - public static IEnumerable AddCurve_PointsTypesLengthMismatch_TestData() - { - yield return new object[] { 1, 2 }; - yield return new object[] { 2, 1 }; - } - - [Theory] - [MemberData(nameof(AddCurve_PointsTypesLengthMismatch_TestData))] - public void Ctor_PointsTypesLengthMismatch_ThrowsArgumentException(int pointsLength, int typesLength) - { - AssertExtensions.Throws(null, () => new GraphicsPath(new Point[pointsLength], new byte[typesLength])); - AssertExtensions.Throws(null, () => new GraphicsPath(new PointF[pointsLength], new byte[typesLength])); - } - - [Fact] - public void Clone_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - Assert.Equal(FillMode.Alternate, clone.FillMode); - AssertEmptyGraphicsPath(clone); - } - } - - [Fact] - public void Reset_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.Reset(); - - Assert.Equal(FillMode.Alternate, gp.FillMode); - AssertEmptyGraphicsPath(gp); - } - } - - [Fact] - public void GraphicsPath_FillModeChange() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.FillMode = FillMode.Winding; - Assert.Equal(FillMode.Winding, gp.FillMode); - } - } - - [Theory] - [InlineData(FillMode.Alternate - 1)] - [InlineData(FillMode.Winding + 1)] - public void GraphicsPath_InvalidFillMode_ThrowsInvalidEnumArgumentException(FillMode fillMode) - { - using (GraphicsPath gp = new GraphicsPath()) - { - Assert.ThrowsAny(() => gp.FillMode = fillMode); - } - } - - [Fact] - public void PathData_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath()) - { - Assert.Equal(0, gp.PathData.Points.Length); - Assert.Equal(0, gp.PathData.Types.Length); - } - } - - [Fact] - public void PathData_CannotChange() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddRectangle(new Rectangle(1, 1, 2, 2)); - Assert.Equal(1f, gp.PathData.Points[0].X); - Assert.Equal(1f, gp.PathData.Points[0].Y); - - gp.PathData.Points[0] = new Point(0, 0); - Assert.Equal(1f, gp.PathData.Points[0].X); - Assert.Equal(1f, gp.PathData.Points[0].Y); - } - } - - [Fact] - public void PathPoints_CannotChange() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddRectangle(new Rectangle(1, 1, 2, 2)); - Assert.Equal(1f, gp.PathPoints[0].X); - Assert.Equal(1f, gp.PathPoints[0].Y); - - gp.PathPoints[0] = new Point(0, 0); - Assert.Equal(1f, gp.PathPoints[0].X); - Assert.Equal(1f, gp.PathPoints[0].Y); - } - } - - [Fact] - public void PathPoints_EmptyPath_ThrowsArgumentException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - Assert.Throws(() => gp.PathPoints); - } - } - - [Fact] - public void PathTypes_CannotChange() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddRectangle(new Rectangle(1, 1, 2, 2)); - Assert.Equal(0, gp.PathTypes[0]); - - gp.PathTypes[0] = 1; - Assert.Equal(0, gp.PathTypes[0]); - } - } - - [Fact] - public void PathTypes_EmptyPath_ThrowsArgumentException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - Assert.Throws(() => gp.PathTypes); - } - } - - [Fact] - public void GetLastPoint_ReturnsExpected() - { - byte[] types = new byte[3] { 0, 1, 1 }; - PointF[] points = new PointF[] - { - new PointF (1f, 1f), new PointF (2f, 2f), new PointF (3f, 3f), - }; - - using (GraphicsPath gp = new GraphicsPath(points, types)) - { - Assert.Equal(gp.GetLastPoint(), points[2]); - } - } - - [Fact] - public void AddLine_Success() - { - using (GraphicsPath gpInt = new GraphicsPath()) - using (GraphicsPath gpFloat = new GraphicsPath()) - using (GraphicsPath gpPointsInt = new GraphicsPath()) - using (GraphicsPath gpfPointsloat = new GraphicsPath()) - { - gpInt.AddLine(1, 1, 2, 2); - // AssertLine() method expects line drawn between points with coordinates 1, 1 and 2, 2, here and below. - AssertLine(gpInt); - - gpFloat.AddLine(1, 1, 2, 2); - AssertLine(gpFloat); - - gpPointsInt.AddLine(new Point(1, 1), new Point(2, 2)); - AssertLine(gpPointsInt); - - gpfPointsloat.AddLine(new PointF(1, 1), new PointF(2, 2)); - AssertLine(gpfPointsloat); - } - } - - [Fact] - public void AddLine_SamePoints_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddLine(new Point(49, 157), new Point(75, 196)); - gpi.AddLine(new Point(75, 196), new Point(102, 209)); - Assert.Equal(3, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1, 1 }, gpi.PathTypes); - - gpi.AddLine(new Point(102, 209), new Point(75, 196)); - Assert.Equal(4, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1, 1, 1 }, gpi.PathTypes); - - gpf.AddLine(new PointF(49, 157), new PointF(75, 196)); - gpf.AddLine(new PointF(75, 196), new PointF(102, 209)); - Assert.Equal(3, gpf.PointCount); - Assert.Equal(new byte[] { 0, 1, 1 }, gpf.PathTypes); - - gpf.AddLine(new PointF(102, 209), new PointF(75, 196)); - Assert.Equal(4, gpf.PointCount); - Assert.Equal(new byte[] { 0, 1, 1, 1 }, gpf.PathTypes); - } - } - - [Fact] - public void AddLines_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddLines(new Point[] { new Point(1, 1), new Point(2, 2) }); - AssertLine(gpi); - - gpf.AddLines(new PointF[] { new PointF(1, 1), new PointF(2, 2) }); - AssertLine(gpf); - } - } - - [Fact] - public void AddLines_SinglePoint_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddLines(new PointF[] { new PointF(1, 1) }); - Assert.Equal(1, gpi.PointCount); - Assert.Equal(0, gpi.PathTypes[0]); - - gpf.AddLines(new PointF[] { new PointF(1, 1) }); - Assert.Equal(1, gpf.PointCount); - Assert.Equal(0, gpf.PathTypes[0]); - } - } - - [Fact] - public void AddLines_SamePoint_Success() - { - Point[] intPoints = new Point[] - { - new Point(49, 157), new Point(49, 157) - }; - - PointF[] floatPoints = new PointF[] - { - new PointF(49, 57), new PointF(49, 57), - new PointF(49, 57), new PointF(49, 57) - }; - - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddLines(intPoints); - Assert.Equal(2, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1 }, gpi.PathTypes); - - gpi.AddLines(intPoints); - Assert.Equal(3, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1, 1 }, gpi.PathTypes); - - gpi.AddLines(intPoints); - Assert.Equal(4, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1, 1, 1 }, gpi.PathTypes); - - gpf.AddLines(floatPoints); - Assert.Equal(4, gpf.PointCount); - Assert.Equal(new byte[] { 0, 1, 1, 1 }, gpf.PathTypes); - - gpf.AddLines(floatPoints); - Assert.Equal(7, gpf.PointCount); - Assert.Equal(new byte[] { 0, 1, 1, 1, 1, 1, 1 }, gpf.PathTypes); - } - } - - [Fact] - public void AddLines_PointsNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("points", () => new GraphicsPath().AddLines((Point[])null)); - AssertExtensions.Throws("points", () => new GraphicsPath().AddLines((PointF[])null)); - } - } - - [Fact] - public void AddLines_ZeroPoints_ThrowsArgumentException() - { - AssertExtensions.Throws("points", null, () => new GraphicsPath().AddLines(new Point[0])); - AssertExtensions.Throws("points", null, () => new GraphicsPath().AddLines(new PointF[0])); - } - - [Fact] - public void AddArc_Values_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddArc(1, 1, 2, 2, Pi4, Pi4); - // AssertArc() method expects added Arc with parameters - // x=1, y=1, width=2, height=2, startAngle=Pi4, seewpAngle=Pi4 here and below. - AssertArc(gpi); - - gpf.AddArc(1f, 1f, 2f, 2f, Pi4, Pi4); - AssertArc(gpf); - } - } - - [Fact] - public void AddArc_Rectangle_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddArc(new Rectangle(1, 1, 2, 2), Pi4, Pi4); - AssertArc(gpi); - - gpf.AddArc(new RectangleF(1, 1, 2, 2), Pi4, Pi4); - AssertArc(gpf); - } - } - - [Theory] - [InlineData(0, 0)] - [InlineData(1, 0)] - [InlineData(0, 1)] - public void AddArc_ZeroWidthHeight_ThrowsArgumentException(int width, int height) - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddArc(1, 1, width, height, Pi4, Pi4)); - AssertExtensions.Throws(null, () => gp.AddArc(1.0f, 1.0f, (float)width, (float)height, Pi4, Pi4)); - } - } - - [Fact] - public void AddBezier_Points_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddBezier(new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(4, 4)); - // AssertBezier() method expects added Bezier with points (1, 1), (2, 2), (3, 3), (4, 4), here and below. - AssertBezier(gpi); - - gpf.AddBezier(new PointF(1, 1), new PointF(2, 2), new PointF(3, 3), new PointF(4, 4)); - AssertBezier(gpf); - } - } - - [Fact] - public void AddBezier_SamePoints_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gp.AddBezier(new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0)); - Assert.Equal(4, gp.PointCount); - Assert.Equal(new byte[] { 0, 3, 3, 3 }, gp.PathTypes); - - gp.AddBezier(new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0)); - Assert.Equal(7, gp.PointCount); - Assert.Equal(new byte[] { 0, 3, 3, 3, 3, 3, 3 }, gp.PathTypes); - - gpf.AddBezier(new PointF(0, 0), new PointF(0, 0), new PointF(0, 0), new PointF(0, 0)); - Assert.Equal(4, gpf.PointCount); - Assert.Equal(new byte[] { 0, 3, 3, 3 }, gpf.PathTypes); - - gpf.AddBezier(new PointF(0, 0), new PointF(0, 0), new PointF(0, 0), new PointF(0, 0)); - Assert.Equal(7, gpf.PointCount); - Assert.Equal(new byte[] { 0, 3, 3, 3, 3, 3, 3 }, gpf.PathTypes); - } - } - - [Fact] - public void AddBezier_Values_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddBezier(1, 1, 2, 2, 3, 3, 4, 4); - AssertBezier(gpi); - - gpf.AddBezier(1f, 1f, 2f, 2f, 3f, 3f, 4f, 4f); - AssertBezier(gpf); - } - } - - [Fact] - public void AddBeziers_Points_Success() - { - PointF[] points = new PointF[] - { - new PointF(1, 1), new PointF(2, 2), new PointF(3, 3), new PointF(4, 4) - }; - - using (GraphicsPath gpf = new GraphicsPath()) - { - gpf.AddBeziers(points); - AssertBezier(gpf); - } - } - - [Fact] - public void AddBeziers_PointsNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("points", () => gp.AddBeziers((PointF[])null)); - AssertExtensions.Throws("points", () => gp.AddBeziers((Point[])null)); - } - } - - public static IEnumerable AddBeziers_InvalidFloatPointsLength_TestData() - { - yield return new object[] { new PointF[0] }; - yield return new object[] { new PointF[1] { new PointF(1f, 1f) } }; - yield return new object[] { new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) } }; - yield return new object[] { new PointF[3] { new PointF(1f, 1f), new PointF(2f, 2f), new PointF(3f, 3f) } }; - } - - [Theory] - [MemberData(nameof(AddBeziers_InvalidFloatPointsLength_TestData))] - public void AddBeziers_InvalidFloatPointsLength_ThrowsArgumentException(PointF[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddBeziers(points)); - } - } - - [Fact] - public void AddCurve_TwoPoints_Success() - { - Point[] intPoints = new Point[] { new Point(1, 1), new Point(2, 2) }; - PointF[] floatPoints = new PointF[] { new PointF(1, 1), new PointF(2, 2) }; - - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpf.AddCurve(floatPoints); - // AssertCurve() method expects added Curve with points (1, 1), (2, 2), here and below. - AssertCurve(gpf); - - gpi.AddCurve(intPoints); - AssertCurve(gpi); - } - } - - [Fact] - public void AddCurve_TwoPointsWithTension_Success() - { - Point[] intPoints = new Point[] { new Point(1, 1), new Point(2, 2) }; - PointF[] floatPoints = new PointF[] { new PointF(1, 1), new PointF(2, 2) }; - - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddCurve(intPoints, 0.5f); - AssertCurve(gpi); - - gpf.AddCurve(floatPoints, 0.5f); - AssertCurve(gpf); - } - } - - [Fact] - public void AddCurve_SamePoints_Success() - { - Point[] intPoints = new Point[] { new Point(1, 1), new Point(1, 1) }; - PointF[] floatPoints = new PointF[] { new PointF(1, 1), new PointF(1, 1) }; - - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddCurve(intPoints); - Assert.Equal(4, gpi.PointCount); - gpi.AddCurve(intPoints); - Assert.Equal(7, gpi.PointCount); - - gpf.AddCurve(floatPoints); - Assert.Equal(4, gpf.PointCount); - gpf.AddCurve(floatPoints); - Assert.Equal(7, gpf.PointCount); - } - } - - [Fact] - public void AddCurve_LargeTension_Success() - { - Point[] intPoints = new Point[] { new Point(1, 1), new Point(2, 2) }; - PointF[] floatPoints = new PointF[] { new PointF(1, 1), new PointF(2, 2) }; - - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddCurve(intPoints, float.MaxValue); - Assert.Equal(4, gpi.PointCount); - - gpf.AddCurve(floatPoints, float.MaxValue); - Assert.Equal(4, gpf.PointCount); - } - } - - [Fact] - public void AddCurve_Success() - { - PointF[] points = new PointF[] - { - new PointF (37f, 185f), - new PointF (99f, 185f), - new PointF (161f, 159f), - new PointF (223f, 185f), - new PointF (285f, 54f), - }; - - PointF[] expectedPoints = new PointF[] - { - new PointF (37f, 185f), - new PointF (47.33333f, 185f), - new PointF (78.3333f, 189.3333f), - new PointF (99f, 185f), - new PointF (119.6667f, 180.6667f), - new PointF (140.3333f, 159f), - new PointF (161f, 159f), - new PointF (181.6667f, 159f), - new PointF (202.3333f, 202.5f), - new PointF (223f, 185f), - new PointF (243.6667f, 167.5f), - new PointF (274.6667f, 75.8333f), - new PointF (285f, 54f), - }; - - byte[] expectedTypes = new byte[] { 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; - int[] pointsCount = { 4, 7, 10, 13 }; - using (GraphicsPath gp = new GraphicsPath()) - { - for (int i = 0; i < points.Length - 1; i++) - { - gp.AddCurve(points, i, 1, 0.5f); - Assert.Equal(pointsCount[i], gp.PointCount); - } - - AssertPointsSequenceEqual(expectedPoints, gp.PathPoints, Delta); - Assert.Equal(expectedTypes, gp.PathTypes); - } - } - - [Fact] - public void AddCurve_PointsNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("points", () => gp.AddCurve((PointF[])null)); - AssertExtensions.Throws("points", () => gp.AddCurve((Point[])null)); - } - } - - public static IEnumerable AddCurve_InvalidFloatPointsLength_TestData() - { - yield return new object[] { new PointF[0] }; - yield return new object[] { new PointF[1] { new PointF(1f, 1f) } }; - } - - [Theory] - [MemberData(nameof(AddCurve_InvalidFloatPointsLength_TestData))] - public void AddCurve_InvalidFloatPointsLength_ThrowsArgumentException(PointF[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddCurve(points)); - AssertExtensions.Throws(null, () => gp.AddCurve(points, 0, 2, 0.5f)); - } - } - - public static IEnumerable AddCurve_InvalidPointsLength_TestData() - { - yield return new object[] { new Point[0] }; - yield return new object[] { new Point[1] { new Point(1, 1) } }; - } - - [Theory] - [MemberData(nameof(AddCurve_InvalidPointsLength_TestData))] - public void AddCurve_InvalidPointsLength_ThrowsArgumentException(Point[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddCurve(points)); - AssertExtensions.Throws(null, () => gp.AddCurve(points, 0, 2, 0.5f)); - } - } - - public static IEnumerable AddCurve_InvalidSegment_TestData() - { - yield return new object[] { 0 }; - yield return new object[] { -1 }; - } - - [Theory] - [MemberData(nameof(AddCurve_InvalidSegment_TestData))] - public void AddCurve_InvalidSegment_ThrowsArgumentException(int segment) - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddCurve( - new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) }, 0, segment, 0.5f)); - - AssertExtensions.Throws(null, () => gp.AddCurve( - new Point[2] { new Point(1, 1), new Point(2, 2) }, 0, segment, 0.5f)); - } - } - - [Fact] - public void AddCurve_OffsetTooLarge_ThrowsArgumentException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddCurve( - new PointF[3] { new PointF(1f, 1f), new PointF(0f, 20f), new PointF(20f, 0f) }, 1, 2, 0.5f)); - - AssertExtensions.Throws(null, () => gp.AddCurve( - new Point[3] { new Point(1, 1), new Point(0, 20), new Point(20, 0) }, 1, 2, 0.5f)); - } - } - - [Fact] - public void AddClosedCurve_Points_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddClosedCurve(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }); - // AssertClosedCurve() method expects added ClosedCurve with points (1, 1), (2, 2), (3, 3), here and below. - AssertClosedCurve(gpi); - - gpf.AddClosedCurve(new PointF[3] { new PointF(1, 1), new PointF(2, 2), new PointF(3, 3) }); - AssertClosedCurve(gpf); - } - } - - [Fact] - public void AddClosedCurve_SamePoints_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddClosedCurve(new Point[3] { new Point(1, 1), new Point(1, 1), new Point(1, 1) }); - Assert.Equal(10, gpi.PointCount); - gpi.AddClosedCurve(new Point[3] { new Point(1, 1), new Point(1, 1), new Point(1, 1) }); - Assert.Equal(20, gpi.PointCount); - - gpf.AddClosedCurve(new PointF[3] { new PointF(1, 1), new PointF(1, 1), new PointF(1, 1) }); - Assert.Equal(10, gpf.PointCount); - gpf.AddClosedCurve(new PointF[3] { new PointF(1, 1), new PointF(1, 1), new PointF(1, 1) }); - Assert.Equal(20, gpf.PointCount); - } - } - - [Fact] - public void AddClosedCurve_Tension_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddClosedCurve(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }, 0.5f); - AssertClosedCurve(gpi); - - gpf.AddClosedCurve(new PointF[3] { new PointF(1, 1), new PointF(2, 2), new PointF(3, 3) }, 0.5f); - AssertClosedCurve(gpf); - } - } - - [Fact] - public void AddClosedCurve_PointsNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("points", () => gp.AddClosedCurve((PointF[])null)); - AssertExtensions.Throws("points", () => gp.AddClosedCurve((Point[])null)); - } - } - - public static IEnumerable AddClosedCurve_InvalidPointsLength_TestData() - { - yield return new object[] { new Point[0] }; - yield return new object[] { new Point[1] { new Point(1, 1) } }; - yield return new object[] { new Point[2] { new Point(1, 1), new Point(2, 2) } }; - } - - [Theory] - [MemberData(nameof(AddCurve_InvalidPointsLength_TestData))] - public void AddClosedCurve_InvalidPointsLength_ThrowsArgumentException(Point[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddClosedCurve(points)); - } - } - - public static IEnumerable AddClosedCurve_InvalidFloatPointsLength_TestData() - { - yield return new object[] { new PointF[0] }; - yield return new object[] { new PointF[1] { new PointF(1f, 1f) } }; - yield return new object[] { new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) } }; - } - - [Theory] - [MemberData(nameof(AddClosedCurve_InvalidFloatPointsLength_TestData))] - public void AddClosedCurve_InvalidFloatPointsLength_ThrowsArgumentException(PointF[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddClosedCurve(points)); - } - } - - [Fact] - public void AddRectangle_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddRectangle(new Rectangle(1, 1, 2, 2)); - // AssertRectangle() method expects added Rectangle with parameters x=1, y=1, width=2, height=2, here and below. - AssertRectangle(gpi); - - gpf.AddRectangle(new RectangleF(1, 1, 2, 2)); - AssertRectangle(gpf); - } - } - - [Fact] - public void AddRectangle_SameRectangles_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddRectangle(new Rectangle(1, 1, 1, 1)); - Assert.Equal(4, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1, 1, 129 }, gpi.PathTypes); - - PointF endI = gpi.PathPoints[3]; - - gpi.AddRectangle(new Rectangle((int)endI.X, (int)endI.Y, 1, 1)); - Assert.Equal(8, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1, 1, 129, 0, 1, 1, 129 }, gpi.PathTypes); - - gpf.AddRectangle(new RectangleF(1, 1, 1, 1)); - Assert.Equal(4, gpf.PointCount); - Assert.Equal(new byte[] { 0, 1, 1, 129 }, gpf.PathTypes); - Assert.Equal(129, gpf.PathTypes[3]); - - PointF endF = gpf.PathPoints[3]; - - gpf.AddRectangle(new RectangleF(endF.X, endF.Y, 1, 1)); - Assert.Equal(8, gpf.PointCount); - Assert.Equal(new byte[] { 0, 1, 1, 129, 0, 1, 1, 129 }, gpf.PathTypes); - } - } - - [Theory] - [InlineData(0, 0)] - [InlineData(3, 0)] - [InlineData(0, 4)] - public void AddRectangle_ZeroWidthHeight_Success(int width, int height) - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddRectangle(new Rectangle(1, 2, width, height)); - Assert.Equal(0, gpi.PathData.Points.Length); - - gpf.AddRectangle(new RectangleF(1f, 2f, (float)width, (float)height)); - Assert.Equal(0, gpf.PathData.Points.Length); - } - } - - [Fact] - public void AddRectangles_Success() - { - Rectangle[] rectInt = new Rectangle[] { new Rectangle(1, 1, 2, 2), new Rectangle(3, 3, 4, 4) }; - RectangleF[] rectFloat = new RectangleF[] { new RectangleF(1, 1, 2, 2), new RectangleF(3, 3, 4, 4) }; - - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddRectangles(rectInt); - Assert.Equal(8, gpi.PathPoints.Length); - Assert.Equal(8, gpi.PathTypes.Length); - Assert.Equal(8, gpi.PathData.Points.Length); - - gpf.AddRectangles(rectFloat); - Assert.Equal(8, gpf.PathPoints.Length); - Assert.Equal(8, gpf.PathTypes.Length); - Assert.Equal(8, gpf.PathData.Points.Length); - } - } - - [Fact] - public void AddRectangles_SamePoints_Success() - { - Rectangle[] rectInt = new Rectangle[] - { - new Rectangle(1, 1, 0, 0), - new Rectangle(1, 1, 2, 2), - new Rectangle(1, 1, 2, 2) - }; - - RectangleF[] rectFloat = new RectangleF[] - { - new RectangleF(1, 1, 0f, 0f), - new RectangleF(1, 1, 2, 2), - new RectangleF(1, 1, 2, 2) - }; - - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddRectangles(rectInt); - Assert.Equal(8, gpi.PathPoints.Length); - Assert.Equal(8, gpi.PathTypes.Length); - Assert.Equal(8, gpi.PathData.Points.Length); - - gpf.AddRectangles(rectFloat); - Assert.Equal(8, gpf.PathPoints.Length); - Assert.Equal(8, gpf.PathTypes.Length); - Assert.Equal(8, gpf.PathData.Points.Length); - } - } - - [Fact] - public void AddRectangles_RectangleNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("rects", () => gp.AddRectangles((RectangleF[])null)); - AssertExtensions.Throws("rects", () => gp.AddRectangles((Rectangle[])null)); - } - } - - [Fact] - public void AddEllipse_Rectangle_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddEllipse(new Rectangle(1, 1, 2, 2)); - // AssertEllipse() method expects added Ellipse with parameters x=1, y=1, width=2, height=2, here and below. - AssertEllipse(gpi); - - gpf.AddEllipse(new RectangleF(1, 1, 2, 2)); - AssertEllipse(gpf); - } - } - - [Fact] - public void AddEllipse_Values_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddEllipse(1, 1, 2, 2); - AssertEllipse(gpi); - - gpf.AddEllipse(1f, 1f, 2f, 2f); - AssertEllipse(gpf); - } - } - - [Theory] - [InlineData(0, 0)] - [InlineData(2, 0)] - [InlineData(0, 2)] - public void AddEllipse_ZeroWidthHeight_Success(int width, int height) - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddEllipse(1, 1, width, height); - Assert.Equal(13, gpi.PathData.Points.Length); - - gpf.AddEllipse(1f, 2f, (float)width, (float)height); - Assert.Equal(13, gpf.PathData.Points.Length); - } - } - - [Fact] - public void AddPie_Rectangle_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - { - gpi.AddPie(new Rectangle(1, 1, 2, 2), Pi4, Pi4); - // AssertPie() method expects added Pie with parameters - // x=1, y=1, width=2, height=2, startAngle=Pi4, seewpAngle=Pi4 here and below. - AssertPie(gpi); - } - } - - [Fact] - public void AddPie_Values_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddPie(1, 1, 2, 2, Pi4, Pi4); - AssertPie(gpi); - - gpf.AddPie(1f, 1f, 2f, 2f, Pi4, Pi4); - AssertPie(gpf); - } - } - - [Theory] - [InlineData(0, 0)] - [InlineData(2, 0)] - [InlineData(0, 2)] - public void AddPie_ZeroWidthHeight_ThrowsArgumentException(int width, int height) - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddPie(1, 1, height, width, Pi4, Pi4)); - AssertExtensions.Throws(null, () => gp.AddPie(1f, 1f, height, width, Pi4, Pi4)); - AssertExtensions.Throws(null, () => gp.AddPie(new Rectangle(1, 1, height, width), Pi4, Pi4)); - } - } - - [Fact] - public void AddPolygon_Points_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddPolygon(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }); - // AssertPolygon() method expects added Polygon with points (1, 1), (2, 2), (3, 3), here and below. - AssertPolygon(gpi); - - gpf.AddPolygon(new PointF[3] { new PointF(1, 1), new PointF(2, 2), new PointF(3, 3) }); - AssertPolygon(gpf); - } - } - - [Fact] - public void AddPolygon_SamePoints_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddPolygon(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }); - Assert.Equal(3, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1, 129 }, gpi.PathTypes); - - gpi.AddPolygon(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }); - Assert.Equal(6, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1, 129, 0, 1, 129 }, gpi.PathTypes); - - gpi.AddPolygon(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }); - Assert.Equal(9, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1, 129, 0, 1, 129, 0, 1, 129 }, gpi.PathTypes); - - gpi.AddPolygon(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }); - Assert.Equal(12, gpi.PointCount); - Assert.Equal(new byte[] { 0, 1, 129, 0, 1, 129, 0, 1, 129, 0, 1, 129 }, gpi.PathTypes); - - gpf.AddPolygon(new PointF[3] { new PointF(1, 1), new PointF(2, 2), new PointF(3, 3) }); - Assert.Equal(3, gpf.PointCount); - Assert.Equal(new byte[] { 0, 1, 129 }, gpf.PathTypes); - - gpf.AddPolygon(new PointF[3] { new PointF(1, 1), new PointF(2, 2), new PointF(3, 3) }); - Assert.Equal(6, gpf.PointCount); - Assert.Equal(new byte[] { 0, 1, 129, 0, 1, 129 }, gpf.PathTypes); - - gpf.AddPolygon(new PointF[3] { new PointF(1, 1), new PointF(2, 2), new PointF(3, 3) }); - Assert.Equal(9, gpf.PointCount); - Assert.Equal(new byte[] { 0, 1, 129, 0, 1, 129, 0, 1, 129 }, gpf.PathTypes); - - gpf.AddPolygon(new PointF[3] { new PointF(1, 1), new PointF(2, 2), new PointF(3, 3) }); - Assert.Equal(12, gpf.PointCount); - Assert.Equal(new byte[] { 0, 1, 129, 0, 1, 129, 0, 1, 129, 0, 1, 129 }, gpf.PathTypes); - } - } - - [Fact] - public void AddPolygon_PointsNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("points", () => new GraphicsPath().AddPolygon((Point[])null)); - AssertExtensions.Throws("points", () => new GraphicsPath().AddPolygon((PointF[])null)); - } - } - - public static IEnumerable AddPolygon_InvalidFloadPointsLength_TestData() - { - yield return new object[] { new PointF[0] }; - yield return new object[] { new PointF[1] { new PointF(1f, 1f) } }; - yield return new object[] { new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) } }; - } - - [Theory] - [MemberData(nameof(AddPolygon_InvalidFloadPointsLength_TestData))] - public void AddPolygon_InvalidFloadPointsLength_ThrowsArgumentException(PointF[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddPolygon(points)); - } - } - - public static IEnumerable AddPolygon_InvalidPointsLength_TestData() - { - yield return new object[] { new Point[0] }; - yield return new object[] { new Point[1] { new Point(1, 1) } }; - yield return new object[] { new Point[2] { new Point(1, 1), new Point(2, 2) } }; - } - - [Theory] - [MemberData(nameof(AddPolygon_InvalidPointsLength_TestData))] - public void AddPolygon_InvalidPointsLength_ThrowsArgumentException(Point[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => gp.AddPolygon(points)); - } - } - - [Fact] - public void AddPath_Success() - { - using (GraphicsPath inner = new GraphicsPath()) - using (GraphicsPath gp = new GraphicsPath()) - { - inner.AddRectangle(new Rectangle(1, 1, 2, 2)); - gp.AddPath(inner, true); - AssertRectangle(gp); - } - } - - [Fact] - public void AddPath_PathNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("addingPath", () => new GraphicsPath().AddPath(null, false)); - } - } - - [Fact] - public void AddString_Point_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddString("mono", FontFamily.GenericMonospace, 0, 10, new Point(10, 10), StringFormat.GenericDefault); - AssertExtensions.GreaterThan(gpi.PointCount, 0); - - gpf.AddString("mono", FontFamily.GenericMonospace, 0, 10, new PointF(10f, 10f), StringFormat.GenericDefault); - AssertExtensions.GreaterThan(gpf.PointCount, 0); - } - } - - [Fact] - public void AddString_Rectangle_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddString("mono", FontFamily.GenericMonospace, 0, 10, new Rectangle(10, 10, 10, 10), StringFormat.GenericDefault); - AssertExtensions.GreaterThan(gpi.PointCount, 0); - - gpf.AddString("mono", FontFamily.GenericMonospace, 0, 10, new RectangleF(10f, 10f, 10f, 10f), StringFormat.GenericDefault); - AssertExtensions.GreaterThan(gpf.PointCount, 0); - } - } - - [Fact] - public void AddString_NegativeSize_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddString("mono", FontFamily.GenericMonospace, 0, -10, new Point(10, 10), StringFormat.GenericDefault); - AssertExtensions.GreaterThan(gpi.PointCount, 0); - - int gpiLengthOld = gpi.PathPoints.Length; - gpi.AddString("mono", FontFamily.GenericMonospace, 0, -10, new Rectangle(10, 10, 10, 10), StringFormat.GenericDefault); - AssertExtensions.GreaterThan(gpi.PointCount, gpiLengthOld); - - gpf.AddString("mono", FontFamily.GenericMonospace, 0, -10, new PointF(10f, 10f), StringFormat.GenericDefault); - AssertExtensions.GreaterThan(gpf.PointCount, 0); - - int pgfLengthOld = gpf.PathPoints.Length; - gpf.AddString("mono", FontFamily.GenericMonospace, 0, -10, new RectangleF(10f, 10f, 10f, 10f), StringFormat.GenericDefault); - AssertExtensions.GreaterThan(gpf.PointCount, pgfLengthOld); - } - } - - [Fact] - public void AddString_StringFormat_Success() - { - using (GraphicsPath gp1 = new GraphicsPath()) - using (GraphicsPath gp2 = new GraphicsPath()) - using (GraphicsPath gp3 = new GraphicsPath()) - { - gp1.AddString("mono", FontFamily.GenericMonospace, 0, 10, new RectangleF(10f, 10f, 10f, 10f), null); - AssertExtensions.GreaterThan(gp1.PointCount, 0); - - gp2.AddString("mono", FontFamily.GenericMonospace, 0, 10, new RectangleF(10f, 10f, 10f, 10f), StringFormat.GenericDefault); - Assert.Equal(gp1.PointCount, gp2.PointCount); - - gp3.AddString("mono", FontFamily.GenericMonospace, 0, 10, new RectangleF(10f, 10f, 10f, 10f), StringFormat.GenericTypographic); - Assert.NotEqual(gp1.PointCount, gp3.PointCount); - } - } - - [Fact] - public void AddString_EmptyString_Success() - { - using (GraphicsPath gpi = new GraphicsPath()) - using (GraphicsPath gpf = new GraphicsPath()) - { - gpi.AddString(string.Empty, FontFamily.GenericMonospace, 0, 10, new Point(10, 10), StringFormat.GenericDefault); - Assert.Equal(0, gpi.PointCount); - - gpi.AddString(string.Empty, FontFamily.GenericMonospace, 0, 10, new PointF(10f, 10f), StringFormat.GenericDefault); - Assert.Equal(0, gpf.PointCount); - } - } - - [Fact] - public void AddString_StringNull_ThrowsNullReferenceException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - Assert.Throws(() => - gp.AddString(null, FontFamily.GenericMonospace, 0, 10, new Point(10, 10), StringFormat.GenericDefault)); - Assert.Throws(() => - gp.AddString(null, FontFamily.GenericMonospace, 0, 10, new PointF(10f, 10f), StringFormat.GenericDefault)); - Assert.Throws(() => - gp.AddString(null, FontFamily.GenericMonospace, 0, 10, new Rectangle(10, 10, 10, 10), StringFormat.GenericDefault)); - Assert.Throws(() => - gp.AddString(null, FontFamily.GenericMonospace, 0, 10, new RectangleF(10f, 10f, 10f, 10f), StringFormat.GenericDefault)); - } - } - - [Fact] - public void AddString_FontFamilyNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("family", null, () => - new GraphicsPath().AddString("mono", null, 0, 10, new Point(10, 10), StringFormat.GenericDefault)); - } - } - - [Fact] - public void Transform_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (Matrix matrix = new Matrix(1f, 1f, 2f, 2f, 3f, 3f)) - { - gp.AddRectangle(new Rectangle(1, 1, 2, 2)); - AssertRectangle(gp); - gp.Transform(matrix); - Assert.Equal(new float[] { 1f, 1f, 2f, 2f, 3f, 3f }, matrix.Elements); - Assert.Equal(new RectangleF(6f, 6f, 6f, 6f), gp.GetBounds()); - Assert.Equal(new PointF[] { new PointF(6f, 6f), new PointF(8f, 8f), new PointF(12f, 12f), new PointF(10f, 10f) }, gp.PathPoints); - Assert.Equal(new byte[] { 0, 1, 1, 129 }, gp.PathTypes); - } - } - - [Fact] - public void Transform_PathEmpty_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (Matrix matrix = new Matrix(1f, 1f, 2f, 2f, 3f, 3f)) - { - gp.Transform(matrix); - Assert.Equal(new float[] { 1f, 1f, 2f, 2f, 3f, 3f }, matrix.Elements); - AssertEmptyGraphicsPath(gp); - } - } - - [Fact] - public void Transform_MatrixNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("matrix", () => gp.Transform(null)); - } - } - - [Fact] - public void GetBounds_PathEmpty_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath()) - { - Assert.Equal(new RectangleF(0f, 0f, 0f, 0f), gp.GetBounds()); - } - } - - [Fact] - public void GetBounds_Rectangle_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath()) - using (Matrix matrix = new Matrix()) - { - RectangleF rectangle = new RectangleF(1f, 1f, 2f, 2f); - gp.AddRectangle(rectangle); - Assert.Equal(rectangle, gp.GetBounds()); - Assert.Equal(rectangle, gp.GetBounds(null)); - Assert.Equal(rectangle, gp.GetBounds(matrix)); - Assert.Equal(rectangle, gp.GetBounds(null, null)); - } - } - - [Fact] - public void GetBounds_Pie_ReturnsExpected() - { - using (GraphicsPath gp = new GraphicsPath()) - using (Matrix matrix = new Matrix()) - { - Rectangle rectangle = new Rectangle(10, 10, 100, 100); - gp.AddPie(rectangle, 30, 45); - AssertRectangleEqual(new RectangleF(60f, 60f, 43.3f, 48.3f), gp.GetBounds(), 0.1f); - } - } - - [Fact] - public void Flatten_Empty_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.Flatten(); - Assert.Equal(gp.PointCount, clone.PointCount); - } - } - - [Fact] - public void Flatten_MatrixNull_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.Flatten(null); - Assert.Equal(gp.PointCount, clone.PointCount); - } - } - - [Fact] - public void Flatten_MatrixNullFloat_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.Flatten(null, 1f); - Assert.Equal(gp.PointCount, clone.PointCount); - } - } - - [Fact] - public void Flatten_Arc_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.AddArc(0f, 0f, 100f, 100f, 30, 30); - gp.Flatten(); - AssertFlats(gp, clone); - } - } - - [Fact] - public void Flatten_Bezier_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.AddBezier(0, 0, 100, 100, 30, 30, 60, 60); - gp.Flatten(); - AssertFlats(gp, clone); - } - } - - [Fact] - public void Flatten_ClosedCurve_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.AddClosedCurve(new Point[4] - { - new Point (0, 0), new Point (40, 20), - new Point (20, 40), new Point (40, 40) - }); - - gp.Flatten(); - AssertFlats(gp, clone); - } - } - - [Fact] - public void Flatten_Curve_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.AddCurve(new Point[4] - { - new Point (0, 0), new Point (40, 20), - new Point (20, 40), new Point (40, 40) - }); - - gp.Flatten(); - AssertFlats(gp, clone); - } - } - - [Fact] - public void Flatten_Ellipse_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.AddEllipse(10f, 10f, 100f, 100f); - gp.Flatten(); - AssertFlats(gp, clone); - } - } - - [Fact] - public void Flatten_Line_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.AddLine(10f, 10f, 100f, 100f); - gp.Flatten(); - AssertFlats(gp, clone); - } - } - - [Fact] - public void Flatten_Pie_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.AddPie(0, 0, 100, 100, 30, 30); - gp.Flatten(); - AssertFlats(gp, clone); - } - } - - [Fact] - public void Flatten_Polygon_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.AddPolygon(new Point[4] - { - new Point (0, 0), new Point (10, 10), - new Point (20, 20), new Point (40, 40) - }); - - gp.Flatten(); - AssertFlats(gp, clone); - } - } - - [Fact] - public void Flatten_Rectangle_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath clone = Assert.IsType(gp.Clone())) - { - gp.AddRectangle(new Rectangle(0, 0, 100, 100)); - gp.Flatten(); - AssertFlats(gp, clone); - } - } - - [Fact] - public void Warp_DestinationPointsNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("destPoints", () => gp.Warp(null, new RectangleF())); - } - } - - [Fact] - public void Warp_DestinationPointsZero_ThrowsArgumentException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws(null, () => new GraphicsPath().Warp(new PointF[0], new RectangleF())); - } - } - - [Fact] - public void Warp_PathEmpty_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (Matrix matrix = new Matrix()) - { - Assert.Equal(0, gp.PointCount); - gp.Warp(new PointF[1] { new PointF(0, 0) }, new RectangleF(10, 20, 30, 40), matrix); - Assert.Equal(0, gp.PointCount); - } - } - - [Fact] - public void Warp_WarpModeInvalid_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (Matrix matrix = new Matrix()) - { - gp.AddPolygon(new Point[3] { new Point(5, 5), new Point(15, 5), new Point(10, 15) }); - gp.Warp(new PointF[1] { new PointF(0, 0) }, new RectangleF(10, 20, 30, 40), matrix, (WarpMode)int.MinValue); - Assert.Equal(0, gp.PointCount); - } - } - - [Fact] - public void Warp_RectangleEmpty_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddPolygon(new Point[3] { new Point(5, 5), new Point(15, 5), new Point(10, 15) }); - gp.Warp(new PointF[1] { new PointF(0, 0) }, new Rectangle(), null); - AssertWrapNaN(gp); - } - } - - - [Fact] - public void SetMarkers_EmptyPath_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.SetMarkers(); - } - } - - [Fact] - public void SetMarkers_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(new Point(1, 1), new Point(2, 2)); - Assert.Equal(1, gp.PathTypes[1]); - - gp.SetMarkers(); - Assert.Equal(33, gp.PathTypes[1]); - } - } - - [Fact] - public void ClearMarkers_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(new Point(1, 1), new Point(2, 2)); - Assert.Equal(1, gp.PathTypes[1]); - - gp.SetMarkers(); - Assert.Equal(33, gp.PathTypes[1]); - - gp.ClearMarkers(); - Assert.Equal(1, gp.PathTypes[1]); - } - } - - [Fact] - public void ClearMarkers_EmptyPath_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.ClearMarkers(); - } - } - - [Fact] - public void CloseFigure_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(new Point(1, 1), new Point(2, 2)); - Assert.Equal(1, gp.PathTypes[1]); - - gp.CloseFigure(); - Assert.Equal(129, gp.PathTypes[1]); - } - } - - [Fact] - public void CloseFigure_EmptyPath_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.CloseFigure(); - } - } - - [Fact] - public void CloseAllFigures_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(new Point(1, 1), new Point(2, 2)); - gp.StartFigure(); - gp.AddLine(new Point(3, 3), new Point(4, 4)); - Assert.Equal(1, gp.PathTypes[1]); - Assert.Equal(1, gp.PathTypes[3]); - - gp.CloseAllFigures(); - Assert.Equal(129, gp.PathTypes[1]); - Assert.Equal(129, gp.PathTypes[3]); - } - } - - [Fact] - public void CloseAllFigures_EmptyPath_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.CloseAllFigures(); - } - } - - [Fact] - public void StartClose_AddArc() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 1, 2, 2); - gp.AddArc(10, 10, 100, 100, 90, 180); - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(1, types[2]); - Assert.Equal(3, types[gp.PointCount - 3]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddBezier() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 1, 2, 2); - gp.AddBezier(10, 10, 100, 100, 20, 20, 200, 200); - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(1, types[2]); - Assert.Equal(3, types[gp.PointCount - 3]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddBeziers() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 1, 2, 2); - gp.AddBeziers(new Point[7] - { - new Point (10, 10), new Point (20, 10), new Point (20, 20), - new Point (30, 20), new Point (40, 40), new Point (50, 40), - new Point (50, 50) - }); - - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(1, types[2]); - Assert.Equal(3, types[gp.PointCount - 3]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddClosedCurve() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 1, 2, 2); - gp.AddClosedCurve(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }); - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(0, types[2]); - Assert.Equal(131, types[gp.PointCount - 3]); - Assert.Equal(0, types[gp.PointCount - 2]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddCurve() - { - using (GraphicsPath path = new GraphicsPath()) - { - path.AddLine(1, 1, 2, 2); - path.AddCurve(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }); - path.AddLine(10, 10, 20, 20); - byte[] types = path.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(1, types[2]); - Assert.Equal(3, types[path.PointCount - 3]); - Assert.Equal(1, types[path.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddEllipse() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 1, 2, 2); - gp.AddEllipse(10, 10, 100, 100); - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(0, types[2]); - Assert.Equal(131, types[gp.PointCount - 3]); - Assert.Equal(0, types[gp.PointCount - 2]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddLine() - { - using (GraphicsPath path = new GraphicsPath()) - { - path.AddLine(1, 1, 2, 2); - path.AddLine(5, 5, 10, 10); - path.AddLine(10, 10, 20, 20); - byte[] types = path.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(1, types[2]); - Assert.Equal(1, types[path.PointCount - 3]); - Assert.Equal(1, types[path.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddLines() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 1, 2, 2); - gp.AddLines(new Point[4] { new Point(10, 10), new Point(20, 10), new Point(20, 20), new Point(30, 20) }); - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(1, types[2]); - Assert.Equal(1, types[gp.PointCount - 3]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddPath_Connect() - { - using (GraphicsPath gp = new GraphicsPath()) - using (GraphicsPath inner = new GraphicsPath()) - { - inner.AddArc(10, 10, 100, 100, 90, 180); - gp.AddLine(1, 1, 2, 2); - gp.AddPath(inner, true); - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(1, types[2]); - Assert.Equal(3, types[gp.PointCount - 3]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddPath_NoConnect() - { - using (GraphicsPath inner = new GraphicsPath()) - using (GraphicsPath path = new GraphicsPath()) - { - inner.AddArc(10, 10, 100, 100, 90, 180); - path.AddLine(1, 1, 2, 2); - path.AddPath(inner, false); - path.AddLine(10, 10, 20, 20); - byte[] types = path.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(0, types[2]); - Assert.Equal(3, types[path.PointCount - 3]); - Assert.Equal(1, types[path.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddPie() - { - using (GraphicsPath path = new GraphicsPath()) - { - path.AddLine(1, 1, 2, 2); - path.AddPie(10, 10, 10, 10, 90, 180); - path.AddLine(10, 10, 20, 20); - byte[] types = path.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(0, types[2]); - - Assert.Equal(128, (types[path.PointCount - 3] & 128)); - Assert.Equal(0, types[path.PointCount - 2]); - Assert.Equal(1, types[path.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddPolygon() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 1, 2, 2); - gp.AddPolygon(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }); - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(0, types[2]); - Assert.Equal(129, types[gp.PointCount - 3]); - Assert.Equal(0, types[gp.PointCount - 2]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddRectangle() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 1, 2, 2); - gp.AddRectangle(new RectangleF(10, 10, 20, 20)); - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(0, types[2]); - Assert.Equal(129, types[gp.PointCount - 3]); - Assert.Equal(0, types[gp.PointCount - 2]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddRectangles() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 1, 2, 2); - gp.AddRectangles(new RectangleF[2] - { - new RectangleF (10, 10, 20, 20), - new RectangleF (20, 20, 10, 10) - }); - - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(0, types[2]); - Assert.Equal(129, types[gp.PointCount - 3]); - Assert.Equal(0, types[gp.PointCount - 2]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void StartClose_AddString() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 1, 2, 2); - gp.AddString("mono", FontFamily.GenericMonospace, 0, 10, new Point(20, 20), StringFormat.GenericDefault); - gp.AddLine(10, 10, 20, 20); - byte[] types = gp.PathTypes; - - Assert.Equal(0, types[0]); - Assert.Equal(0, types[2]); - Assert.Equal(163, types[gp.PointCount - 3]); - Assert.Equal(1, types[gp.PointCount - 2]); - Assert.Equal(1, types[gp.PointCount - 1]); - } - } - - [Fact] - public void Widen_Pen_Success() - { - PointF[] expectedPoints = new PointF[] - { - new PointF(0.5f, 0.5f), new PointF(3.5f, 0.5f), new PointF(3.5f, 3.5f), - new PointF(0.5f, 3.5f), new PointF(1.5f, 3.0f), new PointF(1.0f, 2.5f), - new PointF(3.0f, 2.5f), new PointF(2.5f, 3.0f), new PointF(2.5f, 1.0f), - new PointF(3.0f, 1.5f), new PointF(1.0f, 1.5f), new PointF(1.5f, 1.0f), - }; - - byte[] expectedTypes = new byte[] { 0, 1, 1, 129, 0, 1, 1, 1, 1, 1, 1, 129 }; - - using (GraphicsPath gp = new GraphicsPath()) - using (Pen pen = new Pen(Color.Blue)) - { - gp.AddRectangle(new Rectangle(1, 1, 2, 2)); - Assert.Equal(4, gp.PointCount); - gp.Widen(pen); - Assert.Equal(12, gp.PointCount); - AssertPointsSequenceEqual(expectedPoints, gp.PathPoints, Delta); - Assert.Equal(expectedTypes, gp.PathTypes); - } - } - - [Fact] - public void Widen_EmptyPath_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (Pen pen = new Pen(Color.Blue)) - { - Assert.Equal(0, gp.PointCount); - gp.Widen(pen); - Assert.Equal(0, gp.PointCount); - } - } - - [Fact] - public void Widen_PenNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("pen", () => gp.Widen(null)); - AssertExtensions.Throws("pen", () => gp.Widen(null, new Matrix())); - AssertExtensions.Throws("pen", () => gp.Widen(null, new Matrix(), 0.67f)); - } - } - - [Fact] - public void Widen_MatrixNull_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (Pen pen = new Pen(Color.Blue)) - { - gp.AddPolygon(new Point[3] { new Point(5, 5), new Point(15, 5), new Point(10, 15) }); - gp.Widen(pen, null); - Assert.Equal(9, gp.PointCount); - AssertWiden3(gp); - } - } - - [Fact] - public void Widen_MatrixEmpty_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - using (Pen pen = new Pen(Color.Blue)) - using (Matrix matrix = new Matrix()) - { - gp.AddPolygon(new Point[3] { new Point(5, 5), new Point(15, 5), new Point(10, 15) }); - gp.Widen(pen, new Matrix()); - Assert.Equal(9, gp.PointCount); - AssertWiden3(gp); - } - - } - - public static IEnumerable Widen_PenSmallWidth_TestData() - { - yield return new object[] { new Rectangle(1, 1, 2, 2), 0f, new RectangleF(0.5f, 0.5f, 3.0f, 3.0f) }; - yield return new object[] { new Rectangle(1, 1, 2, 2), 0.5f, new RectangleF(0.5f, 0.5f, 3.0f, 3.0f) }; - yield return new object[] { new Rectangle(1, 1, 2, 2), 1.0f, new RectangleF(0.5f, 0.5f, 3.0f, 3.0f) }; - yield return new object[] { new Rectangle(1, 1, 2, 2), 1.1f, new RectangleF(0.45f, 0.45f, 3.10f, 3.10f) }; - } - - [Theory] - [MemberData(nameof(Widen_PenSmallWidth_TestData))] - public void Widen_Pen_SmallWidth_Success( - Rectangle rectangle, float penWidth, RectangleF expectedBounds) - { - using (GraphicsPath gp = new GraphicsPath()) - using (Pen pen = new Pen(Color.Aqua, 0)) - using (Matrix matrix = new Matrix()) - { - pen.Width = penWidth; - gp.AddRectangle(rectangle); - gp.Widen(pen); - AssertRectangleEqual(expectedBounds, gp.GetBounds(null), Delta); - AssertRectangleEqual(expectedBounds, gp.GetBounds(matrix), Delta); - } - } - - [Fact] - public void IsOutlineVisible_PenNull_ThrowsArgumentNullException() - { - using (GraphicsPath gp = new GraphicsPath()) - { - AssertExtensions.Throws("pen", () => gp.IsOutlineVisible(1, 1, null)); - AssertExtensions.Throws("pen", () => gp.IsOutlineVisible(1.0f, 1.0f, null)); - AssertExtensions.Throws("pen", () => gp.IsOutlineVisible(new Point(), null)); - AssertExtensions.Throws("pen", () => gp.IsOutlineVisible(new PointF(), null)); - } - } - - [Fact] - public void IsOutlineVisible_LineWithoutGraphics_ReturnsExpected() - { - AssertIsOutlineVisibleLine(null); - } - - [Fact] - public void IsOutlineVisible_LineInsideGraphics_ReturnsExpected() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - AssertIsOutlineVisibleLine(graphics); - } - } - - [Fact] - public void IsOutlineVisible_LineOutsideGraphics_ReturnsExpected() - { - using (Bitmap bitmap = new Bitmap(5, 5)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - AssertIsOutlineVisibleLine(graphics); - } - } - - [Fact] - public void IsOutlineVisible_LineWithGraphicsTransform_ReturnsExpected() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - using (Matrix matrix = new Matrix(2, 0, 0, 2, 50, -50)) - { - graphics.Transform = matrix; - AssertIsOutlineVisibleLine(graphics); - } - } - - [Fact] - public void IsOutlineVisible_LineWithGraphicsPageUnit_ReturnsExpected() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - graphics.PageUnit = GraphicsUnit.Millimeter; - AssertIsOutlineVisibleLine(graphics); - } - } - - [Fact] - public void IsOutlineVisible_LineWithGraphicsPageScale_ReturnsExpected() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - graphics.PageScale = 2.0f; - AssertIsOutlineVisibleLine(graphics); - } - } - - [Fact] - public void IsOutlineVisible_RectangleWithoutGraphics_ReturnsExpected() - { - AssertIsOutlineVisibleRectangle(null); - } - - [Fact] - public void IsVisible_RectangleWithoutGraphics_ReturnsExpected() - { - AssertIsVisibleRectangle(null); - } - - [Fact] - public void IsVisible_RectangleWithGraphics_ReturnsExpected() - { - using (Bitmap bitmap = new Bitmap(40, 40)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - AssertIsVisibleRectangle(graphics); - } - } - - [Fact] - public void IsVisible_EllipseWithoutGraphics_ReturnsExpected() - { - AssertIsVisibleEllipse(null); - } - - [Fact] - public void IsVisible_EllipseWithGraphics_ReturnsExpected() - { - using (Bitmap bitmap = new Bitmap(40, 40)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - AssertIsVisibleEllipse(graphics); - } - } - - [Fact] - public void Reverse_Arc_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddArc(1f, 1f, 2f, 2f, Pi4, Pi4); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Fact] - public void Reverse_Bezier_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddBezier(1, 2, 3, 4, 5, 6, 7, 8); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - public static IEnumerable Reverse_TestData() - { - yield return new object[] - { - new Point[] - { - new Point (1,2), new Point (3,4), new Point (5,6), new Point (7,8), - new Point (9,10), new Point (11,12), new Point (13,14) - } - }; - } - - [Theory] - [MemberData(nameof(Reverse_TestData))] - public void Reverse_Beziers_Success(Point[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddBeziers(points); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Theory] - [MemberData(nameof(Reverse_TestData))] - public void Reverse_ClosedCurve_Success(Point[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddClosedCurve(points); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Theory] - [MemberData(nameof(Reverse_TestData))] - public void Reverse_Curve_Success(Point[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddCurve(points); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Fact] - public void Reverse_Ellipse_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddEllipse(1, 2, 3, 4); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Fact] - public void Reverse_Line_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 2, 3, 4); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Fact] - public void Reverse_LineClosed_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(1, 2, 3, 4); - gp.CloseFigure(); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Theory] - [MemberData(nameof(Reverse_TestData))] - public void Reverse_Lines_Success(Point[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLines(points); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Theory] - [MemberData(nameof(Reverse_TestData))] - public void Reverse_Polygon_Success(Point[] points) - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddPolygon(points); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Fact] - public void Reverse_Rectangle_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddRectangle(new Rectangle(1, 2, 3, 4)); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Fact] - public void Reverse_Rectangles_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - Rectangle[] rects = new Rectangle[] { new Rectangle(1, 2, 3, 4), new Rectangle(5, 6, 7, 8) }; - gp.AddRectangles(rects); - AssertReverse(gp, gp.PathPoints, gp.PathTypes); - } - } - - [Fact] - public void Reverse_Pie_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddPie(1, 2, 3, 4, 10, 20); - byte[] expectedTypes = new byte[] { 0, 3, 3, 3, 129 }; - AssertReverse(gp, gp.PathPoints, expectedTypes); - } - } - - [Fact] - public void Reverse_ArcLineInnerPath_Success() - { - using (GraphicsPath inner = new GraphicsPath()) - using (GraphicsPath gp = new GraphicsPath()) - { - inner.AddArc(1f, 1f, 2f, 2f, Pi4, Pi4); - inner.AddLine(1, 2, 3, 4); - byte[] expectedTypes = new byte[] { 0, 1, 1, 3, 3, 3 }; - gp.AddPath(inner, true); - AssertReverse(gp, gp.PathPoints, expectedTypes); - } - } - - [Fact] - public void Reverse_EllipseRectangle_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddEllipse(50, 51, 50, 100); - gp.AddRectangle(new Rectangle(200, 201, 60, 61)); - byte[] expectedTypes = new byte[] { 0, 1, 1, 129, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 131 }; - AssertReverse(gp, gp.PathPoints, expectedTypes); - } - } - - [Fact] - public void Reverse_String_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddString("Mono::", FontFamily.GenericMonospace, 0, 10, new Point(10, 10), StringFormat.GenericDefault); - byte[] expectedTypes = new byte[] - { - 0,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,129, - 0,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,161, - 0,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,129, - 0,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,161, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,131,0,3, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,163,0,3,3,3, - 3,3,3,3,3,3,3,3,3,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3, - 3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3, - 3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3, - 3,3,3,3,3,3,3,3,3,3,3,161,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3, - 3,3,3,3,3,3,3,3,3,131,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, - 3,3,3,3,3,3,3,163,0,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3, - 3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1, - 1,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3, - 1,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,129 - }; - - AssertReverse(gp, gp.PathPoints, expectedTypes); - } - } - - [Fact] - public void Reverse_Marker_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddRectangle(new Rectangle(200, 201, 60, 61)); - gp.SetMarkers(); - byte[] expectedTypes = new byte[] { 0, 1, 1, 129 }; - AssertReverse(gp, gp.PathPoints, expectedTypes); - } - } - - [Fact] - public void Reverse_SubpathMarker_Success() - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(0, 1, 2, 3); - gp.SetMarkers(); - gp.CloseFigure(); - gp.AddBezier(5, 6, 7, 8, 9, 10, 11, 12); - gp.CloseFigure(); - byte[] expectedTypes = new byte[] { 0, 3, 3, 163, 0, 129 }; - AssertReverse(gp, gp.PathPoints, expectedTypes); - } - - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddLine(0, 1, 2, 3); - gp.SetMarkers(); - gp.StartFigure(); - gp.AddLine(20, 21, 22, 23); - gp.AddBezier(5, 6, 7, 8, 9, 10, 11, 12); - byte[] expectedTypes = new byte[] { 0, 3, 3, 3, 1, 33, 0, 1 }; - AssertReverse(gp, gp.PathPoints, expectedTypes); - } - } - - [Fact] - public void Ctor_PointsTypes_Success() - { - int dX = 520; - int dY = 320; - Point[] expectedPoints = new Point[] - { - new Point(dX-64, dY-24), new Point(dX-59, dY-34), new Point(dX-52, dY-54), - new Point(dX-18, dY-66), new Point(dX-34, dY-47), new Point(dX-43, dY-27), - new Point(dX-44, dY-8), - }; - - byte[] expectedTypes = new byte[] - { - (byte)PathPointType.Start, (byte)PathPointType.Bezier, (byte)PathPointType.Bezier, - (byte)PathPointType.Bezier, (byte)PathPointType.Bezier, (byte)PathPointType.Bezier, - (byte)PathPointType.Bezier - }; - - using (GraphicsPath path = new GraphicsPath(expectedPoints, expectedTypes)) - { - Assert.Equal(7, path.PointCount); - byte[] actualTypes = path.PathTypes; - Assert.Equal(expectedTypes, actualTypes); - } - } - - private void AssertEmptyGraphicsPath(GraphicsPath gp) - { - Assert.Equal(0, gp.PathData.Points.Length); - Assert.Equal(0, gp.PathData.Types.Length); - Assert.Equal(0, gp.PointCount); - } - - private void AssertEqual(float expexted, float actual, float tollerance) - { - AssertExtensions.LessThanOrEqualTo(Math.Abs(expexted - actual), tollerance); - } - - private void AssertLine(GraphicsPath path) - { - PointF[] expectedPoints = new PointF[] - { - new PointF(1f, 1f), new PointF(2f, 2f) - }; - - Assert.Equal(2, path.PathPoints.Length); - Assert.Equal(2, path.PathTypes.Length); - Assert.Equal(2, path.PathData.Points.Length); - AssertExtensions.Equal(new RectangleF(1f, 1f, 1f, 1f), path.GetBounds(), variance: 0.000001f); - Assert.Equal(expectedPoints, path.PathPoints); - Assert.Equal(new byte[] { 0, 1 }, path.PathTypes); - } - - private void AssertArc(GraphicsPath path) - { - PointF[] expectedPoints = new PointF[] - { - new PointF(2.99990582f, 2.01370716f), new PointF(2.99984312f, 2.018276f), - new PointF(2.99974918f, 2.02284455f), new PointF(2.999624f, 2.027412f), - }; - - Assert.Equal(4, path.PathPoints.Length); - Assert.Equal(4, path.PathTypes.Length); - Assert.Equal(4, path.PathData.Points.Length); - AssertExtensions.Equal(new RectangleF(2.99962401f, 2.01370716f, 0f, 0.0137047768f), path.GetBounds(), variance: Delta); - Assert.Equal(expectedPoints, path.PathPoints); - Assert.Equal(new byte[] { 0, 3, 3, 3 }, path.PathTypes); - } - - private void AssertBezier(GraphicsPath path) - { - PointF[] expectedPoints = new PointF[] - { - new PointF(1f, 1f), new PointF(2f, 2f), - new PointF(3f, 3f), new PointF(4f, 4f), - }; - - Assert.Equal(4, path.PointCount); - Assert.Equal(4, path.PathPoints.Length); - Assert.Equal(4, path.PathTypes.Length); - Assert.Equal(4, path.PathData.Points.Length); - AssertExtensions.Equal(new RectangleF(1f, 1f, 3f, 3f), path.GetBounds(), Delta); - AssertPointsSequenceEqual(expectedPoints, path.PathPoints, Delta); - Assert.Equal(new byte[] { 0, 3, 3, 3 }, path.PathTypes); - } - - private void AssertCurve(GraphicsPath path) - { - PointF[] expectedPoints = new PointF[] - { - new PointF(1f, 1f), new PointF(1.16666663f, 1.16666663f), - new PointF(1.83333325f, 1.83333325f), new PointF(2f, 2f) - }; - - Assert.Equal(4, path.PathPoints.Length); - Assert.Equal(4, path.PathTypes.Length); - Assert.Equal(4, path.PathData.Points.Length); - AssertExtensions.Equal(new RectangleF(1f, 1f, 1f, 1f), path.GetBounds(), Delta); - AssertPointsSequenceEqual(expectedPoints, path.PathPoints, Delta); - Assert.Equal(new byte[] { 0, 3, 3, 3 }, path.PathTypes); - } - - private void AssertClosedCurve(GraphicsPath path) - { - Assert.Equal(10, path.PathPoints.Length); - Assert.Equal(10, path.PathTypes.Length); - Assert.Equal(10, path.PathData.Points.Length); - AssertExtensions.Equal(new RectangleF(0.8333333f, 0.8333333f, 2.33333278f, 2.33333278f), path.GetBounds(), Delta); - Assert.Equal(new byte[] { 0, 3, 3, 3, 3, 3, 3, 3, 3, 131 }, path.PathTypes); - } - - private void AssertRectangle(GraphicsPath path) - { - PointF[] expectedPoints = new PointF[] - { - new PointF(1f, 1f), new PointF(3f, 1f), - new PointF(3f, 3f), new PointF(1f, 3f) - }; - - Assert.Equal(4, path.PathPoints.Length); - Assert.Equal(4, path.PathTypes.Length); - Assert.Equal(4, path.PathData.Points.Length); - AssertExtensions.Equal(new RectangleF(1f, 1f, 2f, 2f), path.GetBounds(), Delta); - AssertPointsSequenceEqual(expectedPoints, path.PathPoints, Delta); - Assert.Equal(new byte[] { 0, 1, 1, 129 }, path.PathTypes); - } - - private void AssertEllipse(GraphicsPath path) - { - Assert.Equal(13, path.PathPoints.Length); - Assert.Equal(13, path.PathTypes.Length); - Assert.Equal(13, path.PathData.Points.Length); - AssertExtensions.Equal(new RectangleF(1f, 1f, 2f, 2f), path.GetBounds(), Delta); - Assert.Equal(new byte[] { 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 131 }, path.PathTypes); - } - - private void AssertPie(GraphicsPath path) - { - PointF[] expectedPoints = new PointF[] - { - new PointF(2f, 2f), new PointF(2.99990582f, 2.01370716f), - new PointF(2.99984312f, 2.018276f), new PointF(2.99974918f, 2.02284455f), - new PointF(2.999624f, 2.027412f) - }; - - Assert.Equal(5, path.PathPoints.Length); - Assert.Equal(5, path.PathTypes.Length); - Assert.Equal(5, path.PathData.Points.Length); - AssertRectangleEqual(new RectangleF(2f, 2f, 0.9999058f, 0.0274119377f), path.GetBounds(), Delta); - AssertPointsSequenceEqual(expectedPoints, path.PathPoints, Delta); - Assert.Equal(new byte[] { 0, 1, 3, 3, 131 }, path.PathTypes); - } - - private void AssertPolygon(GraphicsPath path) - { - PointF[] expectedPoints = new PointF[] - { - new PointF(1f, 1f), - new PointF(2f, 2f), - new PointF(3f, 3f) - }; - - Assert.Equal(3, path.PathPoints.Length); - Assert.Equal(3, path.PathTypes.Length); - Assert.Equal(3, path.PathData.Points.Length); - AssertExtensions.Equal(new RectangleF(1f, 1f, 2f, 2f), path.GetBounds(), Delta); - AssertPointsSequenceEqual(expectedPoints, path.PathPoints, Delta); - Assert.Equal(new byte[] { 0, 1, 129 }, path.PathTypes); - } - - private void AssertFlats(GraphicsPath flat, GraphicsPath original) - { - AssertExtensions.GreaterThanOrEqualTo(flat.PointCount, original.PointCount); - for (int i = 0; i < flat.PointCount; i++) - { - Assert.NotEqual(3, flat.PathTypes[i]); - } - } - - private void AssertWrapNaN(GraphicsPath path) - { - byte[] expectedTypes = new byte[] { 0, 1, 129 }; - - Assert.Equal(3, path.PointCount); - Assert.Equal(float.NaN, path.PathPoints[0].X); - Assert.Equal(float.NaN, path.PathPoints[0].Y); - Assert.Equal(float.NaN, path.PathPoints[1].X); - Assert.Equal(float.NaN, path.PathPoints[1].Y); - Assert.Equal(float.NaN, path.PathPoints[2].X); - Assert.Equal(float.NaN, path.PathPoints[2].Y); - Assert.Equal(expectedTypes, path.PathTypes); - } - - private void AssertWiden3(GraphicsPath path) - { - PointF[] expectedPoints = new PointF[] - { - new PointF(4.2f, 4.5f), new PointF(15.8f, 4.5f), - new PointF(10.0f, 16.1f), new PointF(10.4f, 14.8f), - new PointF(9.6f, 14.8f), new PointF(14.6f, 4.8f), - new PointF(15.0f, 5.5f), new PointF(5.0f, 5.5f), - new PointF(5.4f, 4.8f) - }; - - AssertPointsSequenceEqual(expectedPoints, path.PathPoints, 0.25f); - Assert.Equal(new byte[] { 0, 1, 129, 0, 1, 1, 1, 1, 129 }, path.PathTypes); - } - - private void AssertIsOutlineVisibleLine(Graphics graphics) - { - using (GraphicsPath gp = new GraphicsPath()) - using (Pen pen = new Pen(Color.Red, 3.0f)) - { - gp.AddLine(10, 1, 14, 1); - Assert.True(gp.IsOutlineVisible(10, 1, Pens.Red, graphics)); - Assert.True(gp.IsOutlineVisible(10, 2, pen, graphics)); - Assert.False(gp.IsOutlineVisible(10, 2, Pens.Red, graphics)); - - Assert.True(gp.IsOutlineVisible(11.0f, 1.0f, Pens.Red, graphics)); - Assert.True(gp.IsOutlineVisible(11.0f, 1.0f, pen, graphics)); - Assert.False(gp.IsOutlineVisible(11.0f, 2.0f, Pens.Red, graphics)); - - Point point = new Point(12, 2); - Assert.False(gp.IsOutlineVisible(point, Pens.Red, graphics)); - Assert.True(gp.IsOutlineVisible(point, pen, graphics)); - - point.Y = 1; - Assert.True(gp.IsOutlineVisible(point, Pens.Red, graphics)); - - PointF fPoint = new PointF(13.0f, 2.0f); - Assert.False(gp.IsOutlineVisible(fPoint, Pens.Red, graphics)); - Assert.True(gp.IsOutlineVisible(fPoint, pen, graphics)); - - fPoint.Y = 1; - Assert.True(gp.IsOutlineVisible(fPoint, Pens.Red, graphics)); - } - } - - private void AssertIsOutlineVisibleRectangle(Graphics graphics) - { - using (Pen pen = new Pen(Color.Red, 3.0f)) - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddRectangle(new Rectangle(10, 10, 20, 20)); - Assert.True(gp.IsOutlineVisible(10, 10, Pens.Red, graphics)); - Assert.True(gp.IsOutlineVisible(10, 11, pen, graphics)); - Assert.False(gp.IsOutlineVisible(11, 11, Pens.Red, graphics)); - - Assert.True(gp.IsOutlineVisible(11.0f, 10.0f, Pens.Red, graphics)); - Assert.True(gp.IsOutlineVisible(11.0f, 11.0f, pen, graphics)); - Assert.False(gp.IsOutlineVisible(11.0f, 11.0f, Pens.Red, graphics)); - - Point point = new Point(15, 10); - Assert.True(gp.IsOutlineVisible(point, Pens.Red, graphics)); - Assert.True(gp.IsOutlineVisible(point, pen, graphics)); - - point.Y = 15; - Assert.False(gp.IsOutlineVisible(point, Pens.Red, graphics)); - - PointF fPoint = new PointF(29.0f, 29.0f); - Assert.False(gp.IsOutlineVisible(fPoint, Pens.Red, graphics)); - Assert.True(gp.IsOutlineVisible(fPoint, pen, graphics)); - - fPoint.Y = 31.0f; - Assert.True(gp.IsOutlineVisible(fPoint, pen, graphics)); - } - } - - private void AssertIsVisibleRectangle(Graphics graphics) - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddRectangle(new Rectangle(10, 10, 20, 20)); - Assert.False(gp.IsVisible(9, 9, graphics)); - Assert.True(gp.IsVisible(10, 10, graphics)); - Assert.True(gp.IsVisible(20, 20, graphics)); - Assert.True(gp.IsVisible(29, 29, graphics)); - Assert.False(gp.IsVisible(30, 29, graphics)); - Assert.False(gp.IsVisible(29, 30, graphics)); - Assert.False(gp.IsVisible(30, 30, graphics)); - Assert.False(gp.IsVisible(9.4f, 9.4f, graphics)); - Assert.True(gp.IsVisible(9.5f, 9.5f, graphics)); - Assert.True(gp.IsVisible(10f, 10f, graphics)); - Assert.True(gp.IsVisible(20f, 20f, graphics)); - Assert.True(gp.IsVisible(29.4f, 29.4f, graphics)); - Assert.False(gp.IsVisible(29.5f, 29.5f, graphics)); - Assert.False(gp.IsVisible(29.5f, 29.4f, graphics)); - Assert.False(gp.IsVisible(29.4f, 29.5f, graphics)); - } - } - - private void AssertIsVisibleEllipse(Graphics graphics) - { - using (GraphicsPath gp = new GraphicsPath()) - { - gp.AddEllipse(new Rectangle(10, 10, 20, 20)); - Assert.False(gp.IsVisible(10, 10, graphics)); - Assert.True(gp.IsVisible(20, 20, graphics)); - Assert.False(gp.IsVisible(29, 29, graphics)); - Assert.False(gp.IsVisible(10f, 10f, graphics)); - Assert.True(gp.IsVisible(20f, 20f, graphics)); - Assert.False(gp.IsVisible(29.4f, 29.4f, graphics)); - } - } - - private void AssertReverse(GraphicsPath gp, PointF[] expectedPoints, byte[] expectedTypes) - { - gp.Reverse(); - PointF[] reversedPoints = gp.PathPoints; - byte[] reversedTypes = gp.PathTypes; - - int count = gp.PointCount; - Assert.Equal(expectedPoints.Length, gp.PointCount); - Assert.Equal(expectedTypes, gp.PathTypes); - for (int i = 0; i < count; i++) - { - Assert.Equal(expectedPoints[i], reversedPoints[count - i - 1]); - Assert.Equal(expectedTypes[i], reversedTypes[i]); - } - } - - private void AssertPointsSequenceEqual(PointF[] expected, PointF[] actual, float tolerance) - { - int count = expected.Length; - Assert.Equal(expected.Length, actual.Length); - for (int i = 0; i < count; i++) - { - AssertExtensions.LessThanOrEqualTo(Math.Abs(expected[i].X - actual[i].X), tolerance); - AssertExtensions.LessThanOrEqualTo(Math.Abs(expected[i].Y - actual[i].Y), tolerance); - } - } - - private void AssertRectangleEqual(RectangleF expected, RectangleF actual, float tolerance) - { - AssertExtensions.LessThanOrEqualTo(Math.Abs(expected.X - actual.X), tolerance); - AssertExtensions.LessThanOrEqualTo(Math.Abs(expected.Y - actual.Y), tolerance); - AssertExtensions.LessThanOrEqualTo(Math.Abs(expected.Width - actual.Width), tolerance); - AssertExtensions.LessThanOrEqualTo(Math.Abs(expected.Height - actual.Height), tolerance); - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/HatchBrushTests.cs b/src/System.Drawing.Common/tests/Drawing2D/HatchBrushTests.cs deleted file mode 100644 index bee95f4bce3..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/HatchBrushTests.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Drawing2D.Tests; - -public class HatchBrushTests -{ - public static IEnumerable Ctor_HatchStyle_ForeColor_TestData() - { - yield return new object[] { HatchStyle.Horizontal, new Color() }; - yield return new object[] { HatchStyle.SolidDiamond, Color.PapayaWhip }; - } - - [Theory] - [MemberData(nameof(Ctor_HatchStyle_ForeColor_TestData))] - public void Ctor_HatchStyle_ForeColor(HatchStyle hatchStyle, Color foreColor) - { - using (var brush = new HatchBrush(hatchStyle, foreColor)) - { - Assert.Equal(hatchStyle, brush.HatchStyle); - - Assert.NotEqual(foreColor, brush.ForegroundColor); - Assert.Equal(foreColor.ToArgb(), brush.ForegroundColor.ToArgb()); - - Assert.Equal(Color.FromArgb(255, 0, 0, 0), brush.BackgroundColor); - } - } - - public static IEnumerable Ctor_HatchStyle_ForeColor_BackColor_TestData() - { - yield return new object[] { HatchStyle.Horizontal, new Color(), new Color() }; - yield return new object[] { HatchStyle.SolidDiamond, Color.PapayaWhip, Color.Plum }; - } - - [Theory] - [MemberData(nameof(Ctor_HatchStyle_ForeColor_BackColor_TestData))] - public void Ctor_HatchStyle_ForeColor_BackColor(HatchStyle hatchStyle, Color foreColor, Color backColor) - { - using (var brush = new HatchBrush(hatchStyle, foreColor, backColor)) - { - Assert.Equal(hatchStyle, brush.HatchStyle); - - Assert.NotEqual(foreColor, brush.ForegroundColor); - Assert.Equal(foreColor.ToArgb(), brush.ForegroundColor.ToArgb()); - - Assert.NotEqual(backColor, brush.BackgroundColor); - Assert.Equal(backColor.ToArgb(), brush.BackgroundColor.ToArgb()); - } - } - - [Theory] - [InlineData(HatchStyle.Horizontal -1 )] - [InlineData(HatchStyle.SolidDiamond + 1)] - public void Ctor_InvalidHatchStyle_ThrowsArgumentException(HatchStyle hatchStyle) - { - AssertExtensions.Throws("hatchstyle", null, () => new HatchBrush(hatchStyle, Color.Empty)); - AssertExtensions.Throws("hatchstyle", null, () => new HatchBrush(hatchStyle, Color.Empty, Color.Empty)); - } - - [Fact] - public void Clone_Brush_ReturnsClone() - { - using (var brush = new HatchBrush(HatchStyle.DarkDownwardDiagonal, Color.Magenta, Color.Peru)) - { - HatchBrush clone = Assert.IsType(brush.Clone()); - - Assert.NotSame(clone, brush); - Assert.Equal(brush.HatchStyle, clone.HatchStyle); - Assert.Equal(brush.ForegroundColor, clone.ForegroundColor); - Assert.Equal(brush.BackgroundColor, clone.BackgroundColor); - } - } - - [Fact] - public void Clone_ImmutableColor_ReturnsMutableClone() - { - SolidBrush brush = Assert.IsType(Brushes.Bisque); - SolidBrush clone = Assert.IsType(brush.Clone()); - - clone.Color = SystemColors.AppWorkspace; - Assert.Equal(SystemColors.AppWorkspace, clone.Color); - Assert.Equal(Color.Bisque, brush.Color); - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - var brush = new HatchBrush(HatchStyle.DarkHorizontal, Color.PeachPuff, Color.Purple); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Clone()); - } - - [Fact] - public void HatchStyle_EmptyAndGetDisposed_ThrowsArgumentException() - { - var brush = new HatchBrush(HatchStyle.DarkHorizontal, Color.PeachPuff, Color.Purple); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.HatchStyle); - } - - [Fact] - public void ForegroundColor_EmptyAndGetDisposed_ThrowsArgumentException() - { - var brush = new HatchBrush(HatchStyle.DarkHorizontal, Color.PeachPuff, Color.Purple); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.ForegroundColor); - } - - [Fact] - public void BackgroundColor_EmptyAndGetDisposed_ThrowsArgumentException() - { - var brush = new HatchBrush(HatchStyle.DarkHorizontal, Color.PeachPuff, Color.Purple); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.BackgroundColor); - } - - [Fact] - public void Dispose_MultipleTimes_Success() - { - var brush = new HatchBrush(HatchStyle.DarkHorizontal, Color.PeachPuff, Color.Purple); - brush.Dispose(); - brush.Dispose(); - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs b/src/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs deleted file mode 100644 index 3f191433363..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs +++ /dev/null @@ -1,1104 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Drawing2D.Tests; - -public class LinearGradientBrushTests -{ - public static IEnumerable Ctor_Point_TestData() - { - yield return new object[] { new Point(0, 0), new Point(2, 2), Color.Empty, Color.Empty, new RectangleF(0, 0, 2, 2) }; - yield return new object[] { new Point(1, 0), new Point(0, 0), Color.Empty, Color.Red, new RectangleF(0, -0.5f, 1, 1) }; - yield return new object[] { new Point(1, 2), new Point(4, 6), Color.Plum, Color.Red, new RectangleF(1, 2, 3, 4) }; - yield return new object[] { new Point(1, 2), new Point(4, 6), Color.Red, Color.Red, new RectangleF(1, 2, 3, 4) }; - yield return new object[] { new Point(-1, -2), new Point(4, 6), Color.Red, Color.Plum, new RectangleF(-1, -2, 5, 8) }; - yield return new object[] { new Point(-4, -6), new Point(1, 2), Color.Black, Color.Wheat, new RectangleF(-4, -6, 5, 8) }; - yield return new object[] { new Point(4, 6), new Point(-1, -2), Color.Black, Color.Wheat, new RectangleF(-1, -2, 5, 8) }; - yield return new object[] { new Point(4, 6), new Point(1, 2), Color.Black, Color.Wheat, new RectangleF(1, 2, 3, 4) }; - } - - [Theory] - [MemberData(nameof(Ctor_Point_TestData))] - public void Ctor_PointF_PointF_Color_Color(Point point1, Point point2, Color color1, Color color2, RectangleF expectedRectangle) - { - using (var brush = new LinearGradientBrush((PointF)point1, point2, color1, color2)) - { - Assert.Equal(new float[] { 1 }, brush.Blend.Factors); - Assert.Equal(1, brush.Blend.Positions.Length); - - Assert.False(brush.GammaCorrection); - AssertExtensions.Throws(null, () => brush.InterpolationColors); - Assert.Equal(new Color[] { Color.FromArgb(color1.ToArgb()), Color.FromArgb(color2.ToArgb()) }, brush.LinearColors); - Assert.Equal(expectedRectangle, brush.Rectangle); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - - Assert.False(brush.Transform.IsIdentity); - } - } - - [Fact] - public void Ctor_PointF_PointF_Color_Color_FloatRanges() - { - using (var brush = new LinearGradientBrush(new PointF(float.NaN, float.NaN), new PointF(float.PositiveInfinity, float.NegativeInfinity), Color.Plum, Color.Red)) - { - Assert.Equal(float.PositiveInfinity, brush.Rectangle.X); - Assert.Equal(float.NegativeInfinity, brush.Rectangle.Y); - Assert.Equal(float.NaN, brush.Rectangle.Width); - Assert.Equal(float.NaN, brush.Rectangle.Height); - } - } - - [Theory] - [MemberData(nameof(Ctor_Point_TestData))] - public void Ctor_Point_Point_Color_Color(Point point1, Point point2, Color color1, Color color2, RectangleF expectedRectangle) - { - using (var brush = new LinearGradientBrush(point1, point2, color1, color2)) - { - Assert.Equal(new float[] { 1 }, brush.Blend.Factors); - Assert.Equal(1, brush.Blend.Positions.Length); - - Assert.False(brush.GammaCorrection); - AssertExtensions.Throws(null, () => brush.InterpolationColors); - Assert.Equal(new Color[] { Color.FromArgb(color1.ToArgb()), Color.FromArgb(color2.ToArgb()) }, brush.LinearColors); - Assert.Equal(expectedRectangle, brush.Rectangle); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - - Assert.False(brush.Transform.IsIdentity); - } - } - - [Theory] - [InlineData(0, 0)] - [InlineData(1, 1)] - public void Ctor_EqualPoints_ThrowsOutOfMemoryException(int x, int y) - { - Assert.Throws(() => new LinearGradientBrush(new Point(x, y), new Point(x, y), Color.Fuchsia, Color.GhostWhite)); - Assert.Throws(() => new LinearGradientBrush(new PointF(x, y), new PointF(x, y), Color.Fuchsia, Color.GhostWhite)); - } - - public static IEnumerable Ctor_Rectangle_LinearGradientMode_TestData() - { - yield return new object[] { new Rectangle(0, 0, 1, 2), Color.Empty, Color.Red, LinearGradientMode.BackwardDiagonal }; - yield return new object[] { new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, LinearGradientMode.ForwardDiagonal }; - yield return new object[] { new Rectangle(-1, -2, -3, -4), Color.Red, Color.Red, LinearGradientMode.Horizontal }; - yield return new object[] { new Rectangle(1, 2, 3, 4), Color.Red, Color.Plum, LinearGradientMode.Vertical }; - } - - [Theory] - [MemberData(nameof(Ctor_Rectangle_LinearGradientMode_TestData))] - public void Ctor_Rectangle_Color_Color_LinearGradientMode(Rectangle rectangle, Color color1, Color color2, LinearGradientMode linearGradientMode) - { - using (var brush = new LinearGradientBrush(rectangle, color1, color2, linearGradientMode)) - { - Assert.Equal(new float[] { 1 }, brush.Blend.Factors); - Assert.Equal(1, brush.Blend.Positions.Length); - - Assert.False(brush.GammaCorrection); - AssertExtensions.Throws(null, () => brush.InterpolationColors); - Assert.Equal(new Color[] { Color.FromArgb(color1.ToArgb()), Color.FromArgb(color2.ToArgb()) }, brush.LinearColors); - Assert.Equal(rectangle, brush.Rectangle); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - - Assert.Equal(linearGradientMode == LinearGradientMode.Horizontal, brush.Transform.IsIdentity); - } - } - - [Theory] - [MemberData(nameof(Ctor_Rectangle_LinearGradientMode_TestData))] - public void Ctor_RectangleF_Color_Color_LinearGradientMode(Rectangle rectangle, Color color1, Color color2, LinearGradientMode linearGradientMode) - { - using (var brush = new LinearGradientBrush((RectangleF)rectangle, color1, color2, linearGradientMode)) - { - Assert.Equal(new float[] { 1 }, brush.Blend.Factors); - Assert.Equal(1, brush.Blend.Positions.Length); - - Assert.False(brush.GammaCorrection); - AssertExtensions.Throws(null, () => brush.InterpolationColors); - Assert.Equal(new Color[] { Color.FromArgb(color1.ToArgb()), Color.FromArgb(color2.ToArgb()) }, brush.LinearColors); - Assert.Equal(rectangle, brush.Rectangle); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - - Assert.Equal(linearGradientMode == LinearGradientMode.Horizontal, brush.Transform.IsIdentity); - } - } - - public static IEnumerable Ctor_Rectangle_Angle_TestData() - { - yield return new object[] { new Rectangle(0, 0, 1, 2), Color.Empty, Color.Red, 90 }; - yield return new object[] { new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 180 }; - yield return new object[] { new Rectangle(-1, -2, -3, -4), Color.Red, Color.Red, 0 }; - yield return new object[] { new Rectangle(-1, -2, -3, -4), Color.Red, Color.Red, 360 }; - yield return new object[] { new Rectangle(1, 2, 3, 4), Color.Red, Color.Plum, 90 }; - } - - [Theory] - [MemberData(nameof(Ctor_Rectangle_Angle_TestData))] - public void Ctor_Rectangle_Color_Color_Angle(Rectangle rectangle, Color color1, Color color2, float angle) - { - using (var brush = new LinearGradientBrush(rectangle, color1, color2, angle)) - { - Assert.Equal(new float[] { 1 }, brush.Blend.Factors); - Assert.Equal(1, brush.Blend.Positions.Length); - - Assert.False(brush.GammaCorrection); - AssertExtensions.Throws(null, () => brush.InterpolationColors); - Assert.Equal(new Color[] { Color.FromArgb(color1.ToArgb()), Color.FromArgb(color2.ToArgb()) }, brush.LinearColors); - Assert.Equal(rectangle, brush.Rectangle); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - - Assert.Equal((angle % 360) == 0, brush.Transform.IsIdentity); - } - } - - [Theory] - [MemberData(nameof(Ctor_Rectangle_Angle_TestData))] - public void Ctor_RectangleF_Color_Color_Angle(Rectangle rectangle, Color color1, Color color2, float angle) - { - using (var brush = new LinearGradientBrush((RectangleF)rectangle, color1, color2, angle)) - { - Assert.Equal(new float[] { 1 }, brush.Blend.Factors); - Assert.Equal(1, brush.Blend.Positions.Length); - - Assert.False(brush.GammaCorrection); - AssertExtensions.Throws(null, () => brush.InterpolationColors); - Assert.Equal(new Color[] { Color.FromArgb(color1.ToArgb()), Color.FromArgb(color2.ToArgb()) }, brush.LinearColors); - Assert.Equal(rectangle, brush.Rectangle); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - - Assert.Equal((angle % 360) == 0, brush.Transform.IsIdentity); - } - } - - public static IEnumerable Ctor_Rectangle_Angle_IsAngleScalable_TestData() - { - foreach (object[] testData in Ctor_Rectangle_Angle_TestData()) - { - yield return new object[] { testData[0], testData[1], testData[2], testData[3], true }; - yield return new object[] { testData[0], testData[1], testData[2], testData[3], false }; - } - } - [Theory] - [MemberData(nameof(Ctor_Rectangle_Angle_IsAngleScalable_TestData))] - public void Ctor_Rectangle_Color_Color_Angle_IsAngleScalable(Rectangle rectangle, Color color1, Color color2, float angle, bool isAngleScalable) - { - using (var brush = new LinearGradientBrush(rectangle, color1, color2, angle, isAngleScalable)) - { - Assert.Equal(new float[] { 1 }, brush.Blend.Factors); - Assert.Equal(1, brush.Blend.Positions.Length); - - Assert.False(brush.GammaCorrection); - AssertExtensions.Throws(null, () => brush.InterpolationColors); - Assert.Equal(new Color[] { Color.FromArgb(color1.ToArgb()), Color.FromArgb(color2.ToArgb()) }, brush.LinearColors); - Assert.Equal(rectangle, brush.Rectangle); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - - Assert.Equal((angle % 360) == 0, brush.Transform.IsIdentity); - } - } - - [Theory] - [MemberData(nameof(Ctor_Rectangle_Angle_IsAngleScalable_TestData))] - public void Ctor_RectangleF_Color_Color_Angle_IsAngleScalable(Rectangle rectangle, Color color1, Color color2, float angle, bool isAngleScalable) - { - using (var brush = new LinearGradientBrush((RectangleF)rectangle, color1, color2, angle, isAngleScalable)) - { - Assert.Equal(new float[] { 1 }, brush.Blend.Factors); - Assert.Equal(1, brush.Blend.Positions.Length); - - Assert.False(brush.GammaCorrection); - AssertExtensions.Throws(null, () => brush.InterpolationColors); - Assert.Equal(new Color[] { Color.FromArgb(color1.ToArgb()), Color.FromArgb(color2.ToArgb()) }, brush.LinearColors); - Assert.Equal(rectangle, brush.Rectangle); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - - Assert.Equal((angle % 360) == 0, brush.Transform.IsIdentity); - } - } - - [Fact] - public void Ctor_ZeroWidth_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new LinearGradientBrush(new Rectangle(1, 2, 0, 4), Color.Empty, Color.Empty, 0f)); - AssertExtensions.Throws(null, () => new LinearGradientBrush(new RectangleF(1, 2, 0, 4), Color.Empty, Color.Empty, 0f)); - AssertExtensions.Throws(null, () => new LinearGradientBrush(new Rectangle(1, 2, 0, 4), Color.Empty, Color.Empty, LinearGradientMode.BackwardDiagonal)); - AssertExtensions.Throws(null, () => new LinearGradientBrush(new RectangleF(1, 2, 0, 4), Color.Empty, Color.Empty, LinearGradientMode.BackwardDiagonal)); - AssertExtensions.Throws(null, () => new LinearGradientBrush(new Rectangle(1, 2, 0, 4), Color.Empty, Color.Empty, 0, true)); - AssertExtensions.Throws(null, () => new LinearGradientBrush(new RectangleF(1, 2, 0, 4), Color.Empty, Color.Empty, 0, true)); - } - - [Fact] - public void Ctor_ZeroHeight_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new LinearGradientBrush(new Rectangle(1, 2, 3, 0), Color.Empty, Color.Empty, 0f)); - AssertExtensions.Throws(null, () => new LinearGradientBrush(new RectangleF(1, 2, 3, 0), Color.Empty, Color.Empty, 0f)); - AssertExtensions.Throws(null, () => new LinearGradientBrush(new Rectangle(1, 2, 3, 0), Color.Empty, Color.Empty, LinearGradientMode.BackwardDiagonal)); - AssertExtensions.Throws(null, () => new LinearGradientBrush(new RectangleF(1, 2, 3, 0), Color.Empty, Color.Empty, LinearGradientMode.BackwardDiagonal)); - AssertExtensions.Throws(null, () => new LinearGradientBrush(new Rectangle(1, 2, 3, 0), Color.Empty, Color.Empty, 0, true)); - AssertExtensions.Throws(null, () => new LinearGradientBrush(new RectangleF(1, 2, 3, 0), Color.Empty, Color.Empty, 0, true)); - } - - [Theory] - [InlineData(LinearGradientMode.Horizontal - 1)] - [InlineData(LinearGradientMode.BackwardDiagonal + 1)] - public void Ctor_InvalidLinearGradientMode_ThrowsEnumArgumentException(LinearGradientMode linearGradientMode) - { - Assert.ThrowsAny(() => new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Empty, Color.Empty, linearGradientMode)); - Assert.ThrowsAny(() => new LinearGradientBrush(new RectangleF(1, 2, 3, 4), Color.Empty, Color.Empty, linearGradientMode)); - } - - [Fact] - public void Clone_Brush_ReturnsClone() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - LinearGradientBrush clone = Assert.IsType(brush.Clone()); - - Assert.NotSame(clone, brush); - Assert.Equal(brush.Blend.Factors, clone.Blend.Factors); - Assert.Equal(brush.Blend.Positions.Length, clone.Blend.Positions.Length); - Assert.Equal(brush.LinearColors, clone.LinearColors); - Assert.Equal(brush.Rectangle, clone.Rectangle); - Assert.Equal(brush.Transform, clone.Transform); - } - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Clone()); - } - - [Fact] - public void Blend_GetWithInterpolationColorsSet_ReturnsNull() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - var blend = new ColorBlend - { - Colors = new Color[] { Color.Red, Color.PeachPuff, Color.PowderBlue }, - Positions = new float[] { 0, 10, 1 } - }; - - brush.InterpolationColors = blend; - Assert.Null(brush.Blend); - } - } - - [Theory] - [InlineData(new float[] { 1 }, new float[] { 1 })] - [InlineData(new float[] { 0 }, new float[] { 0 })] - [InlineData(new float[] { float.MaxValue }, new float[] { float.MaxValue })] - [InlineData(new float[] { float.MinValue }, new float[] { float.MinValue })] - [InlineData(new float[] { 0.5f, 0.5f }, new float[] { 0, 1 })] - [InlineData(new float[] { 0.4f, 0.3f, 0.2f }, new float[] { 0, 0.5f, 1 })] - [InlineData(new float[] { -1 }, new float[] { -1 })] - [InlineData(new float[] { float.NaN }, new float[] { float.NaN })] - [InlineData(new float[] { 1 }, new float[] { 1, 2 })] - public void Blend_Set_Success(float[] factors, float[] positions) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - var blend = new Blend - { - Factors = factors, - Positions = positions - }; - brush.Blend = blend; - - Assert.Equal(blend.Factors, brush.Blend.Factors); - Assert.Equal(factors.Length, brush.Blend.Positions.Length); - } - } - - [Theory] - [InlineData(new float[] { 1, 2 }, new float[] { 1, 2 })] - [InlineData(new float[] { 1, 2 }, new float[] { 1, 1 })] - [InlineData(new float[] { 1, 2 }, new float[] { 1, 0 })] - [InlineData(new float[] { 0, 0, 0 }, new float[] { 0, 0, 0 })] - public void Blend_InvalidBlend_ThrowsArgumentException(float[] factors, float[] positions) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - var blend = new Blend - { - Factors = factors, - Positions = positions - }; - AssertExtensions.Throws(null, () => brush.Blend = blend); - } - } - - [Fact] - public void Blend_SetNullBlend_ThrowsNullReferenceException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Assert.Throws(() => brush.Blend = null); - } - } - - [Fact] - public void Blend_SetNullBlendFactors_ThrowsNullReferenceException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Assert.Throws(() => brush.Blend = new Blend { Factors = null }); - } - } - - [Fact] - public void Blend_SetNullBlendPositions_ThrowsArgumentException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws("value", "source", () => brush.Blend = new Blend { Factors = new float[2], Positions = null }); - } - } - - [Fact] - public void Blend_SetFactorsLengthGreaterThanPositionsLength_ThrowsArgumentOutOfRangeException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws("value", null, () => brush.Blend = new Blend { Factors = new float[2], Positions = new float[1] }); - } - } - - [Fact] - public void Blend_SetInvalidBlendFactorsLength_ThrowsArgumentException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws(null, () => brush.Blend = new Blend { Factors = new float[0], Positions = new float[0] }); - } - } - - [Fact] - public void Blend_GetSetDisposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Blend); - AssertExtensions.Throws(null, () => brush.Blend = new Blend()); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GammaCorrection_Set_GetReturnsExpected(bool gammaCorrection) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true) { GammaCorrection = gammaCorrection }) - { - Assert.Equal(gammaCorrection, brush.GammaCorrection); - } - } - - [Fact] - public void GammaCorrection_GetSetDisposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.GammaCorrection); - AssertExtensions.Throws(null, () => brush.GammaCorrection = true); - } - - [Fact] - public void InterpolationColors_SetValid_GetReturnsExpected() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - var blend = new ColorBlend - { - Colors = new Color[] { Color.Red, Color.PeachPuff, Color.PowderBlue }, - Positions = new float[] { 0, 10, 1 } - }; - - brush.InterpolationColors = blend; - Assert.Equal(blend.Colors.Select(c => Color.FromArgb(c.ToArgb())), brush.InterpolationColors.Colors); - Assert.Equal(blend.Positions, brush.InterpolationColors.Positions); - } - } - - [Fact] - public void InterpolationColors_SetWithExistingInterpolationColors_OverwritesInterpolationColors() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true) - { - InterpolationColors = new ColorBlend - { - Colors = new Color[] { Color.Wheat, Color.Yellow }, - Positions = new float[] { 0, 1 } - } - }) - { - var blend = new ColorBlend - { - Colors = new Color[] { Color.Red, Color.PeachPuff, Color.PowderBlue }, - Positions = new float[] { 0, 0.5f, 1f } - }; - brush.InterpolationColors = blend; - Assert.Equal(blend.Colors.Select(c => Color.FromArgb(c.ToArgb())), brush.InterpolationColors.Colors); - Assert.Equal(blend.Positions, brush.InterpolationColors.Positions); - } - } - - [Fact] - public void InterpolationColors_SetNullBlend_ThrowsArgumentException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws(null, () => brush.InterpolationColors = null); - } - } - - [Fact] - public void InterpolationColors_SetBlendWithNullColors_ThrowsNullReferenceException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Assert.Throws(() => brush.InterpolationColors = new ColorBlend { Colors = null }); - } - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - public void InterpolationColors_SetBlendWithTooFewColors_ThrowsArgumentException(int colorsLength) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws(null, () => brush.InterpolationColors = new ColorBlend { Colors = new Color[colorsLength] }); - } - } - - [Fact] - public void InterpolationColors_SetNullBlendPositions_ThrowsNullReferenceException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Assert.Throws(() => brush.InterpolationColors = new ColorBlend { Colors = new Color[2], Positions = null }); - } - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(3)] - public void InterpolationColors_SetInvalidBlendPositionsLength_ThrowsArgumentException(int positionsLength) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws(null, () => brush.InterpolationColors = new ColorBlend - { - Colors = new Color[2], - Positions = new float[positionsLength] - }); - } - } - - [Theory] - [InlineData(new float[] { 1, 0, 1 })] - [InlineData(new float[] { 0, 0, 0 })] - public void InterpolationColors_InvalidPositions_ThrowsArgumentException(float[] positions) - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - AssertExtensions.Throws(null, () => brush.InterpolationColors = new ColorBlend - { - Colors = new Color[positions.Length], - Positions = positions - }); - } - - [Fact] - public void InterpolationColors_GetSetDisposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true) - { - InterpolationColors = new ColorBlend - { - Colors = new Color[] { Color.Red, Color.PeachPuff, Color.PowderBlue }, - Positions = new float[] { 0, 0.5f, 1 } - } - }; - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.InterpolationColors); - AssertExtensions.Throws(null, () => brush.InterpolationColors = new ColorBlend - { - Colors = new Color[2], - Positions = new float[] { 0f, 1f } - }); - } - - [Fact] - public void InterpolationColors_SetBlendTriangularShape_ThrowsArgumentException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true) - { - InterpolationColors = new ColorBlend - { - Colors = new Color[] { Color.Red, Color.PeachPuff, Color.PowderBlue }, - Positions = new float[] { 0, 0.5f, 1 } - } - }) - { - Assert.NotNull(brush.InterpolationColors); - - brush.SetBlendTriangularShape(0.5f); - AssertExtensions.Throws(null, () => brush.InterpolationColors); - } - } - - [Fact] - public void InterpolationColors_SetBlend_ThrowsArgumentException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true) - { - InterpolationColors = new ColorBlend - { - Colors = new Color[] { Color.Red, Color.PeachPuff, Color.PowderBlue }, - Positions = new float[] { 0, 0.5f, 1 } - } - }) - { - Assert.NotNull(brush.InterpolationColors); - - brush.Blend = new Blend - { - Factors = new float[1], - Positions = new float[1] - }; - AssertExtensions.Throws(null, () => brush.InterpolationColors); - } - } - - [Fact] - public void LinearColors_SetValid_GetReturnsExpected() - { - Color[] colors = new Color[] { Color.Red, Color.Blue, Color.AntiqueWhite }; - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true) { LinearColors = colors }) - { - Assert.Equal(colors.Take(2).Select(c => Color.FromArgb(c.ToArgb())), brush.LinearColors); - } - } - - [Fact] - public void LinearColors_SetNull_ThrowsNullReferenceException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Assert.Throws(() => brush.LinearColors = null); - } - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - public void LinearColors_SetInvalidLength_ThrowsIndexOutOfRangeException(int length) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Assert.Throws(() => brush.LinearColors = new Color[length]); - } - } - - [Fact] - public void LinearColors_GetSetDisposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.LinearColors); - AssertExtensions.Throws(null, () => brush.LinearColors = new Color[] { Color.Red, Color.Wheat }); - } - - [Fact] - public void Rectangle_GetDisposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Rectangle); - } - - [Fact] - public void Transform_SetValid_GetReturnsExpected() - { - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true) { Transform = transform }) - { - Assert.Equal(transform, brush.Transform); - } - } - - [Fact] - public void Transform_SetNull_ThrowsArgumentNullException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws("value", "matrix", () => brush.Transform = null); - } - } - - [Fact] - public void Transform_GetSetDisposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Transform); - AssertExtensions.Throws(null, () => brush.Transform = new Matrix()); - } - - [Theory] - [InlineData(WrapMode.Tile)] - [InlineData(WrapMode.TileFlipX)] - [InlineData(WrapMode.TileFlipXY)] - [InlineData(WrapMode.TileFlipY)] - public void WrapMode_SetValid_GetReturnsExpected(WrapMode wrapMode) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true) { WrapMode = wrapMode }) - { - Assert.Equal(wrapMode, brush.WrapMode); - } - } - - [Theory] - [InlineData(WrapMode.Tile - 1)] - [InlineData(WrapMode.Clamp + 1)] - public void WrapMode_SetInvalid_ThrowsInvalidEnumArgumentException(WrapMode wrapMode) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Assert.ThrowsAny(() => brush.WrapMode = wrapMode); - } - } - - [Fact] - public void WrapMode_Clamp_ThrowsArgumentException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws(null, () => brush.WrapMode = WrapMode.Clamp); - } - } - - [Fact] - public void WrapMode_GetSetDisposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.WrapMode); - AssertExtensions.Throws(null, () => brush.WrapMode = WrapMode.TileFlipX); - } - - [Fact] - public void ResetTransform_Invoke_SetsTransformToIdentity() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Assert.False(brush.Transform.IsIdentity); - - brush.ResetTransform(); - Assert.True(brush.Transform.IsIdentity); - } - } - - [Fact] - public void ResetTransform_Disposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.ResetTransform()); - } - - [Fact] - public void MultiplyTransform_NoOrder_Success() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - using (var matrix = new Matrix(1, 2, 3, 4, 5, 6)) - { - Matrix expectedTransform = brush.Transform; - expectedTransform.Multiply(matrix); - - brush.MultiplyTransform(matrix); - Assert.Equal(expectedTransform, brush.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend)] - [InlineData(MatrixOrder.Append)] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void MultiplyTransform_Order_Success(MatrixOrder order) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - using (var matrix = new Matrix(1, 2, 3, 4, 5, 6)) - { - Matrix expectedTransform = brush.Transform; - - if (order == MatrixOrder.Append || order == MatrixOrder.Prepend) - { - expectedTransform.Multiply(matrix, order); - } - else - { - // Invalid MatrixOrder is interpreted as MatrixOrder.Append. - expectedTransform.Multiply(matrix, MatrixOrder.Append); - } - - brush.MultiplyTransform(matrix, order); - Assert.Equal(expectedTransform, brush.Transform); - } - } - - [Fact] - public void MultiplyTransform_NullMatrix_ThrowsArgumentNullException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws("matrix", () => brush.MultiplyTransform(null)); - AssertExtensions.Throws("matrix", () => brush.MultiplyTransform(null, MatrixOrder.Append)); - } - } - - [Fact] - public void MultiplyTransform_DisposedMatrix_Nop() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - using (Matrix transform = brush.Transform) - { - var matrix = new Matrix(); - matrix.Dispose(); - - brush.MultiplyTransform(matrix); - brush.MultiplyTransform(matrix, MatrixOrder.Append); - - Assert.Equal(transform, brush.Transform); - } - } - - [Fact] - public void MultiplyTransform_NonInvertibleMatrix_ThrowsArgumentException() - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - using (var matrix = new Matrix(123, 24, 82, 16, 47, 30)) - { - AssertExtensions.Throws(null, () => brush.MultiplyTransform(matrix)); - AssertExtensions.Throws(null, () => brush.MultiplyTransform(matrix, MatrixOrder.Append)); - } - } - - [Fact] - public void MultiplyTransform_Disposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.MultiplyTransform(new Matrix())); - AssertExtensions.Throws(null, () => brush.MultiplyTransform(new Matrix(), MatrixOrder.Prepend)); - } - - [Theory] - [InlineData(-1, -2)] - [InlineData(0, 0)] - [InlineData(1, 2)] - public void TranslateTransform_NoOrder_Success(float dx, float dy) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Matrix expectedTransform = brush.Transform; - expectedTransform.Translate(dx, dy); - - brush.TranslateTransform(dx, dy); - Assert.Equal(expectedTransform, brush.Transform); - } - } - - [Theory] - [InlineData(1, 1, MatrixOrder.Prepend)] - [InlineData(1, 1, MatrixOrder.Append)] - [InlineData(0, 0, MatrixOrder.Prepend)] - [InlineData(0, 0, MatrixOrder.Append)] - [InlineData(-1, -1, MatrixOrder.Prepend)] - [InlineData(-1, -1, MatrixOrder.Append)] - public void TranslateTransform_Order_Success(float dx, float dy, MatrixOrder order) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Matrix expectedTransform = brush.Transform; - expectedTransform.Translate(dx, dy, order); - - brush.TranslateTransform(dx, dy, order); - Assert.Equal(expectedTransform, brush.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void TranslateTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws(null, () => brush.TranslateTransform(0, 0, order)); - } - } - - [Fact] - public void TranslateTransform_Disposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.TranslateTransform(0, 0)); - AssertExtensions.Throws(null, () => brush.TranslateTransform(0, 0, MatrixOrder.Append)); - } - - [Theory] - [InlineData(-1, -2)] - [InlineData(0, 0)] - [InlineData(1, 2)] - public void ScaleTransform_NoOrder_Success(float sx, float sy) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Matrix expectedTransform = brush.Transform; - expectedTransform.Scale(sx, sy); - - brush.ScaleTransform(sx, sy); - Assert.Equal(expectedTransform, brush.Transform); - } - } - - [Theory] - [InlineData(1, 1, MatrixOrder.Prepend)] - [InlineData(1, 1, MatrixOrder.Append)] - [InlineData(0, 0, MatrixOrder.Prepend)] - [InlineData(0, 0, MatrixOrder.Append)] - [InlineData(-1, -1, MatrixOrder.Prepend)] - [InlineData(-1, -1, MatrixOrder.Append)] - public void ScaleTransform_Order_Success(float sx, float sy, MatrixOrder order) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Matrix expectedTransform = brush.Transform; - expectedTransform.Scale(sx, sy, order); - - brush.ScaleTransform(sx, sy, order); - Assert.Equal(expectedTransform, brush.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void ScaleTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws(null, () => brush.ScaleTransform(0, 0, order)); - } - } - - [Fact] - public void ScaleTransform_Disposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.ScaleTransform(0, 0)); - AssertExtensions.Throws(null, () => brush.ScaleTransform(0, 0, MatrixOrder.Append)); - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(1)] - [InlineData(360)] - public void RotateTransform_NoOrder_Success(float angle) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Matrix expectedTransform = brush.Transform; - expectedTransform.Rotate(angle); - - brush.RotateTransform(angle); - Assert.Equal(expectedTransform, brush.Transform); - } - } - - [Theory] - [InlineData(1, MatrixOrder.Prepend)] - [InlineData(1, MatrixOrder.Append)] - [InlineData(0, MatrixOrder.Prepend)] - [InlineData(360, MatrixOrder.Append)] - [InlineData(-1, MatrixOrder.Prepend)] - [InlineData(-1, MatrixOrder.Append)] - public void RotateTransform_Order_Success(float angle, MatrixOrder order) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - Matrix expectedTransform = brush.Transform; - expectedTransform.Rotate(angle, order); - - brush.RotateTransform(angle, order); - Assert.Equal(expectedTransform, brush.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void RotateTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws(null, () => brush.RotateTransform(0, order)); - } - } - - [Fact] - public void RotateTransform_Disposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.RotateTransform(0)); - AssertExtensions.Throws(null, () => brush.RotateTransform(0, MatrixOrder.Append)); - } - - [Theory] - [InlineData(0)] - [InlineData(0.5)] - [InlineData(1)] - [InlineData(float.NaN)] - public void SetSigmalBellShape(float focus) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - brush.SetSigmaBellShape(focus); - } - } - - [Theory] - [InlineData(-0.1)] - [InlineData(1.1)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NegativeInfinity)] - public void SetSigmalBellShape_InvalidFocus_ThrowsArgumentException(float focus) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws("focus", null, () => brush.SetSigmaBellShape(focus)); - AssertExtensions.Throws("focus", null, () => brush.SetSigmaBellShape(focus, 1)); - } - } - - [Theory] - [InlineData(-0.1)] - [InlineData(1.1)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NegativeInfinity)] - public void SetSigmalBellShape_InvalidScale_ThrowsArgumentException(float scale) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws("scale", null, () => brush.SetSigmaBellShape(0.1f, scale)); - } - } - - [Fact] - public void SetSigmalBellShape_Disposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.SetSigmaBellShape(0)); - AssertExtensions.Throws(null, () => brush.SetSigmaBellShape(0, 1)); - } - - [Theory] - [InlineData(0, new float[] { 1, 0 }, new float[] { 0, 1 })] - [InlineData(0.5, new float[] { 0, 1, 0 }, new float[] { 0, 0.5f, 1 })] - [InlineData(1, new float[] { 0, 1 }, new float[] { 0, 1 })] - public void SetBlendTriangularShape_Success(float focus, float[] expectedFactors, float[] expectedPositions) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 0, true)) - { - brush.SetBlendTriangularShape(focus); - - Assert.Equal(expectedFactors, brush.Blend.Factors); - Assert.Equal(expectedPositions, brush.Blend.Positions); - } - } - - [Theory] - [InlineData(0, 1, new float[] { 1, 0 }, new float[] { 0, 1 })] - [InlineData(0.5, 0, new float[] { 0, 0, 0 }, new float[] { 0, 0.5f, 1 })] - [InlineData(0.5, 1, new float[] { 0, 1, 0 }, new float[] { 0, 0.5f, 1 })] - [InlineData(1, 0.5, new float[] { 0, 0.5f }, new float[] { 0, 1 })] - public void SetBlendTriangularShape_Scale_Success(float focus, float scale, float[] expectedFactors, float[] expectedPositions) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 0, true)) - { - brush.SetBlendTriangularShape(focus, scale); - - Assert.Equal(expectedFactors, brush.Blend.Factors); - Assert.Equal(expectedPositions, brush.Blend.Positions); - } - } - - [Theory] - [InlineData(-0.1)] - [InlineData(1.1)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NegativeInfinity)] - public void SetBlendTriangularShape_InvalidFocus_ThrowsArgumentException(float focus) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws("focus", null, () => brush.SetBlendTriangularShape(focus)); - AssertExtensions.Throws("focus", null, () => brush.SetBlendTriangularShape(focus, 1)); - } - } - - [Theory] - [InlineData(-0.1)] - [InlineData(1.1)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NegativeInfinity)] - public void SetBlendTriangularShape_InvalidScale_ThrowsArgumentException(float scale) - { - using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) - { - AssertExtensions.Throws("scale", null, () => brush.SetBlendTriangularShape(0.1f, scale)); - } - } - - [Fact] - public void SetBlendTriangularShape_Disposed_ThrowsArgumentException() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.SetBlendTriangularShape(0)); - AssertExtensions.Throws(null, () => brush.SetBlendTriangularShape(0, 1)); - } - - [Fact] - public void Dispose_MultipleTimes_Success() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - brush.Dispose(); - brush.Dispose(); - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/MatrixTests.Core.cs b/src/System.Drawing.Common/tests/Drawing2D/MatrixTests.Core.cs deleted file mode 100644 index b7c6a8186a9..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/MatrixTests.Core.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Numerics; - -namespace System.Drawing.Drawing2D.Tests; - -public partial class MatrixTests -{ - [Theory] - [MemberData(nameof(MatrixElements_TestData))] - public void Ctor_Matrix3x2(float m11, float m12, float m21, float m22, float dx, float dy, bool isIdentity, bool isInvertible) - { - Matrix3x2 matrix3X2 = new Matrix3x2(m11, m12, m21, m22, dx, dy); - using (var matrix = new Matrix(matrix3X2)) - { - Assert.Equal(new float[] { m11, m12, m21, m22, dx, dy }, matrix.Elements); - Assert.Equal(matrix3X2, matrix.MatrixElements); - Assert.Equal(isIdentity, matrix.IsIdentity); - Assert.Equal(isInvertible, matrix.IsInvertible); - Assert.Equal(dx, matrix.OffsetX); - Assert.Equal(dy, matrix.OffsetY); - } - } - - [Theory] - [MemberData(nameof(MatrixElements_TestData))] - public void MatrixElements_RoundTrip(float m11, float m12, float m21, float m22, float dx, float dy, bool isIdentity, bool isInvertible) - { - Matrix3x2 matrix3X2 = new Matrix3x2(m11, m12, m21, m22, dx, dy); - using (var matrix = new Matrix()) - { - matrix.MatrixElements = matrix3X2; - Assert.Equal(new float[] { m11, m12, m21, m22, dx, dy }, matrix.Elements); - Assert.Equal(matrix3X2, matrix.MatrixElements); - Assert.Equal(isIdentity, matrix.IsIdentity); - Assert.Equal(isInvertible, matrix.IsInvertible); - Assert.Equal(dx, matrix.OffsetX); - Assert.Equal(dy, matrix.OffsetY); - } - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/MatrixTests.cs b/src/System.Drawing.Common/tests/Drawing2D/MatrixTests.cs deleted file mode 100644 index e302b52623c..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/MatrixTests.cs +++ /dev/null @@ -1,896 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2005-2006 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.XUnit; - -namespace System.Drawing.Drawing2D.Tests; - -public partial class MatrixTests -{ - private static Matrix CreateDisposedMatrix() - { - var matrix = new Matrix(); - matrix.Dispose(); - return matrix; - } - - [Fact] - public void Ctor_Default() - { - using (var matrix = new Matrix()) - { - Assert.Equal(new float[] { 1, 0, 0, 1, 0, 0 }, matrix.Elements); - Assert.True(matrix.IsIdentity); - Assert.True(matrix.IsInvertible); - Assert.Equal(0, matrix.OffsetX); - Assert.Equal(0, matrix.OffsetY); - } - } - - [Theory] - [InlineData(float.NaN)] - [InlineData(float.NegativeInfinity)] - [InlineData(float.PositiveInfinity)] - public void Ctor_FloatingPointBoundsInElements(float f) - { - Ctor_Elements(f, 0, 0, 1, 0, 0, false, false); - Ctor_Elements(1, f, 0, 1, 0, 0, false, false); - Ctor_Elements(1, 0, f, 1, 0, 0, false, false); - Ctor_Elements(1, 0, 0, f, 0, 0, false, false); - Ctor_Elements(1, 0, 0, 1, f, 0, false, false); - Ctor_Elements(1, 0, 0, 1, 0, f, false, false); - } - - [Theory] - [MemberData(nameof(MatrixElements_TestData))] - public void Ctor_Elements(float m11, float m12, float m21, float m22, float dx, float dy, bool isIdentity, bool isInvertible) - { - using (var matrix = new Matrix(m11, m12, m21, m22, dx, dy)) - { - Assert.Equal(new float[] { m11, m12, m21, m22, dx, dy }, matrix.Elements); - Assert.Equal(isIdentity, matrix.IsIdentity); - Assert.Equal(isInvertible, matrix.IsInvertible); - Assert.Equal(dx, matrix.OffsetX); - Assert.Equal(dy, matrix.OffsetY); - } - } - - public static TheoryData MatrixElements_TestData - => new() - { - { 1, 0, 0, 1, 0, 0, true, true }, - { 0, 1, 2, 1, 3, 4, false, true }, - { 0, 0, 0, 0, 0, 0, false, false }, - { 1, 2, 3, 4, 5, 6, false, true }, - { -1, -2, -3, -4, -5, -6, false, true }, - { 123, 24, 82, 16, 47, 30, false, false }, - { 156, 46, 0, 0, 106, 19, false, false }, - { 146, 66, 158, 104, 42, 150, false, true }, - { 119, 140, 145, 74, 102, 58, false, true }, - { 1.1f, 0.1f, -0.1f, 0.9f, 0, 0, false, true }, - { 1.01f, 0.01f, -0.01f, 0.99f, 0, 0, false, true }, - { 1.001f, 0.001f, -0.001f, 0.999f, 0, 0, false, true }, - { 1.0001f, 0.0001f, -0.0001f, 0.9999f, 0, 0, true, true }, - { 1.0009f, 0.0009f, -0.0009f, 0.99995f, 0, 0, false, true } - }; - - public static IEnumerable Ctor_Rectangle_Points_TestData() - { - yield return new object[] { new Rectangle(1, 4, 8, 16), new Point[] { new Point(32, 64), new Point(128, 256), new Point(512, 1024) }, new float[] { 12, 24, 30, 60, -100, -200 }, false, false }; - yield return new object[] { new Rectangle(0, 0, 2, 4), new Point[] { new Point(8, 16), new Point(32, 64), new Point(128, 256) }, new float[] { 12, 24, 30, 60, 8, 16 }, false, false }; - yield return new object[] { new Rectangle(0, 0, 1, 1), new Point[] { new Point(0, 0), new Point(0, 0), new Point(0, 0) }, new float[] { 0, 0, 0, 0, 0, 0 }, false, false }; - yield return new object[] { new Rectangle(0, 0, 1, 1), new Point[] { new Point(0, 0), new Point(1, 0), new Point(0, 1) }, new float[] { 1, 0, 0, 1, 0, 0 }, true, true }; - } - - [Theory] - [MemberData(nameof(Ctor_Rectangle_Points_TestData))] - public void Ctor_Rectangle_Points(Rectangle rect, Point[] plgpnts, float[] expectedElements, bool isIdentity, bool isInvertible) - { - using (var matrix = new Matrix(rect, plgpnts)) - { - Assert.Equal(expectedElements, matrix.Elements); - Assert.Equal(isIdentity, matrix.IsIdentity); - Assert.Equal(isInvertible, matrix.IsInvertible); - Assert.Equal(expectedElements[4], matrix.OffsetX); - Assert.Equal(expectedElements[5], matrix.OffsetY); - } - } - - [Theory] - [MemberData(nameof(Ctor_Rectangle_Points_TestData))] - public void Ctor_RectangleF_Points(Rectangle rect, Point[] plgpnts, float[] expectedElements, bool isIdentity, bool isInvertible) - { - using (var matrix = new Matrix(rect, plgpnts.Select(p => (PointF)p).ToArray())) - { - Assert.Equal(expectedElements, matrix.Elements); - Assert.Equal(isIdentity, matrix.IsIdentity); - Assert.Equal(isInvertible, matrix.IsInvertible); - Assert.Equal(expectedElements[4], matrix.OffsetX); - Assert.Equal(expectedElements[5], matrix.OffsetY); - } - } - - [Fact] - public void Ctor_NullPoints_ThrowsArgumentNullException() - { - AssertExtensions.Throws("plgpts", () => new Matrix(new RectangleF(), null)); - AssertExtensions.Throws("plgpts", () => new Matrix(new Rectangle(), null)); - } - - [Theory] - [InlineData(0)] - [InlineData(2)] - [InlineData(4)] - public void Ctor_PointsLengthNotThree_ThrowsArgumentNullException(int length) - { - AssertExtensions.Throws(null, () => new Matrix(new RectangleF(), new PointF[length])); - AssertExtensions.Throws(null, () => new Matrix(new Rectangle(), new Point[length])); - } - - [Fact] - public void Ctor_WidthZero_ThrowsOutOfMemoryException() - { - Assert.Throws(() => new Matrix(new Rectangle(1, 1, 0, 1), new Point[3])); - Assert.Throws(() => new Matrix(new RectangleF(1, 1, 0, 1), new PointF[3])); - } - - [Fact] - public void Ctor_HeightZero_ThrowsOutOfMemoryException() - { - Assert.Throws(() => new Matrix(new Rectangle(1, 1, 1, 0), new Point[3])); - Assert.Throws(() => new Matrix(new RectangleF(1, 1, 1, 0), new PointF[3])); - } - - [Fact] - public void Clone_Matrix_ReturnsExpected() - { - using (var matrix = new Matrix(1, 2, 3, 4, 5, 6)) - using (Matrix clone = Assert.IsType(matrix.Clone())) - { - Assert.NotSame(matrix, clone); - Assert.Equal(new float[] { 1, 2, 3, 4, 5, 6 }, clone.Elements); - } - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedMatrix().Clone()); - } - - public static IEnumerable Equals_TestData() - { - yield return new object[] { new Matrix(), new Matrix(1, 0, 0, 1, 0, 0), true }; - yield return new object[] { new Matrix(), new Matrix(123, 24, 82, 16, 47, 30), false }; - yield return new object[] { new Matrix(), new Matrix(1.1f, 0.1f, -0.1f, 0.9f, 0, 0), false }; - yield return new object[] { new Matrix(), new Matrix(1.01f, 0.01f, -0.01f, 0.99f, 0, 0), false }; - yield return new object[] { new Matrix(), new Matrix(1.001f, 0.001f, -0.001f, 0.999f, 0, 0), false }; - yield return new object[] { new Matrix(), new Matrix(1.0001f, 0.0001f, -0.0001f, 0.9999f, 0, 0), false }; - yield return new object[] { new Matrix(), new Matrix(1.0009f, 0.0009f, -0.0009f, 0.99995f, 0, 0), false }; - - var matrix = new Matrix(1, 2, 3, 4, 5, 6); - yield return new object[] { matrix, matrix, true }; - yield return new object[] { matrix.Clone(), matrix.Clone(), true }; - yield return new object[] { matrix.Clone(), new Matrix(1, 2, 3, 4, 5, 6), true }; - yield return new object[] { matrix.Clone(), new Matrix(2, 2, 3, 4, 5, 6), false }; - yield return new object[] { matrix.Clone(), new Matrix(1, 3, 3, 4, 5, 6), false }; - yield return new object[] { matrix.Clone(), new Matrix(1, 2, 4, 4, 5, 6), false }; - yield return new object[] { matrix.Clone(), new Matrix(1, 2, 3, 5, 5, 6), false }; - yield return new object[] { matrix.Clone(), new Matrix(1, 2, 3, 4, 6, 6), false }; - yield return new object[] { matrix.Clone(), new Matrix(1, 2, 3, 4, 5, 7), false }; - - yield return new object[] { new Matrix(), null, false }; - yield return new object[] { new Matrix(), new object(), false }; - } - - [Theory] - [MemberData(nameof(Equals_TestData))] - public void Equals_Other_ReturnsExpected(Matrix matrix, object other, bool expected) - { - using (matrix) - using (other as IDisposable) - { - Assert.Equal(expected, matrix.Equals(other)); - if (other is Matrix otherMatrix) - { - Assert.Equal(ReferenceEquals(matrix, other), matrix.GetHashCode().Equals(other.GetHashCode())); - } - } - } - - [Fact] - public void Equals_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedMatrix().Equals(new Matrix())); - } - - [Fact] - public void Equals_DisposedOther_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new Matrix().Equals(CreateDisposedMatrix())); - } - - [Fact] - public void Elements_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedMatrix().Elements); - } - - public static IEnumerable Invert_TestData() - { - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), new float[] { -2, 1, 1.5f, -0.5f, 1, -2 } }; - yield return new object[] { new Matrix(1, 0, 0, 1, 8, 8), new float[] { 1, 0, 0, 1, -8, -8 } }; - yield return new object[] { new Matrix(), new float[] { 1, 0, 0, 1, 0, 0 } }; - } - - [Theory] - [MemberData(nameof(Invert_TestData))] - public void Invert_Matrix_Success(Matrix matrix, float[] expectedElements) - { - using (matrix) - { - matrix.Invert(); - Assert.Equal(expectedElements, matrix.Elements); - } - } - - [Theory] - [InlineData(float.NaN)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NegativeInfinity)] - public void Invert_FloatBounds_ThrowsArgumentException(float f) - { - using (var matrix1 = new Matrix(f, 2, 3, 4, 5, 6)) - using (var matrix2 = new Matrix(1, f, 3, 4, 5, 6)) - using (var matrix3 = new Matrix(1, 2, f, 4, 5, 6)) - using (var matrix4 = new Matrix(1, 2, 3, f, 5, 6)) - using (var matrix5 = new Matrix(1, 2, 3, 4, f, 6)) - using (var matrix6 = new Matrix(1, 2, 3, 4, 5, f)) - { - AssertExtensions.Throws(null, () => matrix1.Invert()); - AssertExtensions.Throws(null, () => matrix2.Invert()); - AssertExtensions.Throws(null, () => matrix3.Invert()); - AssertExtensions.Throws(null, () => matrix4.Invert()); - AssertExtensions.Throws(null, () => matrix5.Invert()); - AssertExtensions.Throws(null, () => matrix6.Invert()); - } - } - - [Fact] - public void Invert_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedMatrix().Invert()); - } - - [Fact] - public void IsIdentity_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedMatrix().IsIdentity); - } - - [Fact] - public void IsInvertible_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedMatrix().IsInvertible); - } - - public static IEnumerable Multiply_TestData() - { - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(10, 20, 30, 40, 50, 60), MatrixOrder.Prepend, new float[] { 700, 1000, 1500, 2200, 2350, 3460 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(10, 20, 30, 40, 50, 60), MatrixOrder.Append, new float[] { 700, 1000, 1500, 2200, 2350, 3460 } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(), MatrixOrder.Prepend, new float[] { 10, 20, 30, 40, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(), MatrixOrder.Append, new float[] { 10, 20, 30, 40, 50, 60 } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(0, 0, 0, 0, 0, 0), MatrixOrder.Prepend, new float[] { 0, 0, 0, 0, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(0, 0, 0, 0, 0, 0), MatrixOrder.Append, new float[] { 0, 0, 0, 0, 0, 0 } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(1, 1, 1, 1, 1, 1), MatrixOrder.Prepend, new float[] { 40, 60, 40, 60, 90, 120 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(1, 1, 1, 1, 1, 1), MatrixOrder.Append, new float[] { 30, 30, 70, 70, 111, 111 } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN), MatrixOrder.Prepend, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN), MatrixOrder.Append, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity), MatrixOrder.Prepend, new float[] { float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity), MatrixOrder.Append, new float[] { float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity), MatrixOrder.Prepend, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity), MatrixOrder.Append, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue), MatrixOrder.Prepend, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue), MatrixOrder.Append, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue } }; - } - - [Theory] - [MemberData(nameof(Multiply_TestData))] - public void Multiply_Matrix_Success(Matrix matrix, Matrix multiple, MatrixOrder order, float[] expected) - { - using (matrix) - using (multiple) - { - if (order == MatrixOrder.Prepend) - { - using (Matrix clone1 = matrix.Clone()) - { - clone1.Multiply(multiple); - Assert.Equal(expected, clone1.Elements, new FloatingPointToleranceComparerer(0.00001f)); - } - } - matrix.Multiply(multiple, order); - Assert.Equal(expected, matrix.Elements); - } - } - - [Fact] - public void Multiply_NullMatrix_ThrowsArgumentNullException() - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws("matrix", () => matrix.Multiply(null)); - AssertExtensions.Throws("matrix", () => matrix.Multiply(null, MatrixOrder.Prepend)); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void Multiply_InvalidMatrixOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var matrix = new Matrix()) - using (var other = new Matrix()) - { - AssertExtensions.Throws(null, () => matrix.Multiply(other, order)); - } - } - - [Fact] - public void Multiply_Disposed_ThrowsArgumentException() - { - Matrix disposedMatrix = CreateDisposedMatrix(); - - using (var other = new Matrix()) - { - AssertExtensions.Throws(null, () => disposedMatrix.Multiply(other)); - AssertExtensions.Throws(null, () => disposedMatrix.Multiply(other, MatrixOrder.Prepend)); - } - } - - [Fact] - public void Multiply_DisposedMatrix_ThrowsArgumentException() - { - Matrix disposedMatrix = CreateDisposedMatrix(); - - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => matrix.Multiply(disposedMatrix)); - AssertExtensions.Throws(null, () => matrix.Multiply(disposedMatrix, MatrixOrder.Prepend)); - } - } - - [Fact] - public void Multiply_SameMatrix_ThrowsInvalidOperationException() - { - using (var matrix = new Matrix()) - { - Assert.Throws(() => matrix.Multiply(matrix)); - Assert.Throws(() => matrix.Multiply(matrix, MatrixOrder.Prepend)); - } - } - - [Fact] - public void Reset_Matrix_ReturnsExpected() - { - using (var matrix = new Matrix(1, 2, 3, 4, 5, 6)) - { - matrix.Reset(); - Assert.Equal(new float[] { 1, 0, 0, 1, 0, 0 }, matrix.Elements); - - matrix.Reset(); - Assert.Equal(new float[] { 1, 0, 0, 1, 0, 0 }, matrix.Elements); - } - } - - [Fact] - public void Reset_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedMatrix().Reset()); - } - - public static IEnumerable Rotate_TestData() - { - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), 180, PointF.Empty, MatrixOrder.Prepend, new float[] { -9.999996f, -19.9999943f, -30.0000019f, -40.0000038f, 50, 60 }, null, false }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), 180, PointF.Empty, MatrixOrder.Append, new float[] { -9.999996f, -20, -30f, -40f, -50, -60 }, null, false }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), 540, PointF.Empty, MatrixOrder.Prepend, new float[] { -9.999996f, -19.9999943f, -30.0000019f, -40.0000038f, 50, 60 }, null, false }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), 540, PointF.Empty, MatrixOrder.Append, new float[] { -9.999996f, -20, -30f, -40f, -50, -60 }, null, false }; - - yield return new object[] { new Matrix(), 45, PointF.Empty, MatrixOrder.Prepend, new float[] { 0.707106769f, 0.707106769f, -0.707106829f, 0.707106769f, 0, 0 }, null, false }; - yield return new object[] { new Matrix(), 45, PointF.Empty, MatrixOrder.Append, new float[] { 0.707106769f, 0.707106769f, -0.707106829f, 0.707106769f, 0, 0 }, null, false }; - - using (var rotated45 = new Matrix()) - { - rotated45.Rotate(45); - yield return new object[] { rotated45.Clone(), 135, PointF.Empty, MatrixOrder.Prepend, new float[] { -1, 0, 0, -1, 0, 0 }, null, false }; - yield return new object[] { rotated45.Clone(), 135, PointF.Empty, MatrixOrder.Append, new float[] { -1, 0, 0, -1, 0, 0 }, null, false }; - } - - yield return new object[] { new Matrix(), 90, PointF.Empty, MatrixOrder.Prepend, new float[] { 0, 1, -1, 0, 0, 0 }, null, false }; - yield return new object[] { new Matrix(), 90, PointF.Empty, MatrixOrder.Append, new float[] { 0, 1, -1, 0, 0, 0 }, null, false }; - - using (var rotated90 = new Matrix()) - { - rotated90.Rotate(90); - yield return new object[] { rotated90.Clone(), 270, PointF.Empty, MatrixOrder.Prepend, new float[] { 1, 0, 0, 1, 0, 0 }, null, true }; - yield return new object[] { rotated90.Clone(), 270, PointF.Empty, MatrixOrder.Append, new float[] { 1, 0, 0, 1, 0, 0 }, null, true }; - } - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), 180, new PointF(10, 10), MatrixOrder.Prepend, new float[] { -10, -20, -30, -40, 850, 1260 }, null, false }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), 180, new PointF(10, 10), MatrixOrder.Append, new float[] { -10, -20, -30, -40, -30, -40 }, null, false }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NaN, PointF.Empty, MatrixOrder.Prepend, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, 50, 60 }, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN }, false }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NaN, PointF.Empty, MatrixOrder.Append, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN }, null, false }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.PositiveInfinity, PointF.Empty, MatrixOrder.Prepend, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, 50, 60 }, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN }, false }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.PositiveInfinity, PointF.Empty, MatrixOrder.Append, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN }, null, false }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, PointF.Empty, MatrixOrder.Prepend, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, 50, 60 }, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN }, false }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, PointF.Empty, MatrixOrder.Append, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN }, null, false }; - } - - [Theory] - [MemberData(nameof(Rotate_TestData))] - public void Rotate_Matrix_Success(Matrix matrix, float angle, PointF point, MatrixOrder order, float[] expectedElements, float[] expectedElementsRotateAt, bool isIdentity) - { - using (matrix) - { - if (order == MatrixOrder.Prepend) - { - if (point == Point.Empty) - { - using (Matrix clone1 = matrix.Clone()) - { - clone1.Rotate(angle); - AssertEqualFloatArray(expectedElements, clone1.Elements); - Assert.Equal(isIdentity, clone1.IsIdentity); - } - } - - using (Matrix clone2 = matrix.Clone()) - { - clone2.RotateAt(angle, point); - AssertEqualFloatArray(expectedElementsRotateAt ?? expectedElements, clone2.Elements); - Assert.False(clone2.IsIdentity); - } - } - - if (point == Point.Empty) - { - using (Matrix clone3 = matrix.Clone()) - { - clone3.Rotate(angle, order); - AssertEqualFloatArray(expectedElements, clone3.Elements); - Assert.Equal(isIdentity, clone3.IsIdentity); - } - } - - using (Matrix clone4 = matrix.Clone()) - { - clone4.RotateAt(angle, point, order); - AssertEqualFloatArray(expectedElementsRotateAt ?? expectedElements, clone4.Elements); - Assert.False(clone4.IsIdentity); - } - } - } - - [Fact] - public void Rotate_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedMatrix().Rotate(1, MatrixOrder.Append)); - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void Rotate_InvalidMatrixOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => matrix.Rotate(1, order)); - } - } - - [Fact] - public void RotateAt_Disposed_ThrowsArgumentException() - { - Matrix disposedMatrix = CreateDisposedMatrix(); - - AssertExtensions.Throws(null, () => disposedMatrix.RotateAt(1, PointF.Empty)); - AssertExtensions.Throws(null, () => disposedMatrix.RotateAt(1, PointF.Empty, MatrixOrder.Append)); - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void RotateAt_InvalidMatrixOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => matrix.RotateAt(1, PointF.Empty, order)); - } - } - - public static IEnumerable Scale_TestData() - { - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), 2, 4, MatrixOrder.Prepend, new float[] { 20, 40, 120, 160, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), 2, 4, MatrixOrder.Append, new float[] { 20, 80, 60, 160, 100, 240 } }; - - yield return new object[] { new Matrix(20, 40, 120, 160, 50, 60), 0.5, 0.25, MatrixOrder.Prepend, new float[] { 10, 20, 30, 40, 50, 60 } }; - yield return new object[] { new Matrix(20, 40, 120, 160, 50, 60), 0.5, 0.25, MatrixOrder.Append, new float[] { 10, 10, 60, 40, 25, 15 } }; - - yield return new object[] { new Matrix(20, 40, 120, 160, 50, 60), 0, 0, MatrixOrder.Prepend, new float[] { 0, 0, 0, 0, 50, 60 } }; - yield return new object[] { new Matrix(20, 40, 120, 160, 50, 60), 0, 0, MatrixOrder.Append, new float[] { 0, 0, 0, 0, 0, 0 } }; - - yield return new object[] { new Matrix(20, 40, 120, 160, 50, 60), 1, 1, MatrixOrder.Prepend, new float[] { 20, 40, 120, 160, 50, 60 } }; - yield return new object[] { new Matrix(20, 40, 120, 160, 50, 60), 1, 1, MatrixOrder.Append, new float[] { 20, 40, 120, 160, 50, 60 } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), -2, -4, MatrixOrder.Prepend, new float[] { -20, -40, -120, -160, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), -2, -4, MatrixOrder.Append, new float[] { -20, -80, -60, -160, -100, -240 } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NaN, float.NaN, MatrixOrder.Prepend, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NaN, float.NaN, MatrixOrder.Append, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.PositiveInfinity, float.PositiveInfinity, MatrixOrder.Prepend, new float[] { float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.PositiveInfinity, float.PositiveInfinity, MatrixOrder.Append, new float[] { float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Prepend, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Append, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Prepend, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Append, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue } }; - } - - [Theory] - [MemberData(nameof(Scale_TestData))] - public void Scale_Matrix_Succss(Matrix matrix, float scaleX, float scaleY, MatrixOrder order, float[] expectedElements) - { - using (matrix) - { - if (order == MatrixOrder.Prepend) - { - using (Matrix clone = matrix.Clone()) - { - clone.Scale(scaleX, scaleY); - Assert.Equal(expectedElements, clone.Elements, new FloatingPointToleranceComparerer(0.00001f)); - } - } - - matrix.Scale(scaleX, scaleY, order); - Assert.Equal(expectedElements, matrix.Elements); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void Scale_InvalidMatrixOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => matrix.Shear(1, 2, order)); - } - } - - [Fact] - public void Scale_Disposed_ThrowsArgumentException() - { - Matrix disposedMatrix = CreateDisposedMatrix(); - - AssertExtensions.Throws(null, () => disposedMatrix.Scale(1, 2)); - AssertExtensions.Throws(null, () => disposedMatrix.Scale(1, 2, MatrixOrder.Append)); - } - - public static IEnumerable Shear_TestData() - { - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), 2, 4, MatrixOrder.Prepend, new float[] { 130, 180, 50, 80, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), 2, 4, MatrixOrder.Append, new float[] { 50, 60, 110, 160, 170, 260 } }; - - yield return new object[] { new Matrix(5, 3, 9, 2, 2, 1), 10, 20, MatrixOrder.Prepend, new float[] { 185, 43, 59, 32, 2, 1 } }; - yield return new object[] { new Matrix(5, 3, 9, 2, 2, 1), 10, 20, MatrixOrder.Append, new float[] { 35, 103, 29, 182, 12, 41 } }; - - yield return new object[] { new Matrix(20, 40, 120, 160, 50, 60), 0, 0, MatrixOrder.Prepend, new float[] { 20, 40, 120, 160, 50, 60 } }; - yield return new object[] { new Matrix(20, 40, 120, 160, 50, 60), 0, 0, MatrixOrder.Append, new float[] { 20, 40, 120, 160, 50, 60 } }; - - yield return new object[] { new Matrix(20, 40, 120, 160, 50, 60), 1, 1, MatrixOrder.Prepend, new float[] { 140, 200, 140, 200, 50, 60 } }; - yield return new object[] { new Matrix(20, 40, 120, 160, 50, 60), 1, 1, MatrixOrder.Append, new float[] { 60, 60, 280, 280, 110, 110 } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), -2, -4, MatrixOrder.Prepend, new float[] { -110, -140, 10, 0, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), -2, -4, MatrixOrder.Append, new float[] { -30, -20, -50, -80, -70, -140 } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NaN, float.NaN, MatrixOrder.Prepend, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NaN, float.NaN, MatrixOrder.Append, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.PositiveInfinity, float.PositiveInfinity, MatrixOrder.Prepend, new float[] { float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.PositiveInfinity, float.PositiveInfinity, MatrixOrder.Append, new float[] { float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Prepend, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Append, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity } }; - - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Prepend, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, 50, 60 } }; - yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Append, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue } }; - } - - [Theory] - [MemberData(nameof(Shear_TestData))] - public void Shear_Matrix_Succss(Matrix matrix, float shearX, float shearY, MatrixOrder order, float[] expectedElements) - { - using (matrix) - { - if (order == MatrixOrder.Prepend) - { - using (Matrix clone = matrix.Clone()) - { - clone.Shear(shearX, shearY); - Assert.Equal(expectedElements, clone.Elements, new FloatingPointToleranceComparerer(0.00001f)); - } - } - - matrix.Shear(shearX, shearY, order); - Assert.Equal(expectedElements, matrix.Elements); - } - } - - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void Shear_InvalidMatrixOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => matrix.Shear(1, 2, order)); - } - } - - [Fact] - public void Shear_Disposed_ThrowsArgumentException() - { - Matrix disposedMatrix = CreateDisposedMatrix(); - - AssertExtensions.Throws(null, () => disposedMatrix.Shear(1, 2)); - AssertExtensions.Throws(null, () => disposedMatrix.Shear(1, 2, MatrixOrder.Append)); - } - - public static IEnumerable Translate_TestData() - { - yield return new object[] { new Matrix(2, 4, 6, 8, 10, 12), 5, 10, MatrixOrder.Prepend, new float[] { 2, 4, 6, 8, 80, 112 } }; - yield return new object[] { new Matrix(2, 4, 6, 8, 10, 12), 5, 10, MatrixOrder.Append, new float[] { 2, 4, 6, 8, 15, 22 } }; - - yield return new object[] { new Matrix(), 5, 10, MatrixOrder.Prepend, new float[] { 1, 0, 0, 1, 5, 10 } }; - yield return new object[] { new Matrix(), 5, 10, MatrixOrder.Append, new float[] { 1, 0, 0, 1, 5, 10 } }; - - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.NaN, float.NaN, MatrixOrder.Prepend, new float[] { 1, 2, 3, 4, float.NaN, float.NaN } }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.NaN, float.NaN, MatrixOrder.Append, new float[] { 1, 2, 3, 4, float.NaN, float.NaN } }; - - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.PositiveInfinity, float.PositiveInfinity, MatrixOrder.Prepend, new float[] { 1, 2, 3, 4, float.PositiveInfinity, float.PositiveInfinity } }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.PositiveInfinity, float.PositiveInfinity, MatrixOrder.Append, new float[] { 1, 2, 3, 4, float.PositiveInfinity, float.PositiveInfinity } }; - - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Prepend, new float[] { 1, 2, 3, 4, float.NegativeInfinity, float.NegativeInfinity } }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Append, new float[] { 1, 2, 3, 4, float.NegativeInfinity, float.NegativeInfinity } }; - - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.MaxValue, float.MaxValue, MatrixOrder.Prepend, new float[] { 1, 2, 3, 4, float.MaxValue, float.MaxValue } }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.MaxValue, float.MaxValue, MatrixOrder.Append, new float[] { 1, 2, 3, 4, float.MaxValue, float.MaxValue } }; - } - - [Theory] - [MemberData(nameof(Translate_TestData))] - public void Translate_Matrix_Success(Matrix matrix, float offsetX, float offsetY, MatrixOrder order, float[] expectedElements) - { - using (matrix) - { - if (order == MatrixOrder.Prepend) - { - using (Matrix clone = matrix.Clone()) - { - clone.Translate(offsetX, offsetY); - Assert.Equal(expectedElements, clone.Elements, new FloatingPointToleranceComparerer(0.00001f)); - } - } - - matrix.Translate(offsetX, offsetY, order); - Assert.Equal(expectedElements, matrix.Elements, new FloatingPointToleranceComparerer(0.00001f)); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void Translate_InvalidMatrixOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => matrix.Translate(1, 2, order)); - } - } - - [Fact] - public void Translate_Disposed_ThrowsArgumentException() - { - Matrix disposedMatrix = CreateDisposedMatrix(); - - AssertExtensions.Throws(null, () => disposedMatrix.Translate(1, 2)); - AssertExtensions.Throws(null, () => disposedMatrix.Translate(1, 2, MatrixOrder.Append)); - } - - public static IEnumerable TransformPoints_TestData() - { - yield return new object[] { new Matrix(2, 4, 6, 8, 10, 12), new Point[] { new Point(2, 4), new Point(4, 8) }, new Point[] { new Point(38, 52), new Point(66, 92) } }; - yield return new object[] { new Matrix(), new Point[] { new Point(2, 4), new Point(4, 8) }, new Point[] { new Point(2, 4), new Point(4, 8) } }; - yield return new object[] { new Matrix(2, 4, 6, 8, 10, 12), new Point[1], new Point[] { new Point(10, 12) } }; - } - - [Theory] - [MemberData(nameof(TransformPoints_TestData))] - public void TransformPoints_Point_Success(Matrix matrix, Point[] points, Point[] expectedPoints) - { - using (matrix) - { - matrix.TransformPoints(points); - Assert.Equal(expectedPoints, points); - } - } - - [Theory] - [MemberData(nameof(TransformPoints_TestData))] - public void TransformPoints_PointF_Success(Matrix matrix, Point[] points, Point[] expectedPoints) - { - using (matrix) - { - PointF[] pointFs = points.Select(p => (PointF)p).ToArray(); - matrix.TransformPoints(pointFs); - Assert.Equal(expectedPoints.Select(p => (PointF)p), pointFs); - } - } - - [Fact] - public void TransformPoints_NullPoints_ThrowsArgumentNullException() - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws("pts", () => matrix.TransformPoints((Point[])null)); - AssertExtensions.Throws("pts", () => matrix.TransformPoints((PointF[])null)); - } - } - - [Fact] - public void TransformPoints_EmptyPoints_ThrowsArgumentException() - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => matrix.TransformPoints(new Point[0])); - AssertExtensions.Throws(null, () => matrix.TransformPoints(new PointF[0])); - } - } - - [Fact] - public void TransformPoints_Disposed_ThrowsArgumentException() - { - Matrix disposedMatrix = CreateDisposedMatrix(); - - AssertExtensions.Throws(null, () => disposedMatrix.TransformPoints(new Point[1])); - AssertExtensions.Throws(null, () => disposedMatrix.TransformPoints(new PointF[1])); - } - - public static IEnumerable TransformVectors_TestData() - { - yield return new object[] { new Matrix(2, 4, 6, 8, 10, 12), new Point[] { new Point(2, 4), new Point(4, 8) }, new Point[] { new Point(28, 40), new Point(56, 80) } }; - yield return new object[] { new Matrix(), new Point[] { new Point(2, 4), new Point(4, 8) }, new Point[] { new Point(2, 4), new Point(4, 8) } }; - yield return new object[] { new Matrix(2, 4, 6, 8, 10, 12), new Point[1], new Point[1] }; - } - - [Theory] - [MemberData(nameof(TransformVectors_TestData))] - public void TransformVectors_Point_Success(Matrix matrix, Point[] points, Point[] expectedPoints) - { - using (matrix) - { - matrix.TransformVectors(points); - Assert.Equal(expectedPoints, points); - } - } - - [Theory] - [MemberData(nameof(TransformVectors_TestData))] - public void TransformVectors_PointF_Success(Matrix matrix, Point[] points, Point[] expectedPoints) - { - using (matrix) - { - PointF[] pointFs = points.Select(p => (PointF)p).ToArray(); - matrix.TransformVectors(pointFs); - Assert.Equal(expectedPoints.Select(p => (PointF)p), pointFs); - } - } - - [Theory] - [MemberData(nameof(TransformVectors_TestData))] - public void VectorTransformPoints_Points_Success(Matrix matrix, Point[] points, Point[] expectedPoints) - { - using (matrix) - { - matrix.VectorTransformPoints(points); - Assert.Equal(expectedPoints, points); - } - } - - [Fact] - public void TransformVectors_NullPoints_ThrowsArgumentNullException() - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws("pts", () => matrix.VectorTransformPoints(null)); - AssertExtensions.Throws("pts", () => matrix.TransformVectors((Point[])null)); - AssertExtensions.Throws("pts", () => matrix.TransformVectors((PointF[])null)); - } - } - - [Fact] - public void TransformVectors_EmptyPoints_ThrowsArgumentException() - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => matrix.VectorTransformPoints(new Point[0])); - AssertExtensions.Throws(null, () => matrix.TransformVectors(new Point[0])); - AssertExtensions.Throws(null, () => matrix.TransformVectors(new PointF[0])); - } - } - - [Fact] - public void TransformVectors_Disposed_ThrowsArgumentException() - { - Matrix disposedMatrix = CreateDisposedMatrix(); - - AssertExtensions.Throws(null, () => disposedMatrix.VectorTransformPoints(new Point[1])); - AssertExtensions.Throws(null, () => disposedMatrix.TransformPoints(new Point[1])); - AssertExtensions.Throws(null, () => disposedMatrix.TransformVectors(new PointF[1])); - } - - private static void AssertEqualFloatArray(float[] expected, float[] actual) - { - Assert.Equal(expected.Length, actual.Length); - for (int i = 0; i < expected.Length; i++) - { - try - { - Assert.Equal(expected[i], actual[i], precision: 3); - } - catch - { - Console.WriteLine(i); - Console.WriteLine($"Expected: {string.Join(", ", expected)}"); - Console.WriteLine($"Actual: {string.Join(", ", actual)}"); - throw; - } - } - } -} diff --git a/src/System.Drawing.Common/tests/Drawing2D/PathGradientBrushTests.cs b/src/System.Drawing.Common/tests/Drawing2D/PathGradientBrushTests.cs deleted file mode 100644 index a329ae6c352..00000000000 --- a/src/System.Drawing.Common/tests/Drawing2D/PathGradientBrushTests.cs +++ /dev/null @@ -1,1069 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2005-2006 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace System.Drawing.Drawing2D.Tests; - -public class PathGradientBrushTests -{ - private readonly Point[] _defaultIntPoints = new Point[2] { new Point(1, 2), new Point(20, 30) }; - private readonly PointF[] _defaultFloatPoints = new PointF[2] { new PointF(1, 2), new PointF(20, 30) }; - private readonly RectangleF _defaultRectangle = new(1, 2, 19, 28); - - [Fact] - public void Ctor_Points_ReturnsExpected() - { - using (PathGradientBrush bi = new PathGradientBrush(_defaultIntPoints)) - using (PathGradientBrush bf = new PathGradientBrush(_defaultFloatPoints)) - { - AssertDefaults(bi); - Assert.Equal(WrapMode.Clamp, bi.WrapMode); - AssertDefaults(bf); - Assert.Equal(WrapMode.Clamp, bf.WrapMode); - } - } - - public static IEnumerable WrapMode_TestData() - { - yield return new object[] { WrapMode.Clamp }; - yield return new object[] { WrapMode.Tile }; - yield return new object[] { WrapMode.TileFlipX }; - yield return new object[] { WrapMode.TileFlipXY }; - yield return new object[] { WrapMode.TileFlipY }; - } - - [Theory] - [MemberData(nameof(WrapMode_TestData))] - public void Ctor_PointsWrapMode_ReturnsExpected(WrapMode wrapMode) - { - using (PathGradientBrush brushInt = new PathGradientBrush(_defaultIntPoints, wrapMode)) - using (PathGradientBrush brushFloat = new PathGradientBrush(_defaultFloatPoints, wrapMode)) - { - AssertDefaults(brushInt); - Assert.Equal(wrapMode, brushInt.WrapMode); - AssertDefaults(brushFloat); - Assert.Equal(wrapMode, brushFloat.WrapMode); - } - } - - [Fact] - public void Ctor_PointsNull_ThrowsArgumentNullException() - { - AssertExtensions.Throws("points", () => new PathGradientBrush((Point[])null)); - AssertExtensions.Throws("points", () => new PathGradientBrush((PointF[])null)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - public void Ctor_PointsLengthLessThenTwo_ThrowsOutOfMemoryException(int pointsLength) - { - Assert.Throws(() => new PathGradientBrush(new Point[pointsLength])); - Assert.Throws(() => new PathGradientBrush(new Point[pointsLength], WrapMode.Clamp)); - Assert.Throws(() => new PathGradientBrush(new PointF[pointsLength])); - Assert.Throws(() => new PathGradientBrush(new PointF[pointsLength], WrapMode.Clamp)); - } - - [Fact] - public void Ctor_InvalidWrapMode_ThrowsInvalidEnumArgumentException() - { - Assert.ThrowsAny(() => - new PathGradientBrush(_defaultIntPoints, (WrapMode)int.MaxValue)); - - Assert.ThrowsAny(() => - new PathGradientBrush(_defaultFloatPoints, (WrapMode)int.MaxValue)); - } - - [Fact] - public void Ctor_Path_ReturnsExpected() - { - using (GraphicsPath path = new GraphicsPath(_defaultFloatPoints, new byte[] { 0, 1 })) - using (PathGradientBrush brush = new PathGradientBrush(path)) - { - AssertDefaults(brush); - Assert.Equal(WrapMode.Clamp, brush.WrapMode); - } - } - - [Fact] - public void Ctor_Path_ThrowsArgumentNullException() - { - AssertExtensions.Throws("path", () => new PathGradientBrush((GraphicsPath)null)); - } - - [Fact] - public void Ctor_PathWithLessThenTwoPoints_ThrowsOutOfMemoryException() - { - using (GraphicsPath path = new GraphicsPath()) - { - Assert.Throws(() => new PathGradientBrush(path)); - path.AddLines(new PointF[] { new PointF(1, 1) }); - Assert.Throws(() => new PathGradientBrush(path)); - } - } - - [Fact] - public void Clone_ReturnsExpected() - { - using (GraphicsPath path = new GraphicsPath(_defaultFloatPoints, new byte[] { 0, 1 })) - using (PathGradientBrush brush = new PathGradientBrush(path)) - using (PathGradientBrush clone = Assert.IsType(brush.Clone())) - { - AssertDefaults(clone); - Assert.Equal(WrapMode.Clamp, clone.WrapMode); - } - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Clone()); - } - - [Fact] - public void CenterColor_ReturnsExpected() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - Assert.Equal(Color.Black.ToArgb(), brush.CenterColor.ToArgb()); - brush.CenterColor = Color.Blue; - Assert.Equal(Color.Blue.ToArgb(), brush.CenterColor.ToArgb()); - brush.CenterColor = Color.Transparent; - Assert.Equal(Color.Transparent.ToArgb(), brush.CenterColor.ToArgb()); - } - } - - [Fact] - public void CenterColor_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.CenterColor = Color.Blue); - } - - [Fact] - public void SurroundColors_ReturnsExpected() - { - Color[] expectedColors = new Color[2] { Color.FromArgb(255, 0, 0, 255), Color.FromArgb(255, 255, 0, 0) }; - Color[] sameColors = new Color[2] { Color.FromArgb(255, 255, 255, 0), Color.FromArgb(255, 255, 255, 0) }; - Color[] expectedSameColors = new Color[1] { Color.FromArgb(255, 255, 255, 0) }; - - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - brush.SurroundColors = expectedColors; - Assert.Equal(expectedColors, brush.SurroundColors); - brush.SurroundColors = sameColors; - Assert.Equal(expectedSameColors, brush.SurroundColors); - } - } - - [Fact] - public void SurroundColors_CannotChange() - { - Color[] colors = new Color[2] { Color.FromArgb(255, 0, 0, 255), Color.FromArgb(255, 255, 0, 0) }; - Color[] defaultColors = new Color[1] { Color.FromArgb(255, 255, 255, 255) }; - - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - brush.SurroundColors.ToList().AddRange(colors); - Assert.Equal(defaultColors, brush.SurroundColors); - brush.SurroundColors[0] = Color.FromArgb(255, 0, 0, 255); - Assert.NotEqual(Color.FromArgb(255, 0, 0, 255), brush.SurroundColors[0]); - Assert.Equal(defaultColors, brush.SurroundColors); - } - } - - [Fact] - public void SurroundColors_Disposed_ThrowsArgumentException() - { - Color[] colors = new Color[2] { Color.FromArgb(255, 0, 0, 255), Color.FromArgb(255, 255, 0, 0) }; - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.SurroundColors = colors); - } - - public static IEnumerable SurroundColors_InvalidColorsLength_TestData() - { - yield return new object[] { new Point[2] { new Point(1, 1), new Point(2, 2) }, new Color[0] }; - yield return new object[] { new Point[2] { new Point(1, 1), new Point(2, 2) }, new Color[3] }; - } - - [Theory] - [MemberData(nameof(SurroundColors_InvalidColorsLength_TestData))] - public void SurroundColors_InvalidColorsLength_ThrowsArgumentException(Point[] points, Color[] colors) - { - using (PathGradientBrush brush = new PathGradientBrush(points)) - { - AssertExtensions.Throws(null, () => brush.SurroundColors = colors); - } - } - - [Fact] - public void SurroundColors_Null_ThrowsNullReferenceException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws(() => brush.SurroundColors = null); - } - } - - [Fact] - public void CenterPoint_ReturnsExpected() - { - PointF centralPoint = new PointF(float.MaxValue, float.MinValue); - PointF defaultCentralPoint = new PointF(10.5f, 16f); - - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints, WrapMode.TileFlipXY)) - { - Assert.Equal(defaultCentralPoint, brush.CenterPoint); - brush.CenterPoint = centralPoint; - Assert.Equal(centralPoint, brush.CenterPoint); - - centralPoint.X = float.NaN; - centralPoint.Y = float.NegativeInfinity; - brush.CenterPoint = centralPoint; - Assert.Equal(float.NaN, brush.CenterPoint.X); - Assert.Equal(float.NegativeInfinity, brush.CenterPoint.Y); - } - } - - [Fact] - public void CenterPoint_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.CenterPoint); - } - - public static IEnumerable Blend_FactorsPositions_TestData() - { - yield return new object[] { new float[1] { 1 }, new float[1] { 0 } }; - yield return new object[] { new float[2] { 1, 1 }, new float[2] { 0, 1 } }; - yield return new object[] { new float[3] { 1, 0, 1 }, new float[3] { 0, 3, 1 } }; - yield return new object[] { new float[1] { 1 }, new float[3] { 0, 3, 1 } }; - } - - [Theory] - [MemberData(nameof(Blend_FactorsPositions_TestData))] - public void Blend_ReturnsExpected(float[] factors, float[] positions) - { - int expectedSize = factors.Length; - - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints, WrapMode.TileFlipXY)) - { - brush.Blend = new Blend { Factors = factors, Positions = positions }; - Assert.Equal(factors, brush.Blend.Factors); - Assert.Equal(expectedSize, brush.Blend.Positions.Length); - if (expectedSize == positions.Length && expectedSize != 1) - { - Assert.Equal(factors, brush.Blend.Factors); - Assert.Equal(positions, brush.Blend.Positions); - } - else - { - Assert.Equal(factors, brush.Blend.Factors); - Assert.Equal(1, brush.Blend.Positions.Length); - } - } - } - - [Fact] - public void Blend_CannotChange() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints, WrapMode.TileFlipXY)) - { - brush.Blend.Factors = new float[0]; - Assert.Equal(1, brush.Blend.Factors.Length); - brush.Blend.Factors = new float[2]; - Assert.Equal(1, brush.Blend.Factors.Length); - brush.Blend.Positions = new float[0]; - Assert.Equal(1, brush.Blend.Positions.Length); - brush.Blend.Positions = new float[2]; - Assert.Equal(1, brush.Blend.Positions.Length); - } - } - - [Fact] - public void Blend_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Blend); - } - - public static IEnumerable Blend_InvalidFactorsPositions_TestData() - { - yield return new object[] { new Blend() { Factors = new float[0], Positions = new float[0] } }; - yield return new object[] { new Blend() { Factors = new float[2], Positions = new float[2] { 1, 1 } } }; - yield return new object[] { new Blend() { Factors = new float[2], Positions = new float[2] { 0, 5 } } }; - yield return new object[] { new Blend() { Factors = new float[3], Positions = new float[3] { 0, 1, 5 } } }; - yield return new object[] { new Blend() { Factors = new float[3], Positions = new float[3] { 1, 1, 1 } } }; - } - - [Theory] - [MemberData(nameof(Blend_InvalidFactorsPositions_TestData))] - public void Blend_InvalidFactorPositions_ThrowsArgumentException(Blend blend) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws(null, () => brush.Blend = blend); - } - } - - [Fact] - public void Blend_InvalidFactorPositionsLengthMismatch_ThrowsArgumentOutOfRangeException() - { - Blend invalidBlend = new Blend() { Factors = new float[2], Positions = new float[1] }; - - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws("value", null, () => brush.Blend = invalidBlend); - } - } - - [Fact] - public void Blend_Null_ThrowsNullReferenceException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - Assert.Throws(() => brush.Blend = null); - Assert.Throws(() => brush.Blend = new Blend() { Factors = null, Positions = null}); - Assert.Throws(() => brush.Blend = new Blend() { Factors = null, Positions = new float[0] }); - } - } - - [Fact] - public void Blend_NullBlendProperites_ThrowsArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws("value", "source", () => - brush.Blend = new Blend() { Factors = new float[0], Positions = null }); - } - } - - [Theory] - [InlineData(1f)] - [InlineData(0f)] - [InlineData(0.5f)] - public void SetSigmaBellShape_Focus_Success(float focus) - { - float defaultScale = 1f; - - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - brush.SetSigmaBellShape(focus); - Assert.True(brush.Transform.IsIdentity); - if (focus == 0f) - { - Assert.Equal(focus, brush.Blend.Positions[0]); - Assert.Equal(defaultScale, brush.Blend.Factors[0]); - Assert.Equal(1f, brush.Blend.Positions[brush.Blend.Positions.Length - 1]); - Assert.Equal(0f, brush.Blend.Factors[brush.Blend.Factors.Length - 1]); - } - else if (focus == 1f) - { - Assert.Equal(0f, brush.Blend.Positions[0]); - Assert.Equal(0f, brush.Blend.Factors[0]); - Assert.Equal(focus, brush.Blend.Positions[brush.Blend.Positions.Length - 1]); - Assert.Equal(defaultScale, brush.Blend.Factors[brush.Blend.Factors.Length - 1]); - } - else - { - Assert.Equal(0f, brush.Blend.Positions[0]); - Assert.Equal(0f, brush.Blend.Factors[0]); - Assert.Equal(1f, brush.Blend.Positions[brush.Blend.Positions.Length - 1]); - Assert.Equal(0f, brush.Blend.Factors[brush.Blend.Factors.Length - 1]); - } - } - } - - [Theory] - [InlineData(1f)] - [InlineData(0f)] - [InlineData(0.5f)] - public void SetSigmaBellShape_FocusScale_Success(float focus) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - brush.SetSigmaBellShape(focus); - Assert.True(brush.Transform.IsIdentity); - if (focus == 0f) - { - Assert.Equal(256, brush.Blend.Positions.Length); - Assert.Equal(256, brush.Blend.Factors.Length); - Assert.Equal(focus, brush.Blend.Positions[0]); - Assert.Equal(1f, brush.Blend.Factors[0]); - Assert.Equal(1f, brush.Blend.Positions[brush.Blend.Positions.Length - 1]); - Assert.Equal(0f, brush.Blend.Factors[brush.Blend.Factors.Length - 1]); - } - else if (focus == 1f) - { - Assert.Equal(256, brush.Blend.Positions.Length); - Assert.Equal(256, brush.Blend.Factors.Length); - Assert.Equal(0f, brush.Blend.Positions[0]); - Assert.Equal(0f, brush.Blend.Factors[0]); - Assert.Equal(focus, brush.Blend.Positions[brush.Blend.Positions.Length - 1]); - Assert.Equal(1f, brush.Blend.Factors[brush.Blend.Factors.Length - 1]); - } - else - { - Assert.Equal(511, brush.Blend.Positions.Length); - Assert.Equal(511, brush.Blend.Factors.Length); - Assert.Equal(0f, brush.Blend.Positions[0]); - Assert.Equal(0f, brush.Blend.Factors[0]); - Assert.Equal(focus, brush.Blend.Positions[255]); - Assert.Equal(1f, brush.Blend.Factors[255]); - Assert.Equal(1f, brush.Blend.Positions[brush.Blend.Positions.Length - 1]); - Assert.Equal(0f, brush.Blend.Factors[brush.Blend.Factors.Length - 1]); - } - } - } - - [Fact] - public void SetSigmaBellShape_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.SetSigmaBellShape(1f)); - AssertExtensions.Throws(null, () => brush.SetSigmaBellShape(1f, 1f)); - } - - [Theory] - [InlineData(-1)] - [InlineData(1.1f)] - public void SetSigmaBellShape_InvalidFocus_ThrowsArgumentException(float focus) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws("focus", null, () => brush.SetSigmaBellShape(focus)); - AssertExtensions.Throws("focus", null, () => brush.SetSigmaBellShape(focus, 1f)); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(1.1f)] - public void SetSigmaBellShape_InvalidScale_ThrowsArgumentException(float scale) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws("scale", null, () => brush.SetSigmaBellShape(1f, scale)); - } - } - - [Theory] - [InlineData(1f)] - [InlineData(0f)] - [InlineData(0.5f)] - public void SetBlendTriangularShape_Focus_Success(float focus) - { - float defaultScale = 1f; - - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - brush.SetBlendTriangularShape(focus); - Assert.True(brush.Transform.IsIdentity); - if (focus == 0f) - { - Assert.Equal(new float[2] { defaultScale, 0f }, brush.Blend.Factors); - Assert.Equal(new float[2] { focus, 1f }, brush.Blend.Positions); - } - else if (focus == 1f) - { - Assert.Equal(new float[2] { 0f, defaultScale }, brush.Blend.Factors); - Assert.Equal(new float[2] { 0f, focus }, brush.Blend.Positions); - } - else - { - Assert.Equal(new float[3] { 0f, defaultScale, 0f }, brush.Blend.Factors); - Assert.Equal(new float[3] { 0f, focus, 1f }, brush.Blend.Positions); - } - } - } - - [Theory] - [InlineData(1f)] - [InlineData(0f)] - [InlineData(0.5f)] - public void SetBlendTriangularShape_FocusScale_Success(float focus) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - brush.SetBlendTriangularShape(focus); - Assert.True(brush.Transform.IsIdentity); - Assert.True(brush.Transform.IsIdentity); - if (focus == 0f) - { - Assert.Equal(new float[2] { 1f, 0f }, brush.Blend.Factors); - Assert.Equal(new float[2] { focus, 1f }, brush.Blend.Positions); - } - else if (focus == 1f) - { - Assert.Equal(new float[2] { 0f, 1f }, brush.Blend.Factors); - Assert.Equal(new float[2] { 0f, focus }, brush.Blend.Positions); - } - else - { - Assert.Equal(new float[3] { 0f, 1f, 0f }, brush.Blend.Factors); - Assert.Equal(new float[3] { 0f, focus, 1f }, brush.Blend.Positions); - } - } - } - - [Fact] - public void SetBlendTriangularShape_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.SetBlendTriangularShape(1f)); - AssertExtensions.Throws(null, () => brush.SetBlendTriangularShape(1f, 1f)); - } - - [Theory] - [InlineData(-1)] - [InlineData(1.1f)] - public void SetBlendTriangularShape_InvalidFocus_ThrowsArgumentException(float focus) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws("focus", null, () => brush.SetBlendTriangularShape(focus)); - AssertExtensions.Throws("focus", null, () => brush.SetBlendTriangularShape(focus, 1f)); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(1.1f)] - public void SetBlendTriangularShape_InvalidScale_ThrowsArgumentException(float scale) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws("scale", null, () => brush.SetBlendTriangularShape(1f, scale)); - } - } - - [Fact] - public void InterpolationColors_ReturnsExpected() - { - Color[] expectedColors = new Color[2] { Color.FromArgb(255, 0, 0, 255), Color.FromArgb(255, 255, 0, 0) }; - float[] expectedPositions = new float[] { 0, 1 }; - Color[] sameColors = new Color[2] { Color.FromArgb(255, 255, 255, 0), Color.FromArgb(255, 255, 255, 0) }; - - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - brush.InterpolationColors = new ColorBlend() { Colors = expectedColors, Positions = expectedPositions }; - Assert.Equal(expectedColors, brush.InterpolationColors.Colors); - Assert.Equal(expectedPositions, brush.InterpolationColors.Positions); - - brush.InterpolationColors = new ColorBlend() { Colors = sameColors, Positions = expectedPositions }; - Assert.Equal(sameColors, brush.InterpolationColors.Colors); - Assert.Equal(expectedPositions, brush.InterpolationColors.Positions); - } - } - - [Fact] - public void InterpolationColors_CannotChange() - { - Color[] colors = new Color[2] { Color.FromArgb(255, 0, 0, 255), Color.FromArgb(255, 255, 0, 0) }; - Color[] defaultColors = new Color[1] { Color.Empty }; - - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - brush.InterpolationColors.Colors.ToList().AddRange(colors); - Assert.Equal(defaultColors, brush.InterpolationColors.Colors); - brush.InterpolationColors.Colors = colors; - Assert.Equal(defaultColors, brush.InterpolationColors.Colors); - brush.InterpolationColors.Colors[0] = Color.Pink; - Assert.NotEqual(Color.Pink, brush.InterpolationColors.Colors[0]); - Assert.Equal(defaultColors, brush.InterpolationColors.Colors); - brush.InterpolationColors.Positions = new float[0]; - Assert.Equal(1, brush.InterpolationColors.Positions.Length); - brush.InterpolationColors.Positions = new float[2]; - Assert.Equal(1, brush.InterpolationColors.Positions.Length); - } - } - - [Fact] - public void InterpolationColors_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.InterpolationColors); - } - - [Fact] - public void InterpolationColors_Null_ThrowsNullReferenceException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - Assert.Throws(() => brush.InterpolationColors = null); - } - } - - [Fact] - public void InterpolationColors_NullColors_ThrowsNullReferenceException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - Assert.Throws(() => - brush.InterpolationColors = new ColorBlend() { Colors = null, Positions = null }); - - Assert.Throws(() => - brush.InterpolationColors = new ColorBlend() { Colors = null, Positions = new float[2] }); - } - } - - [Fact] - public void InterpolationColors_NullPoints_ArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws("value", "source", () => - brush.InterpolationColors = new ColorBlend() { Colors = new Color[1], Positions = null }); - } - } - - [Fact] - public void InterpolationColors_Empty_ArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws(null, () => brush.InterpolationColors = new ColorBlend()); - } - } - - [Fact] - public void InterpolationColors_EmptyColors_ArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws(null, () => - brush.InterpolationColors = new ColorBlend() { Colors = new Color[0], Positions = new float[0] }); - } - } - - [Fact] - public void InterpolationColors_PointsLengthGreaterThenColorsLength_ArgumentOutOfRangeException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws("value", null, () => - brush.InterpolationColors = new ColorBlend() { Colors = new Color[1], Positions = new float[2] }); - } - } - - [Fact] - public void InterpolationColors_ColorsLengthGreaterThenPointsLength_ThrowsArgumentOutOfRangeException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - Assert.Throws(() => - brush.InterpolationColors = new ColorBlend() { Colors = new Color[2], Positions = new float[1] }); - } - } - - [Fact] - public void Transform_ReturnsExpected() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix defaultMatrix = new Matrix(1, 0, 0, 1, 0, 0)) - using (Matrix matrix = new Matrix(1, 0, 0, 1, 1, 1)) - { - Assert.Equal(defaultMatrix, brush.Transform); - brush.Transform = matrix; - Assert.Equal(matrix, brush.Transform); - } - } - - [Fact] - public void Transform_EmptyMatrix_ReturnsExpected() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix matrix = new Matrix()) - { - brush.Transform = matrix; - Assert.True(brush.Transform.IsIdentity); - } - } - - [Fact] - public void Transform_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Transform); - } - - [Fact] - public void Transform_Null_ArgumentNullException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws("value", "matrix", () => brush.Transform = null); - } - } - - [Fact] - public void Transform_NonInvertible_ArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix nonInvertible = new Matrix(123, 24, 82, 16, 47, 30)) - { - AssertExtensions.Throws(null, () => brush.Transform = nonInvertible); - } - } - - [Fact] - public void ResetTransform_Success() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix defaultMatrix = new Matrix(1, 0, 0, 1, 0, 0)) - using (Matrix matrix = new Matrix(1, 0, 0, 1, 1, 1)) - { - Assert.Equal(defaultMatrix, brush.Transform); - brush.Transform = matrix; - Assert.Equal(matrix, brush.Transform); - brush.ResetTransform(); - Assert.Equal(defaultMatrix, brush.Transform); - } - } - - [Fact] - public void ResetTransform_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.ResetTransform()); - } - - [Fact] - public void MultiplyTransform_Matrix_Success() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix defaultMatrix = new Matrix(1, 0, 0, 1, 0, 0)) - using (Matrix matrix = new Matrix(1, 0, 0, 1, 1, 1)) - { - defaultMatrix.Multiply(matrix, MatrixOrder.Prepend); - brush.MultiplyTransform(matrix); - Assert.Equal(defaultMatrix, brush.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Append)] - [InlineData(MatrixOrder.Prepend)] - public void MultiplyTransform_MatrixMatrixOrder_Success(MatrixOrder matrixOrder) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix defaultMatrix = new Matrix(1, 0, 0, 1, 0, 0)) - using (Matrix matrix = new Matrix(1, 0, 0, 1, 1, 1)) - { - defaultMatrix.Multiply(matrix, matrixOrder); - brush.MultiplyTransform(matrix, matrixOrder); - Assert.Equal(defaultMatrix, brush.Transform); - } - } - - [Fact] - public void MultiplyTransform_Disposed_ThrowsArgumentException() - { - using (Matrix matrix = new Matrix(1, 0, 0, 1, 1, 1)) - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.MultiplyTransform(matrix, MatrixOrder.Append)); - } - } - - [Fact] - public void MultiplyTransform_NullMatrix_ThrowsArgumentNullException() - { - using (var brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws("matrix", () => brush.MultiplyTransform(null)); - AssertExtensions.Throws("matrix", () => brush.MultiplyTransform(null, MatrixOrder.Append)); - } - } - - [Fact] - public void MultiplyTransform_DisposedMatrix_Nop() - { - using (var brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix transform = brush.Transform) - { - var matrix = new Matrix(); - matrix.Dispose(); - - brush.MultiplyTransform(matrix); - brush.MultiplyTransform(matrix, MatrixOrder.Append); - - Assert.Equal(transform, brush.Transform); - } - } - - [Fact] - public void MultiplyTransform_InvalidMatrixOrder_ArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix matrix = new Matrix(1, 1, 1, 1, 1, 1)) - { - AssertExtensions.Throws(null, () => brush.MultiplyTransform(matrix, (MatrixOrder)int.MinValue)); - } - } - - [Fact] - public void MultiplyTransform_NonInvertible_ArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix nonInvertible = new Matrix(123, 24, 82, 16, 47, 30)) - { - AssertExtensions.Throws(null, () => brush.MultiplyTransform(nonInvertible)); - AssertExtensions.Throws(null, () => brush.MultiplyTransform(nonInvertible, MatrixOrder.Append)); - } - } - - [Fact] - public void TranslateTransform_Offset_Success() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix matrix = new Matrix(1, 0, 0, 1, 0, 0)) - { - matrix.Translate(20f, 30f, MatrixOrder.Prepend); - brush.TranslateTransform(20f, 30f); - Assert.Equal(matrix, brush.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Append)] - [InlineData(MatrixOrder.Prepend)] - public void TranslateTransform_OffsetMatrixOrder_Success(MatrixOrder matrixOrder) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix matrix = new Matrix(1, 0, 0, 1, 0, 0)) - { - matrix.Translate(20f, 30f, matrixOrder); - brush.TranslateTransform(20f, 30f, matrixOrder); - Assert.Equal(matrix, brush.Transform); - } - } - - [Fact] - public void TranslateTransform_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.TranslateTransform(20f, 30f, MatrixOrder.Append)); - } - - [Fact] - public void TranslateTransform_InvalidMatrixOrder_ArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws(null, () => brush.TranslateTransform(20f, 30f, (MatrixOrder)int.MinValue)); - } - } - - [Fact] - public void ScaleTransform_Scale_Success() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix matrix = new Matrix(1, 0, 0, 1, 0, 0)) - { - matrix.Scale(2, 4, MatrixOrder.Prepend); - brush.ScaleTransform(2, 4); - Assert.Equal(matrix, brush.Transform); - - matrix.Scale(0.5f, 0.25f, MatrixOrder.Prepend); - brush.ScaleTransform(0.5f, 0.25f); - Assert.True(brush.Transform.IsIdentity); - - matrix.Scale(float.MaxValue, float.MinValue, MatrixOrder.Prepend); - brush.ScaleTransform(float.MaxValue, float.MinValue); - Assert.Equal(matrix, brush.Transform); - - matrix.Scale(float.MinValue, float.MaxValue, MatrixOrder.Prepend); - brush.ScaleTransform(float.MinValue, float.MaxValue); - Assert.Equal(matrix, brush.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Append)] - [InlineData(MatrixOrder.Prepend)] - public void ScaleTransform_ScaleMatrixOrder_Success(MatrixOrder matrixOrder) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix matrix = new Matrix(1, 0, 0, 1, 0, 0)) - { - matrix.Scale(0.25f, 2, matrixOrder); - brush.ScaleTransform(0.25f, 2, matrixOrder); - Assert.Equal(matrix, brush.Transform); - } - } - - [Fact] - public void ScaleTransform_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.ScaleTransform(0.25f, 2, MatrixOrder.Append)); - } - - [Fact] - public void ScaleTransform_InvalidMatrixOrder_ArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws(null, () => brush.ScaleTransform(1, 1, (MatrixOrder)int.MinValue)); - } - } - - [Fact] - public void RotateTransform_Angle_Success() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix matrix = new Matrix(1, 0, 0, 1, 0, 0)) - { - matrix.Rotate(90, MatrixOrder.Prepend); - brush.RotateTransform(90); - Assert.Equal(matrix, brush.Transform); - - brush.RotateTransform(270); - Assert.True(brush.Transform.IsIdentity); - } - } - - [Theory] - [InlineData(MatrixOrder.Append)] - [InlineData(MatrixOrder.Prepend)] - public void RotateTransform_AngleMatrixOrder_Success(MatrixOrder matrixOrder) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - using (Matrix matrix = new Matrix(1, 0, 0, 1, 0, 0)) - { - matrix.Rotate(45, matrixOrder); - brush.RotateTransform(45, matrixOrder); - Assert.Equal(matrix, brush.Transform); - } - } - - [Fact] - public void RotateTransform_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.RotateTransform(45, MatrixOrder.Append)); - } - - [Fact] - public void RotateTransform_InvalidMatrixOrder_ArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - AssertExtensions.Throws(null, () => brush.RotateTransform(45, (MatrixOrder)int.MinValue)); - } - } - - [Fact] - public void FocusScales_ReturnsExpected() - { - var point = new PointF(2.5f, 3.4f); - - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - brush.FocusScales = point; - Assert.Equal(point, brush.FocusScales); - } - } - - [Fact] - public void FocusScales_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.FocusScales); - } - - [Theory] - [MemberData(nameof(WrapMode_TestData))] - public void WrapMode_ReturnsExpected(WrapMode wrapMode) - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - brush.WrapMode = wrapMode; - Assert.Equal(wrapMode, brush.WrapMode); - } - } - - [Fact] - public void WrapMode_Disposed_ThrowsArgumentException() - { - PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.WrapMode); - } - - [Fact] - public void WrapMode_Invalid_InvalidEnumArgumentException() - { - using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) - { - Assert.ThrowsAny(() => brush.WrapMode = (WrapMode)int.MinValue); - } - } - - private void AssertDefaults(PathGradientBrush brush) - { - Assert.Equal(_defaultRectangle, brush.Rectangle); - Assert.Equal(new float[] { 1 }, brush.Blend.Factors); - Assert.Equal(1, brush.Blend.Positions.Length); - Assert.Equal(new PointF(10.5f, 16f), brush.CenterPoint); - Assert.Equal(new Color[] { Color.Empty }, brush.InterpolationColors.Colors); - Assert.Equal(new Color[] { Color.FromArgb(255, 255, 255, 255) }, brush.SurroundColors); - Assert.Equal(new float[] { 0 }, brush.InterpolationColors.Positions); - Assert.True(brush.Transform.IsIdentity); - Assert.True(brush.FocusScales.IsEmpty); - } -} diff --git a/src/System.Drawing.Common/tests/DrawingTest.cs b/src/System.Drawing.Common/tests/DrawingTest.cs deleted file mode 100644 index aebef3cd9ff..00000000000 --- a/src/System.Drawing.Common/tests/DrawingTest.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Imaging; - -namespace System.Drawing.Tests; - -public abstract class DrawingTest -{ - private static Security.Cryptography.MD5 s_md5 = Security.Cryptography.MD5.Create(); - - protected unsafe void ValidateBitmapContent(Bitmap bitmap, params byte[] expectedHash) - { - BitmapData data = bitmap.LockBits(new Rectangle(default, bitmap.Size), ImageLockMode.ReadWrite, bitmap.PixelFormat); - try - { - byte[] hash = new byte[expectedHash.Length]; - if (!s_md5.TryComputeHash( - new ReadOnlySpan((void*)data.Scan0, data.Stride * data.Height), - hash, - out _)) - { - Assert.Fail("Could not compute hash."); - } - - Assert.Equal(expectedHash, hash); - } - finally - { - bitmap.UnlockBits(data); - } - } -} diff --git a/src/System.Drawing.Common/tests/FontFamilyTests.cs b/src/System.Drawing.Common/tests/FontFamilyTests.cs deleted file mode 100644 index 6c740802544..00000000000 --- a/src/System.Drawing.Common/tests/FontFamilyTests.cs +++ /dev/null @@ -1,297 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Text; - -namespace System.Drawing.Tests; - -public class FontFamilyTests -{ - [Theory] - [InlineData(GenericFontFamilies.Serif - 1, "Courier New")] // Value is outside the enum range. - [InlineData(GenericFontFamilies.Monospace + 1, "Courier New")] // Value is outside the enum range. - [InlineData(GenericFontFamilies.Monospace, "Courier New")] - [InlineData(GenericFontFamilies.SansSerif, "Microsoft Sans Serif")] - [InlineData(GenericFontFamilies.Serif, "Times New Roman")] - public void Ctor_GenericFamily(GenericFontFamilies genericFamily, string expectedName) - { - using (var fontFamily = new FontFamily(genericFamily)) - { - Assert.Equal(expectedName, fontFamily.Name); - } - } - - [Theory] - [InlineData("Courier New", "Courier New")] - [InlineData("Microsoft Sans Serif", "Microsoft Sans Serif")] - [InlineData("Times New Roman", "Times New Roman")] - [InlineData("times new roman", "Times New Roman")] - public void Ctor_Name(string name, string expectedName) - { - using (var fontFamily = new FontFamily(name)) - { - Assert.Equal(expectedName, fontFamily.Name); - } - } - - [Fact] - public void Ctor_Name_FontCollection() - { - using (var fontCollection = new PrivateFontCollection()) - { - fontCollection.AddFontFile(Helpers.GetTestFontPath("CodeNewRoman.otf")); - - using (var fontFamily = new FontFamily("Code New Roman", fontCollection)) - { - Assert.Equal("Code New Roman", fontFamily.Name); - } - } - } - - [Theory] - [InlineData(null)] - [InlineData("NoSuchFont")] - [InlineData("Serif")] - public void Ctor_NoSuchFontName_ThrowsArgumentException(string name) - { - AssertExtensions.Throws(null, () => new FontFamily(name)); - AssertExtensions.Throws(null, () => new FontFamily(name, null)); - } - - [Fact] - public void Ctor_NoSuchFontNameInCollection_ThrowsArgumentException() - { - using (var fontCollection = new PrivateFontCollection()) - { - AssertExtensions.Throws(null, () => new FontFamily("Times New Roman", fontCollection)); - } - } - - public static IEnumerable Equals_TestData() - { - FontFamily fontFamily = FontFamily.GenericMonospace; - yield return new object[] { fontFamily, fontFamily, true }; - yield return new object[] { FontFamily.GenericMonospace, FontFamily.GenericMonospace, true }; - yield return new object[] { FontFamily.GenericMonospace, FontFamily.GenericSansSerif, false }; - - yield return new object[] { FontFamily.GenericSansSerif, new object(), false }; - yield return new object[] { FontFamily.GenericSansSerif, null, false }; - } - - [Theory] - [MemberData(nameof(Equals_TestData))] - public void Equals_Object_ReturnsExpected(FontFamily fontFamily, object other, bool expected) - { - try - { - Assert.Equal(expected, fontFamily.Equals(other)); - } - finally - { - fontFamily.Dispose(); - (other as IDisposable)?.Dispose(); - } - } - - // This will fail on any platform we use libgdiplus, with any - // installed system fonts whose name is longer than 31 chars. - // macOS 10.15+ ships out of the box with a problem font - [Fact] - public void Families_Get_ReturnsExpected() - { -#pragma warning disable 0618 // FontFamily.GetFamilies is deprecated. - using (var image = new Bitmap(10, 10)) - using (var graphics = Graphics.FromImage(image)) - { - FontFamily[] families = FontFamily.Families; - FontFamily[] familiesWithGraphics = FontFamily.GetFamilies(graphics); - - // FontFamily.Equals uses the native handle to determine equality. However, GDI+ does not always - // cache handles, so we cannot just Assert.Equal(families, familiesWithGraphics); - Assert.Equal(families.Length, familiesWithGraphics.Length); - - for (int i = 0; i < families.Length; i++) - { - Assert.Equal(families[i].Name, familiesWithGraphics[i].Name); - } - - foreach (FontFamily fontFamily in families) - { - using (FontFamily copy = new FontFamily(fontFamily.Name)) - { - Assert.Equal(fontFamily.Name, copy.Name); - } - } - } -#pragma warning restore 0618 - } - - [Fact] - public void GenericMonospace_Get_ReturnsExpected() - { - using (FontFamily fontFamily1 = FontFamily.GenericMonospace) - { - using (FontFamily fontFamily2 = FontFamily.GenericMonospace) - { - Assert.NotSame(fontFamily1, fontFamily2); - Assert.Equal("Courier New", fontFamily2.Name); - } - } - } - - [Fact] - public void GenericSansSerif_Get_ReturnsExpected() - { - using (FontFamily fontFamily1 = FontFamily.GenericSansSerif) - { - using (FontFamily fontFamily2 = FontFamily.GenericSansSerif) - { - Assert.NotSame(fontFamily1, fontFamily2); - Assert.Equal("Microsoft Sans Serif", fontFamily2.Name); - } - } - } - - [Fact] - public void GenericSerif_Get_ReturnsExpected() - { - using (FontFamily fontFamily1 = FontFamily.GenericSerif) - { - using (FontFamily fontFamily2 = FontFamily.GenericSerif) - { - Assert.NotSame(fontFamily1, fontFamily2); - Assert.Equal("Times New Roman", fontFamily2.Name); - } - } - } - - [Fact] - public void GetFamilies_NullGraphics_ThrowsArgumentNullException() - { -#pragma warning disable 0618 // FontFamily.GetFamilies is deprecated. - AssertExtensions.Throws("graphics", () => FontFamily.GetFamilies(null)); -#pragma warning restore 0618 - } - - [Fact] - public void GetHashCode_Invoke_ReturnsNameHashCode() - { - using (FontFamily fontFamily = FontFamily.GenericSansSerif) - { - Assert.Equal(fontFamily.GetName(0).GetHashCode(), fontFamily.GetHashCode()); - } - } - - public static IEnumerable FontStyle_TestData() - { - yield return new object[] { FontStyle.Bold }; - yield return new object[] { FontStyle.Italic }; - yield return new object[] { FontStyle.Regular }; - yield return new object[] { FontStyle.Strikeout }; - yield return new object[] { FontStyle.Strikeout }; - yield return new object[] { FontStyle.Regular - 1 }; - yield return new object[] { FontStyle.Strikeout + 1 }; - } - - [Theory] - [MemberData(nameof(FontStyle_TestData))] - public void FontFamilyProperties_CustomFont_ReturnsExpected(FontStyle style) - { - using (var fontCollection = new PrivateFontCollection()) - { - fontCollection.AddFontFile(Helpers.GetTestFontPath("CodeNewRoman.otf")); - - using (var fontFamily = new FontFamily("Code New Roman", fontCollection)) - { - Assert.True(fontFamily.IsStyleAvailable(style)); - Assert.Equal(1884, fontFamily.GetCellAscent(style)); - Assert.Equal(514, fontFamily.GetCellDescent(style)); - Assert.Equal(2048, fontFamily.GetEmHeight(style)); - Assert.Equal(2398, fontFamily.GetLineSpacing(style)); - } - } - } - - [Fact] - public void IsStyleAvailable_Disposed_ThrowsArgumentException() - { - FontFamily fontFamily = FontFamily.GenericMonospace; - fontFamily.Dispose(); - - AssertExtensions.Throws(null, () => fontFamily.IsStyleAvailable(FontStyle.Italic)); - } - - [Fact] - public void GetEmHeight_Disposed_ThrowsArgumentException() - { - FontFamily fontFamily = FontFamily.GenericMonospace; - fontFamily.Dispose(); - - AssertExtensions.Throws(null, () => fontFamily.GetEmHeight(FontStyle.Italic)); - } - - private const int FrenchLCID = 1036; - - [Theory] - [InlineData(-1, "Code New Roman")] - [InlineData(0, "Code New Roman")] - [InlineData(int.MaxValue, "Code New Roman")] - // This font has been modified to change the name to "Bonjour" if the language is French. - [InlineData(FrenchLCID, "Bonjour")] - public void GetName_LanguageCode_ReturnsExpected(int languageCode, string expectedName) - { - using (var fontCollection = new PrivateFontCollection()) - { - fontCollection.AddFontFile(Helpers.GetTestFontPath("CodeNewRoman.ttf")); - - using (var fontFamily = new FontFamily("Code New Roman", fontCollection)) - { - Assert.Equal(expectedName, fontFamily.GetName(languageCode)); - } - } - } - - [Fact] - public void GetName_Disposed_ThrowsArgumentException() - { - FontFamily fontFamily = FontFamily.GenericMonospace; - fontFamily.Dispose(); - - AssertExtensions.Throws(null, () => fontFamily.GetName(0)); - } - - [Fact] - public void GetCellAscent_Disposed_ThrowsArgumentException() - { - FontFamily fontFamily = FontFamily.GenericMonospace; - fontFamily.Dispose(); - - AssertExtensions.Throws(null, () => fontFamily.GetCellAscent(FontStyle.Italic)); - } - - [Fact] - public void GetCellDescent_Disposed_ThrowsArgumentException() - { - FontFamily fontFamily = FontFamily.GenericMonospace; - fontFamily.Dispose(); - - AssertExtensions.Throws(null, () => fontFamily.GetCellDescent(FontStyle.Italic)); - } - - [Fact] - public void GetLineSpacing_Disposed_ThrowsArgumentException() - { - FontFamily fontFamily = FontFamily.GenericMonospace; - fontFamily.Dispose(); - - AssertExtensions.Throws(null, () => fontFamily.GetLineSpacing(FontStyle.Italic)); - } - - [Fact] - public void Dispose_MultipleTimes_Nop() - { - FontFamily fontFamily = FontFamily.GenericMonospace; - fontFamily.Dispose(); - fontFamily.Dispose(); - } -} diff --git a/src/System.Drawing.Common/tests/FontTests.cs b/src/System.Drawing.Common/tests/FontTests.cs deleted file mode 100644 index abfdaa64524..00000000000 --- a/src/System.Drawing.Common/tests/FontTests.cs +++ /dev/null @@ -1,975 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Text; -using System.Runtime.InteropServices; - -namespace System.Drawing.Tests; - -public class FontTests -{ - public static IEnumerable Ctor_Family_Size_TestData() - { - yield return new object[] { FontFamily.GenericMonospace, 1 }; - yield return new object[] { FontFamily.GenericSerif, float.MaxValue }; - } - - public static IEnumerable FontFamily_Equals_SameFamily_TestData() - { - yield return new object[] { FontFamily.GenericMonospace, 1 }; - yield return new object[] { FontFamily.GenericSerif, float.MaxValue }; - yield return new object[] { FontFamily.GenericSansSerif, 10 }; - } - - public static IEnumerable FontFamily_Equals_DifferentFamily_TestData() - { - yield return new object[] { FontFamily.GenericMonospace, FontFamily.GenericSerif }; - yield return new object[] { FontFamily.GenericSansSerif, FontFamily.GenericSerif }; - yield return new object[] { FontFamily.GenericSansSerif, FontFamily.GenericMonospace }; - } - - [Theory] - [MemberData(nameof(FontFamily_Equals_SameFamily_TestData))] - public void Font_Equals_SameFontFamily(FontFamily fontFamily, float size) - { - using (var font1 = new Font(fontFamily, size)) - using (var font2 = new Font(fontFamily, size)) - { - Assert.True(font1.Equals(font2)); - } - } - - [Theory] - [MemberData(nameof(FontFamily_Equals_DifferentFamily_TestData))] - public void Font_Equals_DifferentFontFamily(FontFamily fontFamily1, FontFamily fontFamily2) - { - using (var font1 = new Font(fontFamily1, 9)) - using (var font2 = new Font(fontFamily2, 9)) - { - // In some Linux distros all the default fonts live under the same family (Fedora, Centos, Redhat) - if (font1.FontFamily.GetHashCode() != font2.FontFamily.GetHashCode()) - Assert.False(font1.Equals(font2)); - } - } - - [Fact] - public void FontFamily_Equals_NullObject() - { - FontFamily nullFamily = null; - Assert.False(FontFamily.GenericMonospace.Equals(nullFamily)); - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_TestData))] - public void Ctor_Family_Size(FontFamily fontFamily, float emSize) - { - try - { - using (var font = new Font(fontFamily, emSize)) - { - VerifyFont(font, fontFamily.Name, emSize, FontStyle.Regular, GraphicsUnit.Point, 1, false); - } - } - finally - { - fontFamily.Dispose(); - } - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_TestData))] - public void Ctor_FamilyName_Size(FontFamily fontFamily, float emSize) - { - try - { - using (var font = new Font(fontFamily.Name, emSize)) - { - VerifyFont(font, fontFamily.Name, emSize, FontStyle.Regular, GraphicsUnit.Point, 1, false); - } - } - finally - { - fontFamily.Dispose(); - } - } - - public static IEnumerable Ctor_Family_Size_Style_TestData() - { - yield return new object[] { FontFamily.GenericMonospace, 1, FontStyle.Bold }; - yield return new object[] { FontFamily.GenericSerif, 2, FontStyle.Italic }; - yield return new object[] { FontFamily.GenericSansSerif, 3, FontStyle.Regular }; - yield return new object[] { FontFamily.GenericSerif, 4, FontStyle.Strikeout }; - yield return new object[] { FontFamily.GenericSerif, float.MaxValue, FontStyle.Underline }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)(-1) }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)int.MinValue }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)int.MaxValue }; - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_Style_TestData))] - public void Ctor_Family_Size_Style(FontFamily fontFamily, float emSize, FontStyle style) - { - try - { - using (var font = new Font(fontFamily, emSize, style)) - { - VerifyFont(font, fontFamily.Name, emSize, style, GraphicsUnit.Point, 1, false); - } - } - finally - { - fontFamily.Dispose(); - } - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_Style_TestData))] - public void Ctor_FamilyName_Size_Style(FontFamily fontFamily, float emSize, FontStyle style) - { - try - { - using (var font = new Font(fontFamily.Name, emSize, style)) - { - VerifyFont(font, fontFamily.Name, emSize, style, GraphicsUnit.Point, 1, false); - } - } - finally - { - fontFamily.Dispose(); - } - } - - public static IEnumerable Ctor_Family_Size_Unit_TestData() - { - yield return new object[] { FontFamily.GenericMonospace, 1, GraphicsUnit.Document }; - yield return new object[] { FontFamily.GenericSerif, 2, GraphicsUnit.Inch }; - yield return new object[] { FontFamily.GenericSansSerif, 3, GraphicsUnit.Millimeter }; - yield return new object[] { FontFamily.GenericSerif, 4, GraphicsUnit.Point }; - yield return new object[] { FontFamily.GenericSerif, float.MaxValue, GraphicsUnit.Pixel }; - yield return new object[] { FontFamily.GenericSerif, 16, GraphicsUnit.World }; - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_Unit_TestData))] - public void Ctor_Family_Size_Unit(FontFamily fontFamily, float emSize, GraphicsUnit unit) - { - try - { - using (var font = new Font(fontFamily, emSize, unit)) - { - VerifyFont(font, fontFamily.Name, emSize, FontStyle.Regular, unit, 1, false); - } - } - finally - { - fontFamily.Dispose(); - } - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_Unit_TestData))] - public void Ctor_FamilyName_Size_Unit(FontFamily fontFamily, float emSize, GraphicsUnit unit) - { - try - { - using (var font = new Font(fontFamily.Name, emSize, unit)) - { - VerifyFont(font, fontFamily.Name, emSize, FontStyle.Regular, unit, 1, false); - } - } - finally - { - fontFamily.Dispose(); - } - } - - public static IEnumerable Ctor_Family_Size_Style_Unit_TestData() - { - yield return new object[] { FontFamily.GenericMonospace, 1, FontStyle.Bold, GraphicsUnit.Document }; - yield return new object[] { FontFamily.GenericSerif, 2, FontStyle.Italic, GraphicsUnit.Inch }; - yield return new object[] { FontFamily.GenericSansSerif, 3, FontStyle.Regular, GraphicsUnit.Millimeter }; - yield return new object[] { FontFamily.GenericSerif, 4, FontStyle.Strikeout, GraphicsUnit.Point }; - yield return new object[] { FontFamily.GenericSerif, float.MaxValue, FontStyle.Underline, GraphicsUnit.Pixel }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)(-1), GraphicsUnit.World }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)int.MinValue, GraphicsUnit.Millimeter }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)int.MaxValue, GraphicsUnit.Millimeter }; - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_Style_Unit_TestData))] - public void Ctor_Family_Size_Style_Unit(FontFamily fontFamily, float emSize, FontStyle style, GraphicsUnit unit) - { - try - { - using (var font = new Font(fontFamily, emSize, style, unit)) - { - VerifyFont(font, fontFamily.Name, emSize, style, unit, 1, false); - } - } - finally - { - fontFamily.Dispose(); - } - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_Style_Unit_TestData))] - public void Ctor_FamilyName_Size_Style_Unit(FontFamily fontFamily, float emSize, FontStyle style, GraphicsUnit unit) - { - try - { - using (var font = new Font(fontFamily.Name, emSize, style, unit)) - { - VerifyFont(font, fontFamily.Name, emSize, style, unit, 1, false); - } - } - finally - { - fontFamily.Dispose(); - } - } - - public static IEnumerable Ctor_Family_Size_Style_Unit_GdiCharSet_TestData() - { - yield return new object[] { FontFamily.GenericMonospace, 1, FontStyle.Bold, GraphicsUnit.Document, 0 }; - yield return new object[] { FontFamily.GenericSerif, 2, FontStyle.Italic, GraphicsUnit.Inch, 1 }; - yield return new object[] { FontFamily.GenericSansSerif, 3, FontStyle.Regular, GraphicsUnit.Millimeter, 255 }; - yield return new object[] { FontFamily.GenericSerif, 4, FontStyle.Strikeout, GraphicsUnit.Point, 10 }; - yield return new object[] { FontFamily.GenericSerif, float.MaxValue, FontStyle.Underline, GraphicsUnit.Pixel, 10 }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)(-1), GraphicsUnit.World, 8 }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)int.MinValue, GraphicsUnit.Millimeter, 127 }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)int.MaxValue, GraphicsUnit.Millimeter, 200 }; - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_Style_Unit_GdiCharSet_TestData))] - public void Ctor_Family_Size_Style_Unit_GdiCharSet(FontFamily fontFamily, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) - { - try - { - using (var font = new Font(fontFamily, emSize, style, unit, gdiCharSet)) - { - VerifyFont(font, fontFamily.Name, emSize, style, unit, gdiCharSet, false); - } - } - finally - { - fontFamily.Dispose(); - } - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_Style_Unit_GdiCharSet_TestData))] - public void Ctor_FamilyName_Size_Style_Unit_GdiCharSet(FontFamily fontFamily, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) - { - try - { - using (var font = new Font(fontFamily.Name, emSize, style, unit, gdiCharSet)) - { - VerifyFont(font, fontFamily.Name, emSize, style, unit, gdiCharSet, false); - } - } - finally - { - fontFamily.Dispose(); - } - } - - public static IEnumerable Ctor_Family_Size_Style_Unit_GdiCharSet_GdiVerticalFont_TestData() - { - yield return new object[] { FontFamily.GenericMonospace, 1, FontStyle.Bold, GraphicsUnit.Document, 0, true }; - yield return new object[] { FontFamily.GenericSerif, 2, FontStyle.Italic, GraphicsUnit.Inch, 1, false }; - yield return new object[] { FontFamily.GenericSansSerif, 3, FontStyle.Regular, GraphicsUnit.Millimeter, 255, true }; - yield return new object[] { FontFamily.GenericSerif, 4, FontStyle.Strikeout, GraphicsUnit.Point, 10, false }; - yield return new object[] { FontFamily.GenericSerif, float.MaxValue, FontStyle.Underline, GraphicsUnit.Pixel, 10, true }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)(-1), GraphicsUnit.World, 8, false }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)int.MinValue, GraphicsUnit.Millimeter, 127, true }; - yield return new object[] { FontFamily.GenericSerif, 16, (FontStyle)int.MaxValue, GraphicsUnit.Millimeter, 200, false }; - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_Style_Unit_GdiCharSet_GdiVerticalFont_TestData))] - public void Ctor_Family_Size_Style_Unit_GdiCharSet_GdiVerticalFont(FontFamily fontFamily, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) - { - try - { - using (var font = new Font(fontFamily, emSize, style, unit, gdiCharSet, gdiVerticalFont)) - { - VerifyFont(font, fontFamily.Name, emSize, style, unit, gdiCharSet, gdiVerticalFont); - } - } - finally - { - fontFamily.Dispose(); - } - } - - [Theory] - [MemberData(nameof(Ctor_Family_Size_Style_Unit_GdiCharSet_GdiVerticalFont_TestData))] - public void Ctor_FamilyName_Size_Style_Unit_GdiCharSet_GdiVerticalFont(FontFamily fontFamily, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) - { - try - { - using (var font = new Font(fontFamily.Name, emSize, style, unit, gdiCharSet, gdiVerticalFont)) - { - VerifyFont(font, fontFamily.Name, emSize, style, unit, gdiCharSet, gdiVerticalFont); - } - } - finally - { - fontFamily.Dispose(); - } - } - - [Fact] - public void Ctor_FamilyNamePrefixedWithAtSign_StripsSign() - { - using (FontFamily family = FontFamily.GenericMonospace) - using (var font = new Font($"@{family.Name}", 10)) - { - Assert.Equal(family.Name, font.Name); - Assert.Equal($"@{family.Name}", font.OriginalFontName); - } - } - - [Fact] - public void Ctor_NullFont_ThrowsNullReferenceException() - { - Assert.Throws(() => new Font(null, FontStyle.Regular)); - } - - [Fact] - public void Ctor_DisposedFont_Success() - { - using (FontFamily family = FontFamily.GenericSerif) - { - var font = new Font(family, 10); - font.Dispose(); - - using (var copy = new Font(font, FontStyle.Italic)) - { - Assert.Equal(FontStyle.Italic, copy.Style); - Assert.Equal(family.Name, copy.Name); - } - } - } - - [Fact] - public void Ctor_NullFamily_ThrowsArgumentNullException() - { - AssertExtensions.Throws("family", () => new Font((FontFamily)null, 10)); - AssertExtensions.Throws("family", () => new Font((FontFamily)null, 10, FontStyle.Italic)); - AssertExtensions.Throws("family", () => new Font((FontFamily)null, 10, GraphicsUnit.Display)); - AssertExtensions.Throws("family", () => new Font((FontFamily)null, 10, FontStyle.Italic, GraphicsUnit.Display)); - AssertExtensions.Throws("family", () => new Font((FontFamily)null, 10, FontStyle.Italic, GraphicsUnit.Display, 10)); - AssertExtensions.Throws("family", () => new Font((FontFamily)null, 10, FontStyle.Italic, GraphicsUnit.Display, 10, gdiVerticalFont: true)); - } - - [Fact] - public void Ctor_DisposedFamily_ThrowsArgumentException() - { - FontFamily family = FontFamily.GenericSansSerif; - family.Dispose(); - - AssertExtensions.Throws(null, () => new Font(family, 10)); - AssertExtensions.Throws(null, () => new Font(family, 10, FontStyle.Italic)); - AssertExtensions.Throws(null, () => new Font(family, 10, GraphicsUnit.Display)); - AssertExtensions.Throws(null, () => new Font(family, 10, FontStyle.Italic, GraphicsUnit.Display)); - AssertExtensions.Throws(null, () => new Font(family, 10, FontStyle.Italic, GraphicsUnit.Display, 10)); - AssertExtensions.Throws(null, () => new Font(family, 10, FontStyle.Italic, GraphicsUnit.Display, 10, gdiVerticalFont: true)); - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(float.NaN)] - [InlineData(float.NegativeInfinity)] - [InlineData(float.PositiveInfinity)] - public void Ctor_InvalidEmSize_ThrowsArgumentException(float emSize) - { - using (FontFamily family = FontFamily.GenericSansSerif) - { - AssertExtensions.Throws("emSize", () => new Font(family, emSize)); - AssertExtensions.Throws("emSize", () => new Font(family.Name, emSize)); - AssertExtensions.Throws("emSize", () => new Font(family, emSize, FontStyle.Italic)); - AssertExtensions.Throws("emSize", () => new Font(family.Name, emSize, FontStyle.Italic)); - AssertExtensions.Throws("emSize", () => new Font(family, emSize, GraphicsUnit.Document)); - AssertExtensions.Throws("emSize", () => new Font(family.Name, emSize, GraphicsUnit.Document)); - AssertExtensions.Throws("emSize", () => new Font(family, emSize, FontStyle.Italic, GraphicsUnit.Document)); - AssertExtensions.Throws("emSize", () => new Font(family.Name, emSize, FontStyle.Italic, GraphicsUnit.Document)); - AssertExtensions.Throws("emSize", () => new Font(family, emSize, FontStyle.Italic, GraphicsUnit.Document, 10)); - AssertExtensions.Throws("emSize", () => new Font(family.Name, emSize, FontStyle.Italic, GraphicsUnit.Document, 10)); - AssertExtensions.Throws("emSize", () => new Font(family, emSize, FontStyle.Italic, GraphicsUnit.Document, 10, gdiVerticalFont: true)); - AssertExtensions.Throws("emSize", () => new Font(family.Name, emSize, FontStyle.Italic, GraphicsUnit.Document, 10, gdiVerticalFont: true)); - } - } - - [Theory] - [InlineData(GraphicsUnit.Display)] - [InlineData(GraphicsUnit.World - 1)] - [InlineData(GraphicsUnit.Millimeter + 1)] - public void Ctor_InvalidUnit_ThrowsArgumentException(GraphicsUnit unit) - { - using (FontFamily family = FontFamily.GenericSansSerif) - { - AssertExtensions.Throws(null, () => new Font(family, 10, unit)); - AssertExtensions.Throws(null, () => new Font(family.Name, 10, unit)); - AssertExtensions.Throws(null, () => new Font(family, 10, FontStyle.Italic, unit)); - AssertExtensions.Throws(null, () => new Font(family.Name, 10, FontStyle.Italic, unit)); - AssertExtensions.Throws(null, () => new Font(family, 10, FontStyle.Italic, unit, 10)); - AssertExtensions.Throws(null, () => new Font(family.Name, 10, FontStyle.Italic, unit, 10)); - AssertExtensions.Throws(null, () => new Font(family, 10, FontStyle.Italic, unit, 10, gdiVerticalFont: true)); - AssertExtensions.Throws(null, () => new Font(family.Name, 10, FontStyle.Italic, unit, 10, gdiVerticalFont: true)); - } - } - - [Fact] - public void Clone_Invoke_ReturnsExpected() - { - using (FontFamily family = FontFamily.GenericSansSerif) - using (var font = new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: true)) - { - Font clone = Assert.IsType(font.Clone()); - Assert.NotSame(font, clone); - - Assert.Equal(font.Name, clone.FontFamily.Name); - Assert.Equal(font.Size, clone.Size); - Assert.Equal(font.Style, clone.Style); - Assert.Equal(font.Unit, clone.Unit); - Assert.Equal(font.GdiCharSet, clone.GdiCharSet); - Assert.Equal(font.GdiVerticalFont, clone.GdiVerticalFont); - } - } - - [Fact] - public void Clone_DisposedFont_ThrowsArgumentException() - { - using (FontFamily family = FontFamily.GenericSansSerif) - { - var font = new Font(family, 10); - font.Dispose(); - - AssertExtensions.Throws(null, () => font.Clone()); - } - } - - public static IEnumerable Equals_TestData() - { - FontFamily family = FontFamily.GenericSansSerif; - var font = new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: true); - - yield return new object[] { font, font, true }; - yield return new object[] { font.Clone(), new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: true), false }; - yield return new object[] { font.Clone(), new Font(family, 9, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: true), false }; - yield return new object[] { font.Clone(), new Font(family, 10, FontStyle.Italic, GraphicsUnit.Millimeter, 10, gdiVerticalFont: true), false }; - yield return new object[] { font.Clone(), new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 9, gdiVerticalFont: true), false }; - yield return new object[] { font.Clone(), new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: false), false }; - - yield return new object[] { new Font(family, 10), new object(), false }; - yield return new object[] { new Font(family, 10), null, false }; - } - - [Theory] - [MemberData(nameof(Equals_TestData))] - public void Equals_Other_ReturnsExpected(Font font, object other, bool expected) - { - // Windows7 GDI+ returns different results than later versions of Windows. - if (PlatformDetection.IsWindows7) - { - return; - } - - try - { - Assert.Equal(expected, font.Equals(other)); - Assert.Equal(font.GetHashCode(), font.GetHashCode()); - } - finally - { - font.Dispose(); - if (other is Font otherFont && !ReferenceEquals(font, otherFont)) - { - otherFont.Dispose(); - } - } - } - - [Fact] - public void FromHdc_ZeroHdc_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => Font.FromHdc(IntPtr.Zero)); - } - - [Fact] - public void FromHdc_GraphicsHdc_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - IntPtr hdc = graphics.GetHdc(); - try - { - AssertExtensions.Throws(null, () => Font.FromHdc(hdc)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void FromHfont_Zero_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => Font.FromHfont(IntPtr.Zero)); - } - - [Fact] - public void GetHeight_Parameterless_ReturnsExpected() - { - using (FontFamily family = FontFamily.GenericSansSerif) - using (var font = new Font(family, 10)) - { - float height = font.GetHeight(); - AssertExtensions.GreaterThan(height, 0); - - Assert.Equal((int)Math.Ceiling(height), font.Height); - } - } - - [Fact] - public void GetHeight_Graphics_ReturnsExpected() - { - using (FontFamily family = FontFamily.GenericSansSerif) - using (var font = new Font(family, 10)) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - Assert.Equal((double)font.GetHeight(graphics.DpiY), font.GetHeight(graphics), 5); - } - } - - [Theory] - [InlineData(0, 0)] - [InlineData(-1, -0.1571995)] - [InlineData(1, 0.1571995)] - [InlineData(float.NaN, float.NaN)] - [InlineData(float.PositiveInfinity, float.PositiveInfinity)] - [InlineData(float.NegativeInfinity, float.NegativeInfinity)] - public void GetHeight_Dpi_ReturnsExpected(float dpi, float expected) - { - using (FontFamily family = FontFamily.GenericSansSerif) - using (var font = new Font(family, 10)) - { - Assert.Equal((double)expected, font.GetHeight(dpi), 5); - } - } - - [Fact] - public void GetHeight_NullGraphics_ThrowsArgumentNullException() - { - using (FontFamily family = FontFamily.GenericSansSerif) - using (var font = new Font(family, 10)) - { - AssertExtensions.Throws("graphics", () => font.GetHeight(null)); - } - } - - [Fact] - public void GetHeight_DisposedGraphics_ThrowsArgumentException() - { - using (FontFamily family = FontFamily.GenericMonospace) - using (var font = new Font(family, 10)) - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => font.GetHeight(graphics)); - } - } - - [Fact] - public void GetHeight_Disposed_ThrowsArgumentException() - { - using (FontFamily family = FontFamily.GenericSansSerif) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var font = new Font(family, 10); - font.Dispose(); - - AssertExtensions.Throws(null, () => font.GetHeight()); - AssertExtensions.Throws(null, () => font.GetHeight(10)); - AssertExtensions.Throws(null, () => font.GetHeight(graphics)); - } - } - - [Theory] - [InlineData(FontStyle.Bold, int.MinValue, 0)] - [InlineData(FontStyle.Bold, -2147483099, 0)] - [InlineData(FontStyle.Regular, -2147483098, 0)] - [InlineData(FontStyle.Regular, -1, 0)] - [InlineData(FontStyle.Regular, 0, 0)] - [InlineData(FontStyle.Regular, 300, 0)] - [InlineData(FontStyle.Regular, 400, 0)] - [InlineData(FontStyle.Strikeout | FontStyle.Underline | FontStyle.Italic, 549, 1)] - [InlineData(FontStyle.Strikeout | FontStyle.Underline | FontStyle.Italic | FontStyle.Bold, 550, 1)] - [InlineData(FontStyle.Strikeout | FontStyle.Underline | FontStyle.Bold | FontStyle.Italic, int.MaxValue, 1)] - public void FromLogFont_ValidLogFont_ReturnsExpected(FontStyle fontStyle, int weight, byte charSet) - { - // The boundary values of the weight that is considered Bold are different between Windows 7 and Windows 8. - if (PlatformDetection.IsWindows7 || PlatformDetection.IsWindows8x) - { - return; - } - - using (FontFamily family = FontFamily.GenericMonospace) - { - var logFont = new LOGFONT - { - lfFaceName = family.Name, - lfWeight = weight, - lfItalic = (fontStyle & FontStyle.Italic) != 0 ? (byte)1 : (byte)0, - lfStrikeOut = (fontStyle & FontStyle.Strikeout) != 0 ? (byte)1 : (byte)0, - lfUnderline = (fontStyle & FontStyle.Underline) != 0 ? (byte)1 : (byte)0, - lfCharSet = charSet - }; - using (Font font = Font.FromLogFont(logFont)) - { - VerifyFont(font, family.Name, font.Size, fontStyle, GraphicsUnit.World, charSet, expectedGdiVerticalFont: false); - } - } - } - - [Fact] - public void FromLogFont_NullLogFont_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - IntPtr hdc = graphics.GetHdc(); - try - { - if (PlatformDetection.IsNetFramework) - { - AssertExtensions.Throws(null, () => Font.FromLogFont(null)); - AssertExtensions.Throws(null, () => Font.FromLogFont(null, hdc)); - } - else - { - AssertExtensions.Throws("lf", () => Font.FromLogFont(null)); - AssertExtensions.Throws("lf", () => Font.FromLogFont(null, hdc)); - } - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void FromLogFont_InvalidLogFont_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - IntPtr hdc = graphics.GetHdc(); - try - { - var logFont = new LOGFONT(); - AssertExtensions.Throws(null, () => Font.FromLogFont(logFont)); - AssertExtensions.Throws(null, () => Font.FromLogFont(logFont, hdc)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void FromLogFont_UnblittableStruct() - { - const byte OUT_TT_ONLY_PRECIS = 7; - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - var logFont = new UnblittableLOGFONT - { - lfOutPrecision = OUT_TT_ONLY_PRECIS - }; - - using (Font font = Font.FromLogFont(logFont)) - { - Assert.NotNull(font); - Assert.NotEmpty(font.Name); - } - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Serializable()] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public struct UnblittableLOGFONT - { - public int lfHeight; - public int lfWidth; - public int lfEscapement; - public int lfOrientation; - public int lfWeight; - public byte lfItalic; - public byte lfUnderline; - public byte lfStrikeOut; - public byte lfCharSet; - public byte lfOutPrecision; - public byte lfClipPrecision; - public byte lfQuality; - public byte lfPitchAndFamily; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] - public string lfFaceName; - } - - [Theory] - [InlineData(GraphicsUnit.Document)] - [InlineData(GraphicsUnit.Inch)] - [InlineData(GraphicsUnit.Millimeter)] - [InlineData(GraphicsUnit.Pixel)] - [InlineData(GraphicsUnit.Point)] - [InlineData(GraphicsUnit.World)] - public void SizeInPoints_Get_ReturnsExpected(GraphicsUnit unit) - { - using (FontFamily family = FontFamily.GenericMonospace) - using (var font = new Font(family, 10, unit)) - { - float sizeInPoints = font.SizeInPoints; - if (unit == GraphicsUnit.Point) - { - Assert.Equal(font.Size, sizeInPoints); - } - else - { - Assert.True(sizeInPoints > 0); - } - } - } - - [Theory] - [InlineData(FontStyle.Strikeout | FontStyle.Bold | FontStyle.Italic, 255, true, "@", 700)] - [InlineData(FontStyle.Regular, 0, false, "", 400)] - [InlineData(FontStyle.Regular, 10, false, "", 400)] - public void ToLogFont_Invoke_ReturnsExpected(FontStyle fontStyle, byte gdiCharSet, bool gdiVerticalFont, string expectedNamePrefix, int expectedWeight) - { - using (FontFamily family = FontFamily.GenericMonospace) - using (var font = new Font(family, 10, fontStyle, GraphicsUnit.Point, gdiCharSet, gdiVerticalFont)) - { - var logFont = new LOGFONT(); - font.ToLogFont(logFont); - - Assert.Equal(-13, logFont.lfHeight); - Assert.Equal(0, logFont.lfWidth); - Assert.Equal(0, logFont.lfEscapement); - Assert.Equal(0, logFont.lfOrientation); - Assert.Equal(expectedWeight, logFont.lfWeight); - Assert.Equal(font.Italic ? 1 : 0, logFont.lfItalic); - Assert.Equal(font.Underline ? 1 : 0, logFont.lfUnderline); - Assert.Equal(font.Strikeout ? 1 : 0, logFont.lfStrikeOut); - Assert.Equal(SystemFonts.DefaultFont.GdiCharSet <= 2 ? font.GdiCharSet : SystemFonts.DefaultFont.GdiCharSet, logFont.lfCharSet); - Assert.Equal(0, logFont.lfOutPrecision); - Assert.Equal(0, logFont.lfClipPrecision); - Assert.Equal(0, logFont.lfQuality); - Assert.Equal(0, logFont.lfPitchAndFamily); - Assert.Equal($"{expectedNamePrefix}{family.Name}", logFont.lfFaceName); - } - } - - [Theory] - [InlineData(TextRenderingHint.SystemDefault)] - [InlineData(TextRenderingHint.AntiAlias)] - [InlineData(TextRenderingHint.AntiAliasGridFit)] - [InlineData(TextRenderingHint.SingleBitPerPixel)] - [InlineData(TextRenderingHint.SingleBitPerPixelGridFit)] - [InlineData(TextRenderingHint.ClearTypeGridFit)] - public void ToLogFont_InvokeGraphics_ReturnsExpected(TextRenderingHint textRenderingHint) - { - using (FontFamily family = FontFamily.GenericMonospace) - using (var font = new Font(family, 10)) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.TextRenderingHint = textRenderingHint; - - var logFont = new LOGFONT(); - font.ToLogFont(logFont, graphics); - - Assert.Equal(-13, logFont.lfHeight); - Assert.Equal(0, logFont.lfWidth); - Assert.Equal(0, logFont.lfEscapement); - Assert.Equal(0, logFont.lfOrientation); - Assert.Equal(400, logFont.lfWeight); - Assert.Equal(0, logFont.lfItalic); - Assert.Equal(0, logFont.lfUnderline); - Assert.Equal(0, logFont.lfStrikeOut); - Assert.Equal(SystemFonts.DefaultFont.GdiCharSet <= 2 ? font.GdiCharSet : SystemFonts.DefaultFont.GdiCharSet, logFont.lfCharSet); - Assert.Equal(0, logFont.lfOutPrecision); - Assert.Equal(0, logFont.lfClipPrecision); - Assert.Equal(0, logFont.lfQuality); - Assert.Equal(0, logFont.lfPitchAndFamily); - Assert.Equal(family.Name, logFont.lfFaceName); - } - } - - [Fact] - public void ToLogFont_NullLogFont_ThrowsArgumentNullException() - { - using (FontFamily family = FontFamily.GenericMonospace) - using (var font = new Font(family, 10)) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - Assert.Throws(() => font.ToLogFont(null)); - Assert.Throws(() => font.ToLogFont(null, graphics)); - } - } - - [Fact] - public void ToLogFont_NullGraphics_ThrowsArgumentNullException() - { - using (FontFamily family = FontFamily.GenericMonospace) - using (var font = new Font(family, 10)) - { - AssertExtensions.Throws("graphics", () => font.ToLogFont(new LOGFONT(), null)); - } - } - - [Fact] - public void ToLogFont_DisposedGraphics_ThrowsArgumentException() - { - using (FontFamily family = FontFamily.GenericMonospace) - using (var font = new Font(family, 10)) - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - Assert.Throws(() => font.ToLogFont(new LOGFONT(), graphics)); - } - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public class LOGFONT - { - public int lfHeight; - public int lfWidth; - public int lfEscapement; - public int lfOrientation; - public int lfWeight; - public byte lfItalic; - public byte lfUnderline; - public byte lfStrikeOut; - public byte lfCharSet; - public byte lfOutPrecision; - public byte lfClipPrecision; - public byte lfQuality; - public byte lfPitchAndFamily; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] - public string lfFaceName; - } - - [Fact] - public void ToHfont_SimpleFont_Roundtrips() - { - using (FontFamily family = FontFamily.GenericSansSerif) - using (var font = new Font(family, 10)) - { - IntPtr hfont = font.ToHfont(); - Assert.NotEqual(IntPtr.Zero, hfont); - Assert.NotEqual(hfont, font.ToHfont()); - - Font newFont = Font.FromHfont(hfont); - Assert.Equal(font.Name, newFont.Name); - } - } - - [Fact] - public void ToHfont_ComplicatedFont_DoesNotRoundtrip() - { - using (FontFamily family = FontFamily.GenericSansSerif) - using (var font = new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: true)) - { - IntPtr hfont = font.ToHfont(); - Assert.NotEqual(IntPtr.Zero, hfont); - Assert.NotEqual(hfont, font.ToHfont()); - - Font newFont = Font.FromHfont(hfont); - Assert.NotEqual(font.Name, newFont.Name); - } - } - - [Fact] - public void ToHfont_Disposed_ThrowsArgumentException() - { - using (FontFamily family = FontFamily.GenericSansSerif) - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var font = new Font(family, 10); - font.Dispose(); - - AssertExtensions.Throws(null, () => font.ToHfont()); - } - } - - [Fact] - public void ToString_Invoke_ReturnsExpected() - { - using (FontFamily family = FontFamily.GenericSansSerif) - using (var font = new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: true)) - { - Assert.Equal($"[Font: Name={family.Name}, Size=10, Units=4, GdiCharSet=10, GdiVerticalFont=True]", font.ToString()); - } - } - - private static void VerifyFont(Font font, string expectedName, float expectedEmSize, FontStyle expectedStyle, GraphicsUnit expectedUnit, byte expectedGdiCharset, bool expectedGdiVerticalFont) - { - Assert.Equal(expectedName, font.Name); - Assert.Equal(expectedEmSize, font.Size); - - Assert.Equal(expectedStyle, font.Style); - Assert.Equal((expectedStyle & FontStyle.Bold) != 0, font.Bold); - Assert.Equal((expectedStyle & FontStyle.Italic) != 0, font.Italic); - Assert.Equal((expectedStyle & FontStyle.Strikeout) != 0, font.Strikeout); - Assert.Equal((expectedStyle & FontStyle.Underline) != 0, font.Underline); - - Assert.Equal(expectedUnit, font.Unit); - Assert.Equal(expectedGdiCharset, font.GdiCharSet); - Assert.Equal(expectedGdiVerticalFont, font.GdiVerticalFont); - - Assert.False(font.IsSystemFont); - Assert.Empty(font.SystemFontName); - } - - [Fact] - public void GetHashCode_DifferentNameSameSizeStyleUnit_HashCodeIsNotSame() - { - using FontFamily family1 = FontFamily.GenericSansSerif; - using var font1 = new Font(family1, 1, FontStyle.Bold, GraphicsUnit.Point); - - using FontFamily family2 = FontFamily.GenericMonospace; - using var font2 = new Font(family2, 1, FontStyle.Bold, GraphicsUnit.Point); - // This test depends on machine setup and whether the fonts we use are installed or not. - // If not installed we could get the same font for the two Font families we are testing for. - if (font1.Name.Equals(font2.Name, StringComparison.OrdinalIgnoreCase)) - return; - - Assert.NotEqual(font1.GetHashCode(), font2.GetHashCode()); - } -} diff --git a/src/System.Drawing.Common/tests/GdiPlusHandlesTests.cs b/src/System.Drawing.Common/tests/GdiPlusHandlesTests.cs deleted file mode 100644 index 8480d47ec7d..00000000000 --- a/src/System.Drawing.Common/tests/GdiPlusHandlesTests.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using Microsoft.DotNet.RemoteExecutor; -using Xunit.Sdk; - -namespace System.Drawing.Tests; - -public static class GdiPlusHandlesTests -{ - public static bool IsDrawingAndRemoteExecutorSupported => RemoteExecutor.IsSupported; - - [ConditionalFact(nameof(IsDrawingAndRemoteExecutorSupported))] - public static void GraphicsDrawIconDoesNotLeakHandles() - { - RemoteExecutor.Invoke(() => - { - const int handleTreshold = 1; - using Bitmap bmp = new(100, 100); - using Icon ico = new(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico")); - - IntPtr hdc = Helpers.GetDC(Helpers.GetForegroundWindow()); - using Graphics graphicsFromHdc = Graphics.FromHdc(hdc); - - using Process currentProcess = Process.GetCurrentProcess(); - IntPtr processHandle = currentProcess.Handle; - - int initialHandles = Helpers.GetGuiResources(processHandle, 0); - ValidateNoWin32Error(initialHandles); - - for (int i = 0; i < 5000; i++) - { - graphicsFromHdc.DrawIcon(ico, 100, 100); - } - - int finalHandles = Helpers.GetGuiResources(processHandle, 0); - ValidateNoWin32Error(finalHandles); - - Assert.InRange(finalHandles, initialHandles - handleTreshold, initialHandles + handleTreshold); - }).Dispose(); - } - - private static void ValidateNoWin32Error(int handleCount) - { - if (handleCount == 0) - { - int error = Marshal.GetLastWin32Error(); - - if (error != 0) - throw new XunitException($"GetGuiResources failed with win32 error: {error}"); - } - } - -} diff --git a/src/System.Drawing.Common/tests/GlobalUsings.cs b/src/System.Drawing.Common/tests/GlobalUsings.cs deleted file mode 100644 index af753dde135..00000000000 --- a/src/System.Drawing.Common/tests/GlobalUsings.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -global using System.Drawing; -global using System.Diagnostics; -global using Xunit; diff --git a/src/System.Drawing.Common/tests/GraphicsTests.Core.cs b/src/System.Drawing.Common/tests/GraphicsTests.Core.cs deleted file mode 100644 index 400f7f4afb9..00000000000 --- a/src/System.Drawing.Common/tests/GraphicsTests.Core.cs +++ /dev/null @@ -1,223 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; -using System.Numerics; - -namespace System.Drawing.Tests; - -public partial class GraphicsTests -{ - private static Matrix3x2 s_testMatrix = Matrix3x2.CreateRotation(45) * Matrix3x2.CreateScale(2) * Matrix3x2.CreateTranslation(new Vector2(10, 20)); - - - [Fact] - public void TransformElements_SetNonInvertibleMatrix_ThrowsArgumentException() - { - using (var image = new Bitmap(5, 5)) - using (Graphics graphics = Graphics.FromImage(image)) - { - Matrix3x2 matrix = new Matrix3x2(123, 24, 82, 16, 47, 30); - AssertExtensions.Throws(null, () => graphics.TransformElements = matrix); - } - } - - [Fact] - public void TransformElements_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.TransformElements); - Assert.Throws(() => graphics.TransformElements = Matrix3x2.Identity); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void TransformElements_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.TransformElements); - AssertExtensions.Throws(null, () => graphics.TransformElements = Matrix3x2.Identity); - } - } - - [Fact] - public void TransformElements_RoundTrip() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.TransformElements = s_testMatrix; - Assert.Equal(s_testMatrix, graphics.TransformElements); - - using (Matrix matrix = graphics.Transform) - { - Assert.Equal(s_testMatrix, matrix.MatrixElements); - } - - using (Matrix matrix = new Matrix()) - { - graphics.Transform = matrix; - Assert.True(graphics.TransformElements.IsIdentity); - } - } - } - - [Fact] - public void DrawRectangle_NullPen_ThrowsArgumentNullException_Core() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawRectangle(null, new RectangleF(0f, 0f, 1f, 1f))); - // other DrawRectangle overloads tested in DrawRectangle_NullPen_ThrowsArgumentNullException() - } - } - - [Fact] - public void DrawRectangle_DisposedPen_ThrowsArgumentException_Core() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawRectangle(pen, new RectangleF(0f, 0f, 1f, 1f))); - // other DrawRectangle overloads tested in DrawRectangle_DisposedPen_ThrowsArgumentException() - } - } - - [Fact] - public void DrawRectangle_Busy_ThrowsInvalidOperationException_Core() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawRectangle(pen, new RectangleF(0f, 0f, 1f, 1f))); - // other DrawRectangle overloads tested in DrawRectangle_Busy_ThrowsInvalidOperationException() - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawRectangle_Disposed_ThrowsArgumentException_Core() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawRectangle(pen, new RectangleF(0f, 0f, 1f, 1f))); - // other DrawRectangle overloads tested in DrawRectangle_Disposed_ThrowsArgumentException() - } - } - - [Fact] - public void FillPie_NullPen_ThrowsArgumentNullException_Core() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("brush", () => graphics.FillPie(null, new RectangleF(0, 0, 1, 1), 0, 90)); - // other FillPie overloads tested in FillPie_NullPen_ThrowsArgumentNullException() - } - } - - [Fact] - public void FillPie_DisposedPen_ThrowsArgumentException_Core() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var brush = new SolidBrush(Color.Red); - brush.Dispose(); - - AssertExtensions.Throws(null, () => graphics.FillPie(brush, new RectangleF(0, 0, 1, 1), 0, 90)); - // other FillPie overloads tested in FillPie_DisposedPen_ThrowsArgumentException() - } - } - - [Fact] - public void FillPie_ZeroWidth_ThrowsArgumentException_Core() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new SolidBrush(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.FillPie(brush, new RectangleF(0, 0, 0, 1), 0, 90)); - // other FillPie overloads tested in FillPie_ZeroWidth_ThrowsArgumentException() - } - } - - [Fact] - public void FillPie_ZeroHeight_ThrowsArgumentException_Core() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new SolidBrush(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.FillPie(brush, new RectangleF(0, 0, 1, 0), 0, 90)); - // other FillPie overloads tested in FillPie_ZeroHeight_ThrowsArgumentException() - } - } - - [Fact] - public void FillPie_Busy_ThrowsInvalidOperationException_Core() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new SolidBrush(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.FillPie(brush, new RectangleF(0, 0, 1, 1), 0, 90)); - // other FillPie overloads tested in FillPie_Busy_ThrowsInvalidOperationException() - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void FillPie_Disposed_ThrowsArgumentException_Core() - { - using (var image = new Bitmap(10, 10)) - using (var brush = new SolidBrush(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.FillPie(brush, new RectangleF(0, 0, 1, 1), 0, 90)); - // other FillPie overloads tested in FillPie_Disposed_ThrowsArgumentException() - } - } - - - -} diff --git a/src/System.Drawing.Common/tests/GraphicsTests.cs b/src/System.Drawing.Common/tests/GraphicsTests.cs deleted file mode 100644 index 9b3919b818d..00000000000 --- a/src/System.Drawing.Common/tests/GraphicsTests.cs +++ /dev/null @@ -1,3278 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.Drawing.Text; - -namespace System.Drawing.Tests; - -public partial class GraphicsTests -{ - public static bool IsWindows7OrWindowsArm64 => PlatformDetection.IsWindows7 || (PlatformDetection.IsWindows && PlatformDetection.IsArm64Process); - - [Fact] - public void GetHdc_FromHdc_Roundtrips() - { - using (var bitmap = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - IntPtr hdc = graphics.GetHdc(); - try - { - Assert.NotEqual(IntPtr.Zero, hdc); - - using (Graphics graphicsCopy = Graphics.FromHdc(hdc)) - { - VerifyGraphics(graphicsCopy, graphicsCopy.VisibleClipBounds); - } - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void GetHdc_SameImage_ReturnsSame() - { - using (var bitmap = new Bitmap(10, 10)) - using (Graphics graphics1 = Graphics.FromImage(bitmap)) - using (Graphics graphics2 = Graphics.FromImage(bitmap)) - { - try - { - Assert.Equal(graphics1.GetHdc(), graphics2.GetHdc()); - } - finally - { - graphics1.ReleaseHdc(); - graphics2.ReleaseHdc(); - } - } - } - - [Fact] - public void GetHdc_NotReleased_ThrowsInvalidOperationException() - { - using (var bitmap = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.GetHdc()); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void GetHdc_Disposed_ThrowsObjectDisposedException() - { - using (var bitmap = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(bitmap); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.GetHdc()); - } - } - - public static IEnumerable FromHdc_TestData() - { - yield return new object[] { Helpers.GetDC(IntPtr.Zero) }; - yield return new object[] { Helpers.GetWindowDC(IntPtr.Zero) }; - - // Likely the source of #51097- grabbing whatever the current foreground window is is not a great idea. - // Whatever that window is it could disappear at any time and what it's clipping info would be pretty - // random. - // https://github.com/dotnet/winforms/issues/8829 - - // IntPtr foregroundWindow = Helpers.GetForegroundWindow(); - // yield return new object[] { Helpers.GetDC(foregroundWindow) }; - } - - [Theory] - [MemberData(nameof(FromHdc_TestData))] - public void FromHdc_ValidHdc_ReturnsExpected(IntPtr hdc) - { - using (Graphics graphics = Graphics.FromHdc(hdc)) - { - Rectangle expected = Helpers.GetWindowDCRect(hdc); - VerifyGraphics(graphics, expected); - } - } - - [Theory] - [MemberData(nameof(FromHdc_TestData))] - public void FromHdc_ValidHdcWithContext_ReturnsExpected(IntPtr hdc) - { - using (Graphics graphics = Graphics.FromHdc(hdc, IntPtr.Zero)) - { - Rectangle expected = Helpers.GetWindowDCRect(hdc); - VerifyGraphics(graphics, expected); - } - } - - [Theory] - [MemberData(nameof(FromHdc_TestData))] - public void FromHdcInternal_GetDC_ReturnsExpected(IntPtr hdc) - { - using (Graphics graphics = Graphics.FromHdcInternal(hdc)) - { - Rectangle expected = Helpers.GetWindowDCRect(hdc); - VerifyGraphics(graphics, expected); - } - } - - [Fact] - public void FromHdc_ZeroHdc_ThrowsArgumentNullException() - { - AssertExtensions.Throws("hdc", () => Graphics.FromHdc(IntPtr.Zero)); - } - - [Fact] - public void FromHdcInternal_ZeroHdc_ThrowsOutOfMemoryException() - { - Assert.Throws(() => Graphics.FromHdcInternal(IntPtr.Zero)); - } - - [Fact] - public void FromHdc_ZeroHdc_ThrowsOutOfMemoryException() - { - Assert.Throws(() => Graphics.FromHdc(IntPtr.Zero, (IntPtr)10)); - } - - [Fact] - public void FromHdc_InvalidHdc_ThrowsOutOfMemoryException() - { - Assert.Throws(() => Graphics.FromHwnd((IntPtr)10)); - Assert.Throws(() => Graphics.FromHwndInternal((IntPtr)10)); - } - - [Fact] - public void ReleaseHdc_ValidHdc_ResetsHdc() - { - using (var bitmap = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - IntPtr hdc = graphics.GetHdc(); - graphics.ReleaseHdc(); - AssertExtensions.Throws(null, () => graphics.ReleaseHdc(hdc)); - AssertExtensions.Throws(null, () => graphics.ReleaseHdcInternal(hdc)); - - hdc = graphics.GetHdc(); - graphics.ReleaseHdc(hdc); - AssertExtensions.Throws(null, () => graphics.ReleaseHdc()); - AssertExtensions.Throws(null, () => graphics.ReleaseHdcInternal(hdc)); - - hdc = graphics.GetHdc(); - graphics.ReleaseHdcInternal(hdc); - AssertExtensions.Throws(null, () => graphics.ReleaseHdc()); - AssertExtensions.Throws(null, () => graphics.ReleaseHdcInternal(hdc)); - } - } - - [Fact] - public void ReleaseHdc_NoSuchHdc_ResetsHdc() - { - using (var bitmap = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - IntPtr hdc = graphics.GetHdc(); - graphics.ReleaseHdc((IntPtr)10); - AssertExtensions.Throws(null, () => graphics.ReleaseHdcInternal((IntPtr)10)); - - hdc = graphics.GetHdc(); - graphics.ReleaseHdcInternal((IntPtr)10); - AssertExtensions.Throws(null, () => graphics.ReleaseHdc((IntPtr)10)); - } - } - - [Fact] - public void ReleaseHdc_OtherGraphicsHdc_Success() - { - using (var bitmap1 = new Bitmap(10, 10)) - using (var bitmap2 = new Bitmap(10, 10)) - using (Graphics graphics1 = Graphics.FromImage(bitmap1)) - using (Graphics graphics2 = Graphics.FromImage(bitmap2)) - { - IntPtr hdc1 = graphics1.GetHdc(); - IntPtr hdc2 = graphics2.GetHdc(); - Assert.NotEqual(hdc1, hdc2); - - graphics1.ReleaseHdc(hdc2); - AssertExtensions.Throws(null, () => graphics1.ReleaseHdc(hdc1)); - - graphics2.ReleaseHdc(hdc1); - AssertExtensions.Throws(null, () => graphics2.ReleaseHdc(hdc2)); - } - } - - [Fact] - public void ReleaseHdc_NoHdc_ThrowsArgumentException() - { - using (var bitmap = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - AssertExtensions.Throws(null, () => graphics.ReleaseHdc()); - AssertExtensions.Throws(null, () => graphics.ReleaseHdc(IntPtr.Zero)); - AssertExtensions.Throws(null, () => graphics.ReleaseHdcInternal(IntPtr.Zero)); - } - } - - [Fact] - public void ReleaseHdc_Disposed_ThrowsObjectDisposedException() - { - using (var bitmap = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(bitmap); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.ReleaseHdc()); - AssertExtensions.Throws(null, () => graphics.ReleaseHdc(IntPtr.Zero)); - AssertExtensions.Throws(null, () => graphics.ReleaseHdcInternal(IntPtr.Zero)); - } - } - - public static IEnumerable Hwnd_TestData() - { - yield return new object[] { IntPtr.Zero }; - yield return new object[] { Helpers.GetForegroundWindow() }; - } - - [Theory] - [MemberData(nameof(Hwnd_TestData))] - public void FromHwnd_ValidHwnd_ReturnsExpected(IntPtr hWnd) - { - using (Graphics graphics = Graphics.FromHwnd(hWnd)) - { - Rectangle expected = Helpers.GetHWndRect(hWnd); - VerifyGraphics(graphics, expected); - } - } - - [Theory] - [MemberData(nameof(Hwnd_TestData))] - public void FromHwndInternal_ValidHwnd_ReturnsExpected(IntPtr hWnd) - { - using (Graphics graphics = Graphics.FromHwnd(hWnd)) - { - Rectangle expected = Helpers.GetHWndRect(hWnd); - VerifyGraphics(graphics, expected); - } - } - - [Fact] - public void FromHwnd_InvalidHwnd_ThrowsOutOfMemoryException() - { - Assert.Throws(() => Graphics.FromHdc((IntPtr)10)); - Assert.Throws(() => Graphics.FromHdcInternal((IntPtr)10)); - } - - [Theory] - [InlineData(PixelFormat.Format16bppRgb555)] - [InlineData(PixelFormat.Format16bppRgb565)] - [InlineData(PixelFormat.Format24bppRgb)] - [InlineData(PixelFormat.Format32bppArgb)] - [InlineData(PixelFormat.Format32bppPArgb)] - [InlineData(PixelFormat.Format32bppRgb)] - [InlineData(PixelFormat.Format48bppRgb)] - [InlineData(PixelFormat.Format64bppArgb)] - [InlineData(PixelFormat.Format64bppPArgb)] - public void FromImage_Bitmap_Success(PixelFormat format) - { - using (var image = new Bitmap(10, 10, format)) - using (Graphics graphics = Graphics.FromImage(image)) - { - VerifyGraphics(graphics, new Rectangle(Point.Empty, image.Size)); - } - } - - [Fact] - public void FromImage_NullImage_ThrowsArgumentNullException() - { - AssertExtensions.Throws("image", () => Graphics.FromImage(null)); - } - - [Theory] - [InlineData(PixelFormat.Format1bppIndexed)] - [InlineData(PixelFormat.Format4bppIndexed)] - [InlineData(PixelFormat.Format8bppIndexed)] - public void FromImage_IndexedImage_ThrowsException(PixelFormat format) - { - using (var image = new Bitmap(10, 10, format)) - { - Exception exception = AssertExtensions.Throws(() => Graphics.FromImage(image)); - if (exception is ArgumentException argumentException) - Assert.Equal("image", argumentException.ParamName); - } - } - - [Fact] - public void FromImage_DisposedImage_ThrowsArgumentException() - { - var image = new Bitmap(10, 10); - image.Dispose(); - - AssertExtensions.Throws(null, () => Graphics.FromImage(image)); - } - - [Fact] - public void FromImage_Metafile_ThrowsOutOfMemoryException() - { - using (var image = new Metafile(Helpers.GetTestBitmapPath("telescope_01.wmf"))) - { - Assert.Throws(() => Graphics.FromImage(image)); - } - } - - [Theory] - [InlineData(PixelFormat.Format16bppArgb1555)] - [InlineData(PixelFormat.Format16bppGrayScale)] - public void FromImage_Invalid16BitFormat_ThrowsOutOfMemoryException(PixelFormat format) - { - using (var image = new Bitmap(10, 10, format)) - { - Assert.Throws(() => Graphics.FromImage(image)); - } - } - - public static IEnumerable CompositingMode_TestData() - { - yield return new object[] { CompositingMode.SourceCopy, Color.FromArgb(160, 255, 255, 255) }; - yield return new object[] { CompositingMode.SourceOver, Color.FromArgb(220, 185, 185, 185) }; - } - - [Theory] - [MemberData(nameof(CompositingMode_TestData))] - public void CompositingMode_Set_GetReturnsExpected(CompositingMode mode, Color expectedOverlap) - { - Color transparentBlack = Color.FromArgb(160, 0, 0, 0); - Color transparentWhite = Color.FromArgb(160, 255, 255, 255); - - using (var transparentBlackBrush = new SolidBrush(transparentBlack)) - using (var transparentWhiteBrush = new SolidBrush(transparentWhite)) - using (var image = new Bitmap(3, 3)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var targetImage = new Bitmap(3, 3)) - using (Graphics targetGraphics = Graphics.FromImage(targetImage)) - { - graphics.CompositingMode = mode; - Assert.Equal(mode, graphics.CompositingMode); - - graphics.FillRectangle(transparentBlackBrush, new Rectangle(0, 0, 2, 2)); - graphics.FillRectangle(transparentWhiteBrush, new Rectangle(1, 1, 2, 2)); - - targetGraphics.DrawImage(image, Point.Empty); - Helpers.VerifyBitmap(targetImage, new Color[][] - { - new Color[] { transparentBlack, transparentBlack, Helpers.EmptyColor }, - new Color[] { transparentBlack, expectedOverlap, transparentWhite }, - new Color[] { Helpers.EmptyColor, transparentWhite, transparentWhite } - }); - } - } - - [Theory] - [InlineData(CompositingMode.SourceOver - 1)] - [InlineData(CompositingMode.SourceCopy + 1)] - public void CompositingMode_SetInvalid_ThrowsInvalidEnumArgumentException(CompositingMode compositingMode) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("value", () => graphics.CompositingMode = compositingMode); - } - } - - [Fact] - public void CompositingMode_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.CompositingMode); - Assert.Throws(() => graphics.CompositingMode = CompositingMode.SourceCopy); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void CompositingMode_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.CompositingMode); - AssertExtensions.Throws(null, () => graphics.CompositingMode = CompositingMode.SourceCopy); - } - } - - public static IEnumerable CompositingQuality_TestData() - { - Color transparentBlack = Color.FromArgb(160, 0, 0, 0); - Color transparentWhite = Color.FromArgb(160, 255, 255, 255); - var basicExpectedColors = new Color[][] - { - new Color[] { transparentBlack, transparentBlack, Helpers.EmptyColor }, - new Color[] { transparentBlack, Color.FromArgb(220, 185, 185, 185), transparentWhite }, - new Color[] { Helpers.EmptyColor, transparentWhite, transparentWhite } - }; - - yield return new object[] { CompositingQuality.AssumeLinear, basicExpectedColors }; - yield return new object[] { CompositingQuality.Default, basicExpectedColors }; - yield return new object[] { CompositingQuality.HighSpeed, basicExpectedColors }; - yield return new object[] { CompositingQuality.Invalid, basicExpectedColors }; - - var gammaCorrectedColors = new Color[][] - { - new Color[] { Color.FromArgb(159, 0, 0, 0), Color.FromArgb(159, 0, 0, 0), Color.FromArgb(0, 0, 0, 0) }, - new Color[] { Color.FromArgb(159, 0, 0, 0), Color.FromArgb(219, 222, 222, 222), Color.FromArgb(159, 255, 255, 255) }, - new Color[] { Color.FromArgb(0, 0, 0, 0), Color.FromArgb(159, 255, 255, 255), Color.FromArgb(159, 255, 255, 255) } - }; - yield return new object[] { CompositingQuality.GammaCorrected, gammaCorrectedColors }; - yield return new object[] { CompositingQuality.HighQuality, gammaCorrectedColors }; - } - - [Theory] - [MemberData(nameof(CompositingQuality_TestData))] - public void CompositingQuality_Set_GetReturnsExpected(CompositingQuality quality, Color[][] expectedIntersectionColor) - { - Color transparentBlack = Color.FromArgb(160, 0, 0, 0); - Color transparentWhite = Color.FromArgb(160, 255, 255, 255); - - using (var transparentBlackBrush = new SolidBrush(transparentBlack)) - using (var transparentWhiteBrush = new SolidBrush(transparentWhite)) - using (var image = new Bitmap(3, 3)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.CompositingQuality = quality; - Assert.Equal(quality, graphics.CompositingQuality); - - graphics.FillRectangle(transparentBlackBrush, new Rectangle(0, 0, 2, 2)); - graphics.FillRectangle(transparentWhiteBrush, new Rectangle(1, 1, 2, 2)); - - Helpers.VerifyBitmap(image, expectedIntersectionColor); - } - } - - [Theory] - [InlineData(CompositingQuality.Invalid - 1)] - [InlineData(CompositingQuality.AssumeLinear + 1)] - public void CompositingQuality_SetInvalid_ThrowsInvalidEnumArgumentException(CompositingQuality compositingQuality) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("value", () => graphics.CompositingQuality = compositingQuality); - } - } - - [Fact] - public void CompositingQuality_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.CompositingQuality); - Assert.Throws(() => graphics.CompositingQuality = CompositingQuality.AssumeLinear); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void CompositingQuality_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.CompositingQuality); - AssertExtensions.Throws(null, () => graphics.CompositingQuality = CompositingQuality.AssumeLinear); - } - } - - [Fact] - public void Dispose_MultipleTimesWithoutHdc_Success() - { - using (var bitmap = new Bitmap(10, 10)) - { - var graphics = Graphics.FromImage(bitmap); - graphics.Dispose(); - graphics.Dispose(); - - // The backing image is not disposed. - Assert.Equal(10, bitmap.Height); - } - } - - [Fact] - public void Dispose_MultipleTimesWithHdc_Success() - { - using (var bitmap = new Bitmap(10, 10)) - { - var graphics = Graphics.FromImage(bitmap); - graphics.GetHdc(); - - graphics.Dispose(); - graphics.Dispose(); - - // The backing image is not disposed. - Assert.Equal(10, bitmap.Height); - } - } - - [Fact] - public void DpiX_GetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DpiX); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DpiX_GetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DpiX); - } - } - - [Fact] - public void DpiY_GetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DpiX); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DpiY_GetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DpiX); - } - } - - [Theory] - [InlineData(FlushIntention.Flush)] - [InlineData(FlushIntention.Sync)] - [InlineData(FlushIntention.Flush - 1)] // Not in the range of valid values of FlushIntention. - [InlineData(FlushIntention.Sync + 1)] // Not in the range of valid values of FlushIntention. - public void Flush_MultipleTimes_Success(FlushIntention intention) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - if (intention == FlushIntention.Flush) - { - graphics.Flush(); - graphics.Flush(); - } - - graphics.Flush(intention); - graphics.Flush(intention); - } - } - - [Fact] - public void Flush_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.Flush()); - Assert.Throws(() => graphics.Flush(FlushIntention.Sync)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void Flush_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.Flush()); - AssertExtensions.Throws(null, () => graphics.Flush(FlushIntention.Flush)); - } - } - - [Theory] - [InlineData(InterpolationMode.Bicubic, InterpolationMode.Bicubic)] - [InlineData(InterpolationMode.Bilinear, InterpolationMode.Bilinear)] - [InlineData(InterpolationMode.Default, InterpolationMode.Bilinear)] - [InlineData(InterpolationMode.High, InterpolationMode.HighQualityBicubic)] - [InlineData(InterpolationMode.HighQualityBicubic, InterpolationMode.HighQualityBicubic)] - [InlineData(InterpolationMode.HighQualityBilinear, InterpolationMode.HighQualityBilinear)] - [InlineData(InterpolationMode.Low, InterpolationMode.Bilinear)] - [InlineData(InterpolationMode.NearestNeighbor, InterpolationMode.NearestNeighbor)] - public void InterpolationMode_SetValid_GetReturnsExpected(InterpolationMode interpolationMode, InterpolationMode expectedInterpolationMode) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.InterpolationMode = interpolationMode; - Assert.Equal(expectedInterpolationMode, graphics.InterpolationMode); - } - } - - [Theory] - [InlineData(InterpolationMode.Invalid - 1)] - [InlineData(InterpolationMode.HighQualityBicubic + 1)] - public void InterpolationMode_SetInvalid_ThrowsInvalidEnumArgumentException(InterpolationMode interpolationMode) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("value", () => graphics.InterpolationMode = interpolationMode); - } - } - - [Fact] - public void InterpolationMode_SetToInvalid_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.InterpolationMode = InterpolationMode.Invalid); - } - } - - [Fact] - public void InterpolationMode_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.InterpolationMode); - Assert.Throws(() => graphics.InterpolationMode = InterpolationMode.HighQualityBilinear); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void InterpolationMode_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.InterpolationMode); - AssertExtensions.Throws(null, () => graphics.InterpolationMode = InterpolationMode.HighQualityBilinear); - } - } - - [Theory] - [InlineData(1)] - [InlineData(1000000032)] - [InlineData(float.NaN)] - public void PageScale_SetValid_GetReturnsExpected(float pageScale) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.PageScale = pageScale; - Assert.Equal(pageScale, graphics.PageScale); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(1000000033)] - [InlineData(float.NegativeInfinity)] - [InlineData(float.PositiveInfinity)] - public void PageScale_SetInvalid_ThrowsArgumentException(float pageScale) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.PageScale = pageScale); - } - } - - [Fact] - public void PageScale_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.PageScale); - Assert.Throws(() => graphics.PageScale = 10); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void PageScale_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.PageScale); - AssertExtensions.Throws(null, () => graphics.PageScale = 10); - } - } - - [Theory] - [InlineData(GraphicsUnit.Display)] - [InlineData(GraphicsUnit.Document)] - [InlineData(GraphicsUnit.Inch)] - [InlineData(GraphicsUnit.Millimeter)] - [InlineData(GraphicsUnit.Pixel)] - [InlineData(GraphicsUnit.Point)] - public void PageUnit_SetValid_GetReturnsExpected(GraphicsUnit pageUnit) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.PageUnit = pageUnit; - Assert.Equal(pageUnit, graphics.PageUnit); - } - } - - [Theory] - [InlineData(GraphicsUnit.World - 1)] - [InlineData(GraphicsUnit.Millimeter + 1)] - public void PageUnit_SetInvalid_ThrowsInvalidEnumArgumentException(GraphicsUnit pageUnit) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("value", () => graphics.PageUnit = pageUnit); - } - } - - [Fact] - public void PageUnit_SetWorld_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.PageUnit = GraphicsUnit.World); - } - } - - [Fact] - public void PageUnit_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.PageUnit); - Assert.Throws(() => graphics.PageUnit = GraphicsUnit.Document); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void PageUnit_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.PageUnit); - AssertExtensions.Throws(null, () => graphics.PageUnit = GraphicsUnit.Document); - } - } - - [Theory] - [InlineData(PixelOffsetMode.Default)] - [InlineData(PixelOffsetMode.Half)] - [InlineData(PixelOffsetMode.HighQuality)] - [InlineData(PixelOffsetMode.HighSpeed)] - [InlineData(PixelOffsetMode.None)] - public void PixelOffsetMode_SetValid_GetReturnsExpected(PixelOffsetMode pixelOffsetMode) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.PixelOffsetMode = pixelOffsetMode; - Assert.Equal(pixelOffsetMode, graphics.PixelOffsetMode); - } - } - - [Theory] - [InlineData(PixelOffsetMode.Invalid - 1)] - [InlineData(PixelOffsetMode.Half + 1)] - public void PixelOffsetMode_SetInvalid_ThrowsInvalidEnumArgumentException(PixelOffsetMode pixelOffsetMode) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("value", () => graphics.PixelOffsetMode = pixelOffsetMode); - } - } - - [Fact] - public void PixelOffsetMode_SetToInvalid_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.PixelOffsetMode = PixelOffsetMode.Invalid); - } - } - - [Fact] - public void PixelOffsetMode_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.PixelOffsetMode); - Assert.Throws(() => graphics.PixelOffsetMode = PixelOffsetMode.Default); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void PixelOffsetMode_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.PixelOffsetMode); - AssertExtensions.Throws(null, () => graphics.PixelOffsetMode = PixelOffsetMode.Default); - } - } - - public static IEnumerable RenderingOrigin_TestData() - { - Color empty = Color.FromArgb(255, 0, 0, 0); - Color red = Color.FromArgb(Color.Red.ToArgb()); - - yield return new object[] - { - new Point(0, 0), - new Color[][] - { - new Color[] { red, red, red }, - new Color[] { red, empty, empty }, - new Color[] { red, empty, empty } - } - }; - - yield return new object[] - { - new Point(1, 1), - new Color[][] - { - new Color[] { empty, red, empty }, - new Color[] { red, red, red }, - new Color[] { empty, red, empty } - } - }; - - var allEmpty = new Color[][] - { - new Color[] { empty, empty, empty }, - new Color[] { empty, empty, empty }, - new Color[] { empty, empty, empty } - }; - - yield return new object[] { new Point(-3, -3), allEmpty }; - yield return new object[] { new Point(3, 3), allEmpty }; - } - - [Theory] - [MemberData(nameof(RenderingOrigin_TestData))] - public void RenderingOrigin_SetToCustom_RendersExpected(Point renderingOrigin, Color[][] expectedRendering) - { - Color red = Color.FromArgb(Color.Red.ToArgb()); - - using (var image = new Bitmap(3, 3)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new HatchBrush(HatchStyle.Cross, red)) - { - graphics.RenderingOrigin = renderingOrigin; - Assert.Equal(renderingOrigin, graphics.RenderingOrigin); - - graphics.FillRectangle(brush, new Rectangle(0, 0, 3, 3)); - Helpers.VerifyBitmap(image, expectedRendering); - } - } - - [Fact] - public void RenderingOrigin_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.RenderingOrigin); - Assert.Throws(() => graphics.RenderingOrigin = Point.Empty); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void RenderingOrigin_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.RenderingOrigin); - AssertExtensions.Throws(null, () => graphics.RenderingOrigin = Point.Empty); - } - } - - [Theory] - [InlineData(SmoothingMode.AntiAlias, SmoothingMode.AntiAlias)] - [InlineData(SmoothingMode.Default, SmoothingMode.None)] - [InlineData(SmoothingMode.HighQuality, SmoothingMode.AntiAlias)] - [InlineData(SmoothingMode.HighSpeed, SmoothingMode.None)] - [InlineData(SmoothingMode.None, SmoothingMode.None)] - public void SmoothingMode_SetValid_GetReturnsExpected(SmoothingMode smoothingMode, SmoothingMode expectedSmoothingMode) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.SmoothingMode = smoothingMode; - Assert.Equal(expectedSmoothingMode, graphics.SmoothingMode); - } - } - - [Theory] - [InlineData(SmoothingMode.Invalid - 1)] - [InlineData(SmoothingMode.AntiAlias + 1)] - public void SmoothingMode_SetInvalid_ThrowsInvalidEnumArgumentException(SmoothingMode smoothingMode) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("value", () => graphics.SmoothingMode = smoothingMode); - } - } - - [Fact] - public void SmoothingMode_SetToInvalid_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.SmoothingMode = SmoothingMode.Invalid); - } - } - - [Fact] - public void SmoothingMode_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.SmoothingMode); - Assert.Throws(() => graphics.SmoothingMode = SmoothingMode.AntiAlias); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void SmoothingMode_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.SmoothingMode); - AssertExtensions.Throws(null, () => graphics.SmoothingMode = SmoothingMode.AntiAlias); - } - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(12)] - public void TextContrast_SetValid_GetReturnsExpected(int textContrast) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.TextContrast = textContrast; - Assert.Equal(textContrast, graphics.TextContrast); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(13)] - public void TextContrast_SetInvalid_ThrowsArgumentException(int textContrast) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.TextContrast = textContrast); - } - } - - [Fact] - public void TextContrast_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.TextContrast); - Assert.Throws(() => graphics.TextContrast = 5); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void TextContrast_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.TextContrast); - AssertExtensions.Throws(null, () => graphics.TextContrast = 5); - } - } - - [Theory] - [InlineData(TextRenderingHint.AntiAlias)] - [InlineData(TextRenderingHint.AntiAliasGridFit)] - [InlineData(TextRenderingHint.ClearTypeGridFit)] - [InlineData(TextRenderingHint.SingleBitPerPixel)] - [InlineData(TextRenderingHint.SingleBitPerPixelGridFit)] - [InlineData(TextRenderingHint.SystemDefault)] - public void TextRenderingHint_SetValid_GetReturnsExpected(TextRenderingHint textRenderingHint) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.TextRenderingHint = textRenderingHint; - Assert.Equal(textRenderingHint, graphics.TextRenderingHint); - } - } - - [Theory] - [InlineData(TextRenderingHint.SystemDefault - 1)] - [InlineData(TextRenderingHint.ClearTypeGridFit + 1)] - public void TextRenderingHint_SetInvalid_ThrowsInvalidEnumArgumentException(TextRenderingHint textRenderingHint) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("value", () => graphics.TextRenderingHint = textRenderingHint); - } - } - - [Fact] - public void TextRenderingHint_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.TextRenderingHint); - Assert.Throws(() => graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void TextRenderingHint_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.TextRenderingHint); - AssertExtensions.Throws(null, () => graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit); - } - } - - [Fact] - public void Transform_SetValid_GetReturnsExpected() - { - Color empty = Helpers.EmptyColor; - Color red = Color.FromArgb(Color.Red.ToArgb()); - - using (var image = new Bitmap(5, 5)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new SolidBrush(red)) - using (var matrix = new Matrix()) - { - matrix.Scale(1f / 3, 2); - matrix.Translate(2, 1); - matrix.Rotate(270); - - graphics.Transform = matrix; - graphics.FillRectangle(brush, new Rectangle(0, 0, 3, 2)); - Helpers.VerifyBitmap(image, new Color[][] - { - new Color[] { empty, red, empty, empty, empty }, - new Color[] { empty, red, empty, empty, empty }, - new Color[] { empty, empty, empty, empty, empty }, - new Color[] { empty, empty, empty, empty, empty }, - new Color[] { empty, empty, empty, empty, empty } - }); - } - } - - [Fact] - public void Transform_SetNull_ThrowsNullReferenceException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - Assert.Throws(() => graphics.Transform = null); - } - } - - [Fact] - public void Transform_SetDisposedMatrix_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var matrix = new Matrix(); - matrix.Dispose(); - - AssertExtensions.Throws(null, () => graphics.Transform = matrix); - } - } - - [Fact] - public void Transform_SetNonInvertibleMatrix_ThrowsArgumentException() - { - using (var image = new Bitmap(5, 5)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var matrix = new Matrix(123, 24, 82, 16, 47, 30)) - { - AssertExtensions.Throws(null, () => graphics.Transform = matrix); - } - } - - [Fact] - public void Transform_GetSetWhenBusy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var matrix = new Matrix()) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.Transform); - Assert.Throws(() => graphics.Transform = matrix); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void Transform_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var matrix = new Matrix()) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.Transform); - AssertExtensions.Throws(null, () => graphics.Transform = matrix); - } - } - - [Fact] - public void ResetTransform_Invoke_SetsTransformToIdentity() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - Assert.False(graphics.Transform.IsIdentity); - - graphics.ResetTransform(); - Assert.True(graphics.Transform.IsIdentity); - } - } - - [Fact] - public void ResetTransform_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.ResetTransform()); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void ResetTransform_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.ResetTransform()); - } - } - - [Fact] - public void MultiplyTransform_NoOrder_Success() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - using (var matrix = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - Matrix expectedTransform = graphics.Transform; - expectedTransform.Multiply(matrix); - - graphics.MultiplyTransform(matrix); - Assert.Equal(expectedTransform, graphics.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend)] - [InlineData(MatrixOrder.Append)] - public void MultiplyTransform_Order_Success(MatrixOrder order) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - using (var matrix = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - Matrix expectedTransform = graphics.Transform; - expectedTransform.Multiply(matrix, order); - - graphics.MultiplyTransform(matrix, order); - Assert.Equal(expectedTransform, graphics.Transform); - } - } - - [Fact] - public void MultiplyTransform_NullMatrix_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("matrix", () => graphics.MultiplyTransform(null)); - AssertExtensions.Throws("matrix", () => graphics.MultiplyTransform(null, MatrixOrder.Append)); - } - } - - [Fact] - public void MultiplyTransform_DisposedMatrix_Nop() - { - var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true); - Matrix transform = brush.Transform; - - var matrix = new Matrix(); - matrix.Dispose(); - - brush.MultiplyTransform(matrix); - brush.MultiplyTransform(matrix, MatrixOrder.Append); - - Assert.Equal(transform, brush.Transform); - } - - [Fact] - public void MultiplyTransform_NonInvertibleMatrix_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var matrix = new Matrix(123, 24, 82, 16, 47, 30)) - { - AssertExtensions.Throws(null, () => graphics.MultiplyTransform(matrix)); - AssertExtensions.Throws(null, () => graphics.MultiplyTransform(matrix, MatrixOrder.Append)); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void MultiplyTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => graphics.MultiplyTransform(matrix, order)); - } - } - - [Fact] - public void MultiplyTransform_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var matrix = new Matrix()) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.MultiplyTransform(matrix)); - Assert.Throws(() => graphics.MultiplyTransform(matrix, MatrixOrder.Append)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void MultiplyTransform_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var matrix = new Matrix()) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.MultiplyTransform(matrix)); - AssertExtensions.Throws(null, () => graphics.MultiplyTransform(matrix, MatrixOrder.Prepend)); - } - } - - [Theory] - [InlineData(-1, -2)] - [InlineData(0, 0)] - [InlineData(1, 2)] - public void TranslateTransform_NoOrder_Success(float dx, float dy) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - Matrix expectedTransform = graphics.Transform; - expectedTransform.Translate(dx, dy); - - graphics.TranslateTransform(dx, dy); - Assert.Equal(expectedTransform, graphics.Transform); - } - } - - [Theory] - [InlineData(1, 1, MatrixOrder.Prepend)] - [InlineData(1, 1, MatrixOrder.Append)] - [InlineData(0, 0, MatrixOrder.Prepend)] - [InlineData(0, 0, MatrixOrder.Append)] - [InlineData(-1, -1, MatrixOrder.Prepend)] - [InlineData(-1, -1, MatrixOrder.Append)] - public void TranslateTransform_Order_Success(float dx, float dy, MatrixOrder order) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - Matrix expectedTransform = graphics.Transform; - expectedTransform.Translate(dx, dy, order); - - graphics.TranslateTransform(dx, dy, order); - Assert.Equal(expectedTransform, graphics.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void TranslateTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.TranslateTransform(0, 0, order)); - } - } - - [Fact] - public void TranslateTransform_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.TranslateTransform(0, 0)); - Assert.Throws(() => graphics.TranslateTransform(0, 0, MatrixOrder.Append)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void TranslateTransform_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.TranslateTransform(0, 0)); - AssertExtensions.Throws(null, () => graphics.TranslateTransform(0, 0, MatrixOrder.Append)); - } - } - - [Theory] - [InlineData(-1, -2)] - [InlineData(1, 2)] - public void ScaleTransform_NoOrder_Success(float sx, float sy) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - Matrix expectedTransform = graphics.Transform; - expectedTransform.Scale(sx, sy); - - graphics.ScaleTransform(sx, sy); - Assert.Equal(expectedTransform, graphics.Transform); - } - } - - [Theory] - [InlineData(1, 1, MatrixOrder.Prepend)] - [InlineData(1, 1, MatrixOrder.Append)] - [InlineData(-1, -1, MatrixOrder.Prepend)] - [InlineData(-1, -1, MatrixOrder.Append)] - public void ScaleTransform_Order_Success(float sx, float sy, MatrixOrder order) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - Matrix expectedTransform = graphics.Transform; - expectedTransform.Scale(sx, sy, order); - - graphics.ScaleTransform(sx, sy, order); - Assert.Equal(expectedTransform, graphics.Transform); - } - } - - [Fact] - public void ScaleTransform_ZeroZero_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.ScaleTransform(0, 0)); - AssertExtensions.Throws(null, () => graphics.ScaleTransform(0, 0, MatrixOrder.Append)); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void ScaleTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.ScaleTransform(0, 0, order)); - } - } - - [Fact] - public void ScaleTransform_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.ScaleTransform(0, 0)); - Assert.Throws(() => graphics.ScaleTransform(0, 0, MatrixOrder.Append)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void ScaleTransform_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.ScaleTransform(0, 0)); - AssertExtensions.Throws(null, () => graphics.ScaleTransform(0, 0, MatrixOrder.Append)); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(1)] - [InlineData(360)] - public void RotateTransform_NoOrder_Success(float angle) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - Matrix expectedTransform = graphics.Transform; - expectedTransform.Rotate(angle); - - graphics.RotateTransform(angle); - Assert.Equal(expectedTransform, graphics.Transform); - } - } - - [Theory] - [InlineData(1, MatrixOrder.Prepend)] - [InlineData(1, MatrixOrder.Append)] - [InlineData(0, MatrixOrder.Prepend)] - [InlineData(360, MatrixOrder.Append)] - [InlineData(-1, MatrixOrder.Prepend)] - [InlineData(-1, MatrixOrder.Append)] - public void RotateTransform_Order_Success(float angle, MatrixOrder order) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - Matrix expectedTransform = graphics.Transform; - expectedTransform.Rotate(angle, order); - - graphics.RotateTransform(angle, order); - Assert.Equal(expectedTransform, graphics.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void RotateTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder order) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.RotateTransform(0, order)); - } - } - - [Fact] - public void RotateTransform_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.RotateTransform(0)); - Assert.Throws(() => graphics.RotateTransform(0, MatrixOrder.Append)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void RotateTransform_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.RotateTransform(0)); - AssertExtensions.Throws(null, () => graphics.RotateTransform(0, MatrixOrder.Append)); - } - } - - public static IEnumerable CopyFromScreen_TestData() - { - yield return new object[] { 0, 0, 0, 0, new Size(0, 0) }; - yield return new object[] { int.MinValue, int.MinValue, 0, 0, new Size(1, 1) }; - yield return new object[] { int.MaxValue, int.MaxValue, 0, 0, new Size(1, 1) }; - yield return new object[] { int.MaxValue, int.MaxValue, 0, 0, new Size(1, 1) }; - yield return new object[] { 0, 0, -1, -1, new Size(1, 1) }; - yield return new object[] { 0, 0, int.MaxValue, int.MaxValue, new Size(1, 1) }; - yield return new object[] { 0, 0, 0, 0, new Size(-1, -1) }; - } - - [Theory] - [MemberData(nameof(CopyFromScreen_TestData))] - public void CopyFromScreen_OutOfRange_DoesNotAffectGraphics(int sourceX, int sourceY, int destinationX, int destinationY, Size size) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - Color plum = Color.FromArgb(Color.Plum.ToArgb()); - image.SetPixel(0, 0, plum); - - graphics.CopyFromScreen(sourceX, sourceY, destinationX, destinationY, size); - graphics.CopyFromScreen(new Point(sourceX, sourceY), new Point(destinationX, destinationY), size); - Assert.Equal(plum, image.GetPixel(0, 0)); - } - } - - [Theory] - [InlineData(0, 0, 0, 0, 10, 10)] - [InlineData(0, 0, 0, 0, int.MaxValue, int.MaxValue)] - [InlineData(1, 1, 2, 2, 3, 3)] - public void CopyFromScreen_ValidRange_AffectsGraphics(int sourceX, int sourceY, int destinationX, int destinationY, int width, int height) - { - Color color = Color.FromArgb(2, 3, 4); - using Bitmap image = new(10, 10); - using Graphics graphics = Graphics.FromImage(image); - using SolidBrush brush = new(color); - - graphics.FillRectangle(brush, new Rectangle(0, 0, 10, 10)); - graphics.CopyFromScreen(sourceX, sourceY, destinationX, destinationY, new Size(width, height)); - - Rectangle drawnRect = new Rectangle(destinationX, destinationY, width, height); - for (int y = 0; y < image.Height; y++) - { - for (int x = 0; x < image.Width; x++) - { - Color imageColor = image.GetPixel(x, y); - if (!drawnRect.Contains(x, y)) - { - Assert.Equal(color, imageColor); - } - else - { - Assert.NotEqual(color, imageColor); - } - } - } - } - - public static IEnumerable CopyPixelOperation_TestData() - { - yield return new object[] { CopyPixelOperation.NoMirrorBitmap }; - yield return new object[] { CopyPixelOperation.Blackness }; - yield return new object[] { CopyPixelOperation.NotSourceErase }; - yield return new object[] { CopyPixelOperation.NotSourceCopy }; - yield return new object[] { CopyPixelOperation.SourceErase }; - yield return new object[] { CopyPixelOperation.DestinationInvert }; - yield return new object[] { CopyPixelOperation.PatInvert }; - yield return new object[] { CopyPixelOperation.SourceInvert }; - yield return new object[] { CopyPixelOperation.SourceAnd }; - yield return new object[] { CopyPixelOperation.MergePaint }; - yield return new object[] { CopyPixelOperation.MergeCopy }; - yield return new object[] { CopyPixelOperation.SourceCopy }; - yield return new object[] { CopyPixelOperation.SourcePaint }; - yield return new object[] { CopyPixelOperation.SourceCopy }; - yield return new object[] { CopyPixelOperation.PatCopy }; - yield return new object[] { CopyPixelOperation.PatPaint }; - yield return new object[] { CopyPixelOperation.Whiteness }; - yield return new object[] { CopyPixelOperation.CaptureBlt }; - yield return new object[] { CopyPixelOperation.CaptureBlt }; - } - - [Theory] - [MemberData(nameof(CopyPixelOperation_TestData))] - public void CopyFromScreen_IntsAndValidCopyPixelOperation_Success(CopyPixelOperation copyPixelOperation) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - // We don't know what the screen looks like at this point in time, so - // just make sure that this doesn't fail. - graphics.CopyFromScreen(0, 0, 0, 0, new Size(1, 1), copyPixelOperation); - } - } - - [Theory] - [MemberData(nameof(CopyPixelOperation_TestData))] - public void CopyFromScreen_PointsAndValidCopyPixelOperation_Success(CopyPixelOperation copyPixelOperation) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - // We don't know what the screen looks like at this point in time, so - // just make sure that this doesn't fail. - graphics.CopyFromScreen(Point.Empty, Point.Empty, new Size(1, 1), copyPixelOperation); - } - } - - [Theory] - [InlineData(CopyPixelOperation.NoMirrorBitmap + 1)] - [InlineData(CopyPixelOperation.Blackness - 1)] - [InlineData(CopyPixelOperation.NotSourceErase - 1)] - [InlineData(CopyPixelOperation.NotSourceCopy - 1)] - [InlineData(CopyPixelOperation.SourceErase - 1)] - [InlineData(CopyPixelOperation.DestinationInvert - 1)] - [InlineData(CopyPixelOperation.PatInvert - 1)] - [InlineData(CopyPixelOperation.SourceInvert - 1)] - [InlineData(CopyPixelOperation.SourceAnd - 1)] - [InlineData(CopyPixelOperation.MergePaint - 1)] - [InlineData(CopyPixelOperation.MergeCopy - 1)] - [InlineData(CopyPixelOperation.SourceCopy - 1)] - [InlineData(CopyPixelOperation.SourcePaint - 1)] - [InlineData(CopyPixelOperation.PatCopy - 1)] - [InlineData(CopyPixelOperation.PatPaint - 1)] - [InlineData(CopyPixelOperation.Whiteness - 1)] - [InlineData(CopyPixelOperation.CaptureBlt - 1)] - [InlineData(CopyPixelOperation.CaptureBlt + 1)] - public void CopyFromScreen_InvalidCopyPixelOperation_ThrowsInvalidEnumArgumentException(CopyPixelOperation copyPixelOperation) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - Assert.ThrowsAny(() => graphics.CopyFromScreen(1, 2, 3, 4, Size.Empty, copyPixelOperation)); - } - } - - [Fact] - public void CopyFromScreen_Busy_ThrowsInvalidOperationException() - { - using Bitmap image = new(10, 10); - using Graphics graphics = Graphics.FromImage(image); - - nint hdc = graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.CopyFromScreen(0, 0, 0, 0, Size.Empty)); - Assert.Throws(() => graphics.CopyFromScreen(0, 0, 0, 0, Size.Empty, CopyPixelOperation.DestinationInvert)); - Assert.Throws(() => graphics.CopyFromScreen(Point.Empty, Point.Empty, Size.Empty)); - Assert.Throws(() => graphics.CopyFromScreen(Point.Empty, Point.Empty, Size.Empty, CopyPixelOperation.DestinationInvert)); - } - finally - { - graphics.ReleaseHdc(); - } - } - - [Fact] - public void CopyFromScreen_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.CopyFromScreen(0, 0, 0, 0, Size.Empty)); - AssertExtensions.Throws(null, () => graphics.CopyFromScreen(0, 0, 0, 0, Size.Empty, CopyPixelOperation.MergeCopy)); - AssertExtensions.Throws(null, () => graphics.CopyFromScreen(Point.Empty, Point.Empty, Size.Empty)); - AssertExtensions.Throws(null, () => graphics.CopyFromScreen(Point.Empty, Point.Empty, Size.Empty, CopyPixelOperation.MergeCopy)); - } - } - - public static IEnumerable TransformPoints_TestData() - { - yield return new object[] - { - CoordinateSpace.Device, - CoordinateSpace.Page, - new Point[] { new Point(1, 1), new Point(2, 2) }, - new Point[] { new Point(1, 1), new Point(2, 2) } - }; - - yield return new object[] - { - CoordinateSpace.Device, - CoordinateSpace.World, - new Point[] { new Point(1, 1), new Point(2, 2) }, - new Point[] { new Point(9, 12), new Point(13, 18) } - }; - - yield return new object[] - { - CoordinateSpace.Page, - CoordinateSpace.Device, - new Point[] { new Point(1, 1), new Point(2, 2) }, - new Point[] { new Point(1, 1), new Point(2, 2) } - }; - - yield return new object[] - { - CoordinateSpace.Page, - CoordinateSpace.World, - new Point[] { new Point(1, 1), new Point(2, 2) }, - new Point[] { new Point(9, 12), new Point(13, 18) } - }; - - yield return new object[] - { - CoordinateSpace.World, - CoordinateSpace.Device, - new Point[] { new Point(1, 1), new Point(2, 2) }, - new Point[] { new Point(1, -1), new Point(0, -1) } - }; - - yield return new object[] - { - CoordinateSpace.World, - CoordinateSpace.Page, - new Point[] { new Point(1, 1), new Point(2, 2) }, - new Point[] { new Point(1, -1), new Point(0, -1) } - }; - } - - [Theory] - [MemberData(nameof(TransformPoints_TestData))] - public void TransformPoints_Points_Success(CoordinateSpace destSpace, CoordinateSpace srcSpace, Point[] points, Point[] expected) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.PageScale = 10; - graphics.Transform = transform; - - graphics.TransformPoints(destSpace, srcSpace, points); - Assert.Equal(expected, points); - } - } - - public static IEnumerable TransformPointFs_TestData() - { - yield return new object[] - { - CoordinateSpace.Device, - CoordinateSpace.Page, - new PointF[] { new Point(1, 1), new Point(2, 2) }, - new PointF[] { new Point(1, 1), new Point(2, 2) } - }; - - yield return new object[] - { - CoordinateSpace.Device, - CoordinateSpace.World, - new PointF[] { new Point(1, 1), new Point(2, 2) }, - new PointF[] { new Point(9, 12), new Point(13, 18) } - }; - - yield return new object[] - { - CoordinateSpace.Page, - CoordinateSpace.Device, - new PointF[] { new Point(1, 1), new Point(2, 2) }, - new PointF[] { new Point(1, 1), new Point(2, 2) } - }; - - yield return new object[] - { - CoordinateSpace.Page, - CoordinateSpace.World, - new PointF[] { new Point(1, 1), new Point(2, 2) }, - new PointF[] { new Point(9, 12), new Point(13, 18) } - }; - - yield return new object[] - { - CoordinateSpace.World, - CoordinateSpace.Device, - new PointF[] { new Point(1, 1), new Point(2, 2) }, - new PointF[] { new PointF(0.5f, -1.5f), new Point(0, -1) } - }; - - yield return new object[] - { - CoordinateSpace.World, - CoordinateSpace.Page, - new PointF[] { new Point(1, 1), new Point(2, 2) }, - new PointF[] { new PointF(0.5f, -1.5f), new Point(0, -1) } - }; - } - - [Theory] - [MemberData(nameof(TransformPointFs_TestData))] - public void TransformPoints_PointFs_Success(CoordinateSpace destSpace, CoordinateSpace srcSpace, PointF[] points, PointF[] expected) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.PageScale = 10; - graphics.Transform = transform; - - graphics.TransformPoints(destSpace, srcSpace, points); - Assert.Equal(expected, points); - } - } - - [Theory] - [InlineData(CoordinateSpace.Device)] - [InlineData(CoordinateSpace.World)] - [InlineData(CoordinateSpace.Page)] - public void TransformPoints_PointsAndSameCoordinateSpace_DoesNothing(CoordinateSpace space) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - - var points = new Point[] { new Point(1, 1) }; - graphics.TransformPoints(space, space, points); - Assert.Equal(new Point[] { new Point(1, 1) }, points); - } - } - - [Theory] - [InlineData(CoordinateSpace.Device)] - [InlineData(CoordinateSpace.World)] - [InlineData(CoordinateSpace.Page)] - public void TransformPoints_PointFsAndSameCoordinateSpace_DoesNothing(CoordinateSpace space) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - graphics.Transform = transform; - - var points = new PointF[] { new PointF(1, 1) }; - graphics.TransformPoints(space, space, points); - Assert.Equal(new PointF[] { new PointF(1, 1) }, points); - } - } - - [Theory] - [InlineData(CoordinateSpace.World - 1)] - [InlineData(CoordinateSpace.Device + 1)] - public void TransformPoints_InvalidDestSpace_ThrowsArgumentException(CoordinateSpace destSpace) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.TransformPoints(destSpace, CoordinateSpace.World, new Point[] { new Point(1, 1) })); - AssertExtensions.Throws(null, () => graphics.TransformPoints(destSpace, CoordinateSpace.World, new PointF[] { new PointF(1, 1) })); - } - } - - [Theory] - [InlineData(CoordinateSpace.World - 1)] - [InlineData(CoordinateSpace.Device + 1)] - public void TransformPoints_InvalidSourceSpace_ThrowsArgumentException(CoordinateSpace srcSpace) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.TransformPoints(CoordinateSpace.World, srcSpace, new Point[] { new Point(1, 1) })); - AssertExtensions.Throws(null, () => graphics.TransformPoints(CoordinateSpace.World, srcSpace, new PointF[] { new PointF(1, 1) })); - } - } - - [Fact] - public void TransformPoints_NullPoints_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pts", () => graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Page, (Point[])null)); - AssertExtensions.Throws("pts", () => graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Page, (PointF[])null)); - } - } - - [Fact] - public void TransformPoints_EmptyPoints_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws(null, () => graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Page, new Point[0])); - AssertExtensions.Throws(null, () => graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Page, new PointF[0])); - } - } - - [Fact] - public void TransformPoints_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Page, new Point[] { Point.Empty })); - Assert.Throws(() => graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Page, new PointF[] { PointF.Empty })); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void TransformPoints_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Page, new Point[] { Point.Empty })); - AssertExtensions.Throws(null, () => graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Page, new PointF[] { PointF.Empty })); - } - } - - public static IEnumerable GetNearestColor_TestData() - { - yield return new object[] { PixelFormat.Format32bppArgb, Color.Red, Color.FromArgb(Color.Red.ToArgb()) }; - yield return new object[] { PixelFormat.Format16bppRgb555, Color.Red, Color.FromArgb(255, 248, 0, 0) }; - } - - [Theory] - [MemberData(nameof(GetNearestColor_TestData))] - public void GetNearestColor_Color_ReturnsExpected(PixelFormat pixelFormat, Color color, Color expected) - { - using (var image = new Bitmap(10, 10, pixelFormat)) - using (Graphics graphics = Graphics.FromImage(image)) - { - Assert.Equal(expected, graphics.GetNearestColor(color)); - } - } - - [Fact] - public void GetNearestColor_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.GetNearestColor(Color.Red)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void GetNearestColor_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.GetNearestColor(Color.Red)); - } - } - - [Fact] - public void DrawArc_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawArc(null, new Rectangle(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws("pen", () => graphics.DrawArc(null, 0, 0, 1, 1, 0, 90)); - AssertExtensions.Throws("pen", () => graphics.DrawArc(null, new RectangleF(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws("pen", () => graphics.DrawArc(null, 0f, 0f, 1f, 1f, 0, 90)); - } - } - - [Fact] - public void DrawArc_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new Rectangle(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0, 0, 1, 1, 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new RectangleF(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0f, 0f, 1f, 1f, 0, 90)); - } - } - - [Fact] - public void DrawArc_ZeroWidth_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new Rectangle(0, 0, 0, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0, 0, 0, 1, 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new RectangleF(0, 0, 0, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0f, 0f, 0f, 1f, 0, 90)); - } - } - - [Fact] - public void DrawArc_ZeroHeight_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new Rectangle(0, 0, 1, 0), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0, 0, 1, 0, 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new RectangleF(0, 0, 1, 0), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0f, 0f, 1f, 0f, 0, 90)); - } - } - - [Fact] - public void DrawArc_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawArc(pen, new Rectangle(0, 0, 1, 1), 0, 90)); - Assert.Throws(() => graphics.DrawArc(pen, 0, 0, 1, 1, 0, 90)); - Assert.Throws(() => graphics.DrawArc(pen, new RectangleF(0, 0, 1, 1), 0, 90)); - Assert.Throws(() => graphics.DrawArc(pen, 0f, 0f, 1f, 1f, 0, 90)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawArc_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new Rectangle(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0, 0, 1, 1, 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new RectangleF(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0f, 0f, 1f, 1f, 0, 90)); - } - } - - [Fact] - public void DrawRectangle_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawRectangle(null, new Rectangle(0, 0, 1, 1))); - AssertExtensions.Throws("pen", () => graphics.DrawRectangle(null, 0, 0, 1, 1)); - AssertExtensions.Throws("pen", () => graphics.DrawRectangle(null, 0f, 0f, 1f, 1f)); - } - } - - [Fact] - public void DrawRectangle_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawRectangle(pen, new Rectangle(0, 0, 1, 1))); - AssertExtensions.Throws(null, () => graphics.DrawRectangle(pen, 0, 0, 1, 1)); - AssertExtensions.Throws(null, () => graphics.DrawRectangle(pen, 0f, 0f, 1f, 1f)); - } - } - - [Fact] - public void DrawRectangle_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawRectangle(pen, new Rectangle(0, 0, 1, 1))); - Assert.Throws(() => graphics.DrawRectangle(pen, 0, 0, 1, 1)); - Assert.Throws(() => graphics.DrawRectangle(pen, 0f, 0f, 1f, 1f)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawRectangle_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawRectangle(pen, new Rectangle(0, 0, 1, 1))); - AssertExtensions.Throws(null, () => graphics.DrawRectangle(pen, 0, 0, 1, 1)); - AssertExtensions.Throws(null, () => graphics.DrawRectangle(pen, 0f, 0f, 1f, 1f)); - } - } - - [Fact] - public void DrawRectangles_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawRectangles(null, new Rectangle[2])); - AssertExtensions.Throws("pen", () => graphics.DrawRectangles(null, new RectangleF[2])); - } - } - - [Fact] - public void DrawRectangles_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawRectangles(pen, new Rectangle[2])); - AssertExtensions.Throws(null, () => graphics.DrawRectangles(pen, new RectangleF[2])); - } - } - - [Fact] - public void DrawRectangles_NullRectangles_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws("rects", () => graphics.DrawRectangles(pen, (Rectangle[])null)); - AssertExtensions.Throws("rects", () => graphics.DrawRectangles(pen, (RectangleF[])null)); - } - } - - [Fact] - public void DrawRectangles_EmptyRectangles_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawRectangles(pen, new Rectangle[0])); - AssertExtensions.Throws(null, () => graphics.DrawRectangles(pen, new RectangleF[0])); - } - } - - [Fact] - public void DrawRectangles_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawRectangles(pen, new Rectangle[2])); - Assert.Throws(() => graphics.DrawRectangles(pen, new RectangleF[2])); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawRectangles_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawRectangles(pen, new Rectangle[2])); - AssertExtensions.Throws(null, () => graphics.DrawRectangles(pen, new RectangleF[2])); - } - } - - [Fact] - public void DrawEllipse_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawEllipse(null, new Rectangle(0, 0, 1, 1))); - AssertExtensions.Throws("pen", () => graphics.DrawEllipse(null, 0, 0, 1, 1)); - AssertExtensions.Throws("pen", () => graphics.DrawEllipse(null, new RectangleF(0, 0, 1, 1))); - AssertExtensions.Throws("pen", () => graphics.DrawEllipse(null, 0f, 0f, 1f, 1f)); - } - } - - [Fact] - public void DrawEllipse_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - - AssertExtensions.Throws(null, () => graphics.DrawEllipse(pen, new Rectangle(0, 0, 1, 1))); - AssertExtensions.Throws(null, () => graphics.DrawEllipse(pen, 0, 0, 1, 1)); - AssertExtensions.Throws(null, () => graphics.DrawEllipse(pen, new RectangleF(0, 0, 1, 1))); - AssertExtensions.Throws(null, () => graphics.DrawEllipse(pen, 0f, 0f, 1f, 1f)); - } - } - - [Fact] - public void DrawEllipse_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawEllipse(pen, new Rectangle(0, 0, 1, 1))); - Assert.Throws(() => graphics.DrawEllipse(pen, 0, 0, 1, 1)); - Assert.Throws(() => graphics.DrawEllipse(pen, new RectangleF(0, 0, 1, 1))); - Assert.Throws(() => graphics.DrawEllipse(pen, 0f, 0f, 1f, 1f)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawEllipse_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawEllipse(pen, new Rectangle(0, 0, 1, 1))); - AssertExtensions.Throws(null, () => graphics.DrawEllipse(pen, 0, 0, 1, 1)); - AssertExtensions.Throws(null, () => graphics.DrawEllipse(pen, new RectangleF(0, 0, 1, 1))); - AssertExtensions.Throws(null, () => graphics.DrawEllipse(pen, 0f, 0f, 1f, 1f)); - } - } - - [Fact] - public void DrawPie_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawPie(null, new Rectangle(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws("pen", () => graphics.DrawPie(null, 0, 0, 1, 1, 0, 90)); - AssertExtensions.Throws("pen", () => graphics.DrawPie(null, new RectangleF(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws("pen", () => graphics.DrawPie(null, 0f, 0f, 1f, 1f, 0, 90)); - } - } - - [Fact] - public void DrawPie_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, new Rectangle(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, 0, 0, 1, 1, 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, new RectangleF(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, 0f, 0f, 1f, 1f, 0, 90)); - } - } - - [Fact] - public void DrawPie_ZeroWidth_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, new Rectangle(0, 0, 0, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, 0, 0, 0, 1, 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, new RectangleF(0, 0, 0, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, 0f, 0f, 0f, 1f, 0, 90)); - } - } - - [Fact] - public void DrawPie_ZeroHeight_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new Rectangle(0, 0, 1, 0), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0, 0, 1, 0, 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new RectangleF(0, 0, 1, 0), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0f, 0f, 1f, 0f, 0, 90)); - } - } - - [Fact] - public void DrawPie_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawPie(pen, new Rectangle(0, 0, 1, 1), 0, 90)); - Assert.Throws(() => graphics.DrawPie(pen, 0, 0, 1, 1, 0, 90)); - Assert.Throws(() => graphics.DrawPie(pen, new RectangleF(0, 0, 1, 1), 0, 90)); - Assert.Throws(() => graphics.DrawPie(pen, 0f, 0f, 1f, 1f, 0, 90)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawPie_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, new Rectangle(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, 0, 0, 1, 1, 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, new RectangleF(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawPie(pen, 0f, 0f, 1f, 1f, 0, 90)); - } - } - - [Fact] - public void DrawPolygon_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawPolygon(null, new Point[2])); - AssertExtensions.Throws("pen", () => graphics.DrawPolygon(null, new PointF[2])); - } - } - - [Fact] - public void DrawPolygon_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawPolygon(pen, new Point[2])); - AssertExtensions.Throws(null, () => graphics.DrawPolygon(pen, new PointF[2])); - } - } - - [Fact] - public void DrawPolygon_NullPoints_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws("points", () => graphics.DrawPolygon(pen, (Point[])null)); - AssertExtensions.Throws("points", () => graphics.DrawPolygon(pen, (PointF[])null)); - } - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - public void DrawPolygon_InvalidPointsLength_ThrowsArgumentException(int length) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawPolygon(pen, new Point[length])); - AssertExtensions.Throws(null, () => graphics.DrawPolygon(pen, new PointF[length])); - } - } - - [Fact] - public void DrawPolygon_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawPolygon(pen, new Point[2])); - Assert.Throws(() => graphics.DrawPolygon(pen, new PointF[2])); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawPolygon_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawPolygon(pen, new Point[2])); - AssertExtensions.Throws(null, () => graphics.DrawPolygon(pen, new PointF[2])); - } - } - - [Fact] - public void DrawPath_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var graphicsPath = new GraphicsPath()) - { - AssertExtensions.Throws("pen", () => graphics.DrawPath(null, graphicsPath)); - } - } - - [Fact] - public void DrawPath_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var graphicsPath = new GraphicsPath()) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawPath(pen, graphicsPath)); - } - } - - [Fact] - public void DrawPath_NullPath_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws("path", () => graphics.DrawPath(pen, null)); - } - } - - [Fact] - public void DrawPath_DisposedPath_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - var graphicsPath = new GraphicsPath(); - graphicsPath.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawPath(pen, graphicsPath)); - } - } - - [Fact] - public void DrawPath_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - using (var graphicsPath = new GraphicsPath()) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawPath(pen, graphicsPath)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawPath_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - using (var graphicsPath = new GraphicsPath()) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawPath(pen, graphicsPath)); - } - } - - [Fact] - public void DrawCurve_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawCurve(null, new Point[2])); - AssertExtensions.Throws("pen", () => graphics.DrawCurve(null, new PointF[2])); - AssertExtensions.Throws("pen", () => graphics.DrawCurve(null, new Point[2], 1)); - AssertExtensions.Throws("pen", () => graphics.DrawCurve(null, new PointF[2], 1)); - AssertExtensions.Throws("pen", () => graphics.DrawCurve(null, new PointF[2], 0, 2)); - AssertExtensions.Throws("pen", () => graphics.DrawCurve(null, new Point[2], 0, 2, 1)); - AssertExtensions.Throws("pen", () => graphics.DrawCurve(null, new PointF[2], 0, 2, 1)); - } - } - - [Fact] - public void DrawCurve_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new Point[2])); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[2])); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new Point[2], 1)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[2], 1)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[2], 0, 2)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new Point[2], 0, 2, 1)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[2], 0, 2, 1)); - } - } - - [Fact] - public void DrawCurve_NullPoints_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws("points", () => graphics.DrawCurve(pen, (Point[])null)); - AssertExtensions.Throws("points", () => graphics.DrawCurve(pen, (PointF[])null)); - AssertExtensions.Throws("points", () => graphics.DrawCurve(pen, (Point[])null, 1)); - AssertExtensions.Throws("points", () => graphics.DrawCurve(pen, (PointF[])null, 1)); - AssertExtensions.Throws("points", () => graphics.DrawCurve(pen, (PointF[])null, 0, 2)); - AssertExtensions.Throws("points", () => graphics.DrawCurve(pen, (Point[])null, 0, 2, 1)); - AssertExtensions.Throws("points", () => graphics.DrawCurve(pen, (PointF[])null, 0, 2, 1)); - } - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - public void DrawCurve_InvalidPointsLength_ThrowsArgumentException(int length) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new Point[length])); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[length])); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new Point[length], 1)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[length], 1)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[length], 0, length)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new Point[length], 0, length, 1)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[length], 0, length, 1)); - } - } - - [Theory] - [InlineData(4, -1, 4)] - [InlineData(4, 0, -1)] - [InlineData(4, 4, 0)] - [InlineData(4, 0, 5)] - [InlineData(4, 3, 2)] - public void DrawCurve_InvalidOffsetCount_ThrowsArgumentException(int length, int offset, int numberOfSegments) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[length], offset, numberOfSegments)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new Point[length], offset, numberOfSegments, 1)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[length], offset, numberOfSegments, 1)); - } - } - - [Fact] - public void DrawCurve_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawCurve(pen, new Point[2])); - Assert.Throws(() => graphics.DrawCurve(pen, new PointF[2])); - Assert.Throws(() => graphics.DrawCurve(pen, new Point[2], 1)); - Assert.Throws(() => graphics.DrawCurve(pen, new PointF[2], 1)); - Assert.Throws(() => graphics.DrawCurve(pen, new PointF[2], 0, 2)); - Assert.Throws(() => graphics.DrawCurve(pen, new Point[2], 0, 2, 1)); - Assert.Throws(() => graphics.DrawCurve(pen, new PointF[2], 0, 2, 1)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawCurve_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new Point[2])); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[2])); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new Point[2], 1)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[2], 1)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[2], 0, 2)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new Point[2], 0, 2, 1)); - AssertExtensions.Throws(null, () => graphics.DrawCurve(pen, new PointF[2], 0, 2, 1)); - } - } - - [Fact] - public void DrawClosedCurve_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawClosedCurve(null, new Point[3])); - AssertExtensions.Throws("pen", () => graphics.DrawClosedCurve(null, new Point[3], 1, FillMode.Winding)); - AssertExtensions.Throws("pen", () => graphics.DrawClosedCurve(null, new PointF[3])); - AssertExtensions.Throws("pen", () => graphics.DrawClosedCurve(null, new PointF[3], 1, FillMode.Winding)); - } - } - - [Fact] - public void DrawClosedCurve_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new Point[3])); - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new Point[3], 1, FillMode.Winding)); - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new PointF[3])); - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new PointF[3], 1, FillMode.Winding)); - } - } - - [Fact] - public void DrawClosedCurve_NullPoints_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws("points", () => graphics.DrawClosedCurve(pen, (Point[])null)); - AssertExtensions.Throws("points", () => graphics.DrawClosedCurve(pen, (Point[])null, 1, FillMode.Winding)); - AssertExtensions.Throws("points", () => graphics.DrawClosedCurve(pen, (PointF[])null)); - AssertExtensions.Throws("points", () => graphics.DrawClosedCurve(pen, (PointF[])null, 1, FillMode.Winding)); - } - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(2)] - public void DrawClosedCurve_InvalidPointsLength_ThrowsArgumentException(int length) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new Point[length])); - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new Point[length], 1, FillMode.Winding)); - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new PointF[length])); - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new PointF[length], 1, FillMode.Winding)); - } - } - - [Fact] - public void DrawClosedCurve_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawClosedCurve(pen, new Point[3])); - Assert.Throws(() => graphics.DrawClosedCurve(pen, new Point[3], 1, FillMode.Winding)); - Assert.Throws(() => graphics.DrawClosedCurve(pen, new PointF[3])); - Assert.Throws(() => graphics.DrawClosedCurve(pen, new PointF[3], 1, FillMode.Winding)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawClosedCurve_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new Point[3])); - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new Point[3], 1, FillMode.Alternate)); - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new PointF[3])); - AssertExtensions.Throws(null, () => graphics.DrawClosedCurve(pen, new PointF[3], 1, FillMode.Alternate)); - } - } - - [Fact] - public void FillPie_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("brush", () => graphics.FillPie(null, new Rectangle(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws("brush", () => graphics.FillPie(null, 0, 0, 1, 1, 0, 90)); - AssertExtensions.Throws("brush", () => graphics.FillPie(null, 0f, 0f, 1f, 1f, 0, 90)); - } - } - - [Fact] - public void FillPie_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var brush = new SolidBrush(Color.Red); - brush.Dispose(); - - AssertExtensions.Throws(null, () => graphics.FillPie(brush, new Rectangle(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.FillPie(brush, 0, 0, 1, 1, 0, 90)); - AssertExtensions.Throws(null, () => graphics.FillPie(brush, 0f, 0f, 1f, 1f, 0, 90)); - } - } - - [Fact] - public void FillPie_ZeroWidth_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new SolidBrush(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.FillPie(brush, new Rectangle(0, 0, 0, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.FillPie(brush, 0, 0, 0, 1, 0, 90)); - AssertExtensions.Throws(null, () => graphics.FillPie(brush, 0f, 0f, 0f, 1f, 0, 90)); - } - } - - [Fact] - public void FillPie_ZeroHeight_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new SolidBrush(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.FillPie(brush, new Rectangle(0, 0, 1, 0), 0, 90)); - AssertExtensions.Throws(null, () => graphics.FillPie(brush, 0, 0, 1, 0, 0, 90)); - AssertExtensions.Throws(null, () => graphics.FillPie(brush, 0f, 0f, 1f, 0f, 0, 90)); - } - } - - [Fact] - public void FillPie_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new SolidBrush(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.FillPie(brush, new Rectangle(0, 0, 1, 1), 0, 90)); - Assert.Throws(() => graphics.FillPie(brush, 0, 0, 1, 1, 0, 90)); - Assert.Throws(() => graphics.FillPie(brush, 0f, 0f, 1f, 1f, 0, 90)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void FillPie_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var brush = new SolidBrush(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.FillPie(brush, new Rectangle(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.FillPie(brush, 0, 0, 1, 1, 0, 90)); - AssertExtensions.Throws(null, () => graphics.FillPie(brush, 0f, 0f, 1f, 1f, 0, 90)); - } - } - - [Fact] - public void Clear_Color_Success() - { - Color color = Color.FromArgb(Color.Plum.ToArgb()); - - using (var image = new Bitmap(2, 2)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var brush = new SolidBrush(color)) - { - graphics.FillRectangle(brush, new Rectangle(0, 0, 2, 2)); - - graphics.Clear(color); - Helpers.VerifyBitmap(image, new Color[][] - { - new Color[] { color, color }, - new Color[] { color, color } - }); - } - } - - [Fact] - public void Clear_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.Clear(Color.Red)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void Clear_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.Clear(Color.Red)); - } - } - - [Fact] - public void DrawString_DefaultFont_Succeeds() - { - using (var image = new Bitmap(50, 50)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.DrawString("Test text", SystemFonts.DefaultFont, Brushes.White, new Point()); - Helpers.VerifyBitmapNotBlank(image); - } - } - - [Fact] - public void DrawString_CompositingModeSourceCopy_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.CompositingMode = CompositingMode.SourceCopy; - AssertExtensions.Throws( - null, - () => graphics.DrawString("Test text", SystemFonts.DefaultFont, Brushes.White, new Point())); - } - } - - private static void VerifyGraphics(Graphics graphics, RectangleF expectedVisibleClipBounds) - { - Assert.NotNull(graphics.Clip); - Assert.Equal(new RectangleF(-4194304, -4194304, 8388608, 8388608), graphics.ClipBounds); - Assert.Equal(CompositingMode.SourceOver, graphics.CompositingMode); - Assert.Equal(CompositingQuality.Default, graphics.CompositingQuality); - Assert.Equal(96, graphics.DpiX); - Assert.Equal(96, graphics.DpiY); - Assert.Equal(InterpolationMode.Bilinear, graphics.InterpolationMode); - Assert.False(graphics.IsClipEmpty); - Assert.False(graphics.IsVisibleClipEmpty); - Assert.Equal(1, graphics.PageScale); - Assert.Equal(GraphicsUnit.Display, graphics.PageUnit); - Assert.Equal(PixelOffsetMode.Default, graphics.PixelOffsetMode); - Assert.Equal(Point.Empty, graphics.RenderingOrigin); - Assert.Equal(SmoothingMode.None, graphics.SmoothingMode); - Assert.Equal(4, graphics.TextContrast); - Assert.Equal(TextRenderingHint.SystemDefault, graphics.TextRenderingHint); - Assert.Equal(new Matrix(), graphics.Transform); - Assert.Equal(expectedVisibleClipBounds, graphics.VisibleClipBounds); - } - -#if NET8_0_OR_GREATER - [Fact] - public void DrawCachedBitmap_ThrowsArgumentNullException() - { - using Bitmap bitmap = new(10, 10); - using Graphics graphics = Graphics.FromImage(bitmap); - - Assert.Throws(() => graphics.DrawCachedBitmap(null!, 0, 0)); - } - - [Fact] - public void DrawCachedBitmap_DisposedBitmap_ThrowsArgumentException() - { - using Bitmap bitmap = new(10, 10); - using Graphics graphics = Graphics.FromImage(bitmap); - CachedBitmap cachedBitmap = new(bitmap, graphics); - cachedBitmap.Dispose(); - - Assert.Throws(() => graphics.DrawCachedBitmap(cachedBitmap, 0, 0)); - } - - [Fact] - public void DrawCachedBitmap_Simple() - { - using Bitmap bitmap = new(10, 10); - using Graphics graphics = Graphics.FromImage(bitmap); - using CachedBitmap cachedBitmap = new(bitmap, graphics); - - graphics.DrawCachedBitmap(cachedBitmap, 0, 0); - } - - [Fact] - public void DrawCachedBitmap_Translate() - { - using Bitmap bitmap = new(10, 10); - using Graphics graphics = Graphics.FromImage(bitmap); - graphics.TranslateTransform(1.0f, 8.0f); - using CachedBitmap cachedBitmap = new(bitmap, graphics); - - graphics.DrawCachedBitmap(cachedBitmap, 0, 0); - } - - [Fact] - public void DrawCachedBitmap_Rotation_ThrowsInvalidOperation() - { - using Bitmap bitmap = new(10, 10); - using Graphics graphics = Graphics.FromImage(bitmap); - graphics.RotateTransform(36.0f); - using CachedBitmap cachedBitmap = new(bitmap, graphics); - - Assert.Throws(() => graphics.DrawCachedBitmap(cachedBitmap, 0, 0)); - } - - [Theory] - [InlineData(PixelFormat.Format16bppRgb555, PixelFormat.Format32bppRgb, false)] - [InlineData(PixelFormat.Format32bppRgb, PixelFormat.Format16bppRgb555, true)] - [InlineData(PixelFormat.Format32bppArgb, PixelFormat.Format16bppRgb555, false)] - public void DrawCachedBitmap_ColorDepthChange_ThrowsInvalidOperation( - PixelFormat sourceFormat, - PixelFormat destinationFormat, - bool shouldSucceed) - { - using Bitmap bitmap = new(10, 10, sourceFormat); - using Graphics graphics = Graphics.FromImage(bitmap); - using CachedBitmap cachedBitmap = new(bitmap, graphics); - - using Bitmap bitmap2 = new(10, 10, destinationFormat); - using Graphics graphics2 = Graphics.FromImage(bitmap2); - - if (shouldSucceed) - { - graphics2.DrawCachedBitmap(cachedBitmap, 0, 0); - } - else - { - Assert.Throws(() => graphics2.DrawCachedBitmap(cachedBitmap, 0, 0)); - } - } -#endif -} diff --git a/src/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs b/src/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs deleted file mode 100644 index 8baed936268..00000000000 --- a/src/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs +++ /dev/null @@ -1,203 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class Graphics_DrawBezierTests : DrawingTest -{ - [Fact] - public void DrawBezier_Point() - { - using Bitmap bitmap = new(100, 100); - using Pen pen = new(Color.White); - using Graphics graphics = Graphics.FromImage(bitmap); - - graphics.DrawBezier(pen, new(10, 10), new(20, 1), new(35, 5), new(50, 10)); - ValidateBitmapContent( - bitmap, - 0x35, 0xa8, 0x3a, 0x03, 0x1e, 0xbd, 0xd4, 0xc0, 0xa4, 0x70, 0x51, 0xba, 0x09, 0xc1, 0xc1, 0xf9); - } - - [Fact] - public void DrawBezier_Points() - { - using Bitmap bitmap = new(100, 100); - using Pen pen = new(Color.Red); - using Graphics graphics = Graphics.FromImage(bitmap); - Point[] points = - { - new(10, 10), new(20, 1), new(35, 5), new(50, 10), - new(60, 15), new(65, 25), new(50, 30) - }; - - graphics.DrawBeziers(pen, points); - ValidateBitmapContent( - bitmap, - 0x7a, 0x02, 0x29, 0xa0, 0xc5, 0x21, 0x94, 0x31, 0xc8, 0x96, 0x31, 0x09, 0xcc, 0xd6, 0xec, 0x63); - } - - [Fact] - public void DrawBezier_PointFs() - { - using Bitmap bitmap = new(100, 100); - using Pen pen = new(Color.Red); - using Graphics graphics = Graphics.FromImage(bitmap); - PointF[] points = - { - new(10.0f, 10.0f), new(20.0f, 1.0f), new(35.0f, 5.0f), new(50.0f, 10.0f), - new(60.0f, 15.0f), new(65.0f, 25.0f), new(50.0f, 30.0f) - }; - - graphics.DrawBeziers(pen, points); - ValidateBitmapContent( - bitmap, - 0x7a, 0x02, 0x29, 0xa0, 0xc5, 0x21, 0x94, 0x31, 0xc8, 0x96, 0x31, 0x09, 0xcc, 0xd6, 0xec, 0x63); - } - - [Fact] - public void DrawBezier_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawBezier(null, 1, 2, 3, 4, 5, 6, 7, 8)); - AssertExtensions.Throws("pen", () => graphics.DrawBezier(null, Point.Empty, Point.Empty, Point.Empty, Point.Empty)); - AssertExtensions.Throws("pen", () => graphics.DrawBezier(null, PointF.Empty, PointF.Empty, PointF.Empty, PointF.Empty)); - } - } - - [Fact] - public void DrawBezier_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawBezier(pen, 1, 2, 3, 4, 5, 6, 7, 8)); - AssertExtensions.Throws(null, () => graphics.DrawBezier(pen, Point.Empty, Point.Empty, Point.Empty, Point.Empty)); - AssertExtensions.Throws(null, () => graphics.DrawBezier(pen, PointF.Empty, PointF.Empty, PointF.Empty, PointF.Empty)); - } - } - - [Fact] - public void DrawBezier_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawBezier(pen, 1, 2, 3, 4, 5, 6, 7, 8)); - Assert.Throws(() => graphics.DrawBezier(pen, Point.Empty, Point.Empty, Point.Empty, Point.Empty)); - Assert.Throws(() => graphics.DrawBezier(pen, PointF.Empty, PointF.Empty, PointF.Empty, PointF.Empty)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawBezier_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new Rectangle(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0, 0, 1, 1, 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new RectangleF(0, 0, 1, 1), 0, 90)); - AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0f, 0f, 1f, 1f, 0, 90)); - } - } - - [Fact] - public void DrawBeziers_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawBeziers(null, new Point[2])); - AssertExtensions.Throws("pen", () => graphics.DrawBeziers(null, new PointF[2])); - } - } - - [Fact] - public void DrawBeziers_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new Point[2])); - AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new PointF[2])); - } - } - - [Fact] - public void DrawBeziers_NullPoints_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws("points", () => graphics.DrawBeziers(pen, (Point[])null)); - AssertExtensions.Throws("points", () => graphics.DrawBeziers(pen, (PointF[])null)); - } - } - - [Fact] - public void DrawBeziers_EmptyPoints_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new Point[0])); - AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new PointF[0])); - } - } - - [Fact] - public void DrawBeziers_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawBeziers(pen, new Point[2])); - Assert.Throws(() => graphics.DrawBeziers(pen, new PointF[2])); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawBeziers_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new Point[2])); - AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new PointF[2])); - } - } -} diff --git a/src/System.Drawing.Common/tests/Graphics_DrawLineTests.cs b/src/System.Drawing.Common/tests/Graphics_DrawLineTests.cs deleted file mode 100644 index 8c091cc8b33..00000000000 --- a/src/System.Drawing.Common/tests/Graphics_DrawLineTests.cs +++ /dev/null @@ -1,188 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class Graphics_DrawLineTests : DrawingTest -{ - [Fact] - public void DrawLines_Points() - { - using Bitmap bitmap = new(100, 100); - using Pen pen = new(Color.White); - using Graphics graphics = Graphics.FromImage(bitmap); - - graphics.DrawLines(pen, new Point[] { new(1, 1), new(1, 10), new(20, 5), new(25, 30) }); - - ValidateBitmapContent( - bitmap, - 0xeb, 0xc6, 0x1e, 0xbf, 0xc0, 0x42, 0xa7, 0xfd, 0xcd, 0x24, 0xbc, 0x1c, 0x79, 0x0a, 0x69, 0x07); - } - - [Fact] - public void DrawLines_PointFs() - { - using Bitmap bitmap = new(100, 100); - using Pen pen = new(Color.White); - using Graphics graphics = Graphics.FromImage(bitmap); - - graphics.DrawLines(pen, new PointF[] { new(1.0f, 1.0f), new(1.0f, 10.0f), new(20.0f, 5.0f), new(25.0f, 30.0f) }); - - ValidateBitmapContent( - bitmap, - 0xeb, 0xc6, 0x1e, 0xbf, 0xc0, 0x42, 0xa7, 0xfd, 0xcd, 0x24, 0xbc, 0x1c, 0x79, 0x0a, 0x69, 0x07); - } - - [Fact] - public void DrawLine_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawLine(null, Point.Empty, Point.Empty)); - AssertExtensions.Throws("pen", () => graphics.DrawLine(null, 0, 0, 0, 0)); - AssertExtensions.Throws("pen", () => graphics.DrawLine(null, PointF.Empty, PointF.Empty)); - AssertExtensions.Throws("pen", () => graphics.DrawLine(null, 0f, 0f, 0f, 0f)); - } - } - - [Fact] - public void DrawLine_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawLine(pen, Point.Empty, Point.Empty)); - AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0, 0, 0, 0)); - AssertExtensions.Throws(null, () => graphics.DrawLine(pen, PointF.Empty, PointF.Empty)); - AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0f, 0f, 0f, 0f)); - } - } - - [Fact] - public void DrawLine_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawLine(pen, Point.Empty, Point.Empty)); - Assert.Throws(() => graphics.DrawLine(pen, 0, 0, 0, 0)); - Assert.Throws(() => graphics.DrawLine(pen, PointF.Empty, PointF.Empty)); - Assert.Throws(() => graphics.DrawLine(pen, 0f, 0f, 0f, 0f)); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawLine_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawLine(pen, Point.Empty, Point.Empty)); - AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0, 0, 0, 0)); - AssertExtensions.Throws(null, () => graphics.DrawLine(pen, PointF.Empty, PointF.Empty)); - AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0f, 0f, 0f, 0f)); - } - } - - [Fact] - public void DrawLines_NullPen_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - AssertExtensions.Throws("pen", () => graphics.DrawLines(null, new Point[2])); - AssertExtensions.Throws("pen", () => graphics.DrawLines(null, new PointF[2])); - } - } - - [Fact] - public void DrawLines_DisposedPen_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - var pen = new Pen(Color.Red); - pen.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new Point[2])); - AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new PointF[2])); - } - } - - [Fact] - public void DrawLines_NullPoints_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws("points", () => graphics.DrawLines(pen, (Point[])null)); - AssertExtensions.Throws("points", () => graphics.DrawLines(pen, (PointF[])null)); - } - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - public void DrawLines_InvalidPointsLength_ThrowsArgumentException(int length) - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new Point[length])); - AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new PointF[length])); - } - } - - [Fact] - public void DrawLines_Busy_ThrowsInvalidOperationException() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (var pen = new Pen(Color.Red)) - { - graphics.GetHdc(); - try - { - Assert.Throws(() => graphics.DrawLines(pen, new Point[2])); - Assert.Throws(() => graphics.DrawLines(pen, new PointF[2])); - } - finally - { - graphics.ReleaseHdc(); - } - } - } - - [Fact] - public void DrawLines_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var pen = new Pen(Color.Red)) - { - Graphics graphics = Graphics.FromImage(image); - graphics.Dispose(); - - AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new Point[2])); - AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new PointF[2])); - } - } - -} diff --git a/src/System.Drawing.Common/tests/Graphics_GetContextTests.Core.cs b/src/System.Drawing.Common/tests/Graphics_GetContextTests.Core.cs deleted file mode 100644 index 8852eedf660..00000000000 --- a/src/System.Drawing.Common/tests/Graphics_GetContextTests.Core.cs +++ /dev/null @@ -1,147 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; -using System.Numerics; - -namespace System.Drawing.Tests; - -public partial class Graphics_GetContextTests -{ - [Fact] - public void GetContextInfo_New_DefaultGraphics() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.GetContextInfo(out PointF offset); - Assert.True(offset.IsEmpty); - - graphics.GetContextInfo(out offset, out Region? clip); - Assert.True(offset.IsEmpty); - Assert.Null(clip); - } - } - - [Fact] - public void GetContextInfo_New_Clipping() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (Region initialClip = new Region(new Rectangle(1, 2, 9, 10))) - { - graphics.Clip = initialClip; - - graphics.GetContextInfo(out PointF offset); - Assert.True(offset.IsEmpty); - - graphics.GetContextInfo(out offset, out Region? clip); - Assert.True(offset.IsEmpty); - Assert.NotNull(clip); - Assert.Equal(initialClip.GetBounds(graphics), clip.GetBounds(graphics)); - clip.Dispose(); - } - } - - [Fact] - public void GetContextInfo_New_Transform() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.TransformElements = Matrix3x2.CreateTranslation(1, 2); - - graphics.GetContextInfo(out PointF offset); - Assert.Equal(new PointF(1, 2), offset); - - graphics.GetContextInfo(out offset, out Region? clip); - Assert.Null(clip); - Assert.Equal(new PointF(1, 2), offset); - } - } - - [Fact] - public void GetContextInfo_New_ClipAndTransform() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (Region initialClip = new Region(new Rectangle(1, 2, 9, 10))) - { - graphics.Clip = initialClip; - graphics.TransformElements = Matrix3x2.CreateTranslation(1, 2); - - graphics.GetContextInfo(out PointF offset); - Assert.Equal(new PointF(1, 2), offset); - - graphics.GetContextInfo(out offset, out Region? clip); - Assert.NotNull(clip); - Assert.Equal(new RectangleF(0, 0, 9, 10), clip.GetBounds(graphics)); - Assert.Equal(new PointF(1, 2), offset); - clip.Dispose(); - } - } - - [Fact] - public void GetContextInfo_New_TransformAndClip() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (Region initialClip = new Region(new Rectangle(1, 2, 9, 10))) - { - graphics.TransformElements = Matrix3x2.CreateTranslation(1, 2); - graphics.Clip = initialClip; - - graphics.GetContextInfo(out PointF offset); - Assert.Equal(new PointF(1, 2), offset); - - graphics.GetContextInfo(out offset, out Region? clip); - Assert.NotNull(clip); - Assert.Equal(new RectangleF(1, 2, 9, 10), clip.GetBounds(graphics)); - Assert.Equal(new PointF(1, 2), offset); - clip.Dispose(); - } - } - - [Fact] - public void GetContextInfo_New_ClipAndTransformSaveState() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (Region initialClip = new Region(new Rectangle(1, 2, 9, 10))) - { - graphics.Clip = initialClip; - graphics.TransformElements = Matrix3x2.CreateTranslation(1, 2); - - GraphicsState state = graphics.Save(); - - graphics.GetContextInfo(out PointF offset); - Assert.Equal(new PointF(2, 4), offset); - - graphics.GetContextInfo(out offset, out Region? clip); - Assert.NotNull(clip); - Assert.Equal(new RectangleF(0, 0, 8, 8), clip.GetBounds(graphics)); - Assert.Equal(new PointF(2, 4), offset); - clip.Dispose(); - } - } - - [Fact] - public void GetContextInfo_New_ClipAndTransformSaveAndRestoreState() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - graphics.SetClip(new Rectangle(1, 2, 9, 10)); - graphics.TransformElements = Matrix3x2.CreateTranslation(1, 2); - - GraphicsState state = graphics.Save(); - graphics.GetContextInfo(out PointF offset, out Region? clip); - graphics.Restore(state); - - Assert.NotNull(clip); - Assert.Equal(new RectangleF(0, 0, 8, 8), clip.GetBounds(graphics)); - Assert.Equal(new PointF(2, 4), offset); - clip.Dispose(); - } - } -} diff --git a/src/System.Drawing.Common/tests/Graphics_GetContextTests.cs b/src/System.Drawing.Common/tests/Graphics_GetContextTests.cs deleted file mode 100644 index efb949be4db..00000000000 --- a/src/System.Drawing.Common/tests/Graphics_GetContextTests.cs +++ /dev/null @@ -1,167 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; - -namespace System.Drawing.Tests; - -#pragma warning disable SYSLIB0016 // Type or member is obsolete -public partial class Graphics_GetContextTests : DrawingTest -{ - [Fact] - public void GetContextInfo_DefaultGraphics() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - object info = graphics.GetContextInfo(); - Assert.IsType(info); - object[] infoArray = (object[])info; - Assert.Equal(2, infoArray.Length); - Assert.IsType(infoArray[0]); - Assert.IsType(infoArray[1]); - using (Region region = (Region)infoArray[0]) - using (Matrix matrix = (Matrix)infoArray[1]) - { - Assert.True(region.IsInfinite(graphics)); - Assert.True(matrix.IsIdentity); - } - } - } - - [Fact] - public void GetContextInfo_Clipping() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (Region initialClip = new Region(new Rectangle(1, 2, 9, 10))) - { - graphics.Clip = initialClip; - - object[] info = (object[])graphics.GetContextInfo(); - using (Region region = (Region)info[0]) - using (Matrix matrix = (Matrix)info[1]) - { - Assert.Equal(initialClip.GetBounds(graphics), region.GetBounds(graphics)); - Assert.True(matrix.IsIdentity); - } - } - } - - [Fact] - public void GetContextInfo_Transform() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (Matrix initialTransform = new Matrix()) - { - initialTransform.Translate(1, 2); - graphics.Transform = initialTransform; - - object[] info = (object[])graphics.GetContextInfo(); - using (Region region = (Region)info[0]) - using (Matrix matrix = (Matrix)info[1]) - { - Assert.True(region.IsInfinite(graphics)); - Assert.Equal(initialTransform, matrix); - } - } - } - - [Fact] - public void GetContextInfo_ClipAndTransform() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (Matrix initialTransform = new Matrix()) - using (Region initialClip = new Region(new Rectangle(1, 2, 9, 10))) - { - graphics.Clip = initialClip; - initialTransform.Translate(1, 2); - graphics.Transform = initialTransform; - - object[] info = (object[])graphics.GetContextInfo(); - using (Region region = (Region)info[0]) - using (Matrix matrix = (Matrix)info[1]) - { - Assert.Equal(new RectangleF(0, 0, 9, 10), region.GetBounds(graphics)); - Assert.Equal(initialTransform, matrix); - } - } - } - - [Fact] - public void GetContextInfo_TransformAndClip() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (Matrix initialTransform = new Matrix()) - using (Region initialClip = new Region(new Rectangle(1, 2, 9, 10))) - { - initialTransform.Translate(1, 2); - graphics.Transform = initialTransform; - graphics.Clip = initialClip; - - object[] info = (object[])graphics.GetContextInfo(); - using (Region region = (Region)info[0]) - using (Matrix matrix = (Matrix)info[1]) - { - Assert.Equal(new RectangleF(1, 2, 9, 10), region.GetBounds(graphics)); - Assert.Equal(initialTransform, matrix); - } - } - } - - [Fact] - public void GetContextInfo_ClipAndTransformSaveState() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (Matrix initialTransform = new Matrix()) - using (Region initialClip = new Region(new Rectangle(1, 2, 9, 10))) - { - graphics.Clip = initialClip; - initialTransform.Translate(1, 2); - graphics.Transform = initialTransform; - - GraphicsState state = graphics.Save(); - object[] info = (object[])graphics.GetContextInfo(); - - using (Region region = (Region)info[0]) - using (Matrix matrix = (Matrix)info[1]) - { - initialTransform.Translate(1, 2); - Assert.Equal(new RectangleF(0, 0, 8, 8), region.GetBounds(graphics)); - Assert.Equal(initialTransform, matrix); - } - } - } - - [Fact] - public void GetContextInfo_ClipAndTransformSaveAndRestoreState() - { - using (var image = new Bitmap(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - using (Matrix initialTransform = new Matrix()) - using (Region initialClip = new Region(new Rectangle(1, 2, 9, 10))) - { - graphics.Clip = initialClip; - initialTransform.Translate(1, 2); - graphics.Transform = initialTransform; - - GraphicsState state = graphics.Save(); - object[] info = (object[])graphics.GetContextInfo(); - graphics.Restore(state); - - using (Region region = (Region)info[0]) - using (Matrix matrix = (Matrix)info[1]) - { - initialTransform.Translate(1, 2); - Assert.Equal(new RectangleF(0, 0, 8, 8), region.GetBounds(graphics)); - Assert.Equal(initialTransform, matrix); - } - } - } -} -#pragma warning restore SYSLIB0016 // Type or member is obsolete - diff --git a/src/System.Drawing.Common/tests/Helpers.cs b/src/System.Drawing.Common/tests/Helpers.cs deleted file mode 100644 index 4326249f10a..00000000000 --- a/src/System.Drawing.Common/tests/Helpers.cs +++ /dev/null @@ -1,179 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Printing; -using System.Runtime.InteropServices; -using System.Text; -using Xunit.Sdk; - -namespace System.Drawing; - -public static class Helpers -{ - public const string AnyInstalledPrinters = $"{nameof(Helpers)}.{nameof(IsAnyInstalledPrinters)}"; - public const string WindowsRS3OrEarlier = $"{nameof(Helpers)}.{nameof(IsWindowsRS3OrEarlier)}"; - - public static bool IsWindowsRS3OrEarlier => !PlatformDetection.IsWindows10Version1803OrGreater; - - public static bool IsAnyInstalledPrinters() - { - return PrinterSettings.InstalledPrinters.Count > 0; - } - - public static string GetTestBitmapPath(string fileName) => GetTestPath("bitmaps", fileName); - public static string GetTestFontPath(string fileName) => GetTestPath("fonts", fileName); - public static string GetTestColorProfilePath(string fileName) => GetTestPath("colorProfiles", fileName); - - private static string GetTestPath(string directoryName, string fileName) => Path.Combine(AppContext.BaseDirectory, directoryName, fileName); - - public static void VerifyBitmap(Bitmap bitmap, Color[][] colors) - { - for (int y = 0; y < colors.Length; y++) - { - for (int x = 0; x < colors[y].Length; x++) - { - Color expectedColor = Color.FromArgb(colors[y][x].ToArgb()); - Color actualColor = bitmap.GetPixel(x, y); - - if (expectedColor != actualColor) - { - throw GetBitmapEqualFailureException(bitmap, colors, x, y); - } - } - } - } - - private static Exception GetBitmapEqualFailureException(Bitmap bitmap, Color[][] colors, int firstFailureX, int firstFailureY) - { - // Print out the whole bitmap to provide a view of the whole image, rather than just the difference between - // a single pixel. - var actualStringBuilder = new StringBuilder(); - var expectedStringBuilder = new StringBuilder(); - - actualStringBuilder.AppendLine(); - expectedStringBuilder.AppendLine(); - - for (int y = 0; y < bitmap.Height; y++) - { - for (int x = 0; x < bitmap.Width; x++) - { - PrintColor(actualStringBuilder, bitmap.GetPixel(x, y)); - PrintColor(expectedStringBuilder, colors[y][x]); - if (x != bitmap.Width - 1) - { - actualStringBuilder.Append(", "); - expectedStringBuilder.Append(", "); - } - } - actualStringBuilder.AppendLine(); - expectedStringBuilder.AppendLine(); - } - - return new AssertActualExpectedException(expectedStringBuilder.ToString(), actualStringBuilder.ToString(), $"Bitmaps were different at {firstFailureX}, {firstFailureY}."); - } - - private static void PrintColor(StringBuilder stringBuilder, Color color) - { - stringBuilder.Append($"Color.FromArgb({color.A}, {color.R}, {color.G}, {color.B})"); - } - - public static Color EmptyColor => Color.FromArgb(0, 0, 0, 0); - - private static Rectangle GetRectangle(RECT rect) - { - return new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); - } - - private const int MONITOR_DEFAULTTOPRIMARY = 1; - - [DllImport("libgdiplus", ExactSpelling = true)] - internal static extern string GetLibgdiplusVersion(); - - [DllImport("user32.dll", SetLastError = true)] - private static extern IntPtr MonitorFromWindow(IntPtr hWnd, int dwFlags); - - [DllImport("user32.dll", SetLastError = true)] - private static extern int GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO monitorInfo); - - [DllImport("user32.dll", SetLastError = true)] - internal static extern IntPtr GetForegroundWindow(); - - [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)] - internal static extern int GetGuiResources(IntPtr hProcess, uint flags); - - [DllImport("user32.dll", SetLastError = true)] - internal static extern IntPtr GetDC(IntPtr hWnd); - - [DllImport("user32.dll", SetLastError = true)] - internal static extern IntPtr GetWindowDC(IntPtr hWnd); - - public static Rectangle GetWindowDCRect(IntPtr hdc) => GetHWndRect(WindowFromDC(hdc)); - - public static Rectangle GetHWndRect(IntPtr hWnd) - { - if (hWnd == IntPtr.Zero) - { - return GetMonitorRectForWindow(hWnd); - } - - var rect = new RECT(); - GetClientRect(hWnd, ref rect); - - return GetRectangle(rect); - } - - private static Rectangle GetMonitorRectForWindow(IntPtr hWnd) - { - IntPtr hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY); - Assert.NotEqual(IntPtr.Zero, hMonitor); - - var info = new MONITORINFO(); - info.cbSize = Marshal.SizeOf(info); - int result = GetMonitorInfo(hMonitor, ref info); - Assert.NotEqual(0, result); - - return GetRectangle(info.rcMonitor); - } - - [DllImport("user32.dll", SetLastError = true)] - private static extern int GetClientRect(IntPtr hWnd, ref RECT lpRect); - - [DllImport("user32.dll", SetLastError = true)] - private static extern IntPtr WindowFromDC(IntPtr hdc); - - [StructLayout(LayoutKind.Sequential)] - private struct MONITORINFO - { - public int cbSize; - public RECT rcMonitor; - public RECT rcWork; - public int dwFlags; - } - - [StructLayout(LayoutKind.Sequential)] - private struct RECT - { - public int Left; - public int Top; - public int Right; - public int Bottom; - } - - public static void VerifyBitmapNotBlank(Bitmap bmp) - { - Color emptyColor = Color.FromArgb(0); - for (int y = 0; y < bmp.Height; y++) - { - for (int x = 0; x < bmp.Width; x++) - { - Color pixel = bmp.GetPixel(x, y); - if (!pixel.Equals(emptyColor)) - { - return; - } - } - } - - throw new XunitException("The entire image was blank."); - } -} diff --git a/src/System.Drawing.Common/tests/IconTests.cs b/src/System.Drawing.Common/tests/IconTests.cs deleted file mode 100644 index f326f980d13..00000000000 --- a/src/System.Drawing.Common/tests/IconTests.cs +++ /dev/null @@ -1,927 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2004,2006-2008 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -using System.ComponentModel; -using System.Drawing.Imaging; -using System.Reflection; -using Microsoft.DotNet.RemoteExecutor; - -namespace System.Drawing.Tests; - -public class IconTests -{ - [Theory] - [InlineData("48x48_multiple_entries_4bit.ico")] - [InlineData("256x256_seven_entries_multiple_bits.ico")] - [InlineData("pngwithheight_icon.ico")] - public void Ctor_FilePath(string name) - { - using (var icon = new Icon(Helpers.GetTestBitmapPath(name))) - { - Assert.Equal(32, icon.Width); - Assert.Equal(32, icon.Height); - Assert.Equal(new Size(32, 32), icon.Size); - } - } - - public static IEnumerable Size_TestData() - { - // Normal size - yield return new object[] { "48x48_multiple_entries_4bit.ico", new Size(16, 16), new Size(16, 16) }; - yield return new object[] { "48x48_multiple_entries_4bit.ico", new Size(-32, -32), new Size(16, 16) }; - yield return new object[] { "48x48_multiple_entries_4bit.ico", new Size(32, 16), new Size(32, 32) }; - yield return new object[] { "256x256_seven_entries_multiple_bits.ico", new Size(48, 48), new Size(48, 48) }; - yield return new object[] { "256x256_seven_entries_multiple_bits.ico", new Size(0, 0), new Size(32, 32) }; - yield return new object[] { "256x256_seven_entries_multiple_bits.ico", new Size(1, 1), new Size(256, 256) }; - - // Unusual size - yield return new object[] { "10x16_one_entry_32bit.ico", new Size(16, 16), new Size(10, 16) }; - yield return new object[] { "10x16_one_entry_32bit.ico", new Size(32, 32), new Size(11, 22) }; - - // Only 256 - yield return new object[] { "256x256_one_entry_32bit.ico", new Size(0, 0), new Size(256, 256) }; - - yield return new object[] { "256x256_one_entry_32bit.ico", new Size(int.MaxValue, int.MaxValue), new Size(256, 256) }; - } - - [Theory] - [MemberData(nameof(Size_TestData))] - public void Ctor_FilePath_Width_Height(string fileName, Size size, Size expectedSize) - { - using (var icon = new Icon(Helpers.GetTestBitmapPath(fileName), size.Width, size.Height)) - { - Assert.Equal(expectedSize.Width, icon.Width); - Assert.Equal(expectedSize.Height, icon.Height); - Assert.Equal(expectedSize, icon.Size); - } - } - - [Theory] - [MemberData(nameof(Size_TestData))] - public void Ctor_FilePath_Size(string fileName, Size size, Size expectedSize) - { - using (var icon = new Icon(Helpers.GetTestBitmapPath(fileName), size)) - { - Assert.Equal(expectedSize.Width, icon.Width); - Assert.Equal(expectedSize.Height, icon.Height); - Assert.Equal(expectedSize, icon.Size); - } - } - - [Fact] - public void Ctor_NullFilePath_ThrowsArgumentNullException() - { - AssertExtensions.Throws("path", () => new Icon((string)null)); - AssertExtensions.Throws("path", () => new Icon((string)null, new Size(32, 32))); - AssertExtensions.Throws("path", () => new Icon((string)null, 32, 32)); - } - - [Fact] - public void Ctor_Stream() - { - using (var stream = File.OpenRead(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"))) - { - var icon = new Icon(stream); - Assert.Equal(32, icon.Width); - Assert.Equal(32, icon.Height); - Assert.Equal(new Size(32, 32), icon.Size); - } - } - - [Fact] - public void Ctor_Stream_Trickled() - { - var stream = new TrickleStream(File.ReadAllBytes(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"))); - var icon = new Icon(stream); - Assert.Equal(32, icon.Width); - Assert.Equal(32, icon.Height); - Assert.Equal(new Size(32, 32), icon.Size); - } - - private sealed class TrickleStream : MemoryStream - { - public TrickleStream(byte[] bytes) : base(bytes) { } - public override int Read(byte[] buffer, int offset, int count) => base.Read(buffer, offset, Math.Min(count, 1)); - } - - [Theory] - [MemberData(nameof(Size_TestData))] - public void Ctor_Stream_Width_Height(string fileName, Size size, Size expectedSize) - { - using (var stream = File.OpenRead(Helpers.GetTestBitmapPath(fileName))) - using (var icon = new Icon(stream, size.Width, size.Height)) - { - Assert.Equal(expectedSize.Width, icon.Width); - Assert.Equal(expectedSize.Height, icon.Height); - Assert.Equal(expectedSize, icon.Size); - } - } - - [Theory] - [MemberData(nameof(Size_TestData))] - public void Ctor_Stream_Size(string fileName, Size size, Size expectedSize) - { - using (var stream = File.OpenRead(Helpers.GetTestBitmapPath(fileName))) - using (var icon = new Icon(stream, size)) - { - Assert.Equal(expectedSize.Width, icon.Width); - Assert.Equal(expectedSize.Height, icon.Height); - Assert.Equal(expectedSize, icon.Size); - } - } - - [Fact] - public void Ctor_NullStream_ThrowsArgumentNullException() - { - AssertExtensions.Throws("stream", null, () => new Icon((Stream)null)); - AssertExtensions.Throws("stream", null, () => new Icon((Stream)null, 32, 32)); - AssertExtensions.Throws("stream", null, () => new Icon((Stream)null, new Size(32, 32))); - } - - public static IEnumerable Ctor_InvalidBytesInStream_TestData() - { - // No start entry. - yield return new object[] { new byte[0], typeof(ArgumentException) }; - yield return new object[] { new byte[6], typeof(ArgumentException) }; - yield return new object[] { new byte[21], typeof(ArgumentException) }; - - // First two reserved bits are not zero. - yield return new object[] { new byte[] { 10, 0, 1, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, typeof(ArgumentException) }; - yield return new object[] { new byte[] { 0, 10, 1, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, typeof(ArgumentException) }; - - // The type is not one. - yield return new object[] { new byte[] { 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, typeof(ArgumentException) }; - yield return new object[] { new byte[] { 0, 0, 2, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, typeof(ArgumentException) }; - yield return new object[] { new byte[] { 0, 0, 1, 2, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, typeof(ArgumentException) }; - - // The count is zero. - yield return new object[] { new byte[] { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, typeof(ArgumentException) }; - - // No space for the number of entries specified. - yield return new object[] { new byte[] { 0, 0, 1, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, typeof(ArgumentException) }; - - // The number of entries specified is negative. - yield return new object[] - { - new byte[] { 0, 0, 1, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - - // There is no such thing as a negative number in the native struct, we're throwing ArgumentException - // here now as the data size doesn't match what is expected (as other inputs above). - PlatformDetection.IsNetFramework ? typeof(Win32Exception) : typeof(ArgumentException) - }; - - // The size of an entry is negative. - yield return new object[] { new byte[] { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0 }, typeof(Win32Exception) }; - - // The offset of an entry is negative. - yield return new object[] { new byte[] { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255 }, typeof(ArgumentException) }; - - // The size and offset of an entry refers to an invalid position in the list of entries. - yield return new object[] { new byte[] { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0 }, typeof(ArgumentException) }; - - // The size and offset of an entry overflows. - yield return new object[] - { - new byte[] { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 127, 255, 255, 255, 127 }, - - // Another case where we weren't checking data integrity before invoking. - PlatformDetection.IsNetFramework ? typeof(Win32Exception) : typeof(ArgumentException) - }; - - // The offset and the size of the list of entries overflows. - yield return new object[] { new byte[] { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 127 }, typeof(ArgumentException) }; - - // No handle can be created from this. - yield return new object[] { new byte[] { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, typeof(Win32Exception) }; - } - - [Theory] - [MemberData(nameof(Ctor_InvalidBytesInStream_TestData))] - public void Ctor_InvalidBytesInStream_ThrowsException(byte[] bytes, Type exceptionType) - { - using (var stream = new MemoryStream()) - { - stream.Write(bytes, 0, bytes.Length); - - stream.Position = 0; - Assert.Throws(exceptionType, () => new Icon(stream)); - } - } - - [Theory] - [MemberData(nameof(Size_TestData))] - public void Ctor_Icon_Width_Height(string fileName, Size size, Size expectedSize) - { - using (var sourceIcon = new Icon(Helpers.GetTestBitmapPath(fileName))) - using (var icon = new Icon(sourceIcon, size.Width, size.Height)) - { - Assert.Equal(expectedSize.Width, icon.Width); - Assert.Equal(expectedSize.Height, icon.Height); - Assert.Equal(expectedSize, icon.Size); - Assert.NotEqual(sourceIcon.Handle, icon.Handle); - } - } - - [Theory] - [MemberData(nameof(Size_TestData))] - public void Ctor_Icon_Size(string fileName, Size size, Size expectedSize) - { - using (var sourceIcon = new Icon(Helpers.GetTestBitmapPath(fileName))) - using (var icon = new Icon(sourceIcon, size)) - { - Assert.Equal(expectedSize.Width, icon.Width); - Assert.Equal(expectedSize.Height, icon.Height); - Assert.Equal(expectedSize, icon.Size); - Assert.NotEqual(sourceIcon.Handle, icon.Handle); - } - } - - [Fact] - public void Ctor_NullIcon_ThrowsArgumentNullException() - { - AssertExtensions.Throws("original", null, () => new Icon((Icon)null, 32, 32)); - AssertExtensions.Throws("original", null, () => new Icon((Icon)null, new Size(32, 32))); - } - - [Fact] - public void Ctor_Type_Resource() - { - using (var icon = new Icon(typeof(IconTests), "48x48_multiple_entries_4bit.ico")) - { - Assert.Equal(32, icon.Height); - Assert.Equal(32, icon.Width); - } - } - - [Fact] - public void Ctor_NullType_ThrowsNullReferenceException() - { - Assert.Throws(() => new Icon(null, "48x48_multiple_entries_4bit.ico")); - } - - [Theory] - [InlineData(typeof(Icon), "")] - [InlineData(typeof(Icon), "48x48_multiple_entries_4bit.ico")] - [InlineData(typeof(IconTests), "48x48_MULTIPLE_entries_4bit.ico")] - public void Ctor_InvalidResource_ThrowsArgumentException(Type type, string resource) - { - AssertExtensions.Throws(null, () => new Icon(type, resource)); - } - - [Fact] - public void Ctor_InvalidResource_ThrowsArgumentNullException() - { - AssertExtensions.Throws("resource", null, () => new Icon(typeof(Icon), null)); - } - - [Fact] - public void Clone_ConstructedIcon_Success() - { - using (var icon = new Icon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"))) - using (Icon clone = Assert.IsType(icon.Clone())) - { - Assert.NotSame(icon, clone); - Assert.NotEqual(icon.Handle, clone.Handle); - Assert.Equal(32, clone.Width); - Assert.Equal(32, clone.Height); - Assert.Equal(new Size(32, 32), clone.Size); - } - } - - [Fact] - public void Clone_IconFromHandle_Success() - { - using (var icon = Icon.FromHandle(SystemIcons.Hand.Handle)) - using (Icon clone = Assert.IsType(icon.Clone())) - { - Assert.NotSame(icon, clone); - Assert.NotEqual(icon.Handle, clone.Handle); - Assert.Equal(SystemIcons.Hand.Width, clone.Width); - Assert.Equal(SystemIcons.Hand.Height, clone.Height); - Assert.Equal(SystemIcons.Hand.Size, clone.Size); - } - } - - [Fact] - public void Dispose_IconData_DestroysHandle() - { - var icon = new Icon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico")); - icon.Dispose(); - Assert.Throws(() => icon.Handle); - } - - [Fact] - public void Dispose_OwnsHandle_DestroysHandle() - { - Icon icon = Icon.ExtractAssociatedIcon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico")); - icon.Dispose(); - - Assert.Throws(() => icon.Handle); - } - - [Fact] - public void Dispose_DoesNotOwnHandle_DoesNotDestroyHandle() - { - using (var source = new Icon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"))) - using (var icon = Icon.FromHandle(source.Handle)) - { - IntPtr handle = icon.Handle; - Assert.NotEqual(IntPtr.Zero, handle); - - icon.Dispose(); - Assert.Equal(handle, icon.Handle); - } - } - - [Theory] - [InlineData(16)] - [InlineData(32)] - [InlineData(48)] - public void XpIcon_ToBitmap_Success(int size) - { - using (var icon = new Icon(Helpers.GetTestBitmapPath("48x48_multiple_entries_32bit.ico"), size, size)) - { - Assert.Equal(size, icon.Width); - Assert.Equal(size, icon.Height); - Assert.Equal(new Size(size, size), icon.Size); - - using (Bitmap bitmap = icon.ToBitmap()) - { - Assert.Equal(size, bitmap.Width); - Assert.Equal(size, bitmap.Height); - Assert.Equal(new Size(size, size), bitmap.Size); - } - } - } - - [Fact] - public void ExtractAssociatedIcon_FilePath_Success() - { - ExtractAssociatedIcon_FilePath_Success_Helper(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico")); - } - - [Fact] - public void ExtractAssociatedIcon_UNCFilePath_Success() - { - string bitmapPath = Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"); - string bitmapPathRoot = Path.GetPathRoot(bitmapPath); - string bitmapUncPath = $"\\\\{Environment.MachineName}\\{bitmapPath.Substring(0, bitmapPathRoot.IndexOf(":"))}$\\{bitmapPath.Replace(bitmapPathRoot, "")}"; - - // Some path could not be accessible - // if so we just pass the test - try - { - File.Open(bitmapUncPath, FileMode.Open, FileAccess.Read, FileShare.Read).Dispose(); - } - catch (IOException) - { - return; - } - - Assert.True(new Uri(bitmapUncPath).IsUnc); - - ExtractAssociatedIcon_FilePath_Success_Helper(bitmapUncPath); - } - - private void ExtractAssociatedIcon_FilePath_Success_Helper(string filePath) - { - using (Icon icon = Icon.ExtractAssociatedIcon(filePath)) - { - Assert.Equal(32, icon.Width); - Assert.Equal(32, icon.Height); - } - } - - [Fact] - public void ExtractAssociatedIcon_NonFilePath_ThrowsFileNotFound() - { - // Used to return null at the expense of creating a URI - if (PlatformDetection.IsNetFramework) - { - Assert.Null(Icon.ExtractAssociatedIcon("http://microsoft.com")); - } - else - { - Assert.Throws(() => Icon.ExtractAssociatedIcon("http://microsoft.com")); - } - } - - [Fact] - public void ExtractAssociatedIcon_NullFilePath_ThrowsArgumentNullException() - { - AssertExtensions.Throws("filePath", null, () => Icon.ExtractAssociatedIcon(null)); - } - - [Fact] - public void ExtractAssociatedIcon_InvalidFilePath_ThrowsArgumentException() - { - AssertExtensions.Throws("filePath", null, () => Icon.ExtractAssociatedIcon("")); - } - - - [Fact] - public void ExtractAssociatedIcon_NoSuchPath_ThrowsFileNotFoundException() - { - Assert.Throws(() => Icon.ExtractAssociatedIcon("no-such-file.png")); - } - - [Theory] - [InlineData("16x16_one_entry_4bit.ico")] - [InlineData("32x32_one_entry_4bit.ico")] - [InlineData("48x48_one_entry_1bit.ico")] - [InlineData("64x64_one_entry_8bit.ico")] - [InlineData("96x96_one_entry_8bit.ico")] - [InlineData("256x256_seven_entries_multiple_bits.ico")] - public void Save_OutputStream_Success(string fileName) - { - SaveAndCompare(new Icon(Helpers.GetTestBitmapPath(fileName)), true); - } - - [Fact] - public void Save_OutputStream_ProducesIdenticalBytes() - { - string filePath = Helpers.GetTestBitmapPath("256x256_seven_entries_multiple_bits.ico"); - using (var icon = new Icon(filePath)) - using (var outputStream = new MemoryStream()) - { - icon.Save(outputStream); - Assert.Equal(File.ReadAllBytes(filePath), outputStream.ToArray()); - } - } - - [Fact] - public void Save_HasIconDataAndDisposed_ProducesIdenticalBytes() - { - string filePath = Helpers.GetTestBitmapPath("256x256_seven_entries_multiple_bits.ico"); - var icon = new Icon(filePath); - icon.Dispose(); - using (var outputStream = new MemoryStream()) - { - icon.Save(outputStream); - Assert.Equal(File.ReadAllBytes(filePath), outputStream.ToArray()); - } - } - - [Fact] - public void Save_NullOutputStreamIconData_ThrowsNullReferenceException() - { - using (var icon = new Icon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"))) - { - Assert.Throws(() => icon.Save(null)); - } - } - - [Fact] - public void Save_NullOutputStreamNoIconData_ThrowsArgumentNullException() - { - using (var source = new Icon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"))) - { - var icon = Icon.FromHandle(source.Handle); - icon.Dispose(); - - AssertExtensions.Throws("outputStream", "dataStream", () => icon.Save(null)); - } - } - - [Fact] - public void Save_ClosedOutputStreamIconData_ThrowsException() - { - using (var icon = new Icon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"))) - { - var stream = new MemoryStream(); - stream.Close(); - - Assert.Throws(() => icon.Save(stream)); - } - } - - [Fact] - public void Save_ClosedOutputStreamNoIconData() - { - using (var source = new Icon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"))) - using (var icon = Icon.FromHandle(source.Handle)) - { - var stream = new MemoryStream(); - stream.Close(); - - if (PlatformDetection.IsNetFramework) - { - // The ObjectDisposedException is ignored in previous .NET versions, - // so the following does nothing. - icon.Save(stream); - } - else - { - Assert.Throws(() => icon.Save(stream)); - } - } - } - - [Fact] - public void Save_NoIconDataOwnsHandleAndDisposed_ThrowsObjectDisposedException() - { - Icon icon = Icon.ExtractAssociatedIcon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico")); - icon.Dispose(); - - Assert.Throws(() => icon.Save(new MemoryStream())); - } - - public static IEnumerable ToBitmap_TestData() - { - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico")) }; - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("32x32_one_entry_4bit.ico")) }; - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("48x48_one_entry_1bit.ico")) }; - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("64x64_one_entry_8bit.ico")) }; - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("96x96_one_entry_8bit.ico")) }; - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("256x256_two_entries_multiple_bits.ico"), 48, 48) }; - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("256x256_two_entries_multiple_bits.ico"), 256, 256) }; - yield return new object[] { new Icon(Helpers.GetTestBitmapPath("256x256_two_entries_multiple_bits.ico"), 0, 0) }; - } - - [Theory] - [MemberData(nameof(ToBitmap_TestData))] - public void ToBitmap_BitmapIcon_ReturnsExpected(Icon icon) - { - try - { - using (Bitmap bitmap = icon.ToBitmap()) - { - Assert.NotSame(icon.ToBitmap(), bitmap); - Assert.Equal(PixelFormat.Format32bppArgb, bitmap.PixelFormat); - Assert.Empty(bitmap.Palette.Entries); - Assert.Equal(icon.Width, bitmap.Width); - Assert.Equal(icon.Height, bitmap.Height); - - Assert.Equal(ImageFormat.MemoryBmp, bitmap.RawFormat); - Assert.Equal(2, bitmap.Flags); - } - } - finally - { - icon.Dispose(); - } - } - - [Fact] - public void ToBitmap_BitmapIconFromHandle_ReturnsExpected() - { - // Handle refers to an icon without any colour. This is not in ToBitmap_TestData as there is - // a chance that the original icon will be finalized as it is not kept alive in the iterator. - using (var originalIcon = new Icon(Helpers.GetTestBitmapPath("48x48_one_entry_1bit.ico"))) - using (Icon icon = Icon.FromHandle(originalIcon.Handle)) - { - ToBitmap_BitmapIcon_ReturnsExpected(icon); - } - } - - private const string DontSupportPngFramesInIcons = "Switch.System.Drawing.DontSupportPngFramesInIcons"; - - [Fact] - public void ToBitmap_PngIconSupportedInSwitches_Success() - { - void VerifyPng() - { - using (Icon icon = GetPngIcon()) - using (Bitmap bitmap = icon.ToBitmap()) - { - using (Bitmap secondBitmap = icon.ToBitmap()) - { - Assert.NotSame(icon.ToBitmap(), bitmap); - } - Assert.Equal(PixelFormat.Format32bppArgb, bitmap.PixelFormat); - Assert.Empty(bitmap.Palette.Entries); - Assert.Equal(icon.Width, bitmap.Width); - Assert.Equal(icon.Height, bitmap.Height); - - Assert.Equal(ImageFormat.Png, bitmap.RawFormat); - Assert.Equal(77842, bitmap.Flags); - } - } - - if (RemoteExecutor.IsSupported && (!AppContext.TryGetSwitch(DontSupportPngFramesInIcons, out bool isEnabled) || isEnabled)) - { - RemoteExecutor.Invoke(() => - { - AppContext.SetSwitch(DontSupportPngFramesInIcons, false); - VerifyPng(); - }).Dispose(); - } - else - { - VerifyPng(); - } - } - - [Fact] - public void ToBitmap_PngIconNotSupportedInSwitches_ThrowsArgumentOutOfRangeException() - { - void VerifyPngNotSupported() - { - using (Icon icon = GetPngIcon()) - { - AssertExtensions.Throws(null, () => icon.ToBitmap()); - } - } - - if (RemoteExecutor.IsSupported && (!AppContext.TryGetSwitch(DontSupportPngFramesInIcons, out bool isEnabled) || !isEnabled)) - { - RemoteExecutor.Invoke(() => - { - AppContext.SetSwitch(DontSupportPngFramesInIcons, true); - VerifyPngNotSupported(); - }).Dispose(); - } - else - { - if (AppContext.TryGetSwitch(DontSupportPngFramesInIcons, out bool enabled) && enabled) - VerifyPngNotSupported(); - } - } - - private static Icon GetPngIcon() - { - using (var stream = new MemoryStream()) - { - // Create a PNG inside an ICO. - using (var bitmap = new Bitmap(10, 10)) - { - stream.Write(new byte[] { 0, 0, 1, 0, 1, 0, (byte)bitmap.Width, (byte)bitmap.Height, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 22, 0, 0, 0 }, 0, 22); - - // Writing actual data - bitmap.Save(stream, ImageFormat.Png); - } - - // Getting data length (file length minus header) - long length = stream.Length - 22; - stream.Seek(14, SeekOrigin.Begin); - stream.WriteByte((byte)length); - stream.WriteByte((byte)(length >> 8)); - - // Read the PNG inside an ICO. - stream.Position = 0; - return new Icon(stream); - } - } - - [Fact] - public void FromHandle_IconHandleOneTime_Success() - { - using (var icon1 = new Icon(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"))) - using (Icon icon2 = Icon.FromHandle(icon1.Handle)) - { - Assert.Equal(icon1.Handle, icon2.Handle); - Assert.Equal(icon1.Size, icon2.Size); - SaveAndCompare(icon2, false); - } - } - - [Fact] - public void FromHandle_IconHandleMultipleTime_Success() - { - using (var icon1 = new Icon(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"))) - { - using (Icon icon2 = Icon.FromHandle(icon1.Handle)) - { - Assert.Equal(icon1.Handle, icon2.Handle); - Assert.Equal(icon1.Size, icon2.Size); - SaveAndCompare(icon2, false); - } - using (Icon icon3 = Icon.FromHandle(icon1.Handle)) - { - Assert.Equal(icon1.Handle, icon3.Handle); - Assert.Equal(icon1.Size, icon3.Size); - SaveAndCompare(icon3, false); - } - } - } - - [Fact] - public void FromHandle_BitmapHandleOneTime_Success() - { - IntPtr handle; - using (var icon1 = new Icon(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"))) - { - handle = icon1.ToBitmap().GetHicon(); - } - using (Icon icon2 = Icon.FromHandle(handle)) - { - Assert.Equal(handle, icon2.Handle); - Assert.Equal(new Size(16, 16), icon2.Size); - SaveAndCompare(icon2, false); - } - } - - [Fact] - public void FromHandle_BitmapHandleMultipleTime_Success() - { - IntPtr handle; - using (var icon1 = new Icon(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"))) - { - handle = icon1.ToBitmap().GetHicon(); - } - using (Icon icon2 = Icon.FromHandle(handle)) - { - Assert.Equal(handle, icon2.Handle); - Assert.Equal(new Size(16, 16), icon2.Size); - SaveAndCompare(icon2, false); - } - using (Icon icon3 = Icon.FromHandle(handle)) - { - Assert.Equal(handle, icon3.Handle); - Assert.Equal(new Size(16, 16), icon3.Size); - SaveAndCompare(icon3, false); - } - } - - [Fact] - public void FromHandle_Zero_ThrowsArgumentException() - { - AssertExtensions.Throws("handle", null, () => Icon.FromHandle(IntPtr.Zero)); - } - - [Fact] - public void Size_GetWhenDisposed_ThrowsObjectDisposedException() - { - var icon = new Icon(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico")); - icon.Dispose(); - - Assert.Throws(() => icon.Width); - Assert.Throws(() => icon.Height); - Assert.Throws(() => icon.Size); - } - - private static void SaveAndCompare(Icon icon, bool alpha) - { - using (MemoryStream outputStream = new MemoryStream()) - { - icon.Save(outputStream); - outputStream.Position = 0; - - using (Icon loaded = new Icon(outputStream)) - { - Assert.Equal(icon.Height, loaded.Height); - Assert.Equal(icon.Width, loaded.Width); - - using (Bitmap expected = icon.ToBitmap()) - using (Bitmap actual = loaded.ToBitmap()) - { - Assert.Equal(expected.Height, actual.Height); - Assert.Equal(expected.Width, actual.Width); - - for (int y = 0; y < expected.Height; y++) - { - for (int x = 0; x < expected.Width; x++) - { - Color e = expected.GetPixel(x, y); - Color a = actual.GetPixel(x, y); - if (alpha) - { - Assert.Equal(e.A, a.A); - } - Assert.Equal(e.R, a.R); - Assert.Equal(e.G, a.G); - Assert.Equal(e.B, a.B); - } - } - } - } - } - } - - [Fact] - public void CorrectColorDepthExtracted() - { - using (var stream = File.OpenRead(Helpers.GetTestBitmapPath("pngwithheight_icon.ico"))) - { - using (var icon = new Icon(stream, new Size(32, 32))) - { - // The first 32x32 icon isn't 32 bit. Checking a few pixels that are in the 32 bit entry. - using (Bitmap bitmap = icon.ToBitmap()) - { - Assert.Equal(new Size(32, 32), bitmap.Size); - - int expectedBitDepth; - string fieldName = PlatformDetection.IsNetFramework ? "bitDepth" : "s_bitDepth"; - FieldInfo fi = typeof(Icon).GetField(fieldName, BindingFlags.Static | BindingFlags.NonPublic); - expectedBitDepth = (int)fi.GetValue(null); - - // If the first icon entry was picked, the color would be black: 0xFF000000? - - switch (expectedBitDepth) - { - case 32: - Assert.Equal(0x879EE532u, (uint)bitmap.GetPixel(0, 0).ToArgb()); - Assert.Equal(0x661CD8B7u, (uint)bitmap.GetPixel(0, 31).ToArgb()); - break; - case 16: - case 8: - // There is no 16 bit 32x32 icon in this file, 8 will be picked - // as the closest match. - Assert.Equal(0x00000000u, (uint)bitmap.GetPixel(0, 0).ToArgb()); - Assert.Equal(0xFF000000u, (uint)bitmap.GetPixel(0, 31).ToArgb()); - break; - default: - Assert.False(true, $"Unexpected bitmap depth: {expectedBitDepth}"); - break; - } - } - } - } - } - -#if NET8_0_OR_GREATER - [Fact] - public void ExtractIcon_NullPath_ThrowsArgumentNullException() - { - Assert.Throws(() => { Icon.ExtractIcon(null!, 0, 16); }); - Assert.Throws(() => { Icon.ExtractIcon(null!, 0); }); - } - - [Fact] - public void ExtractIcon_EmptyPath_ThrowsIOException() - { - Assert.Throws(() => { Icon.ExtractIcon(string.Empty, 0, 16); }); - Assert.Throws(() => { Icon.ExtractIcon(string.Empty, 0); }); - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(int.MinValue)] - [InlineData(ushort.MaxValue + 1)] - public void ExtractIcon_InvalidSize_ThrowsArgumentOutOfRange(int size) - { - Assert.Throws(() => { Icon.ExtractIcon("Foo", 0, size); }); - } - - [Fact] - public void ExtractIcon_FileDoesNotExist_ThrowsIOException() - { - Assert.Throws(() => - { - Icon.ExtractIcon(Path.GetRandomFileName() + ".ico", 0, 16); - }); - - Assert.Throws(() => - { - Icon.ExtractIcon(Path.GetRandomFileName() + ".ico", 0); - }); - } - - [Fact] - public void ExtractIcon_InvalidExistingFile_ReturnsNull() - { - using TempFile file = TempFile.Create("NotAnIcon"); - Assert.Null(Icon.ExtractIcon(file.Path, 0, 16)); - Assert.Null(Icon.ExtractIcon(file.Path, 0)); - } - - [Fact] - public void ExtractIcon_IterateRegeditByIndex() - { - Icon? icon; - int count = 0; - while ((icon = Icon.ExtractIcon("regedit.exe", count, 16)) is not null) - { - Assert.NotEqual(0, icon.Handle); - Assert.Equal(16, icon.Width); - Assert.Equal(16, icon.Height); - count++; - icon.Dispose(); - } - - // Recent builds of Windows have added a few more icons to regedit. - Assert.True(count == 7 || count == 5, $"count was {count}, expected 5 or 7"); - } - - [Fact] - public void ExtractIcon_RegeditByResourceId() - { - using Icon? icon = Icon.ExtractIcon("regedit.exe", -100, 256); - Assert.NotNull(icon); - Assert.Equal(256, icon.Width); - Assert.Equal(256, icon.Height); - } -#endif -} diff --git a/src/System.Drawing.Common/tests/ImageTests.cs b/src/System.Drawing.Common/tests/ImageTests.cs deleted file mode 100644 index 7b25bae6adc..00000000000 --- a/src/System.Drawing.Common/tests/ImageTests.cs +++ /dev/null @@ -1,674 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Imaging; -using System.Runtime.InteropServices; -using System.Text; -using Microsoft.DotNet.XUnitExtensions; -using Encoder = System.Drawing.Imaging.Encoder; - -namespace System.Drawing.Tests; - -public class ImageTests -{ - private const int PropertyTagLuminanceTable = 0x5090; - private const int PropertyTagChrominanceTable = 0x5091; - private const int PropertyTagExifUserComment = 0x9286; - private const int PropertyTagTypeASCII = 2; - private const int PropertyTagTypeShort = 3; - - [Fact] - public void PropertyIdList_GetBitmapJpg_Success() - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - Assert.Equal(new int[] { PropertyTagExifUserComment, PropertyTagChrominanceTable, PropertyTagLuminanceTable }, bitmap.PropertyIdList); - Assert.NotSame(bitmap.PropertyIdList, bitmap.PropertyIdList); - } - - [Fact] - public void PropertyIdList_GetEmptyMemoryBitmap_ReturnsExpected() - { - using var bitmap = new Bitmap(1, 1); - Assert.Empty(bitmap.PropertyIdList); - Assert.Same(bitmap.PropertyIdList, bitmap.PropertyIdList); - } - - [Fact] - public void PropertyItems_GetBitmapJpg_Success() - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - PropertyItem[] items = bitmap.PropertyItems; - Assert.Equal(3, items.Length); - Assert.Equal(PropertyTagExifUserComment, items[0].Id); - Assert.Equal(29, items[0].Len); - Assert.Equal(PropertyTagTypeASCII, items[0].Type); - Assert.Equal("LEAD Technologies Inc. V1.01\0", Encoding.ASCII.GetString(items[0].Value)); - Assert.Equal(PropertyTagChrominanceTable, items[1].Id); - Assert.Equal(128, items[1].Len); - Assert.Equal(PropertyTagTypeShort, items[1].Type); - Assert.Equal(new byte[] - { - 0x16, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x17, - 0x00, 0x1B, 0x00, 0x22, 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x1F, - 0x00, 0x22, 0x00, 0x49, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x3E, - 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00 - }, items[1].Value); - Assert.Equal(PropertyTagLuminanceTable, items[2].Id); - Assert.Equal(128, items[2].Len); - Assert.Equal(PropertyTagTypeShort, items[2].Type); - Assert.Equal(new byte[] - { - 0x15, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x43, 0x00, 0x50, 0x00, 0x0F, - 0x00, 0x0F, 0x00, 0x12, 0x00, 0x19, 0x00, 0x22, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x48, 0x00, 0x12, - 0x00, 0x11, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x4B, 0x00, 0x5B, 0x00, 0x49, 0x00, 0x12, - 0x00, 0x16, 0x00, 0x1D, 0x00, 0x26, 0x00, 0x43, 0x00, 0x72, 0x00, 0x69, 0x00, 0x51, 0x00, 0x17, - 0x00, 0x1D, 0x00, 0x30, 0x00, 0x49, 0x00, 0x59, 0x00, 0x8F, 0x00, 0x87, 0x00, 0x65, 0x00, 0x1F, - 0x00, 0x2E, 0x00, 0x48, 0x00, 0x54, 0x00, 0x6A, 0x00, 0x89, 0x00, 0x95, 0x00, 0x79, 0x00, 0x40, - 0x00, 0x54, 0x00, 0x66, 0x00, 0x72, 0x00, 0x87, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x85, 0x00, 0x5F, - 0x00, 0x79, 0x00, 0x7D, 0x00, 0x81, 0x00, 0x93, 0x00, 0x84, 0x00, 0x87, 0x00, 0x82, 0x00, - }, items[2].Value); - - Assert.NotSame(items, bitmap.PropertyItems); - } - - [Fact] - public void PropertyItems_GetEmptyBitmapBmp_Success() - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("almogaver1bit.bmp")); - Assert.Empty(bitmap.PropertyItems); - Assert.Same(bitmap.PropertyItems, bitmap.PropertyItems); - } - - [Fact] - public void PropertyItems_GetEmptyMemoryBitmap_ReturnsExpected() - { - using var bitmap = new Bitmap(1, 1); - Assert.Empty(bitmap.PropertyItems); - Assert.Same(bitmap.PropertyItems, bitmap.PropertyItems); - } - - [Fact] - public void GetPropertyItem_InvokeExistsBitmapBmp_Success() - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - PropertyItem item = bitmap.GetPropertyItem(PropertyTagExifUserComment); - Assert.Equal(PropertyTagExifUserComment, item.Id); - Assert.Equal(29, item.Len); - Assert.Equal(PropertyTagTypeASCII, item.Type); - Assert.Equal("LEAD Technologies Inc. V1.01\0", Encoding.ASCII.GetString(item.Value)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(-1)] - public void GetPropertyItem_NoSuchPropertyItemEmptyMemoryBitmap_ThrowsArgumentException(int propid) - { - using var bitmap = new Bitmap(1, 1); - AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(propid)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(-1)] - public void GetPropertyItem_NoSuchPropertyItemEmptyImageBitmapBmp_ThrowsArgumentException(int propid) - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("almogaver1bit.bmp")); - AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(propid)); - } - - [Fact] - public void RemovePropertyItem_InvokeMemoryBitmap_Success() - { - using var source = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - PropertyItem item1 = source.GetPropertyItem(PropertyTagExifUserComment); - PropertyItem item2 = source.GetPropertyItem(PropertyTagChrominanceTable); - PropertyItem item3 = source.GetPropertyItem(PropertyTagLuminanceTable); - using var bitmap = new Bitmap(1, 1); - bitmap.SetPropertyItem(item1); - bitmap.SetPropertyItem(item2); - bitmap.SetPropertyItem(item3); - - bitmap.RemovePropertyItem(PropertyTagExifUserComment); - Assert.Equal(new int[] { PropertyTagChrominanceTable, PropertyTagLuminanceTable }, bitmap.PropertyIdList); - AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagExifUserComment)); - AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(PropertyTagExifUserComment)); - - bitmap.RemovePropertyItem(PropertyTagLuminanceTable); - Assert.Equal(new int[] { PropertyTagChrominanceTable }, bitmap.PropertyIdList); - AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagLuminanceTable)); - AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(PropertyTagLuminanceTable)); - - bitmap.RemovePropertyItem(PropertyTagChrominanceTable); - Assert.Empty(bitmap.PropertyIdList); - AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagChrominanceTable)); - Assert.Throws(() => bitmap.RemovePropertyItem(PropertyTagChrominanceTable)); - } - - [Fact] - public void RemovePropertyItem_InvokeBitmapJpg_Success() - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - bitmap.RemovePropertyItem(PropertyTagExifUserComment); - Assert.Equal(new int[] { PropertyTagChrominanceTable, PropertyTagLuminanceTable }, bitmap.PropertyIdList); - AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagExifUserComment)); - AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(PropertyTagExifUserComment)); - - bitmap.RemovePropertyItem(PropertyTagLuminanceTable); - Assert.Equal(new int[] { PropertyTagChrominanceTable }, bitmap.PropertyIdList); - AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagLuminanceTable)); - AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(PropertyTagLuminanceTable)); - - bitmap.RemovePropertyItem(PropertyTagChrominanceTable); - Assert.Empty(bitmap.PropertyIdList); - AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagChrominanceTable)); - Assert.Throws(() => bitmap.RemovePropertyItem(PropertyTagChrominanceTable)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(-1)] - public void RemovePropertyItem_NoSuchPropertyItemEmptyMemoryBitmap_ThrowsExternalException(int propid) - { - using var bitmap = new Bitmap(1, 1); - Assert.Throws(() => bitmap.RemovePropertyItem(propid)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(-1)] - public void RemovePropertyItem_NoSuchPropertyItemEmptyImageBitmapBmp_ThrowsExternalException(int propid) - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("almogaver1bit.bmp")); - Assert.Throws(() => bitmap.RemovePropertyItem(propid)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(-1)] - public void RemovePropertyItem_NoSuchPropertyNotEmptyMemoryBitmap_ThrowsArgumentException(int propid) - { - using var source = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - PropertyItem item1 = source.GetPropertyItem(PropertyTagExifUserComment); - PropertyItem item2 = source.GetPropertyItem(PropertyTagChrominanceTable); - PropertyItem item3 = source.GetPropertyItem(PropertyTagLuminanceTable); - using var bitmap = new Bitmap(1, 1); - bitmap.SetPropertyItem(item1); - bitmap.SetPropertyItem(item2); - bitmap.SetPropertyItem(item3); - - AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(propid)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(-1)] - public void RemovePropertyItem_NoSuchPropertyNotEmptyBitmapJpg_ThrowsArgumentException(int propid) - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(propid)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(-1)] - public void SetPropertyItem_InvokeMemoryBitmap_Success(int propid) - { - using var source = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - using var bitmap = new Bitmap(1, 1); - - // Change data. - PropertyItem item = source.GetPropertyItem(PropertyTagExifUserComment); - item.Value = "Hello World\0"u8.ToArray(); - item.Len = item.Value.Length; - - bitmap.SetPropertyItem(item); - - Assert.Equal(new int[] { PropertyTagExifUserComment }, bitmap.PropertyIdList); - PropertyItem[] items = bitmap.PropertyItems; - Assert.Single(items); - Assert.Equal(PropertyTagExifUserComment, items[0].Id); - Assert.Equal(12, items[0].Len); - Assert.Equal(PropertyTagTypeASCII, items[0].Type); - Assert.Equal("Hello World\0", Encoding.ASCII.GetString(items[0].Value)); - - // New data. - item.Id = propid; - item.Value = "New Value\0"u8.ToArray(); - item.Len = item.Value.Length; - - bitmap.SetPropertyItem(item); - - Assert.Equal(new int[] { PropertyTagExifUserComment, propid }, bitmap.PropertyIdList); - items = bitmap.PropertyItems; - Assert.Equal(2, items.Length); - Assert.Equal(PropertyTagExifUserComment, items[0].Id); - Assert.Equal(12, items[0].Len); - Assert.Equal(PropertyTagTypeASCII, items[0].Type); - Assert.Equal("Hello World\0", Encoding.ASCII.GetString(items[0].Value)); - Assert.Equal(propid, items[1].Id); - Assert.Equal(10, items[1].Len); - Assert.Equal(PropertyTagTypeASCII, items[1].Type); - Assert.Equal("New Value\0", Encoding.ASCII.GetString(items[1].Value)); - - // Set same. - bitmap.SetPropertyItem(item); - - Assert.Equal(new int[] { PropertyTagExifUserComment, propid }, bitmap.PropertyIdList); - items = bitmap.PropertyItems; - Assert.Equal(2, items.Length); - Assert.Equal(PropertyTagExifUserComment, items[0].Id); - Assert.Equal(12, items[0].Len); - Assert.Equal(PropertyTagTypeASCII, items[0].Type); - Assert.Equal("Hello World\0", Encoding.ASCII.GetString(items[0].Value)); - Assert.Equal(propid, items[1].Id); - Assert.Equal(10, items[1].Len); - Assert.Equal(PropertyTagTypeASCII, items[1].Type); - Assert.Equal("New Value\0", Encoding.ASCII.GetString(items[1].Value)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(-1)] - public void SetPropertyItem_InvokeBitmapJpg_Success(int propid) - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - - // Change data. - PropertyItem item = bitmap.GetPropertyItem(PropertyTagExifUserComment); - item.Value = "Hello World\0"u8.ToArray(); - item.Len = item.Value.Length; - - bitmap.SetPropertyItem(item); - - Assert.Equal(new int[] { PropertyTagExifUserComment, PropertyTagChrominanceTable, PropertyTagLuminanceTable }, bitmap.PropertyIdList); - PropertyItem[] items = bitmap.PropertyItems; - Assert.Equal(3, items.Length); - Assert.Equal(PropertyTagExifUserComment, items[0].Id); - Assert.Equal(12, items[0].Len); - Assert.Equal(PropertyTagTypeASCII, items[0].Type); - Assert.Equal("Hello World\0", Encoding.ASCII.GetString(items[0].Value)); - Assert.Equal(PropertyTagChrominanceTable, items[1].Id); - Assert.Equal(128, items[1].Len); - Assert.Equal(PropertyTagTypeShort, items[1].Type); - Assert.Equal(new byte[] - { - 0x16, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x17, - 0x00, 0x1B, 0x00, 0x22, 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x1F, - 0x00, 0x22, 0x00, 0x49, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x3E, - 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00 - }, items[1].Value); - Assert.Equal(PropertyTagLuminanceTable, items[2].Id); - Assert.Equal(128, items[2].Len); - Assert.Equal(PropertyTagTypeShort, items[2].Type); - Assert.Equal(new byte[] - { - 0x15, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x43, 0x00, 0x50, 0x00, 0x0F, - 0x00, 0x0F, 0x00, 0x12, 0x00, 0x19, 0x00, 0x22, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x48, 0x00, 0x12, - 0x00, 0x11, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x4B, 0x00, 0x5B, 0x00, 0x49, 0x00, 0x12, - 0x00, 0x16, 0x00, 0x1D, 0x00, 0x26, 0x00, 0x43, 0x00, 0x72, 0x00, 0x69, 0x00, 0x51, 0x00, 0x17, - 0x00, 0x1D, 0x00, 0x30, 0x00, 0x49, 0x00, 0x59, 0x00, 0x8F, 0x00, 0x87, 0x00, 0x65, 0x00, 0x1F, - 0x00, 0x2E, 0x00, 0x48, 0x00, 0x54, 0x00, 0x6A, 0x00, 0x89, 0x00, 0x95, 0x00, 0x79, 0x00, 0x40, - 0x00, 0x54, 0x00, 0x66, 0x00, 0x72, 0x00, 0x87, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x85, 0x00, 0x5F, - 0x00, 0x79, 0x00, 0x7D, 0x00, 0x81, 0x00, 0x93, 0x00, 0x84, 0x00, 0x87, 0x00, 0x82, 0x00, - }, items[2].Value); - - // New data. - item.Id = propid; - item.Value = "New Value\0"u8.ToArray(); - item.Len = item.Value.Length; - - bitmap.SetPropertyItem(item); - - Assert.Equal(new int[] { PropertyTagExifUserComment, PropertyTagChrominanceTable, PropertyTagLuminanceTable, propid }, bitmap.PropertyIdList); - items = bitmap.PropertyItems; - Assert.Equal(4, items.Length); - Assert.Equal(PropertyTagExifUserComment, items[0].Id); - Assert.Equal(12, items[0].Len); - Assert.Equal(PropertyTagTypeASCII, items[0].Type); - Assert.Equal("Hello World\0", Encoding.ASCII.GetString(items[0].Value)); - Assert.Equal(PropertyTagChrominanceTable, items[1].Id); - Assert.Equal(128, items[1].Len); - Assert.Equal(PropertyTagTypeShort, items[1].Type); - Assert.Equal(new byte[] - { - 0x16, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x17, - 0x00, 0x1B, 0x00, 0x22, 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x1F, - 0x00, 0x22, 0x00, 0x49, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x3E, - 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00 - }, items[1].Value); - Assert.Equal(PropertyTagLuminanceTable, items[2].Id); - Assert.Equal(128, items[2].Len); - Assert.Equal(PropertyTagTypeShort, items[2].Type); - Assert.Equal(new byte[] - { - 0x15, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x43, 0x00, 0x50, 0x00, 0x0F, - 0x00, 0x0F, 0x00, 0x12, 0x00, 0x19, 0x00, 0x22, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x48, 0x00, 0x12, - 0x00, 0x11, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x4B, 0x00, 0x5B, 0x00, 0x49, 0x00, 0x12, - 0x00, 0x16, 0x00, 0x1D, 0x00, 0x26, 0x00, 0x43, 0x00, 0x72, 0x00, 0x69, 0x00, 0x51, 0x00, 0x17, - 0x00, 0x1D, 0x00, 0x30, 0x00, 0x49, 0x00, 0x59, 0x00, 0x8F, 0x00, 0x87, 0x00, 0x65, 0x00, 0x1F, - 0x00, 0x2E, 0x00, 0x48, 0x00, 0x54, 0x00, 0x6A, 0x00, 0x89, 0x00, 0x95, 0x00, 0x79, 0x00, 0x40, - 0x00, 0x54, 0x00, 0x66, 0x00, 0x72, 0x00, 0x87, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x85, 0x00, 0x5F, - 0x00, 0x79, 0x00, 0x7D, 0x00, 0x81, 0x00, 0x93, 0x00, 0x84, 0x00, 0x87, 0x00, 0x82, 0x00, - }, items[2].Value); - Assert.Equal(propid, items[3].Id); - Assert.Equal(10, items[3].Len); - Assert.Equal(PropertyTagTypeASCII, items[3].Type); - Assert.Equal("New Value\0", Encoding.ASCII.GetString(items[3].Value)); - - // Set same. - bitmap.SetPropertyItem(item); - - Assert.Equal(new int[] { PropertyTagExifUserComment, PropertyTagChrominanceTable, PropertyTagLuminanceTable, propid }, bitmap.PropertyIdList); - items = bitmap.PropertyItems; - Assert.Equal(4, items.Length); - Assert.Equal(PropertyTagExifUserComment, items[0].Id); - Assert.Equal(12, items[0].Len); - Assert.Equal(PropertyTagTypeASCII, items[0].Type); - Assert.Equal("Hello World\0", Encoding.ASCII.GetString(items[0].Value)); - Assert.Equal(PropertyTagChrominanceTable, items[1].Id); - Assert.Equal(128, items[1].Len); - Assert.Equal(PropertyTagTypeShort, items[1].Type); - Assert.Equal(new byte[] - { - 0x16, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x17, - 0x00, 0x1B, 0x00, 0x22, 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x1F, - 0x00, 0x22, 0x00, 0x49, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x3E, - 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00 - }, items[1].Value); - Assert.Equal(PropertyTagLuminanceTable, items[2].Id); - Assert.Equal(128, items[2].Len); - Assert.Equal(PropertyTagTypeShort, items[2].Type); - Assert.Equal(new byte[] - { - 0x15, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x43, 0x00, 0x50, 0x00, 0x0F, - 0x00, 0x0F, 0x00, 0x12, 0x00, 0x19, 0x00, 0x22, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x48, 0x00, 0x12, - 0x00, 0x11, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x4B, 0x00, 0x5B, 0x00, 0x49, 0x00, 0x12, - 0x00, 0x16, 0x00, 0x1D, 0x00, 0x26, 0x00, 0x43, 0x00, 0x72, 0x00, 0x69, 0x00, 0x51, 0x00, 0x17, - 0x00, 0x1D, 0x00, 0x30, 0x00, 0x49, 0x00, 0x59, 0x00, 0x8F, 0x00, 0x87, 0x00, 0x65, 0x00, 0x1F, - 0x00, 0x2E, 0x00, 0x48, 0x00, 0x54, 0x00, 0x6A, 0x00, 0x89, 0x00, 0x95, 0x00, 0x79, 0x00, 0x40, - 0x00, 0x54, 0x00, 0x66, 0x00, 0x72, 0x00, 0x87, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x85, 0x00, 0x5F, - 0x00, 0x79, 0x00, 0x7D, 0x00, 0x81, 0x00, 0x93, 0x00, 0x84, 0x00, 0x87, 0x00, 0x82, 0x00, - }, items[2].Value); - Assert.Equal(propid, items[3].Id); - Assert.Equal(10, items[3].Len); - Assert.Equal(PropertyTagTypeASCII, items[3].Type); - Assert.Equal("New Value\0", Encoding.ASCII.GetString(items[3].Value)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(-1)] - public void SetPropertyItem_InvokeBitmapBmp_Success(int propid) - { - using var source = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("almogaver1bit.bmp")); - - // Change data. - PropertyItem item = source.GetPropertyItem(PropertyTagExifUserComment); - item.Value = "Hello World\0"u8.ToArray(); - item.Len = item.Value.Length; - - bitmap.SetPropertyItem(item); - - Assert.Equal(new int[] { PropertyTagExifUserComment }, bitmap.PropertyIdList); - PropertyItem[] items = bitmap.PropertyItems; - Assert.Single(items); - Assert.Equal(PropertyTagExifUserComment, items[0].Id); - Assert.Equal(12, items[0].Len); - Assert.Equal(PropertyTagTypeASCII, items[0].Type); - Assert.Equal("Hello World\0", Encoding.ASCII.GetString(items[0].Value)); - - // New data. - item.Id = propid; - item.Value = "New Value\0"u8.ToArray(); - item.Len = item.Value.Length; - - bitmap.SetPropertyItem(item); - - Assert.Equal(new int[] { PropertyTagExifUserComment, propid }, bitmap.PropertyIdList); - items = bitmap.PropertyItems; - Assert.Equal(2, items.Length); - Assert.Equal(PropertyTagExifUserComment, items[0].Id); - Assert.Equal(12, items[0].Len); - Assert.Equal(PropertyTagTypeASCII, items[0].Type); - Assert.Equal("Hello World\0", Encoding.ASCII.GetString(items[0].Value)); - Assert.Equal(propid, items[1].Id); - Assert.Equal(10, items[1].Len); - Assert.Equal(PropertyTagTypeASCII, items[1].Type); - Assert.Equal("New Value\0", Encoding.ASCII.GetString(items[1].Value)); - - // Set same. - bitmap.SetPropertyItem(item); - - Assert.Equal(new int[] { PropertyTagExifUserComment, propid }, bitmap.PropertyIdList); - items = bitmap.PropertyItems; - Assert.Equal(2, items.Length); - Assert.Equal(PropertyTagExifUserComment, items[0].Id); - Assert.Equal(12, items[0].Len); - Assert.Equal(PropertyTagTypeASCII, items[0].Type); - Assert.Equal("Hello World\0", Encoding.ASCII.GetString(items[0].Value)); - Assert.Equal(propid, items[1].Id); - Assert.Equal(10, items[1].Len); - Assert.Equal(PropertyTagTypeASCII, items[1].Type); - Assert.Equal("New Value\0", Encoding.ASCII.GetString(items[1].Value)); - } - - public static IEnumerable InvalidBytes_TestData() - { - // IconTests.Ctor_InvalidBytesInStream_TestData an array of 2 objects, but this test only uses the - // 1st object. - foreach (object[] data in IconTests.Ctor_InvalidBytesInStream_TestData()) - { - yield return new object[] { data[0] }; - } - } - - [Theory] - [MemberData(nameof(InvalidBytes_TestData))] - public void FromFile_InvalidBytes_ThrowsOutOfMemoryException(byte[] bytes) - { - using (var file = TempFile.Create(bytes)) - { - Assert.Throws(() => Image.FromFile(file.Path)); - Assert.Throws(() => Image.FromFile(file.Path, useEmbeddedColorManagement: true)); - } - } - - [Fact] - public void FromFile_NullFileName_ThrowsArgumentNullException() - { - AssertExtensions.Throws("path", () => Image.FromFile(null)); - AssertExtensions.Throws("path", () => Image.FromFile(null, useEmbeddedColorManagement: true)); - } - - [Fact] - public void FromFile_EmptyFileName_ThrowsArgumentNullException() - { - AssertExtensions.Throws("path", null, () => Image.FromFile(string.Empty)); - AssertExtensions.Throws("path", null, () => Image.FromFile(string.Empty, useEmbeddedColorManagement: true)); - } - - [Fact] - public void FromFile_LongSegment_ThrowsException() - { - // Throws PathTooLongException on Desktop and FileNotFoundException elsewhere. - if (PlatformDetection.IsNetFramework) - { - string fileName = new('a', 261); - - Assert.Throws(() => Image.FromFile(fileName)); - Assert.Throws(() => Image.FromFile(fileName, - useEmbeddedColorManagement: true)); - } - else - { - string fileName = new('a', 261); - - Assert.Throws(() => Image.FromFile(fileName)); - Assert.Throws(() => Image.FromFile(fileName, - useEmbeddedColorManagement: true)); - } - } - - [Fact] - public void FromFile_NoSuchFile_ThrowsFileNotFoundException() - { - Assert.Throws(() => Image.FromFile("NoSuchFile")); - Assert.Throws(() => Image.FromFile("NoSuchFile", useEmbeddedColorManagement: true)); - } - - [Theory] - [MemberData(nameof(InvalidBytes_TestData))] - public void FromStream_InvalidBytes_ThrowsArgumentException(byte[] bytes) - { - using (var stream = new MemoryStream()) - { - stream.Write(bytes, 0, bytes.Length); - stream.Position = 0; - - AssertExtensions.Throws(null, () => Image.FromStream(stream)); - Assert.Equal(0, stream.Position); - - AssertExtensions.Throws(null, () => Image.FromStream(stream, useEmbeddedColorManagement: true)); - AssertExtensions.Throws(null, () => Image.FromStream(stream, useEmbeddedColorManagement: true, validateImageData: true)); - Assert.Equal(0, stream.Position); - } - } - - [Fact] - public void FromStream_NullStream_ThrowsArgumentNullException() - { - AssertExtensions.Throws("stream", null, () => Image.FromStream(null)); - AssertExtensions.Throws("stream", null, () => Image.FromStream(null, useEmbeddedColorManagement: true)); - AssertExtensions.Throws("stream", null, () => Image.FromStream(null, useEmbeddedColorManagement: true, validateImageData: true)); - } - - [Theory] - [InlineData(PixelFormat.Format1bppIndexed, 1)] - [InlineData(PixelFormat.Format4bppIndexed, 4)] - [InlineData(PixelFormat.Format8bppIndexed, 8)] - [InlineData(PixelFormat.Format16bppArgb1555, 16)] - [InlineData(PixelFormat.Format16bppGrayScale, 16)] - [InlineData(PixelFormat.Format16bppRgb555, 16)] - [InlineData(PixelFormat.Format16bppRgb565, 16)] - [InlineData(PixelFormat.Format24bppRgb, 24)] - [InlineData(PixelFormat.Format32bppArgb, 32)] - [InlineData(PixelFormat.Format32bppPArgb, 32)] - [InlineData(PixelFormat.Format32bppRgb, 32)] - [InlineData(PixelFormat.Format48bppRgb, 48)] - [InlineData(PixelFormat.Format64bppArgb, 64)] - [InlineData(PixelFormat.Format64bppPArgb, 64)] - public void GetPixelFormatSize_ReturnsExpected(PixelFormat format, int expectedSize) - { - Assert.Equal(expectedSize, Image.GetPixelFormatSize(format)); - } - - [Theory] - [InlineData(PixelFormat.Format16bppArgb1555, true)] - [InlineData(PixelFormat.Format32bppArgb, true)] - [InlineData(PixelFormat.Format32bppPArgb, true)] - [InlineData(PixelFormat.Format64bppArgb, true)] - [InlineData(PixelFormat.Format64bppPArgb, true)] - [InlineData(PixelFormat.Format16bppGrayScale, false)] - [InlineData(PixelFormat.Format16bppRgb555, false)] - [InlineData(PixelFormat.Format16bppRgb565, false)] - [InlineData(PixelFormat.Format1bppIndexed, false)] - [InlineData(PixelFormat.Format24bppRgb, false)] - [InlineData(PixelFormat.Format32bppRgb, false)] - [InlineData(PixelFormat.Format48bppRgb, false)] - [InlineData(PixelFormat.Format4bppIndexed, false)] - [InlineData(PixelFormat.Format8bppIndexed, false)] - public void IsAlphaPixelFormat_ReturnsExpected(PixelFormat format, bool expected) - { - Assert.Equal(expected, Image.IsAlphaPixelFormat(format)); - } - - public static IEnumerable GetEncoderParameterList_ReturnsExpected_TestData() - { - yield return new object[] - { - ImageFormat.Tiff, - new Guid[] - { - Encoder.Compression.Guid, - Encoder.ColorDepth.Guid, - Encoder.SaveFlag.Guid, - new Guid(unchecked((int)0xa219bbc9), unchecked((short)0x0a9d), unchecked((short)0x4005), new byte[] { 0xa3, 0xee, 0x3a, 0x42, 0x1b, 0x8b, 0xb0, 0x6c }) /* Encoder.SaveAsCmyk.Guid */ - } - }; - -#if !NETFRAMEWORK - // NetFX doesn't support pointer-type encoder parameters, and doesn't define Encoder.ImageItems. Skip this test - // on NetFX. - yield return new object[] - { - ImageFormat.Jpeg, - new Guid[] - { - Encoder.Transformation.Guid, - Encoder.Quality.Guid, - Encoder.LuminanceTable.Guid, - Encoder.ChrominanceTable.Guid, - Encoder.ImageItems.Guid - } - }; -#endif - } - - [Theory] - [MemberData(nameof(GetEncoderParameterList_ReturnsExpected_TestData))] - public void GetEncoderParameterList_ReturnsExpected(ImageFormat format, Guid[] expectedParameters) - { - if (PlatformDetection.IsNetFramework) - { - throw new SkipTestException("This is a known bug for .NET Framework"); - } - - ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); - ImageCodecInfo codec = codecs.Single(c => c.FormatID == format.Guid); - - using (var bitmap = new Bitmap(1, 1)) - { - EncoderParameters paramList = bitmap.GetEncoderParameterList(codec.Clsid); - - Assert.Equal( - expectedParameters, - paramList.Param.Select(p => p.Encoder.Guid)); - } - } - - [Fact] - public void Save_InvalidDirectory_ThrowsDirectoryNotFoundException() - { - using (var bitmap = new Bitmap(1, 1)) - { - var badTarget = System.IO.Path.Combine("NoSuchDirectory", "NoSuchFile"); - AssertExtensions.Throws(() => bitmap.Save(badTarget), $"The directory NoSuchDirectory of the filename {badTarget} does not exist."); - } - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/BitmapDataTests.cs b/src/System.Drawing.Common/tests/Imaging/BitmapDataTests.cs deleted file mode 100644 index 045cd4744ac..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/BitmapDataTests.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -public class BitmapDataTests -{ - [Fact] - public void Ctor_Default() - { - BitmapData bd = new BitmapData(); - Assert.Equal(0, bd.Height); - Assert.Equal(0, bd.Width); - Assert.Equal(0, bd.Reserved); - Assert.Equal(IntPtr.Zero, bd.Scan0); - Assert.Equal(0, bd.Stride); - Assert.Equal((PixelFormat)0, bd.PixelFormat); - } - - [Theory] - [InlineData(int.MaxValue)] - [InlineData(0)] - [InlineData(int.MinValue)] - public void Height_SetValid_ReturnsExpected(int value) - { - BitmapData bd = new BitmapData(); - bd.Height = value; - Assert.Equal(value, bd.Height); - } - - [Theory] - [InlineData(int.MaxValue)] - [InlineData(0)] - [InlineData(int.MinValue)] - public void Width_SetValid_ReturnsExpected(int value) - { - BitmapData bd = new BitmapData(); - bd.Width = value; - Assert.Equal(value, bd.Width); - } - - [Theory] - [InlineData(int.MaxValue)] - [InlineData(0)] - [InlineData(int.MinValue)] - public void Reserved_SetValid_ReturnsExpected(int value) - { - BitmapData bd = new BitmapData(); - bd.Reserved = value; - Assert.Equal(value, bd.Reserved); - } - - [Theory] - [InlineData(int.MaxValue)] - [InlineData(0)] - [InlineData(int.MinValue)] - public void Scan0_SetValid_ReturnsExpected(int value) - { - BitmapData bd = new BitmapData(); - bd.Scan0 = new IntPtr(value); - Assert.Equal(new IntPtr(value), bd.Scan0); - } - - [Theory] - [InlineData(int.MaxValue)] - [InlineData(0)] - [InlineData(int.MinValue)] - public void Stride_SetValid_ReturnsExpected(int value) - { - BitmapData bd = new BitmapData(); - bd.Stride = value; - Assert.Equal(value, bd.Stride); - } - - [Theory] - [InlineData(PixelFormat.DontCare)] - [InlineData(PixelFormat.Max)] - [InlineData(PixelFormat.Indexed)] - [InlineData(PixelFormat.Gdi)] - [InlineData(PixelFormat.Format16bppRgb555)] - [InlineData(PixelFormat.Format16bppRgb565)] - [InlineData(PixelFormat.Format24bppRgb)] - [InlineData(PixelFormat.Format32bppRgb)] - [InlineData(PixelFormat.Format1bppIndexed)] - [InlineData(PixelFormat.Format4bppIndexed)] - [InlineData(PixelFormat.Format8bppIndexed)] - [InlineData(PixelFormat.Alpha)] - [InlineData(PixelFormat.Format16bppArgb1555)] - [InlineData(PixelFormat.PAlpha)] - [InlineData(PixelFormat.Format32bppPArgb)] - [InlineData(PixelFormat.Extended)] - [InlineData(PixelFormat.Format16bppGrayScale)] - [InlineData(PixelFormat.Format48bppRgb)] - [InlineData(PixelFormat.Format64bppPArgb)] - [InlineData(PixelFormat.Canonical)] - [InlineData(PixelFormat.Format32bppArgb)] - [InlineData(PixelFormat.Format64bppArgb)] - public void PixelFormat_SetValid_ReturnsExpected(PixelFormat pixelFormat) - { - BitmapData bd = new BitmapData(); - bd.PixelFormat = pixelFormat; - Assert.Equal(pixelFormat, bd.PixelFormat); - } - - [Fact] - public void PixelFormat_SetInvalid_ThrowsInvalidEnumException() - { - BitmapData bd = new BitmapData(); - Assert.ThrowsAny(() => bd.PixelFormat = (PixelFormat)(-1)); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/CachedBitmapTests.cs b/src/System.Drawing.Common/tests/Imaging/CachedBitmapTests.cs deleted file mode 100644 index 3ad43b38e30..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/CachedBitmapTests.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -#if NET8_0_OR_GREATER -public class CachedBitmapTests -{ - [Fact] - public void Ctor_Throws_ArgumentNullException() - { - using var bitmap = new Bitmap(10, 10); - using var graphics = Graphics.FromImage(bitmap); - - Assert.Throws(() => new CachedBitmap(bitmap, null)); - Assert.Throws(() => new CachedBitmap(null, graphics)); - } -} -#endif diff --git a/src/System.Drawing.Common/tests/Imaging/ColorMapTests.cs b/src/System.Drawing.Common/tests/Imaging/ColorMapTests.cs deleted file mode 100644 index 2d29267b07f..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/ColorMapTests.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -public class ColorMapTests -{ - [Fact] - public void Ctor_Default() - { - ColorMap cm = new ColorMap(); - Assert.Equal(new Color(), cm.OldColor); - Assert.Equal(new Color(), cm.NewColor); - } - - [Fact] - public void NewColor_SetValid_ReturnsExpected() - { - ColorMap cm = new ColorMap(); - cm.NewColor = Color.AliceBlue; - Assert.Equal(Color.AliceBlue, cm.NewColor); - } - - [Fact] - public void OldColor_SetValid_ReturnsExpected() - { - ColorMap cm = new ColorMap(); - cm.OldColor = Color.AliceBlue; - Assert.Equal(Color.AliceBlue, cm.OldColor); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/ColorMatrixTests.cs b/src/System.Drawing.Common/tests/Imaging/ColorMatrixTests.cs deleted file mode 100644 index 5d6e006b82b..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/ColorMatrixTests.cs +++ /dev/null @@ -1,282 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2005-2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// -// Authors: -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sebastien Pouliot -// - -namespace System.Drawing.Imaging.Tests; - -public class ColorMatrixTests -{ - [Fact] - public void Ctor_Default() - { - ColorMatrix cm = new ColorMatrix(); - - Assert.Equal(1, cm.Matrix00); - Assert.Equal(1, cm.Matrix11); - Assert.Equal(1, cm.Matrix22); - Assert.Equal(1, cm.Matrix33); - Assert.Equal(1, cm.Matrix44); - Assert.Equal(0, cm.Matrix01); - Assert.Equal(0, cm.Matrix02); - Assert.Equal(0, cm.Matrix03); - Assert.Equal(0, cm.Matrix04); - Assert.Equal(0, cm.Matrix10); - Assert.Equal(0, cm.Matrix12); - Assert.Equal(0, cm.Matrix13); - Assert.Equal(0, cm.Matrix14); - Assert.Equal(0, cm.Matrix20); - Assert.Equal(0, cm.Matrix21); - Assert.Equal(0, cm.Matrix23); - Assert.Equal(0, cm.Matrix24); - Assert.Equal(0, cm.Matrix30); - Assert.Equal(0, cm.Matrix31); - Assert.Equal(0, cm.Matrix32); - Assert.Equal(0, cm.Matrix34); - Assert.Equal(0, cm.Matrix40); - Assert.Equal(0, cm.Matrix41); - Assert.Equal(0, cm.Matrix42); - Assert.Equal(0, cm.Matrix43); - } - - public static IEnumerable BadCtorParams - { - get - { - yield return new object[] { null, typeof(NullReferenceException) }; - yield return new object[] { new float[][] { }, typeof(IndexOutOfRangeException) }; - yield return new object[] { new float[][] { new float[] { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f } }, typeof(IndexOutOfRangeException) }; - yield return new object[] { new float[][] { - new float[] { 0.0f }, - new float[] { 1.0f }, - new float[] { 2.0f }, - new float[] { 3.0f }, - new float[] { 4.0f }, - new float[] { 5.0f } } - , typeof(IndexOutOfRangeException) }; - } - } - - public static float[][] IndexedColorMatrix - { - get - { - return new float[][] { - new float[] { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f}, - new float[] { 1.0f, 1.1f, 1.2f, 1.3f, 1.4f}, - new float[] { 2.0f, 2.1f, 2.2f, 2.3f, 2.4f}, - new float[] { 3.0f, 3.1f, 3.2f, 3.3f, 3.4f}, - new float[] { 4.0f, 4.1f, 4.2f, 4.3f, 4.4f}, - }; - } - } - - [Theory] - [MemberData(nameof(BadCtorParams))] - public void Ctor_BadValues_ThrowsExpectedException(float[][] newColorMatrix, Type expectedException) - { - Assert.Throws(expectedException, () => new ColorMatrix(newColorMatrix)); - } - - [Fact] - public void Ctor_TooBigArraySize_MapOnly4and4Elements() - { - ColorMatrix cm = new ColorMatrix(new float[][] { - new float[] { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f }, - new float[] { 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f }, - new float[] { 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f }, - new float[] { 3.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.5f }, - new float[] { 4.0f, 4.1f, 4.2f, 4.3f, 4.4f, 4.5f }, - new float[] { 5.0f, 5.1f, 5.2f, 5.3f, 5.4f, 5.5f } - }); - - Assert.Equal(0.0f, cm.Matrix00); - Assert.Equal(0.1f, cm.Matrix01); - Assert.Equal(0.2f, cm.Matrix02); - Assert.Equal(0.3f, cm.Matrix03); - Assert.Equal(0.4f, cm.Matrix04); - Assert.Equal(1.0f, cm.Matrix10); - Assert.Equal(1.1f, cm.Matrix11); - Assert.Equal(1.2f, cm.Matrix12); - Assert.Equal(1.3f, cm.Matrix13); - Assert.Equal(1.4f, cm.Matrix14); - Assert.Equal(2.0f, cm.Matrix20); - Assert.Equal(2.1f, cm.Matrix21); - Assert.Equal(2.2f, cm.Matrix22); - Assert.Equal(2.3f, cm.Matrix23); - Assert.Equal(2.4f, cm.Matrix24); - Assert.Equal(3.0f, cm.Matrix30); - Assert.Equal(3.1f, cm.Matrix31); - Assert.Equal(3.2f, cm.Matrix32); - Assert.Equal(3.3f, cm.Matrix33); - Assert.Equal(3.4f, cm.Matrix34); - Assert.Equal(4.0f, cm.Matrix40); - Assert.Equal(4.1f, cm.Matrix41); - Assert.Equal(4.2f, cm.Matrix42); - Assert.Equal(4.3f, cm.Matrix43); - Assert.Equal(4.4f, cm.Matrix44); - } - - [Fact] - public void AccessToNotExistingElement_ThrowsIndexOutOfRangeException() - { - ColorMatrix cm = new ColorMatrix(new float[][] { - new float[] { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f }, - new float[] { 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f }, - new float[] { 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f }, - new float[] { 3.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.5f }, - new float[] { 4.0f, 4.1f, 4.2f, 4.3f, 4.4f, 4.5f }, - new float[] { 5.0f, 5.1f, 5.2f, 5.3f, 5.4f, 5.5f } - }); - Assert.Throws(() => _ = cm[5, 5]); - } - - [Fact] - public void Ctor_SetValue_ReturnsExpected() - { - ColorMatrix cm = new ColorMatrix(IndexedColorMatrix); - - Assert.Equal(0.0f, cm.Matrix00); - Assert.Equal(1.0f, cm.Matrix10); - Assert.Equal(2.0f, cm.Matrix20); - Assert.Equal(3.0f, cm.Matrix30); - Assert.Equal(4.0f, cm.Matrix40); - - Assert.Equal(0.1f, cm.Matrix01); - Assert.Equal(1.1f, cm.Matrix11); - Assert.Equal(2.1f, cm.Matrix21); - Assert.Equal(3.1f, cm.Matrix31); - Assert.Equal(4.1f, cm.Matrix41); - - Assert.Equal(0.2f, cm.Matrix02); - Assert.Equal(1.2f, cm.Matrix12); - Assert.Equal(2.2f, cm.Matrix22); - Assert.Equal(3.2f, cm.Matrix32); - Assert.Equal(4.2f, cm.Matrix42); - - Assert.Equal(0.3f, cm.Matrix03); - Assert.Equal(1.3f, cm.Matrix13); - Assert.Equal(2.3f, cm.Matrix23); - Assert.Equal(3.3f, cm.Matrix33); - Assert.Equal(4.3f, cm.Matrix43); - - Assert.Equal(0.4f, cm.Matrix04); - Assert.Equal(1.4f, cm.Matrix14); - Assert.Equal(2.4f, cm.Matrix24); - Assert.Equal(3.4f, cm.Matrix34); - Assert.Equal(4.4f, cm.Matrix44); - - for (int i = 0; i < 5; i++) - { - for (int j = 0; j < 5; j++) - { - Assert.Equal(IndexedColorMatrix[i][j], cm[i, j]); - } - } - } - - [Fact] - public void MatrixElement_SetValues_ReturnsExpected() - { - ColorMatrix cm = new ColorMatrix(); - - cm.Matrix00 = 1; - cm.Matrix01 = 2; - cm.Matrix02 = 3; - cm.Matrix03 = 4; - cm.Matrix04 = 5; - cm.Matrix10 = 6; - cm.Matrix11 = 7; - cm.Matrix12 = 8; - cm.Matrix13 = 9; - cm.Matrix14 = 10; - cm.Matrix20 = 11; - cm.Matrix21 = 12; - cm.Matrix22 = 13; - cm.Matrix23 = 14; - cm.Matrix24 = 15; - cm.Matrix30 = 16; - cm.Matrix31 = 17; - cm.Matrix32 = 18; - cm.Matrix33 = 19; - cm.Matrix34 = 20; - cm.Matrix40 = 21; - cm.Matrix41 = 22; - cm.Matrix42 = 23; - cm.Matrix43 = 24; - cm.Matrix44 = 25; - - Assert.Equal(1, cm.Matrix00); - Assert.Equal(2, cm.Matrix01); - Assert.Equal(3, cm.Matrix02); - Assert.Equal(4, cm.Matrix03); - Assert.Equal(5, cm.Matrix04); - Assert.Equal(6, cm.Matrix10); - Assert.Equal(7, cm.Matrix11); - Assert.Equal(8, cm.Matrix12); - Assert.Equal(9, cm.Matrix13); - Assert.Equal(10, cm.Matrix14); - Assert.Equal(11, cm.Matrix20); - Assert.Equal(12, cm.Matrix21); - Assert.Equal(13, cm.Matrix22); - Assert.Equal(14, cm.Matrix23); - Assert.Equal(15, cm.Matrix24); - Assert.Equal(16, cm.Matrix30); - Assert.Equal(17, cm.Matrix31); - Assert.Equal(18, cm.Matrix32); - Assert.Equal(19, cm.Matrix33); - Assert.Equal(20, cm.Matrix34); - Assert.Equal(21, cm.Matrix40); - Assert.Equal(22, cm.Matrix41); - Assert.Equal(23, cm.Matrix42); - Assert.Equal(24, cm.Matrix43); - Assert.Equal(25, cm.Matrix44); - } - - [Fact] - public void MatrixElementByIndexer_SetValue_ReturnsExpetecd() - { - ColorMatrix cm = new ColorMatrix(IndexedColorMatrix); - - for (int i = 0; i < 5; i++) - { - for (int j = 0; j < 5; j++) - { - cm[i, j] = IndexedColorMatrix[i][j]; - } - } - - for (int i = 0; i < 5; i++) - { - for (int j = 0; j < 5; j++) - { - Assert.Equal(IndexedColorMatrix[i][j], cm[i, j]); - } - } - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/EncoderParameterTests.cs b/src/System.Drawing.Common/tests/Imaging/EncoderParameterTests.cs deleted file mode 100644 index dd0ebcf3bc3..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/EncoderParameterTests.cs +++ /dev/null @@ -1,358 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -public class EncoderParameterTests -{ - private static readonly Encoder s_anyEncoder = Encoder.ChrominanceTable; - - private void CheckEncoderParameter(EncoderParameter encoderParameter, Encoder expectedEncoder, EncoderParameterValueType expectedType, int expectedNumberOfValues) - { - Assert.Equal(expectedEncoder.Guid, encoderParameter.Encoder.Guid); - Assert.Equal(expectedType, encoderParameter.ValueType); - Assert.Equal(expectedType, encoderParameter.Type); - Assert.Equal(expectedNumberOfValues, encoderParameter.NumberOfValues); - } - - public static IEnumerable Ctor_Encoder_Byte_TestData - { - get - { - yield return new object[] { Encoder.ChrominanceTable, byte.MinValue }; - yield return new object[] { Encoder.ColorDepth, byte.MinValue }; - yield return new object[] { Encoder.Compression, byte.MinValue }; - yield return new object[] { Encoder.LuminanceTable, byte.MinValue }; - yield return new object[] { Encoder.Quality, byte.MinValue }; - yield return new object[] { Encoder.RenderMethod, byte.MinValue }; - yield return new object[] { Encoder.SaveFlag, byte.MinValue }; - yield return new object[] { Encoder.ScanMethod, byte.MinValue }; - yield return new object[] { Encoder.Transformation, byte.MinValue }; - yield return new object[] { Encoder.Version, byte.MinValue }; - yield return new object[] { new Encoder(Guid.NewGuid()), byte.MinValue }; - yield return new object[] { new Encoder(Guid.NewGuid()), 1 }; - yield return new object[] { new Encoder(Guid.NewGuid()), byte.MaxValue }; - } - } - - [Theory] - [MemberData(nameof(Ctor_Encoder_Byte_TestData))] - public void Ctor_Encoder_Byte(Encoder encoder, byte value) - { - using (EncoderParameter ep = new EncoderParameter(encoder, value)) - { - CheckEncoderParameter(ep, encoder, EncoderParameterValueType.ValueTypeByte, 1); - } - } - - [Theory] - [InlineData(false, EncoderParameterValueType.ValueTypeByte)] - [InlineData(true, EncoderParameterValueType.ValueTypeUndefined)] - public void Ctor_Encoder_ByteValue_Bool(bool undefined, EncoderParameterValueType expected) - { - EncoderParameter ep = new EncoderParameter(s_anyEncoder, 0, undefined); - CheckEncoderParameter(ep, s_anyEncoder, expected, 1); - } - - [Theory] - [InlineData(0)] - [InlineData(short.MinValue)] - [InlineData(short.MaxValue)] - public void Ctor_Encoder_Short(short value) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, value)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeShort, 1); - } - } - - [Theory] - [InlineData(0)] - [InlineData(long.MinValue)] - [InlineData(long.MaxValue)] - public void Ctor_Encoder_Long(long value) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, value)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeLong, 1); - } - } - - [Theory] - [InlineData(int.MaxValue, int.MaxValue)] - [InlineData(10, 5)] - [InlineData(-10, -5)] - public void Ctor_Encoder_Numerator_Denominator(int numerator, int denominator) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, numerator, denominator)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeRational, 1); - } - } - - [Theory] - [InlineData(0, 0, 0, 0)] - [InlineData(1, 2, 3, 4)] - public void Ctor_Encoder_Numerator1_Denominator1_Numerator2_Denominator2(int numerator1, int denominator1, int numerator2, int denominator2) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, numerator1, denominator1, numerator2, denominator2)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeRationalRange, 1); - } - } - - [Theory] - [InlineData(0, 0)] - [InlineData(1, 2)] - public void Ctor_Encoder_RangeBegin_RangeEnd(long rangeBegin, long rangeEnd) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, rangeBegin, rangeEnd)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeLongRange, 1); - } - } - - [Theory] - [InlineData("someStringValue")] - [InlineData("")] - public void Ctor_Encoder_String(string value) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, value)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeAscii, value.Length); - } - } - - [Theory] - [InlineData(new byte[] { })] - [InlineData(new byte[] { 0, 1, 2, 3 })] - public void Ctor_Encoder_ByteArray(byte[] value) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, value)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeByte, value.Length); - } - } - - [Theory] - [InlineData(new byte[] { 1, 2 }, false, EncoderParameterValueType.ValueTypeByte)] - [InlineData(new byte[] { 1, 2 }, true, EncoderParameterValueType.ValueTypeUndefined)] - public void Ctor_Encoder_ByteArray_Bool(byte[] value, bool undefined, EncoderParameterValueType expected) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, value, undefined)) - { - CheckEncoderParameter(ep, s_anyEncoder, expected, value.Length); - } - } - - [Theory] - [InlineData(new short[] { })] - [InlineData(new short[] { 0, 1, 2, 3 })] - public void Ctor_Encoder_ShortArray(short[] value) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, value)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeShort, value.Length); - } - } - - [Theory] - [InlineData(new long[] { })] - [InlineData(new long[] { 0, 1, 2, 3 })] - public void Ctor_Encoder_LongArray(long[] value) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, value)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeLong, value.Length); - } - } - - [Theory] - [InlineData(new int[] { 0, 1, 2, 3 }, new int[] { 5, 6, 7, 8 })] - public void Ctor_Encoder_NumeratorArray_DenominatorArray(int[] numerator, int[] denominator) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, numerator, denominator)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeRational, numerator.Length); - } - } - - [Theory] - [InlineData(new long[] { 0, 1, 2, 3 }, new long[] { 5, 6, 7, 8 })] - public void Ctor_Encoder_RangeBeginArray_RangeEndArray(long[] rangeBegin, long[] rangeEnd) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, rangeBegin, rangeEnd)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeLongRange, rangeBegin.Length); - } - } - - [Theory] - [InlineData(new int[] { 0, 1, 2, 3 }, new int[] { 4, 5, 6, 7 }, new int[] { 8, 9, 10, 11 }, new int[] { 12, 13, 14, 15 })] - public void Ctor_Encoder_Numerator1Array_Denominator1Array_Numerator2Array_Denominator2Array(int[] numerator1, int[] denominator1, int[] numerator2, int[] denominator2) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, numerator1, denominator1, numerator2, denominator2)) - { - CheckEncoderParameter(ep, s_anyEncoder, EncoderParameterValueType.ValueTypeRationalRange, numerator1.Length); - } - } - - public static IEnumerable Encoder_NumberOfValues_TestData - { - get - { - yield return new object[] { 0, EncoderParameterValueType.ValueTypeAscii, IntPtr.Zero }; - yield return new object[] { 0, EncoderParameterValueType.ValueTypeByte, IntPtr.Zero }; - yield return new object[] { 0, EncoderParameterValueType.ValueTypeLong, IntPtr.Zero }; - yield return new object[] { 0, EncoderParameterValueType.ValueTypeLongRange, IntPtr.Zero }; - yield return new object[] { 0, EncoderParameterValueType.ValueTypeRational, IntPtr.Zero }; - yield return new object[] { 0, EncoderParameterValueType.ValueTypeRationalRange, IntPtr.Zero }; - yield return new object[] { 0, EncoderParameterValueType.ValueTypeShort, IntPtr.Zero }; - yield return new object[] { 0, EncoderParameterValueType.ValueTypeUndefined, IntPtr.Zero }; - yield return new object[] { 0, EncoderParameterValueType.ValueTypeUndefined, IntPtr.Zero }; - } - } - - [Theory] - [MemberData(nameof(Encoder_NumberOfValues_TestData))] - public void Ctor_Encoder_NumberOfValues_Type_Value(int numberOfValues, EncoderParameterValueType type, IntPtr value) - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, numberOfValues, type, value)) - { - CheckEncoderParameter(ep, s_anyEncoder, type, numberOfValues); - } - } - - [Fact] - public void Encoder_ReturnsExpecetd() - { - Encoder encoder = new Encoder(Guid.NewGuid()); - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, 0) - { - Encoder = encoder - }) - { - Assert.Equal(encoder.Guid, ep.Encoder.Guid); - } - } - - [Fact] - public void Ctor_Encoder_NumberOfValues_NotExistingType_ThrowsInvalidOperationException() - { - Assert.Throws(() => new EncoderParameter(s_anyEncoder, 1, (EncoderParameterValueType)999, IntPtr.Zero)); - } - - [Theory] - [InlineData(new int[] { 1, 2 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, typeof(ArgumentException))] - [InlineData(new int[] { 1 }, new int[] { 1, 2 }, new int[] { 1 }, new int[] { 1 }, typeof(ArgumentException))] - [InlineData(null, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, typeof(NullReferenceException))] - [InlineData(new int[] { 1 }, null, new int[] { 1 }, new int[] { 1 }, typeof(NullReferenceException))] - [InlineData(new int[] { 1 }, new int[] { 1 }, null, new int[] { 1 }, typeof(NullReferenceException))] - [InlineData(new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, null, typeof(NullReferenceException))] - public void Ctor_Encoder_Numerator1Array_Denominator1Array_Numerator2Array_Denominator2Array_InvalidParameters_ThrowsExpected(int[] numerator1, int[] denominator1, int[] numerator2, int[] denominator2, Type expected) - { - Assert.Throws(expected, () => new EncoderParameter(s_anyEncoder, numerator1, denominator1, numerator2, denominator2)); - } - - [Fact] - public void Encoder_Null_ThrowsNullReferenceException() - { - using (EncoderParameter ep = new EncoderParameter(s_anyEncoder, 0)) - { - Assert.Throws(() => ep.Encoder = null); - } - } - - [Theory] - [InlineData(new int[] { 0 }, new int[] { 0, 1 }, typeof(ArgumentException))] - [InlineData(new int[] { 0, 1 }, new int[] { 0 }, typeof(ArgumentException))] - [InlineData(new int[] { 0, 1 }, null, typeof(NullReferenceException))] - [InlineData(null, new int[] { 0, 1 }, typeof(NullReferenceException))] - public void Ctor_Numerator_Denominator_IvalidValues_ThrowsExpected(int[] numerator, int[] denominator, Type expected) - { - Assert.Throws(expected, () => new EncoderParameter(s_anyEncoder, numerator, denominator)); - } - - [Theory] - [InlineData(new long[] { 0 }, new long[] { 0, 1 }, typeof(ArgumentException))] - [InlineData(new long[] { 0, 1 }, new long[] { 0 }, typeof(ArgumentException))] - [InlineData(new long[] { 0, 1 }, null, typeof(NullReferenceException))] - [InlineData(null, new long[] { 0, 1 }, typeof(NullReferenceException))] - public void Ctor_RangeBegin_RangeEnd_InvalidValues_ThrowsExpected(long[] rangeBegin, long[] rangeEnd, Type expected) - { - Assert.Throws(expected, () => new EncoderParameter(s_anyEncoder, rangeBegin, rangeEnd)); - } - - [Fact] - public void Ctor_Encoder_NullString_ThrowsNullReferenceException() - { - Assert.Throws(() => new EncoderParameter(s_anyEncoder, (string)null)); - } - - [Fact] - public void Ctor_Encoder_ByteArray_ThrowsNullReferenceException() - { - Assert.Throws(() => new EncoderParameter(s_anyEncoder, (byte[])null)); - } - - public static IEnumerable EncoderParameterCtor_NullEncoder_TestData - { - get - { - yield return new object[] { new Action(() => new EncoderParameter(null, (byte)0)) }; - yield return new object[] { new Action(() => new EncoderParameter(null, (byte)0, false)) }; - yield return new object[] { new Action(() => new EncoderParameter(null, (short)0)) }; - yield return new object[] { new Action(() => new EncoderParameter(null, numerator: 0, denominator: 0)) }; - yield return new object[] { new Action(() => new EncoderParameter(null, rangebegin: 0, rangeend: 0)) }; - yield return new object[] { new Action(() => new EncoderParameter(null, 0, 0, 0, 0)) }; - yield return new object[] { new Action(() => new EncoderParameter(null, "anyString")) }; - yield return new object[] { new Action(() => new EncoderParameter(null, new byte[] { })) }; - yield return new object[] { new Action(() => new EncoderParameter(null, new byte[] { }, false)) }; - yield return new object[] { new Action(() => new EncoderParameter(null, new short[] { })) }; - yield return new object[] { new Action(() => new EncoderParameter(null, new long[] { })) }; - yield return new object[] { new Action(() => new EncoderParameter(null, new int[] { }, new int[] { })) }; - yield return new object[] { new Action(() => new EncoderParameter(null, new long[] { }, new long[] { })) }; - } - } - - [Fact] - public void Ctor_NullEncoder_ThrowsNullReferenceException() - { - Assert.Throws(() => new EncoderParameter(null, (byte)0)); - Assert.Throws(() => new EncoderParameter(null, (byte)0, false)); - Assert.Throws(() => new EncoderParameter(null, (short)0)); - Assert.Throws(() => new EncoderParameter(null, numerator: 0, denominator: 0)); - Assert.Throws(() => new EncoderParameter(null, rangebegin: 0, rangeend: 0)); - Assert.Throws(() => new EncoderParameter(null, 0, 0, 0, 0)); - Assert.Throws(() => new EncoderParameter(null, "anyString")); - Assert.Throws(() => new EncoderParameter(null, new byte[] { })); - Assert.Throws(() => new EncoderParameter(null, new byte[] { }, false)); - Assert.Throws(() => new EncoderParameter(null, new short[] { })); - Assert.Throws(() => new EncoderParameter(null, new long[] { })); - Assert.Throws(() => new EncoderParameter(null, new int[] { }, new int[] { })); - Assert.Throws(() => new EncoderParameter(null, new long[] { }, new long[] { })); - } - - [Theory] - [InlineData(EncoderParameterValueType.ValueTypeShort, (int.MaxValue / 2) + 1, typeof(OverflowException))] - [InlineData(EncoderParameterValueType.ValueTypeLong, (int.MaxValue / 4) + 1, typeof(OverflowException))] - [InlineData(EncoderParameterValueType.ValueTypeRational, (int.MaxValue / 8) + 1, typeof(OverflowException))] - [InlineData(EncoderParameterValueType.ValueTypeLongRange, (int.MaxValue / 8) + 1, typeof(OverflowException))] - [InlineData(EncoderParameterValueType.ValueTypeRationalRange, (int.MaxValue / 16) + 1, typeof(OverflowException))] - public void Ctor_Encoder_TooBigNumberOfValues_Type_Value_AccessViolationException(EncoderParameterValueType type, int numberOfValues, Type expected) - { - Assert.Throws(expected, () => new EncoderParameter(s_anyEncoder, numberOfValues, type, IntPtr.Zero)); - } - - [Theory] - [InlineData(-1)] - [InlineData(int.MinValue)] - [SkipOnArchitecture(TestArchitectures.X86, "backwards compatibility on 32 bit platforms may not throw")] - // This test may depend on amount of RAM and system configuration and load. - public void Ctor_Encoder_NegativeNumberOfValues_Type_Value_OutOfMemoryException(int numberOfValues) - { - IntPtr anyValue = IntPtr.Zero; - EncoderParameterValueType anyType = EncoderParameterValueType.ValueTypeAscii; - Assert.Throws(() => new EncoderParameter(s_anyEncoder, numberOfValues, anyType, anyValue)); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/EncoderParametersTests.cs b/src/System.Drawing.Common/tests/Imaging/EncoderParametersTests.cs deleted file mode 100644 index b542737c707..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/EncoderParametersTests.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -public class EncoderParametersTests -{ - [Fact] - public void Ctor_Default() - { - using (EncoderParameters ep = new EncoderParameters()) - { - Assert.NotNull(ep.Param); - Assert.Equal(new EncoderParameter[1], ep.Param); - } - } - - [Theory] - [InlineData(1)] - public void Ctor_Count_Default(int count) - { - using (EncoderParameters ep = new EncoderParameters(count)) - { - Assert.NotNull(ep.Param); - Assert.Equal(new EncoderParameter[count], ep.Param); - } - } - - public static IEnumerable Param_TestData - { - get - { - yield return new object[] { new EncoderParameter[1] }; - yield return new object[] { new EncoderParameter[1] { new EncoderParameter(Encoder.ChrominanceTable, 0) } }; - yield return new object[] { new EncoderParameter[1] { null } }; - } - } - - [Theory] - [MemberData(nameof(Param_TestData))] - public void Param_Success(EncoderParameter[] param) - { - using (EncoderParameters ep = new EncoderParameters()) - { - ep.Param = param; - Assert.Equal(param, ep.Param); - } - } - - [Theory] - [MemberData(nameof(Param_TestData))] - public void Dispose_Success(EncoderParameter[] param) - { - EncoderParameters ep = new EncoderParameters(); - ep.Param = param; - ep.Dispose(); - Assert.Null(ep.Param); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/EncoderTests.cs b/src/System.Drawing.Common/tests/Imaging/EncoderTests.cs deleted file mode 100644 index 21335bde4fc..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/EncoderTests.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -public class EncoderTests -{ - [Fact] - public void Ctor_Guid() - { - Guid guid = Guid.NewGuid(); - Encoder encoder = new Encoder(guid); - Assert.Equal(guid, encoder.Guid); - } - - public static IEnumerable EncoderTestData - { - get - { - yield return new object[] { Encoder.Compression.Guid, new Guid(unchecked((int)0xe09d739d), unchecked((short)0xccd4), unchecked((short)0x44ee), new byte[] { 0x8e, 0xba, 0x3f, 0xbf, 0x8b, 0xe4, 0xfc, 0x58 }) }; - yield return new object[] { Encoder.ColorDepth.Guid, new Guid(0x66087055, unchecked((short)0xad66), unchecked((short)0x4c7c), new byte[] { 0x9a, 0x18, 0x38, 0xa2, 0x31, 0x0b, 0x83, 0x37 }) }; - yield return new object[] { Encoder.ScanMethod.Guid, new Guid(0x3a4e2661, (short)0x3109, (short)0x4e56, new byte[] { 0x85, 0x36, 0x42, 0xc1, 0x56, 0xe7, 0xdc, 0xfa }) }; - yield return new object[] { Encoder.Version.Guid, new Guid(0x24d18c76, unchecked((short)0x814a), unchecked((short)0x41a4), new byte[] { 0xbf, 0x53, 0x1c, 0x21, 0x9c, 0xcc, 0xf7, 0x97 }) }; - yield return new object[] { Encoder.RenderMethod.Guid, new Guid(0x6d42c53a, (short)0x229a, (short)0x4825, new byte[] { 0x8b, 0xb7, 0x5c, 0x99, 0xe2, 0xb9, 0xa8, 0xb8 }) }; - yield return new object[] { Encoder.Quality.Guid, new Guid(0x1d5be4b5, unchecked((short)0xfa4a), unchecked((short)0x452d), new byte[] { 0x9c, 0xdd, 0x5d, 0xb3, 0x51, 0x05, 0xe7, 0xeb }) }; - yield return new object[] { Encoder.Transformation.Guid, new Guid(unchecked((int)0x8d0eb2d1), unchecked((short)0xa58e), unchecked((short)0x4ea8), new byte[] { 0xaa, 0x14, 0x10, 0x80, 0x74, 0xb7, 0xb6, 0xf9 }) }; - yield return new object[] { Encoder.LuminanceTable.Guid, new Guid(unchecked((int)0xedb33bce), unchecked((short)0x0266), unchecked((short)0x4a77), new byte[] { 0xb9, 0x04, 0x27, 0x21, 0x60, 0x99, 0xe7, 0x17 }) }; - yield return new object[] { Encoder.ChrominanceTable.Guid, new Guid(unchecked((int)0xf2e455dc), unchecked((short)0x09b3), unchecked((short)0x4316), new byte[] { 0x82, 0x60, 0x67, 0x6a, 0xda, 0x32, 0x48, 0x1c }) }; - yield return new object[] { Encoder.SaveFlag.Guid, new Guid(unchecked((int)0x292266fc), unchecked((short)0xac40), unchecked((short)0x47bf), new byte[] { 0x8c, 0xfc, 0xa8, 0x5b, 0x89, 0xa6, 0x55, 0xde }) }; - } - } - - [Theory] - [MemberData(nameof(EncoderTestData))] - public void DefinedEncoders_ReturnsExpected(Guid defined, Guid expected) - { - Assert.Equal(expected, defined); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/FrameDimensionTests.cs b/src/System.Drawing.Common/tests/Imaging/FrameDimensionTests.cs deleted file mode 100644 index 333da677dcc..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/FrameDimensionTests.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -public class FrameDimensionTests -{ - [Fact] - public void Ctor_Guid() - { - Guid guid = Guid.NewGuid(); - FrameDimension fd = new FrameDimension(guid); - Assert.Equal(guid, fd.Guid); - } - - public static IEnumerable ImageFormatGuidTestData - { - get - { - yield return new object[] { new Guid("{6aedbd6d-3fb5-418a-83a6-7f45229dc872}"), FrameDimension.Time }; - yield return new object[] { new Guid("{84236f7b-3bd3-428f-8dab-4ea1439ca315}"), FrameDimension.Resolution }; - yield return new object[] { new Guid("{7462dc86-6180-4c7e-8e3f-ee7333a7a483}"), FrameDimension.Page }; - yield return new object[] { new Guid("48749428-316f-496a-ab30-c819a92b3137"), new FrameDimension(new Guid("48749428-316f-496a-ab30-c819a92b3137")) }; - } - } - - public static IEnumerable FrameDimensionEqualsTestData - { - get - { - yield return new object[] { new FrameDimension(new Guid("48749428-316f-496a-ab30-c819a92b3137")), new FrameDimension(new Guid("48749428-316f-496a-ab30-c819a92b3137")), true }; - yield return new object[] { new FrameDimension(new Guid("48749428-316f-496a-ab30-c819a92b3137")), new FrameDimension(new Guid("b96b3cad-0728-11d3-9d7b-0000f81ef32e")), false }; - yield return new object[] { new FrameDimension(new Guid("48749428-316f-496a-ab30-c819a92b3137")), null, false }; - yield return new object[] { new FrameDimension(new Guid("48749428-316f-496a-ab30-c819a92b3137")), new object(), false }; - } - } - - public static IEnumerable FrameDimensionToStringTestData - { - get - { - yield return new object[] { "Time", FrameDimension.Time }; - yield return new object[] { "Resolution", FrameDimension.Resolution }; - yield return new object[] { "Page", FrameDimension.Page }; - yield return new object[] { "[FrameDimension: 48749428-316f-496a-ab30-c819a92b3137]", new FrameDimension(new Guid("48749428-316f-496a-ab30-c819a92b3137")) }; - } - } - - [Theory] - [MemberData(nameof(ImageFormatGuidTestData))] - public void Guid_ReturnsExpected(Guid expected, FrameDimension frameDimension) - { - Assert.Equal(expected, frameDimension.Guid); - } - - [Theory] - [MemberData(nameof(FrameDimensionEqualsTestData))] - public void Equals_Object_ReturnsExpected(FrameDimension frameDimension, object obj, bool result) - { - Assert.Equal(result, frameDimension.Equals(obj)); - } - - [Fact] - public void GetHashCode_Success() - { - Guid guid = Guid.NewGuid(); - Assert.Equal(guid.GetHashCode(), new FrameDimension(guid).GetHashCode()); - } - - [Theory] - [MemberData(nameof(FrameDimensionToStringTestData))] - public void ToString_ReturnsExpected(string expected, FrameDimension imageFormat) - { - Assert.Equal(expected, imageFormat.ToString()); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/ImageAttributesTests.cs b/src/System.Drawing.Common/tests/Imaging/ImageAttributesTests.cs deleted file mode 100644 index f87327c82b4..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/ImageAttributesTests.cs +++ /dev/null @@ -1,1475 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2005-2006 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Drawing.Drawing2D; - -namespace System.Drawing.Imaging.Tests; - -public class ImageAttributesTests -{ - private readonly Rectangle _rectangle = new(0, 0, 64, 64); - private readonly Color _actualYellow = Color.FromArgb(255, 255, 255, 0); - private readonly Color _actualGreen = Color.FromArgb(255, 0, 255, 0); - private readonly Color _expectedRed = Color.FromArgb(255, 255, 0, 0); - private readonly Color _expectedBlack = Color.FromArgb(255, 0, 0, 0); - private readonly ColorMatrix _greenComponentToZeroColorMatrix = new(new float[][] - { - new float[] {1, 0, 0, 0, 0}, - new float[] {0, 0, 0, 0, 0}, - new float[] {0, 0, 1, 0, 0}, - new float[] {0, 0, 0, 1, 0}, - new float[] {0, 0, 0, 0, 0}, - }); - - private readonly ColorMatrix _grayMatrix = new(new float[][] { - new float[] {1, 0, 0, 0, 0}, - new float[] {0, 2, 0, 0, 0}, - new float[] {0, 0, 3, 0, 0}, - new float[] {0, 0, 0, 1, 0}, - new float[] {0, 0, 0, 0, 0}, - }); - - private readonly ColorMap[] _yellowToRedColorMap = new ColorMap[] - { - new ColorMap() { OldColor = Color.FromArgb(255, 255, 255, 0), NewColor = Color.FromArgb(255, 255, 0, 0) } - }; - - [Fact] - public void Ctor_Default_Success() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - } - - [Fact] - public void Clone_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix); - - using (ImageAttributes clone = Assert.IsAssignableFrom(imageAttr.Clone())) - { - bitmap.SetPixel(0, 0, _actualYellow); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, clone); - Assert.Equal(_expectedRed, bitmap.GetPixel(0, 0)); - } - } - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.Clone()); - } - - [Fact] - public void SetColorMatrix_ColorMatrix_Success() - { - using (var brush = new SolidBrush(_actualGreen)) - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix); - bitmap.SetPixel(0, 0, _actualYellow); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_expectedRed, bitmap.GetPixel(0, 0)); - - graphics.FillRectangle(brush, _rectangle); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_expectedBlack, bitmap.GetPixel(0, 0)); - } - } - - public static IEnumerable ColorMatrix_DropShadowRepaintWhenAreaIsSmallerThanTheFilteredElement_TestData() - { - yield return new object[] { Color.FromArgb(100, 255, 0, 0) }; - yield return new object[] { Color.FromArgb(255, 255, 155, 155) }; - } - - [Theory] - [MemberData(nameof(ColorMatrix_DropShadowRepaintWhenAreaIsSmallerThanTheFilteredElement_TestData))] - public void SetColorMatrix_ColorMatrixI_Success(Color color) - { - ColorMatrix colorMatrix = new ColorMatrix(new float[][] - { - new float[] {1, 0, 0, 0, 0}, - new float[] {0, 1, 0, 0, 0}, - new float[] {0, 0, 1, 0, 0}, - new float[] {0, 0, 0, 0.5f, 0}, - new float[] {0, 0, 0, 0, 1}, - }); - - using (var brush = new SolidBrush(color)) - using (var bitmapBig = new Bitmap(200, 100)) - using (var bitmapSmall = new Bitmap(100, 100)) - using (var graphicsSmallBitmap = Graphics.FromImage(bitmapSmall)) - using (var graphicsBigBitmap = Graphics.FromImage(bitmapBig)) - using (var imageAttr = new ImageAttributes()) - { - graphicsSmallBitmap.FillRectangle(Brushes.White, 0, 0, 100, 100); - graphicsSmallBitmap.FillEllipse(brush, 0, 0, 100, 100); - graphicsBigBitmap.FillRectangle(Brushes.White, 0, 0, 200, 100); - imageAttr.SetColorMatrix(colorMatrix); - graphicsBigBitmap.DrawImage(bitmapSmall, new Rectangle(0, 0, 100, 100), 0, 0, 100, 100, GraphicsUnit.Pixel, null); - graphicsBigBitmap.DrawImage(bitmapSmall, new Rectangle(100, 0, 100, 100), 0, 0, 100, 100, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 255, 155, 155), bitmapBig.GetPixel(50, 50)); - Assert.Equal(Color.FromArgb(255, 255, 205, 205), bitmapBig.GetPixel(150, 50)); - } - } - - [Fact] - public void SetColorMatrix_ColorMatrixFlags_Success() - { - var grayShade = Color.FromArgb(255, 100, 100, 100); - - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - bitmap.SetPixel(0, 0, _actualYellow); - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.Default); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_expectedRed, bitmap.GetPixel(0, 0)); - - bitmap.SetPixel(0, 0, grayShade); - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.SkipGrays); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(grayShade, bitmap.GetPixel(0, 0)); - } - } - - public static IEnumerable ColorAdjustType_TestData() - { - yield return new object[] { ColorAdjustType.Default }; - yield return new object[] { ColorAdjustType.Bitmap }; - } - - [Theory] - [MemberData(nameof(ColorAdjustType_TestData))] - public void SetColorMatrix_ColorMatrixDefaultFlagType_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var brush = new SolidBrush(_actualYellow)) - using (var pen = new Pen(brush)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.Default, type); - - bitmap.SetPixel(0, 0, _actualGreen); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_expectedBlack, bitmap.GetPixel(0, 0)); - - graphics.FillRectangle(brush, _rectangle); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_expectedRed, bitmap.GetPixel(0, 0)); - - graphics.DrawRectangle(pen, _rectangle); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_expectedRed, bitmap.GetPixel(0, 0)); - } - } - - public static IEnumerable ColorAdjustTypeI_TestData() - { - yield return new object[] { ColorAdjustType.Brush }; - yield return new object[] { ColorAdjustType.Pen }; - yield return new object[] { ColorAdjustType.Text }; - } - - [Theory] - [MemberData(nameof(ColorAdjustTypeI_TestData))] - public void SetColorMatrix_ColorMatrixDefaultFlagTypeI_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var brush = new SolidBrush(_actualYellow)) - using (var pen = new Pen(brush)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.Default, type); - - bitmap.SetPixel(0, 0, _actualGreen); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_actualGreen, bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void SetColorMatrix_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix)); - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.Default)); - AssertExtensions.Throws(null, () => - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Default)); - } - - [Fact] - public void SetColorMatrix_NullMatrix_ThrowsArgumentException() - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrix(null)); - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrix(null, ColorMatrixFlag.Default)); - AssertExtensions.Throws(null, () => - imageAttr.SetColorMatrix(null, ColorMatrixFlag.Default, ColorAdjustType.Default)); - } - } - - public static IEnumerable ColorAdjustType_InvalidTypes_TestData() - { - yield return new object[] { (ColorAdjustType.Default - 1) }; - yield return new object[] { ColorAdjustType.Count }; - yield return new object[] { ColorAdjustType.Any }; - yield return new object[] { (ColorAdjustType.Any + 1) }; - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void SetColorMatrix_InvalidTypes_ThrowsInvalidEnumArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.Default, type)); - } - } - - public static IEnumerable ColorMatrixFlag_InvalidFlags_TestData() - { - yield return new object[] { (ColorMatrixFlag.Default - 1) }; - yield return new object[] { ColorMatrixFlag.AltGrays }; - yield return new object[] { (ColorMatrixFlag.AltGrays + 1) }; - yield return new object[] { (ColorMatrixFlag)int.MinValue }; - yield return new object[] { (ColorMatrixFlag)int.MaxValue }; - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void SetColorMatrix_InvalidFlags_ThrowsArgumentException(ColorMatrixFlag flag) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, flag)); - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, flag, ColorAdjustType.Default)); - } - } - - [Fact] - public void ClearColorMatrix_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix); - imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix); - imageAttr.ClearColorMatrix(); - - bitmap.SetPixel(0, 0, _actualGreen); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_actualGreen, bitmap.GetPixel(0, 0)); - } - } - - public static IEnumerable ColorAdjustType_AllTypesAllowed_TestData() - { - yield return new object[] { ColorAdjustType.Default }; - yield return new object[] { ColorAdjustType.Bitmap }; - yield return new object[] { ColorAdjustType.Brush }; - yield return new object[] { ColorAdjustType.Pen }; - yield return new object[] { ColorAdjustType.Text }; - } - - [Theory] - [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] - public void ClearColorMatrix_DefaultFlagType_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var brush = new SolidBrush(_actualYellow)) - using (var pen = new Pen(brush)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.Default, type); - imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix, ColorMatrixFlag.Default, type); - imageAttr.ClearColorMatrix(type); - - bitmap.SetPixel(0, 0, _actualGreen); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_actualGreen, bitmap.GetPixel(0, 0)); - - graphics.FillRectangle(brush, _rectangle); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_actualYellow, bitmap.GetPixel(0, 0)); - - graphics.DrawRectangle(pen, _rectangle); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_actualYellow, bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void ClearColorMatrix_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.ClearColorMatrix()); - AssertExtensions.Throws(null, () => imageAttr.ClearColorMatrix(ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void ClearColorMatrix_InvalidTypes_ThrowsInvalidEnumArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.ClearColorMatrix(type)); - } - } - - [Fact] - public void SetColorMatrices_ColorMatrixGrayMatrix_Success() - { - using (var brush = new SolidBrush(_actualGreen)) - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix); - bitmap.SetPixel(0, 0, _actualYellow); - bitmap.SetPixel(1, 1, Color.FromArgb(255, 100, 100, 100)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_expectedRed, bitmap.GetPixel(0, 0)); - Assert.Equal(Color.FromArgb(255, 100, 0, 100), bitmap.GetPixel(1, 1)); - } - } - - public static IEnumerable SetColorMatrices_Flags_TestData() - { - yield return new object[] { ColorMatrixFlag.Default, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 100, 0, 100) }; - yield return new object[] { ColorMatrixFlag.SkipGrays, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.AltGrays, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 100, 200, 255) }; - } - - [Theory] - [MemberData(nameof(SetColorMatrices_Flags_TestData))] - public void SetColorMatrices_ColorMatrixGrayMatrixFlags_Success(ColorMatrixFlag flag, Color grayShade, Color expectedGrayShade) - { - using (var brush = new SolidBrush(_actualGreen)) - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix, flag); - bitmap.SetPixel(0, 0, _actualYellow); - bitmap.SetPixel(1, 1, grayShade); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_expectedRed, bitmap.GetPixel(0, 0)); - Assert.Equal(expectedGrayShade, bitmap.GetPixel(1, 1)); - } - } - - public static IEnumerable SetColorMatrices_FlagsTypes_TestData() - { - yield return new object[] { ColorMatrixFlag.Default, ColorAdjustType.Default, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 100, 0, 100) }; - yield return new object[] { ColorMatrixFlag.SkipGrays, ColorAdjustType.Default, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.AltGrays, ColorAdjustType.Default, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 100, 200, 255) }; - yield return new object[] { ColorMatrixFlag.Default, ColorAdjustType.Bitmap, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 100, 0, 100) }; - yield return new object[] { ColorMatrixFlag.SkipGrays, ColorAdjustType.Bitmap, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.AltGrays, ColorAdjustType.Bitmap, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 100, 200, 255) }; - } - - [Theory] - [MemberData(nameof(SetColorMatrices_FlagsTypes_TestData))] - public void SetColorMatrices_ColorMatrixGrayMatrixFlagsTypes_Success - (ColorMatrixFlag flag, ColorAdjustType type, Color grayShade, Color expectedGrayShade) - { - using (var brush = new SolidBrush(_actualGreen)) - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix, flag, type); - bitmap.SetPixel(0, 0, _actualYellow); - bitmap.SetPixel(1, 1, grayShade); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_expectedRed, bitmap.GetPixel(0, 0)); - Assert.Equal(expectedGrayShade, bitmap.GetPixel(1, 1)); - } - } - - public static IEnumerable SetColorMatrices_FlagsTypesI_TestData() - { - yield return new object[] { ColorMatrixFlag.Default, ColorAdjustType.Pen, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.SkipGrays, ColorAdjustType.Pen, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.AltGrays, ColorAdjustType.Pen, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.Default, ColorAdjustType.Brush, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.SkipGrays, ColorAdjustType.Brush, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.AltGrays, ColorAdjustType.Brush, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.Default, ColorAdjustType.Text, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.SkipGrays, ColorAdjustType.Text, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorMatrixFlag.AltGrays, ColorAdjustType.Text, Color.FromArgb(255, 100, 100, 100) }; - } - - [Theory] - [MemberData(nameof(SetColorMatrices_FlagsTypesI_TestData))] - public void SetColorMatrices_ColorMatrixGrayMatrixFlagsTypesI_Success(ColorMatrixFlag flag, ColorAdjustType type, Color grayShade) - { - using (var brush = new SolidBrush(_actualGreen)) - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix, flag, type); - bitmap.SetPixel(0, 0, _actualYellow); - bitmap.SetPixel(1, 1, grayShade); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_actualYellow, bitmap.GetPixel(0, 0)); - Assert.Equal(grayShade, bitmap.GetPixel(1, 1)); - } - } - - [Fact] - public void SetColorMatrices_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix)); - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix, ColorMatrixFlag.Default)); - AssertExtensions.Throws(null, () => - imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix, ColorMatrixFlag.Default, ColorAdjustType.Default)); - } - - [Fact] - public void SetColorMatrices_NullMatrices_ThrowsArgumentException() - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrices(null, _grayMatrix)); - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrices(null, _grayMatrix, ColorMatrixFlag.Default)); - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, null, ColorMatrixFlag.AltGrays)); - AssertExtensions.Throws(null, () => - imageAttr.SetColorMatrices(null, _grayMatrix, ColorMatrixFlag.Default, ColorAdjustType.Default)); - AssertExtensions.Throws(null, () => - imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, null, ColorMatrixFlag.AltGrays, ColorAdjustType.Default)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void SetColorMatrices_InvalidTypes_ThrowsInvalidEnumArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => - imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix, ColorMatrixFlag.Default, type)); - } - } - - [Theory] - [InlineData(ColorMatrixFlag.Default - 1)] - [InlineData(ColorMatrixFlag.AltGrays + 1)] - [InlineData((ColorMatrixFlag)int.MinValue)] - [InlineData((ColorMatrixFlag)int.MaxValue)] - public void SetColorMatrices_InvalidFlags_ThrowsArgumentException(ColorMatrixFlag flag) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix, flag)); - AssertExtensions.Throws(null, () => - imageAttr.SetColorMatrices(_greenComponentToZeroColorMatrix, _grayMatrix, flag, ColorAdjustType.Default)); - } - } - - [Fact] - public void SetThreshold_Threshold_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetThreshold(0.7f); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 230, 50, 220)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 255, 0, 255), bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_TestData))] - public void SetThreshold_ThresholdType_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetThreshold(0.7f, type); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 230, 50, 220)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 255, 0, 255), bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustTypeI_TestData))] - public void SetThreshold_ThresholdTypeI_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetThreshold(0.7f, type); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 230, 50, 220)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 230, 50, 220), bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void SetThreshold_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.SetThreshold(0.5f)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void SetThreshold_InvalidType_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetThreshold(0.5f, type)); - } - } - - [Fact] - public void ClearThreshold_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetThreshold(0.7f); - imageAttr.ClearThreshold(); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 230, 50, 220)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 230, 50, 220), bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] - public void ClearThreshold_ThresholdTypeI_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetThreshold(0.7f, type); - imageAttr.ClearThreshold(type); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 230, 50, 220)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 230, 50, 220), bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void ClearThreshold_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.ClearThreshold(ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void ClearThreshold_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.ClearThreshold(type)); - } - } - - [Fact] - public void SetGamma_Gamma_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetGamma(2.2f); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 255, 0)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 33, 255, 0), bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_TestData))] - public void SetGamma_GammaType_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetGamma(2.2f, type); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 255, 0)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 33, 255, 0), bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustTypeI_TestData))] - public void SetGamma_GammaTypeI_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetGamma(2.2f, type); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 255, 0)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 255, 0), bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void SetGamma_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.SetGamma(2.2f)); - AssertExtensions.Throws(null, () => imageAttr.SetGamma(2.2f, ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void SetGamma_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetGamma(2.2f, type)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] - public void ClearGamma_Type_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetGamma(2.2f, type); - imageAttr.ClearGamma(type); - - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 255, 0)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 255, 0), bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void ClearGamma_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.ClearGamma(ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void ClearGamma_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.ClearGamma(type)); - } - } - - [Fact] - public void SetNoOp_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetGamma(2.2f); - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix); - imageAttr.SetNoOp(); - bitmap.SetPixel(0, 0, _actualGreen); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_actualGreen, bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] - public void SetNoOp_Type_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetGamma(2.2f, type); - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.Default, type); - imageAttr.SetNoOp(type); - - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 255, 0)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 255, 0), bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void SetNoOp_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.SetNoOp()); - AssertExtensions.Throws(null, () => imageAttr.SetNoOp(ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void SetNoOp_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetNoOp(type)); - } - } - - [Fact] - public void ClearNoOp_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetGamma(2.2f); - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix); - imageAttr.SetNoOp(); - imageAttr.ClearNoOp(); - - bitmap.SetPixel(0, 0, _actualGreen); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_expectedBlack, bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_TestData))] - public void ClearNoOp_Type_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetGamma(2.2f, type); - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.Default, type); - imageAttr.SetNoOp(type); - imageAttr.ClearNoOp(type); - - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 255, 0)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 33, 0, 0), bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustTypeI_TestData))] - public void ClearNoOp_TypeI_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetGamma(2.2f, type); - imageAttr.SetColorMatrix(_greenComponentToZeroColorMatrix, ColorMatrixFlag.Default, type); - imageAttr.SetNoOp(type); - imageAttr.ClearNoOp(type); - - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 255, 0)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 255, 0), bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void ClearNoOp_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.ClearNoOp()); - AssertExtensions.Throws(null, () => imageAttr.ClearNoOp(ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void ClearNoOp_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.ClearNoOp(type)); - } - } - - [Fact] - public void SetColorKey_Success() - { - using var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height); - using var graphics = Graphics.FromImage(bitmap); - using var imageAttr = new ImageAttributes(); - - imageAttr.SetColorKey(Color.FromArgb(50, 50, 50), Color.FromArgb(150, 150, 150)); - - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 100, 100)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 100, 100), bitmap.GetPixel(0, 0)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_TestData))] - public void SetColorKey_Type_Success(ColorAdjustType type) - { - using var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height); - using var graphics = Graphics.FromImage(bitmap); - using var imageAttr = new ImageAttributes(); - - imageAttr.SetColorKey(Color.FromArgb(50, 50, 50), Color.FromArgb(150, 150, 150), type); - - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 100, 100)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 100, 100), bitmap.GetPixel(0, 0)); - } - - [Theory] - [MemberData(nameof(ColorAdjustTypeI_TestData))] - public void SetColorKey_TypeI_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorKey(Color.FromArgb(50, 50, 50), Color.FromArgb(150, 150, 150), type); - - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 100, 100)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 100, 100), bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void SetColorKey_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.SetColorKey(Color.FromArgb(50, 50, 50), Color.FromArgb(150, 150, 150))); - AssertExtensions.Throws(null, () => - imageAttr.SetColorKey(Color.FromArgb(50, 50, 50), Color.FromArgb(150, 150, 150), ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void SetColorKey_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => - imageAttr.SetColorKey(Color.FromArgb(50, 50, 50), Color.FromArgb(150, 150, 150), type)); - } - } - - [Fact] - public void ClearColorKey_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorKey(Color.FromArgb(50, 50, 50), Color.FromArgb(150, 150, 150)); - imageAttr.ClearColorKey(); - - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 100, 100)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 100, 100), bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] - public void ClearColorKey_Type_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetColorKey(Color.FromArgb(50, 50, 50), Color.FromArgb(150, 150, 150), type); - imageAttr.ClearColorKey(type); - - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 100, 100)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 100, 100), bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void ClearColorKey_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.ClearColorKey()); - AssertExtensions.Throws(null, () => imageAttr.ClearColorKey(ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void ClearColorKey_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.ClearColorKey(type)); - } - } - - public static IEnumerable SetOutputChannel_ColorChannelFlag_TestData() - { - yield return new object[] { ColorChannelFlag.ColorChannelC, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 198, 198, 198) }; - yield return new object[] { ColorChannelFlag.ColorChannelK, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 108, 108, 108) }; - yield return new object[] { ColorChannelFlag.ColorChannelM, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 204, 204, 204) }; - yield return new object[] { ColorChannelFlag.ColorChannelY, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 207, 207, 207) }; - } - - [Theory] - [MemberData(nameof(SetOutputChannel_ColorChannelFlag_TestData))] - public void SetOutputChannel_Flag_Success(ColorChannelFlag flag, Color actualColor, Color expectedColor) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetOutputChannel(flag); - - bitmap.SetPixel(0, 0, actualColor); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(expectedColor, bitmap.GetPixel(0, 0)); - } - } - - public static IEnumerable SetOutputChannel_ColorChannelFlagType_TestData() - { - yield return new object[] { ColorChannelFlag.ColorChannelC, ColorAdjustType.Default, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 198, 198, 198) }; - yield return new object[] { ColorChannelFlag.ColorChannelK, ColorAdjustType.Default, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 108, 108, 108) }; - yield return new object[] { ColorChannelFlag.ColorChannelM, ColorAdjustType.Default, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 204, 204, 204) }; - yield return new object[] { ColorChannelFlag.ColorChannelY, ColorAdjustType.Default, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 207, 207, 207) }; - yield return new object[] { ColorChannelFlag.ColorChannelC, ColorAdjustType.Bitmap, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 198, 198, 198) }; - yield return new object[] { ColorChannelFlag.ColorChannelK, ColorAdjustType.Bitmap, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 108, 108, 108) }; - yield return new object[] { ColorChannelFlag.ColorChannelM, ColorAdjustType.Bitmap, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 204, 204, 204) }; - yield return new object[] { ColorChannelFlag.ColorChannelY, ColorAdjustType.Bitmap, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 207, 207, 207) }; - } - - [Theory] - [MemberData(nameof(SetOutputChannel_ColorChannelFlagType_TestData))] - public void SetOutputChannel_FlagType_Success(ColorChannelFlag flag, ColorAdjustType type, Color actualColor, Color expectedColor) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetOutputChannel(flag, type); - - bitmap.SetPixel(0, 0, actualColor); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(expectedColor, bitmap.GetPixel(0, 0)); - } - } - - public static IEnumerable SetOutputChannel_ColorChannelFlagTypeI_TestData() - { - yield return new object[] { ColorChannelFlag.ColorChannelC, ColorAdjustType.Brush, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelK, ColorAdjustType.Brush, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelM, ColorAdjustType.Brush, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelY, ColorAdjustType.Brush, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelC, ColorAdjustType.Pen, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelK, ColorAdjustType.Pen, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelM, ColorAdjustType.Pen, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelY, ColorAdjustType.Pen, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelC, ColorAdjustType.Text, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelK, ColorAdjustType.Text, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelM, ColorAdjustType.Text, Color.FromArgb(255, 100, 100, 100) }; - yield return new object[] { ColorChannelFlag.ColorChannelY, ColorAdjustType.Text, Color.FromArgb(255, 100, 100, 100) }; - } - - [Theory] - [MemberData(nameof(SetOutputChannel_ColorChannelFlagTypeI_TestData))] - public void SetOutputChannel_FlagTypeI_Success(ColorChannelFlag flag, ColorAdjustType type, Color color) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetOutputChannel(flag, type); - - bitmap.SetPixel(0, 0, color); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(color, bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void SetOutputChannel_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.SetOutputChannel(ColorChannelFlag.ColorChannelY)); - AssertExtensions.Throws(null, () => imageAttr.SetOutputChannel(ColorChannelFlag.ColorChannelY, ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void SetOutputChannel_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetOutputChannel(ColorChannelFlag.ColorChannelY, type)); - } - } - - public static IEnumerable SetOutputChannel_InvalidColorChannelFlags_TestData() - { - yield return new object[] { (ColorChannelFlag)int.MinValue }; - yield return new object[] { ColorChannelFlag.ColorChannelC - 1 }; - yield return new object[] { ColorChannelFlag.ColorChannelLast }; - yield return new object[] { ColorChannelFlag.ColorChannelLast + 1 }; - yield return new object[] { (ColorChannelFlag)int.MaxValue }; - } - - [Theory] - [MemberData(nameof(SetOutputChannel_InvalidColorChannelFlags_TestData))] - public void SetOutputChannel_InvalidFlags_ThrowsArgumentException(ColorChannelFlag flag) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetOutputChannel(flag)); - AssertExtensions.Throws(null, () => imageAttr.SetOutputChannel(flag, ColorAdjustType.Default)); - } - } - - [Fact] - public void ClearOutputChannel_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetOutputChannel(ColorChannelFlag.ColorChannelC); - imageAttr.ClearOutputChannel(); - - bitmap.SetPixel(0, 0, _actualGreen); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_actualGreen, bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] - public void ClearOutputChannel_Type_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetOutputChannel(ColorChannelFlag.ColorChannelC, type); - imageAttr.ClearOutputChannel(type); - - bitmap.SetPixel(0, 0, _actualGreen); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_actualGreen, bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void ClearOutputChannel_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.ClearOutputChannel()); - AssertExtensions.Throws(null, () => imageAttr.ClearOutputChannel(ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void ClearOutputChannel_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.ClearOutputChannel(type)); - } - } - - [Fact] - public void SetOutputChannelColorProfile_Name_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetOutputChannel(ColorChannelFlag.ColorChannelC); - imageAttr.SetOutputChannelColorProfile(Helpers.GetTestColorProfilePath("RSWOP.icm")); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 100, 100)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 198, 198, 198), bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void SetOutputChannelColorProfile_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => - imageAttr.SetOutputChannelColorProfile(Helpers.GetTestColorProfilePath("RSWOP.icm"))); - AssertExtensions.Throws(null, () => - imageAttr.SetOutputChannelColorProfile(Helpers.GetTestColorProfilePath("RSWOP.icm"), ColorAdjustType.Default)); - } - - [Fact] - public void SetOutputChannelColorProfile_Null_ThrowsArgumentNullException() - { - using (var imageAttr = new ImageAttributes()) - { - Assert.Throws(() => imageAttr.SetOutputChannelColorProfile(null)); - Assert.Throws(() => imageAttr.SetOutputChannelColorProfile(null, ColorAdjustType.Default)); - } - } - - [Fact] - public void SetOutputChannelColorProfile_InvalidPath_ThrowsArgumentException() - { - using (var imageAttr = new ImageAttributes()) - { - Assert.Throws(() => imageAttr.SetOutputChannelColorProfile(string.Empty)); - Assert.Throws(() => imageAttr.SetOutputChannelColorProfile(string.Empty, ColorAdjustType.Default)); - } - } - - [Fact] - public void SetOutputChannelColorProfile_InvalidPath_ThrowsOutOfMemoryException() - { - using (var imageAttr = new ImageAttributes()) - { - Assert.Throws(() => imageAttr.SetOutputChannelColorProfile("invalidPath")); - Assert.Throws(() => imageAttr.SetOutputChannelColorProfile("invalidPath", ColorAdjustType.Default)); - } - } - - [Fact] - public void SetOutputChannelColorProfile_InvalidPath_ThrowsPathTooLongException() - { - string fileNameTooLong = new('a', short.MaxValue); - using (var imageAttr = new ImageAttributes()) - { - Assert.Throws(() => imageAttr.SetOutputChannelColorProfile(fileNameTooLong)); - Assert.Throws(() => imageAttr.SetOutputChannelColorProfile(fileNameTooLong, ColorAdjustType.Default)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void SetOutputChannelColorProfile_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetOutputChannelColorProfile("path", type)); - } - } - - [Fact] - public void ClearOutputChannelColorProfile_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetOutputChannel(ColorChannelFlag.ColorChannelC); - imageAttr.SetOutputChannelColorProfile(Helpers.GetTestColorProfilePath("RSWOP.icm")); - imageAttr.ClearOutputChannelColorProfile(); - imageAttr.ClearOutputChannel(); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 100, 100)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 100, 100), bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] - public void ClearOutputChannelColorProfile_Type_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetOutputChannel(ColorChannelFlag.ColorChannelC, type); - imageAttr.SetOutputChannelColorProfile(Helpers.GetTestColorProfilePath("RSWOP.icm"), type); - imageAttr.ClearOutputChannelColorProfile(type); - imageAttr.ClearOutputChannel(type); - bitmap.SetPixel(0, 0, Color.FromArgb(255, 100, 100, 100)); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(Color.FromArgb(255, 100, 100, 100), bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void ClearOutputChannelColorProfile_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.ClearOutputChannelColorProfile()); - AssertExtensions.Throws(null, () => imageAttr.ClearOutputChannelColorProfile(ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void ClearOutputChannelColorProfile_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.ClearOutputChannelColorProfile(type)); - } - } - - [Fact] - public void SetRemapTable_Map_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetRemapTable(_yellowToRedColorMap); - bitmap.SetPixel(0, 0, _yellowToRedColorMap[0].OldColor); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_yellowToRedColorMap[0].NewColor, bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_TestData))] - public void SetRemapTable_MapType_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetRemapTable(_yellowToRedColorMap, type); - bitmap.SetPixel(0, 0, _yellowToRedColorMap[0].OldColor); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_yellowToRedColorMap[0].NewColor, bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustTypeI_TestData))] - public void SetRemapTable_MapTypeI_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetRemapTable(_yellowToRedColorMap, type); - bitmap.SetPixel(0, 0, _yellowToRedColorMap[0].OldColor); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_yellowToRedColorMap[0].OldColor, bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void SetRemapTable_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.SetRemapTable(_yellowToRedColorMap)); - AssertExtensions.Throws(null, () => imageAttr.SetRemapTable(_yellowToRedColorMap, ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void SetRemapTable_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetRemapTable(_yellowToRedColorMap, type)); - } - } - - [Fact] - public void SetRemapTable_NullMap_ThrowsNullReferenceException() - { - using (var imageAttr = new ImageAttributes()) - { - Assert.Throws(() => imageAttr.SetRemapTable(null, ColorAdjustType.Default)); - } - } - - [Fact] - public void SetRemapTable_NullMapMeber_ThrowsNullReferenceException() - { - using (var imageAttr = new ImageAttributes()) - { - Assert.Throws(() => imageAttr.SetRemapTable(new ColorMap[1] { null }, ColorAdjustType.Default)); - } - } - - [Fact] - public void SetRemapTable_EmptyMap_ThrowsArgumentException() - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.SetRemapTable(new ColorMap[0], ColorAdjustType.Default)); - } - } - - [Fact] - public void ClearRemapTable_Success() - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetRemapTable(_yellowToRedColorMap); - imageAttr.ClearRemapTable(); - bitmap.SetPixel(0, 0, _yellowToRedColorMap[0].OldColor); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_yellowToRedColorMap[0].OldColor, bitmap.GetPixel(0, 0)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] - public void ClearRemapTable_Type_Success(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var graphics = Graphics.FromImage(bitmap)) - using (var imageAttr = new ImageAttributes()) - { - imageAttr.SetRemapTable(_yellowToRedColorMap, type); - imageAttr.ClearRemapTable(type); - bitmap.SetPixel(0, 0, _yellowToRedColorMap[0].OldColor); - graphics.DrawImage(bitmap, _rectangle, _rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height, GraphicsUnit.Pixel, imageAttr); - Assert.Equal(_yellowToRedColorMap[0].OldColor, bitmap.GetPixel(0, 0)); - } - } - - [Fact] - public void ClearRemapTable_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.ClearRemapTable()); - AssertExtensions.Throws(null, () => imageAttr.ClearRemapTable(ColorAdjustType.Default)); - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void ClearRemapTable_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.ClearRemapTable(type)); - } - } - - [Fact] - public void SetWrapMode_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - AssertExtensions.Throws(null, () => imageAttr.SetWrapMode(WrapMode.Clamp)); - AssertExtensions.Throws(null, () => imageAttr.SetWrapMode(WrapMode.Clamp, Color.Black)); - AssertExtensions.Throws(null, () => imageAttr.SetWrapMode(WrapMode.Clamp, Color.Black, true)); - } - - [Fact] - public void GetAdjustedPalette_Disposed_ThrowsArgumentException() - { - var imageAttr = new ImageAttributes(); - imageAttr.Dispose(); - - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - { - AssertExtensions.Throws(null, () => imageAttr.GetAdjustedPalette(bitmap.Palette, ColorAdjustType.Default)); - } - } - - [Fact] - public void GetAdjustedPalette_NullPallete_ThrowsNullReferenceException() - { - using (var imageAttr = new ImageAttributes()) - { - Assert.Throws(() => imageAttr.GetAdjustedPalette(null, ColorAdjustType.Default)); - } - } - - [Theory] - [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] - public void GetAdjustedPalette_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) - { - using (var bitmap = new Bitmap(_rectangle.Width, _rectangle.Height)) - using (var imageAttr = new ImageAttributes()) - { - AssertExtensions.Throws(null, () => imageAttr.GetAdjustedPalette(bitmap.Palette, type)); - } - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/ImageCodecInfoTests.cs b/src/System.Drawing.Common/tests/Imaging/ImageCodecInfoTests.cs deleted file mode 100644 index 5052ae22c59..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/ImageCodecInfoTests.cs +++ /dev/null @@ -1,215 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Authors: -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sebastien Pouliot -// -// (C) 2004 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -using System.Collections; -using System.Text.RegularExpressions; - -namespace System.Drawing.Imaging.Tests; - -public class ImageCodecInfoTests -{ - private const string GIF_CSID = "557cf402-1a04-11d3-9a73-0000f81ef32e"; - private const string EMF_CSID = "557cf403-1a04-11d3-9a73-0000f81ef32e"; - private const string BMP_DIB_RLE_CSID = "557cf400-1a04-11d3-9a73-0000f81ef32e"; - private const string JPG_JPEG_JPE_JFIF_CSID = "557cf401-1a04-11d3-9a73-0000f81ef32e"; - private const string PNG_CSID = "557cf406-1a04-11d3-9a73-0000f81ef32e"; - private const string ICO_CSID = "557cf407-1a04-11d3-9a73-0000f81ef32e"; - private const string WMF_CSID = "557cf404-1a04-11d3-9a73-0000f81ef32e"; - private const string TIF_CSID = "557cf405-1a04-11d3-9a73-0000f81ef32e"; - - private Hashtable decoders; - private Hashtable encoders; - - public ImageCodecInfoTests() - { - decoders = new Hashtable(); - encoders = new Hashtable(); - - foreach (ImageCodecInfo decoder in ImageCodecInfo.GetImageDecoders()) - decoders[decoder.Clsid] = decoder; - - foreach (ImageCodecInfo encoder in ImageCodecInfo.GetImageEncoders()) - encoders[encoder.Clsid] = encoder; - } - - private ImageCodecInfo GetEncoder(string clsid) - { - return (ImageCodecInfo)encoders[new Guid(clsid)]; - } - - private ImageCodecInfo GetDecoder(string clsid) - { - return (ImageCodecInfo)decoders[new Guid(clsid)]; - } - - private void CheckDecoderAndEncoder(string clsid, ImageFormat format, string CodecName, string DllName, - string FilenameExtension, ImageCodecFlags Flags, string FormatDescription, - string MimeType, int Version, int signatureLength, string mask, string pattern, string pattern2) - { - ImageCodecInfo encoder = GetEncoder(clsid); - ImageCodecInfo decoder = GetDecoder(clsid); - - if (encoder != null) - { - CheckImageCodecInfo(format, CodecName, DllName, FilenameExtension, Flags, FormatDescription, MimeType, signatureLength, mask, pattern, pattern2, encoder); - } - if (decoder != null) - { - CheckImageCodecInfo(format, CodecName, DllName, FilenameExtension, Flags, FormatDescription, MimeType, signatureLength, mask, pattern, pattern2, decoder); - } - } - - private void CheckImageCodecInfo(ImageFormat format, string CodecName, string DllName, string FilenameExtension, ImageCodecFlags Flags, string FormatDescription, string MimeType, int signatureLength, string mask, string pattern, string pattern2, ImageCodecInfo codecInfo) - { - Regex extRegex = new Regex(@"^(\*\.\w+(;(\*\.\w+))*;)?" + - Regex.Escape(FilenameExtension) + @"(;\*\.\w+(;(\*\.\w+))*)?$", - RegexOptions.IgnoreCase | RegexOptions.Singleline); - - Assert.Equal(format.Guid, codecInfo.FormatID); - Assert.Contains(CodecName, codecInfo.CodecName); - Assert.Equal(DllName, codecInfo.DllName); - Assert.Matches(extRegex, codecInfo.FilenameExtension); - Assert.Equal(Flags, codecInfo.Flags); - Assert.Contains(FormatDescription, codecInfo.FormatDescription); - Assert.Contains(MimeType, codecInfo.MimeType); - Assert.Equal(signatureLength, codecInfo.SignatureMasks.Length); - - for (int i = 0; i < signatureLength; i++) - { - Assert.Equal(mask, BitConverter.ToString(codecInfo.SignatureMasks[i])); - } - - Assert.Equal(signatureLength, codecInfo.SignaturePatterns.Length); - Assert.Equal(pattern, BitConverter.ToString(codecInfo.SignaturePatterns[0])); - if (pattern2 != null) - Assert.Equal(pattern2, BitConverter.ToString(codecInfo.SignaturePatterns[1])); - } - - public static IEnumerable CodecInfoTestData - { - get - { - yield return new object[] { WMF_CSID, ImageFormat.Wmf, - "WMF", null, "*.WMF", - ImageCodecFlags.Builtin | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap, - "WMF", "image/x-wmf", 1, 1, "FF-FF-FF-FF", "D7-CD-C6-9A", null}; - - yield return new object[] { EMF_CSID, ImageFormat.Emf, - "EMF", null, "*.EMF", - ImageCodecFlags.Builtin | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap, - "EMF", "image/x-emf", 1, 1, "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-FF-FF-FF-FF", - "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-20-45-4D-46", null}; - - yield return new object[] { ICO_CSID, ImageFormat.Icon, - "ICO", null, "*.ICO", - ImageCodecFlags.Builtin | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap, - "ICO", "image/x-icon", 1, 1, "FF-FF-FF-FF", "00-00-01-00", null}; - - yield return new object[] { TIF_CSID, ImageFormat.Tiff, - "TIFF", null, "*.TIF;*.TIFF", - ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap, - "TIFF", "image/tiff", 1, 2, "FF-FF", "49-49", "4D-4D" }; - - yield return new object[] { PNG_CSID, ImageFormat.Png, - "PNG", null, "*.PNG", - ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap, - "PNG", "image/png", 1, 1, "FF-FF-FF-FF-FF-FF-FF-FF", "89-50-4E-47-0D-0A-1A-0A", null }; - - yield return new object[] { JPG_JPEG_JPE_JFIF_CSID, ImageFormat.Jpeg, - "JPEG", null, "*.JPG", - ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap, - "JPEG", "image/jpeg", 1, 1, "FF-FF", "FF-D8", null}; - - yield return new object[] { GIF_CSID, ImageFormat.Gif, - "GIF", null, "*.GIF", - ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap, - "GIF", "image/gif", 1, 2, "FF-FF-FF-FF-FF-FF", "47-49-46-38-39-61", "47-49-46-38-37-61"}; - - yield return new object[] { BMP_DIB_RLE_CSID, ImageFormat.Bmp, - "BMP", null, "*.BMP", - ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap, - "BMP", "image/bmp", 1, 1, "FF-FF", "42-4D", null }; - } - } - - [Theory] - [InlineData(GIF_CSID)] - [InlineData(EMF_CSID)] - [InlineData(BMP_DIB_RLE_CSID)] - [InlineData(JPG_JPEG_JPE_JFIF_CSID)] - [InlineData(PNG_CSID)] - [InlineData(ICO_CSID)] - [InlineData(WMF_CSID)] - [InlineData(TIF_CSID)] - public void GetDecoder_Success(string csid) - { - Assert.NotNull(GetDecoder(csid)); - } - - [Theory] - [InlineData(GIF_CSID)] - [InlineData(BMP_DIB_RLE_CSID)] - [InlineData(JPG_JPEG_JPE_JFIF_CSID)] - [InlineData(PNG_CSID)] - [InlineData(TIF_CSID)] - public void GetEncoder_Success(string csid) - { - Assert.NotNull(GetEncoder(csid)); - } - - [Fact] - public void CountEncoders_ReturnsExcpected() - { - Assert.Equal(5, encoders.Count); - } - - [Fact] - public void CountDecoders_ReturnsExcpected() - { - Assert.Equal(8, decoders.Count); - } - - [Theory] - [MemberData(nameof(CodecInfoTestData))] - public void CheckDecoderAndEncoder_ReturnsExpecetd(string clsid, ImageFormat format, string codecName, string dllName, - string fileNameExtension, ImageCodecFlags flags, string formatDescription, - string mimeType, int version, int signatureLength, string mask, string pattern, string pattern2) - { - CheckDecoderAndEncoder(clsid, format, codecName, dllName, fileNameExtension, flags, formatDescription, mimeType, version, signatureLength, mask, pattern, pattern2); - } - - [Theory] - [InlineData(WMF_CSID)] - [InlineData(EMF_CSID)] - [InlineData(ICO_CSID)] - public void GetEncoder_NoSuchEncoding_ReturnsNull(string clsid) - { - Assert.Null(GetEncoder(clsid)); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/ImageFormatTests.cs b/src/System.Drawing.Common/tests/Imaging/ImageFormatTests.cs deleted file mode 100644 index 2845c4bd09b..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/ImageFormatTests.cs +++ /dev/null @@ -1,123 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -public class ImageFormatTests -{ - private static ImageFormat BmpImageFormat = new(new Guid("b96b3cab-0728-11d3-9d7b-0000f81ef32e")); - private static ImageFormat EmfImageFormat = new(new Guid("b96b3cac-0728-11d3-9d7b-0000f81ef32e")); - private static ImageFormat ExifImageFormat = new(new Guid("b96b3cb2-0728-11d3-9d7b-0000f81ef32e")); - private static ImageFormat GifImageFormat = new(new Guid("b96b3cb0-0728-11d3-9d7b-0000f81ef32e")); - private static ImageFormat TiffImageFormat = new(new Guid("b96b3cb1-0728-11d3-9d7b-0000f81ef32e")); - private static ImageFormat PngImageFormat = new(new Guid("b96b3caf-0728-11d3-9d7b-0000f81ef32e")); - private static ImageFormat MemoryBmpImageFormat = new(new Guid("b96b3caa-0728-11d3-9d7b-0000f81ef32e")); - private static ImageFormat IconImageFormat = new(new Guid("b96b3cb5-0728-11d3-9d7b-0000f81ef32e")); - private static ImageFormat JpegImageFormat = new(new Guid("b96b3cae-0728-11d3-9d7b-0000f81ef32e")); - private static ImageFormat WmfImageFormat = new(new Guid("b96b3cad-0728-11d3-9d7b-0000f81ef32e")); - private static ImageFormat HeifImageFormat = new(new Guid("{b96b3cb6-0728-11d3-9d7b-0000f81ef32e}")); - private static ImageFormat WebpImageFormat = new(new Guid("{b96b3cb7-0728-11d3-9d7b-0000f81ef32e}")); - private static ImageFormat CustomImageFormat = new(new Guid("48749428-316f-496a-ab30-c819a92b3137")); - - public static IEnumerable ImageFormatGuidTestData - { - get - { - yield return new object[] { BmpImageFormat.Guid, ImageFormat.Bmp }; - yield return new object[] { EmfImageFormat.Guid, ImageFormat.Emf }; - yield return new object[] { ExifImageFormat.Guid, ImageFormat.Exif }; - yield return new object[] { GifImageFormat.Guid, ImageFormat.Gif }; - yield return new object[] { TiffImageFormat.Guid, ImageFormat.Tiff }; - yield return new object[] { PngImageFormat.Guid, ImageFormat.Png }; - yield return new object[] { MemoryBmpImageFormat.Guid, ImageFormat.MemoryBmp }; - yield return new object[] { IconImageFormat.Guid, ImageFormat.Icon }; - yield return new object[] { JpegImageFormat.Guid, ImageFormat.Jpeg }; - yield return new object[] { WmfImageFormat.Guid, ImageFormat.Wmf }; -#if NET - yield return new object[] { HeifImageFormat.Guid, ImageFormat.Heif }; - yield return new object[] { WebpImageFormat.Guid, ImageFormat.Webp }; -#endif - yield return new object[] { new Guid("48749428-316f-496a-ab30-c819a92b3137"), CustomImageFormat }; - } - } - - public static IEnumerable ImageFormatToStringTestData - { - get - { - yield return new object[] { "Bmp", ImageFormat.Bmp }; - yield return new object[] { "Emf", ImageFormat.Emf }; - yield return new object[] { "Exif", ImageFormat.Exif }; - yield return new object[] { "Gif", ImageFormat.Gif }; - yield return new object[] { "Tiff", ImageFormat.Tiff }; - yield return new object[] { "Png", ImageFormat.Png }; - yield return new object[] { "MemoryBMP", ImageFormat.MemoryBmp }; - yield return new object[] { "Icon", ImageFormat.Icon }; - yield return new object[] { "Jpeg", ImageFormat.Jpeg }; - yield return new object[] { "Wmf", ImageFormat.Wmf }; -#if NET - yield return new object[] { "Heif", ImageFormat.Heif }; - yield return new object[] { "Webp", ImageFormat.Webp }; -#endif - yield return new object[] { "[ImageFormat: 48749428-316f-496a-ab30-c819a92b3137]", CustomImageFormat }; - } - } - - public static IEnumerable ImageFromFileToStringTestData - { - get - { - yield return new object[] { Path.Combine("bitmaps", "nature24bits.gif"), "Gif" }; - yield return new object[] { Path.Combine("bitmaps", "nature24bits.jpg"), "Jpeg" }; - yield return new object[] { Path.Combine("bitmaps", "VisualPng.ico"), "Icon"}; - yield return new object[] { Path.Combine("bitmaps", "almogaver32bits.tif"), "Tiff" }; - } - } - - public static IEnumerable ImageFormatEqualsTestData - { - get - { - yield return new object[] { new ImageFormat(new Guid("48749428-316f-496a-ab30-c819a92b3137")), new ImageFormat(new Guid("48749428-316f-496a-ab30-c819a92b3137")), true }; - yield return new object[] { new ImageFormat(new Guid("48749428-316f-496a-ab30-c819a92b3137")), new ImageFormat(new Guid("b96b3cad-0728-11d3-9d7b-0000f81ef32e")), false }; - yield return new object[] { new ImageFormat(new Guid("48749428-316f-496a-ab30-c819a92b3137")), null, false }; - yield return new object[] { new ImageFormat(new Guid("48749428-316f-496a-ab30-c819a92b3137")), new object(), false }; - } - } - - [Theory] - [MemberData(nameof(ImageFormatGuidTestData))] - public void Guid_ReturnsExpected(Guid expectedGuid, ImageFormat imageFormat) - { - Assert.Equal(expectedGuid, imageFormat.Guid); - } - - [Theory] - [MemberData(nameof(ImageFormatToStringTestData))] - public void ToString_ReturnsExpected(string expected, ImageFormat imageFormat) - { - Assert.Equal(expected, imageFormat.ToString()); - } - - [Theory] - [MemberData(nameof(ImageFromFileToStringTestData))] - public void Image_RawFormat_ToString(string path, string expected) - { - var img = Image.FromFile(path); - Assert.Equal(expected, img.RawFormat.ToString()); - } - - [Theory] - [MemberData(nameof(ImageFormatEqualsTestData))] - public void Equals_Object_ReturnsExpected(ImageFormat imageFormat, object obj, bool result) - { - Assert.Equal(result, imageFormat.Equals(obj)); - } - - [Fact] - public void GetHashCode_Success() - { - Guid guid = Guid.NewGuid(); - Assert.Equal(guid.GetHashCode(), new ImageFormat(guid).GetHashCode()); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/MetaHeaderTests.cs b/src/System.Drawing.Common/tests/Imaging/MetaHeaderTests.cs deleted file mode 100644 index 7d6b3b3194a..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/MetaHeaderTests.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -public class MetaHeaderTests -{ - [Fact] - public void Ctor_Default() - { - MetaHeader mh = new MetaHeader(); - Assert.Equal(0, mh.HeaderSize); - Assert.Equal(0, mh.MaxRecord); - Assert.Equal(0, mh.NoObjects); - Assert.Equal(0, mh.NoParameters); - Assert.Equal(0, mh.Size); - Assert.Equal(0, mh.Type); - Assert.Equal(0, mh.Version); - } - - [Theory] - [InlineData(short.MaxValue)] - [InlineData(0)] - [InlineData(short.MinValue)] - public void ShortProperties_SetValues_ReturnsExpected(short value) - { - MetaHeader mh = new MetaHeader(); - mh.HeaderSize = value; - mh.NoObjects = value; - mh.NoParameters = value; - mh.Type = value; - mh.Version = value; - Assert.Equal(value, mh.HeaderSize); - Assert.Equal(value, mh.NoObjects); - Assert.Equal(value, mh.NoParameters); - Assert.Equal(value, mh.Type); - Assert.Equal(value, mh.Version); - } - - [Theory] - [InlineData(int.MaxValue)] - [InlineData(0)] - [InlineData(int.MinValue)] - public void IntProperties_SetValues_ReturnsExpected(int value) - { - MetaHeader mh = new MetaHeader(); - mh.Size = value; - mh.MaxRecord = value; - Assert.Equal(value, mh.Size); - Assert.Equal(value, mh.MaxRecord); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/MetafileTests.cs b/src/System.Drawing.Common/tests/Imaging/MetafileTests.cs deleted file mode 100644 index 9274ea35438..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/MetafileTests.cs +++ /dev/null @@ -1,1097 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2005-2006 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Runtime.InteropServices; - -namespace System.Drawing.Imaging.Tests; - -public class MetafileTests -{ - private const string WmfFile = "telescope_01.wmf"; - private const string BmpFile = "bitmap_173x183_indexed_8bit.bmp"; - private readonly Rectangle _rectangle = new(0, 0, 64, 64); - private readonly RectangleF _rectangleF = new(0, 0, 64, 64); - - [Fact] - public void Ctor_IntPtrZero_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new Metafile(IntPtr.Zero, false)); - } - - [Fact] - public void Ctor_IntPtrToWmf_ThrowsExternalException() - { - using (var metafile = new Metafile(GetPath(WmfFile))) - { - Assert.Throws(() => new Metafile(metafile.GetHenhmetafile(), false)); - } - } - - [Fact] - public void Ctor_String_Success() - { - using (var metafile = new Metafile(GetPath(WmfFile))) - { - AssertMetafile(metafile); - } - } - - [Fact] - public void Ctor_Bitmap_ThrowsExternalException() - { - Assert.Throws(() => new Metafile(GetPath(BmpFile))); - } - - [Fact] - public void Ctor_NullString_ThrowsArgumentNullException() - { - AssertExtensions.Throws("path", () => new Metafile((string)null)); - } - - [Fact] - public void Ctor_InvalidPath_ThrowsExternalException() - { - Assert.Throws(() => new Metafile("fileNotExist")); - } - - public static IEnumerable InvalidPath_TestData() - { - yield return new object[] { new string('a', 261) }; - yield return new object[] { @"fileNo*-//\\#@(found" }; - yield return new object[] { string.Empty }; - } - - [Theory] - [InlineData("bad\0name")] - [InlineData("")] - public void Ctor_InvalidPath_ThrowsArgumentException(string path) - { - AssertExtensions.Throws("path", null, () => new Metafile(path)); - } - - [Fact] - public void Ctor_Stream_Success() - { - using (FileStream stream = File.OpenRead(GetPath(WmfFile))) - using (var metafile = new Metafile(stream)) - { - AssertMetafile(metafile); - } - } - - [Fact] - public void Ctor_NullStream_ThrowsArgumentException() - { - AssertExtensions.Throws("stream", null, () => new Metafile((Stream)null)); - } - - [Fact] - public void Ctor_EmptyStream_ThrowsExternalException() - { - using (var stream = new MemoryStream()) - { - Assert.Throws(() => new Metafile(stream)); - } - } - - public static IEnumerable EmfType_TestData() - { - yield return new object[] { EmfType.EmfOnly }; - yield return new object[] { EmfType.EmfPlusDual }; - yield return new object[] { EmfType.EmfPlusOnly }; - } - - [Theory] - [MemberData(nameof(EmfType_TestData))] - public void Ctor_IntPtrEmfType_Success(EmfType emfType) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(g.GetHdc(), emfType)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), emfType); - } - } - - public static IEnumerable EmfType_Invalid_TestData() - { - yield return new object[] { (EmfType.EmfOnly - 1) }; - yield return new object[] { (EmfType.EmfPlusDual + 1) }; - yield return new object[] { (EmfType)int.MaxValue }; - yield return new object[] { (EmfType)int.MinValue }; - } - - [Theory] - [MemberData(nameof(EmfType_Invalid_TestData))] - public void Ctor_IntPtrInvalidEmfType_ThrowsArgumentException(EmfType emfType) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - AssertExtensions.Throws(null, () => new Metafile(g.GetHdc(), emfType)); - } - } - - [Fact] - public void Ctor_NullEmfType_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new Metafile((IntPtr)null, EmfType.EmfOnly)); - } - - [Fact] - public void Ctor_ZeroPointerEmfType_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new Metafile(IntPtr.Zero, EmfType.EmfOnly)); - } - - public static IEnumerable Description_TestData() - { - yield return new object[] { null }; - yield return new object[] { "description" }; - } - - [Theory] - [MemberData(nameof(Description_TestData))] - public void Ctor_IntPtrEmfTypeString_Success(string description) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(g.GetHdc(), EmfType.EmfOnly, description)) - { - AssertMetafileIsBlank(metafile); - } - } - - [Theory] - [MemberData(nameof(InvalidPath_TestData))] - public void Ctor_ZeroPointerEmfTypeInvalidString_ThrowsArgumentException(string description) - { - AssertExtensions.Throws(null, () => new Metafile(IntPtr.Zero, EmfType.EmfOnly, description)); - } - - [Fact] - public void Ctor_IntPtrRectangleF_Success() - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(g.GetHdc(), _rectangleF)) - { - AssertMetafileIsBlank(metafile); - } - } - - public static IEnumerable MetafileFrameUnit_TestData() - { - yield return new object[] { MetafileFrameUnit.Pixel }; - yield return new object[] { MetafileFrameUnit.Point }; - yield return new object[] { MetafileFrameUnit.Inch }; - yield return new object[] { MetafileFrameUnit.Document }; - yield return new object[] { MetafileFrameUnit.Millimeter }; - yield return new object[] { MetafileFrameUnit.GdiCompatible }; - } - - [Theory] - [MemberData(nameof(MetafileFrameUnit_TestData))] - public void Ctor_IntPtrRectangleFMetafileFrameUnit_Success(MetafileFrameUnit frameUnit) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(g.GetHdc(), _rectangleF, frameUnit)) - { - AssertMetafileIsBlank(metafile); - } - } - - [Theory] - [MemberData(nameof(EmfType_TestData))] - public void Ctor_IntPtrRectangleFMetafileFrameUnitEmfType_Success(EmfType emfType) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(g.GetHdc(), _rectangleF, MetafileFrameUnit.Pixel, emfType)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), emfType); - } - } - - [Theory] - [MemberData(nameof(Description_TestData))] - public void Ctor_IntPtrRectangleFMetafileFrameUnitEmfTypeString_Success(string description) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(g.GetHdc(), _rectangleF, MetafileFrameUnit.Pixel, EmfType.EmfOnly, description)) - { - AssertMetafileIsBlank(metafile); - } - } - - [Fact] - public void Ctor_IntPtrRectangle_Success() - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(g.GetHdc(), _rectangle)) - { - AssertMetafileIsBlank(metafile); - } - } - - [Theory] - [MemberData(nameof(MetafileFrameUnit_TestData))] - public void Ctor_IntPtrRectangleMetafileFrameUnit_Success(MetafileFrameUnit frameUnit) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(g.GetHdc(), _rectangle, frameUnit)) - { - AssertMetafileIsBlank(metafile); - } - } - - [Theory] - [MemberData(nameof(EmfType_TestData))] - public void Ctor_IntPtrRectangleMetafileFrameUnitEmfType_Success(EmfType emfType) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(g.GetHdc(), _rectangle, MetafileFrameUnit.Pixel, emfType)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), emfType); - } - } - - [Theory] - [MemberData(nameof(Description_TestData))] - public void Ctor_IntPtrRectangleMetafileFrameUnitEmfTypeString_Success(string description) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(g.GetHdc(), _rectangle, MetafileFrameUnit.Pixel, EmfType.EmfOnly, description)) - { - AssertMetafileIsBlank(metafile); - } - } - - [Fact] - public void Ctor_IntPtrZeroI_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new Metafile(IntPtr.Zero, _rectangleF)); - AssertExtensions.Throws(null, () => new Metafile(IntPtr.Zero, _rectangleF, MetafileFrameUnit.Pixel)); - AssertExtensions.Throws(null, () => - new Metafile(IntPtr.Zero, _rectangleF, MetafileFrameUnit.Pixel, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => - new Metafile(IntPtr.Zero, _rectangleF, MetafileFrameUnit.Pixel, EmfType.EmfOnly, "description")); - - AssertExtensions.Throws(null, () => new Metafile(IntPtr.Zero, _rectangle)); - AssertExtensions.Throws(null, () => new Metafile(IntPtr.Zero, _rectangle, MetafileFrameUnit.Pixel)); - AssertExtensions.Throws(null, () => - new Metafile(IntPtr.Zero, _rectangle, MetafileFrameUnit.Pixel, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => - new Metafile(IntPtr.Zero, _rectangle, MetafileFrameUnit.Pixel, EmfType.EmfOnly, "description")); - } - - public static IEnumerable MetafileFrameUnit_Invalid_TestData() - { - yield return new object[] { (MetafileFrameUnit.Pixel - 1) }; - yield return new object[] { (MetafileFrameUnit.GdiCompatible + 1) }; - yield return new object[] { (MetafileFrameUnit)int.MaxValue }; - yield return new object[] { (MetafileFrameUnit)int.MinValue }; - } - - [Theory] - [MemberData(nameof(MetafileFrameUnit_Invalid_TestData))] - public void Ctor_InvalidMetafileFrameUnit_ThrowsArgumentException(MetafileFrameUnit farameUnit) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws(null, () => new Metafile(referenceHdc, _rectangleF, farameUnit)); - AssertExtensions.Throws(null, () => new Metafile(referenceHdc, _rectangleF, farameUnit, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => - new Metafile(referenceHdc, _rectangleF, farameUnit, EmfType.EmfOnly, "description")); - - AssertExtensions.Throws(null, () => new Metafile(referenceHdc, _rectangle, farameUnit)); - AssertExtensions.Throws(null, () => new Metafile(referenceHdc, _rectangle, farameUnit, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => - new Metafile(referenceHdc, _rectangle, farameUnit, EmfType.EmfOnly, "description")); - } - } - - [Theory] - [MemberData(nameof(EmfType_Invalid_TestData))] - public void Ctor_InvalidEmfType_ThrowsArgumentException(EmfType emfType) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws(null, () => - new Metafile(referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, emfType)); - AssertExtensions.Throws(null, () => - new Metafile(referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, emfType, "description")); - - AssertExtensions.Throws(null, () => - new Metafile(referenceHdc, _rectangle, MetafileFrameUnit.GdiCompatible, emfType)); - AssertExtensions.Throws(null, () => - new Metafile(referenceHdc, _rectangle, MetafileFrameUnit.GdiCompatible, emfType, "description")); - } - } - - [Fact] - public void Ctor_StringIntPtr_Success() - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(fileName, g.GetHdc())) - { - AssertMetafileIsBlank(metafile); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Theory] - [MemberData(nameof(EmfType_TestData))] - public void Ctor_StringIntPtrEmfType_Success(EmfType emfType) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(fileName, g.GetHdc(), emfType)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), emfType); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Theory] - [MemberData(nameof(Description_TestData))] - public void Ctor_StringIntPtrEmfTypeDescription_Success(string description) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(fileName, g.GetHdc(), EmfType.EmfPlusDual, description)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), EmfType.EmfPlusDual); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Fact] - public void Ctor_IntPtrZeroII_ThrowsArgumentException() - { - string fileName = GetPath("newTestImage.wmf"); - AssertExtensions.Throws(null, () => new Metafile(fileName, IntPtr.Zero)); - AssertExtensions.Throws(null, () => new Metafile(fileName, IntPtr.Zero, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => new Metafile(fileName, IntPtr.Zero, EmfType.EmfOnly, "description")); - DeleteFile(fileName); - } - - [Theory] - [MemberData(nameof(EmfType_Invalid_TestData))] - public void Ctor_InvalidEmfTypeI_ThrowsArgumentException(EmfType emfType) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws(null, () => new Metafile(fileName, referenceHdc, emfType)); - AssertExtensions.Throws(null, () => new Metafile(fileName, referenceHdc, emfType, "description")); - DeleteFile(fileName); - } - } - - [Fact] - public void Ctor_NullPath_ThrowsArgumentNullException() - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws("path", () => new Metafile((string)null, referenceHdc)); - AssertExtensions.Throws("path", () => new Metafile((string)null, referenceHdc, EmfType.EmfOnly)); - AssertExtensions.Throws("path", () => new Metafile((string)null, referenceHdc, EmfType.EmfOnly, "description")); - } - } - - [Theory] - [InlineData("bad\0path")] - [InlineData("")] - public void Ctor_InvalidPathI_ThrowsArgumentException(string fileName) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws("path", null, () => new Metafile(fileName, referenceHdc)); - AssertExtensions.Throws("path", null, () => new Metafile(fileName, referenceHdc, EmfType.EmfOnly)); - AssertExtensions.Throws("path", null, () => new Metafile(fileName, referenceHdc, EmfType.EmfOnly, "description")); - } - } - - [Fact] - public void Ctor_PathTooLong_ThrowsPathTooLongException() - { - string fileName = GetPath(new string('a', short.MaxValue)); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - Assert.Throws(() => new Metafile(fileName, referenceHdc)); - Assert.Throws(() => new Metafile(fileName, referenceHdc, EmfType.EmfOnly)); - Assert.Throws(() => new Metafile(fileName, referenceHdc, EmfType.EmfOnly, "description")); - DeleteFile(fileName); - } - } - - [Fact] - public void Ctor_StringIntPtrRectangleF_Success() - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(fileName, g.GetHdc(), _rectangleF)) - { - AssertMetafileIsBlank(metafile); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Theory] - [MemberData(nameof(MetafileFrameUnit_TestData))] - public void Ctor_StringIntPtrRectangleFMetafileFrameUnit_Success(MetafileFrameUnit frameUnit) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(fileName, g.GetHdc(), _rectangleF, frameUnit)) - { - AssertMetafileIsBlank(metafile); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Theory] - [MemberData(nameof(EmfType_TestData))] - public void Ctor_StringIntPtrRectangleFMetafileFrameUnitEmfType_Success(EmfType emfType) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(fileName, g.GetHdc(), _rectangleF, MetafileFrameUnit.GdiCompatible, emfType)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), emfType); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Theory] - [MemberData(nameof(Description_TestData))] - public void Ctor_StringIntPtrRectangleFMetafileFrameUnitEmfTypeString_Success(string description) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile( - fileName, g.GetHdc(), _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, description)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), EmfType.EmfOnly); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Theory] - [MemberData(nameof(Description_TestData))] - public void Ctor_RectangleFEmpty_Success(string description) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile( - fileName, g.GetHdc(), new RectangleF(), MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, description)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), EmfType.EmfOnly); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Fact] - public void Ctor_StringIntPtrRectangle_Success() - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(fileName, g.GetHdc(), _rectangle)) - { - AssertMetafileIsBlank(metafile); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Theory] - [MemberData(nameof(MetafileFrameUnit_TestData))] - public void Ctor_StringIntPtrRectangleMetafileFrameUnit_Success(MetafileFrameUnit frameUnit) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(fileName, g.GetHdc(), _rectangle, frameUnit)) - { - AssertMetafileIsBlank(metafile); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Theory] - [MemberData(nameof(EmfType_TestData))] - public void Ctor_StringIntPtrRectangleMetafileFrameUnitEmfType_Success(EmfType emfType) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile(fileName, g.GetHdc(), _rectangle, MetafileFrameUnit.GdiCompatible, emfType)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), emfType); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Theory] - [MemberData(nameof(Description_TestData))] - public void Ctor_StringIntPtrRectangleMetafileFrameUnitEmfTypeString_Success(string description) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile( - fileName, g.GetHdc(), _rectangle, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, description)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), EmfType.EmfOnly); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Theory] - [MemberData(nameof(Description_TestData))] - public void Ctor_RectangleEmpty_Success(string description) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var metafile = new Metafile( - fileName, g.GetHdc(), new Rectangle(), MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, description)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), EmfType.EmfOnly); - Assert.True(File.Exists(fileName)); - } - - File.Delete(fileName); - } - - [Fact] - public void Ctor_IntPtrZeroIII_ThrowsArgumentException() - { - string fileName = GetPath("newTestImage.wmf"); - AssertExtensions.Throws(null, () => new Metafile(fileName, IntPtr.Zero, _rectangleF)); - AssertExtensions.Throws(null, () => new Metafile(fileName, IntPtr.Zero, _rectangleF, MetafileFrameUnit.GdiCompatible)); - AssertExtensions.Throws(null, () => - new Metafile(fileName, IntPtr.Zero, _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => - new Metafile(fileName, IntPtr.Zero, _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, "description")); - - AssertExtensions.Throws(null, () => new Metafile(fileName, IntPtr.Zero, _rectangle)); - AssertExtensions.Throws(null, () => new Metafile(fileName, IntPtr.Zero, _rectangle, MetafileFrameUnit.GdiCompatible)); - AssertExtensions.Throws(null, () => - new Metafile(fileName, IntPtr.Zero, _rectangle, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => - new Metafile(fileName, IntPtr.Zero, _rectangle, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, "description")); - DeleteFile(fileName); - } - - [Theory] - [MemberData(nameof(MetafileFrameUnit_Invalid_TestData))] - public void Ctor_InvalidFrameUnit_ThrowsArgumentException(MetafileFrameUnit frameUnit) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws(null, () => new Metafile(fileName, referenceHdc, _rectangleF, frameUnit)); - AssertExtensions.Throws(null, () => - new Metafile(fileName, referenceHdc, _rectangleF, frameUnit, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => - new Metafile(fileName, referenceHdc, _rectangleF, frameUnit, EmfType.EmfOnly, "description")); - - AssertExtensions.Throws(null, () => new Metafile(fileName, referenceHdc, _rectangle, frameUnit)); - AssertExtensions.Throws(null, () => - new Metafile(fileName, referenceHdc, _rectangle, frameUnit, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => - new Metafile(fileName, referenceHdc, _rectangle, frameUnit, EmfType.EmfOnly, "description")); - DeleteFile(fileName); - } - } - - [Theory] - [MemberData(nameof(EmfType_Invalid_TestData))] - public void Ctor_InvalidEmfTypeII_ThrowsArgumentException(EmfType emfType) - { - string fileName = GetPath("newTestImage.wmf"); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws(null, () => - new Metafile(fileName, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, emfType)); - AssertExtensions.Throws(null, () => - new Metafile(fileName, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, emfType, "description")); - - AssertExtensions.Throws(null, () => - new Metafile(fileName, referenceHdc, _rectangle, MetafileFrameUnit.GdiCompatible, emfType)); - AssertExtensions.Throws(null, () => - new Metafile(fileName, referenceHdc, _rectangle, MetafileFrameUnit.GdiCompatible, emfType, "description")); - DeleteFile(fileName); - } - } - - [Fact] - public void Ctor_NullPathI_ThrowsArgumentNullException() - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws("path", () => new Metafile((string)null, referenceHdc, _rectangleF)); - AssertExtensions.Throws("path", () => - new Metafile((string)null, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible)); - AssertExtensions.Throws("path", () => - new Metafile((string)null, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly)); - AssertExtensions.Throws("path", () => - new Metafile((string)null, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, "description")); - } - } - - [Theory] - [InlineData("bad\0path")] - [InlineData("")] - public void Ctor_InvalidPathII_ThrowsArgumentException(string fileName) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws("path", null, () => new Metafile(fileName, referenceHdc, _rectangleF)); - AssertExtensions.Throws("path", null, () => - new Metafile(fileName, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible)); - AssertExtensions.Throws("path", null, () => - new Metafile(fileName, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly)); - AssertExtensions.Throws("path", null, () => - new Metafile(fileName, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, "description")); - } - } - - [Fact] - public void Ctor_PathTooLongI_ThrowsPathTooLongException() - { - string fileName = GetPath(new string('a', 261)); - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - Assert.Throws(() => new Metafile(fileName, referenceHdc, _rectangleF)); - Assert.Throws(() => - new Metafile(fileName, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible)); - Assert.Throws(() => - new Metafile(fileName, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly)); - Assert.Throws(() => - new Metafile(fileName, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, "description")); - DeleteFile(fileName); - } - } - - [Fact] - public void Ctor_StreamIntPtrRectangle_Success() - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var stream = new MemoryStream()) - using (var metafile = new Metafile(stream, g.GetHdc(), _rectangle)) - { - AssertMetafileIsBlank(metafile); - } - } - - [Theory] - [MemberData(nameof(MetafileFrameUnit_TestData))] - public void Ctor_StreamIntPtrRectangleMetafileFrameUnit_Success(MetafileFrameUnit frameUnit) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var stream = new MemoryStream()) - using (var metafile = new Metafile(stream, g.GetHdc(), _rectangle, frameUnit)) - { - AssertMetafileIsBlank(metafile); - } - } - - [Theory] - [MemberData(nameof(EmfType_TestData))] - public void Ctor_StreamIntPtrRectangleMetafileFrameUnitEmfType_Success(EmfType emfType) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var stream = new MemoryStream()) - using (var metafile = new Metafile(stream, g.GetHdc(), _rectangle, MetafileFrameUnit.GdiCompatible, emfType)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), emfType); - } - } - - [Theory] - [MemberData(nameof(Description_TestData))] - public void Ctor_StreamIntPtrRectangleMetafileFrameUnitEmfTypeString_Success(string description) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var stream = new MemoryStream()) - using (var metafile = new Metafile( - stream, g.GetHdc(), _rectangle, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, description)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), EmfType.EmfOnly); - } - } - - [Theory] - [MemberData(nameof(Description_TestData))] - public void Ctor_RectangleEmptyI_Success(string description) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - using (var stream = new MemoryStream()) - using (var metafile = new Metafile( - stream, g.GetHdc(), new Rectangle(), MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, description)) - { - AssertMetafileIsBlank(metafile); - AssertEmfType(metafile.GetMetafileHeader(), EmfType.EmfOnly); - } - } - - [Fact] - public void Ctor_IntPtrZeroIV_ThrowsArgumentException() - { - using (var stream = new MemoryStream()) - { - AssertExtensions.Throws(null, () => new Metafile(stream, IntPtr.Zero, _rectangle)); - AssertExtensions.Throws(null, () => new Metafile(stream, IntPtr.Zero, _rectangle, MetafileFrameUnit.GdiCompatible)); - AssertExtensions.Throws(null, () => - new Metafile(stream, IntPtr.Zero, _rectangle, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => - new Metafile(stream, IntPtr.Zero, _rectangle, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, "description")); - } - } - - [Theory] - [MemberData(nameof(MetafileFrameUnit_Invalid_TestData))] - public void Ctor_InvalidFrameUnitIII_ThrowsArgumentException(MetafileFrameUnit frameUnit) - { - using (var stream = new MemoryStream()) - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws(null, () => new Metafile(stream, referenceHdc, _rectangle, frameUnit)); - AssertExtensions.Throws(null, () => - new Metafile(stream, referenceHdc, _rectangle, frameUnit, EmfType.EmfOnly)); - AssertExtensions.Throws(null, () => - new Metafile(stream, referenceHdc, _rectangle, frameUnit, EmfType.EmfOnly, "description")); - } - } - - [Theory] - [MemberData(nameof(EmfType_Invalid_TestData))] - public void Ctor_InvalidEmfTypeIII_ThrowsArgumentException(EmfType emfType) - { - using (var stream = new MemoryStream()) - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - AssertExtensions.Throws(null, () => - new Metafile(stream, referenceHdc, _rectangle, MetafileFrameUnit.GdiCompatible, emfType)); - AssertExtensions.Throws(null, () => - new Metafile(stream, referenceHdc, _rectangle, MetafileFrameUnit.GdiCompatible, emfType, "description")); - } - } - - [Fact] - public void Ctor_NullStream_ThrowsNullReferenceException() - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr referenceHdc = g.GetHdc(); - Assert.Throws(() => new Metafile((Stream)null, referenceHdc, _rectangleF)); - Assert.Throws(() => new Metafile((Stream)null, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible)); - Assert.Throws(() => - new Metafile((Stream)null, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly)); - Assert.Throws(() => - new Metafile((Stream)null, referenceHdc, _rectangleF, MetafileFrameUnit.GdiCompatible, EmfType.EmfOnly, "description")); - } - } - - [Fact] - public void Static_GetMetafileHeader_String_ReturnsExpected() - { - MetafileHeader header = Metafile.GetMetafileHeader(GetPath(WmfFile)); - AssertMetafileHeader(header); - } - - [Fact] - public void Static_GetMetafileHeader_IntPtr_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => Metafile.GetMetafileHeader(IntPtr.Zero)); - using (var metafile = new Metafile(GetPath(WmfFile))) - { - AssertExtensions.Throws(null, () => Metafile.GetMetafileHeader(metafile.GetHenhmetafile())); - } - } - - [Theory] - [InlineData("bad\0path")] - [InlineData("")] - public void Static_GetMetafileHeader_InvalidPath_ThrowsArgumentException(string fileName) - { - AssertExtensions.Throws("path", null, () => Metafile.GetMetafileHeader(fileName)); - } - - [Fact] - public void Static_GetMetafileHeader_NullString_ThrowsArgumentNullException() - { - AssertExtensions.Throws("path", () => Metafile.GetMetafileHeader((string)null)); - } - - [Fact] - public void Static_GetMetafileHeader_Stream_ReturnsExpected() - { - using (FileStream stream = File.OpenRead(GetPath(WmfFile))) - { - MetafileHeader header = Metafile.GetMetafileHeader(stream); - AssertMetafileHeader(header); - } - } - - [Fact] - public void Static_GetMetafileHeader_NullStream_ThrowsNullReferenceException() - { - Assert.Throws(() => Metafile.GetMetafileHeader((Stream)null)); - } - - [Fact] - public void Static_GetMetafileHeader_EmptyStream_ArgumentException() - { - using (var stream = new MemoryStream()) - { - AssertExtensions.Throws(null, () => Metafile.GetMetafileHeader(stream)); - } - } - - [Fact] - public void GetMetafileHeader_ReturnsExpected() - { - using (var metafile = new Metafile(GetPath(WmfFile))) - { - MetafileHeader headerA = metafile.GetMetafileHeader(); - MetafileHeader headerB = metafile.GetMetafileHeader(); - AssertMetafileHeader(headerA); - Assert.NotSame(headerA, headerB); - } - } - - [Fact] - public void GetMetafileHeader_Disposed_ThrowsArgumentException() - { - var metafile = new Metafile(GetPath(WmfFile)); - metafile.Dispose(); - - AssertExtensions.Throws(null, () => metafile.GetMetafileHeader()); - } - - [Fact] - public void GetHenhmetafile_ReturnsExpected() - { - using (var metafile = new Metafile(GetPath(WmfFile))) - { - Assert.NotEqual(IntPtr.Zero, metafile.GetHenhmetafile()); - } - } - - [Fact] - public void GetHenhmetafile_Disposed_ThrowsArgumentException() - { - var metafile = new Metafile(GetPath(WmfFile)); - metafile.Dispose(); - - AssertExtensions.Throws(null, () => metafile.GetHenhmetafile()); - } - - [Fact] - public void PlayRecord_Disposed_ThrowsArgumentException() - { - var metafile = new Metafile(GetPath(WmfFile)); - metafile.Dispose(); - - AssertExtensions.Throws(null, () => - metafile.PlayRecord(EmfPlusRecordType.BeginContainer, 0, 1, new byte[1])); - } - - private void DeleteFile(string path) - { - if (File.Exists(path)) - { - File.Delete(path); - } - } - - private string GetPath(string fileName) - { - return Helpers.GetTestBitmapPath(fileName); - } - - private void AssertEmfType(MetafileHeader metafileHeader, EmfType emfType) - { - switch (emfType) - { - case EmfType.EmfOnly: - Assert.True(metafileHeader.IsEmf()); - break; - case EmfType.EmfPlusDual: - Assert.True(metafileHeader.IsEmfPlusDual()); - break; - case EmfType.EmfPlusOnly: - Assert.True(metafileHeader.IsEmfPlusOnly()); - break; - } - } - - private void AssertMetafileIsBlank(Metafile metafile) - { - GraphicsUnit graphicsUnit = (GraphicsUnit)int.MaxValue; - - AssertMetafileHeaderIsBlank(metafile.GetMetafileHeader()); - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // This values are incorrect on libgdiplus. - Assert.Equal(new Rectangle(0, 0, 1, 1), metafile.GetBounds(ref graphicsUnit)); - Assert.Equal(GraphicsUnit.Pixel, graphicsUnit); - } - } - - private void AssertMetafileHeaderIsBlank(MetafileHeader metafileHeader) - { - Assert.Equal(new Rectangle(0, 0, 0, 0), metafileHeader.Bounds); - Assert.Equal(0, metafileHeader.MetafileSize); - } - - private void AssertMetafile(Metafile metafile) - { - GraphicsUnit graphicsUnit = (GraphicsUnit)int.MaxValue; - - AssertMetafileHeader(metafile.GetMetafileHeader()); - Assert.Equal(new Rectangle(-30, -40, 3096, 4127), metafile.GetBounds(ref graphicsUnit)); - Assert.Equal(GraphicsUnit.Pixel, graphicsUnit); - } - - private void AssertMetafileHeader(MetafileHeader header) - { - Assert.Equal(MetafileType.WmfPlaceable, header.Type); - Assert.Equal(0x300, header.Version); - Assert.Equal(new Rectangle(-30, -40, 3096, 4127), header.Bounds); - Assert.Equal(606, header.DpiX); - Assert.Equal(606, header.DpiY); - Assert.Equal(0, header.EmfPlusHeaderSize); - Assert.Equal(0, header.LogicalDpiX); - Assert.Equal(0, header.LogicalDpiY); - Assert.Equal(3474, header.MetafileSize); - Assert.NotNull(header.WmfHeader); - Assert.False(header.IsDisplay()); - Assert.False(header.IsEmf()); - Assert.False(header.IsEmfOrEmfPlus()); - Assert.False(header.IsEmfPlus()); - Assert.False(header.IsEmfPlusDual()); - Assert.False(header.IsEmfPlusOnly()); - Assert.True(header.IsWmf()); - Assert.True(header.IsWmfPlaceable()); - - Assert.Equal(9, header.WmfHeader.HeaderSize); - Assert.Equal(98, header.WmfHeader.MaxRecord); - Assert.Equal(3, header.WmfHeader.NoObjects); - Assert.Equal(0, header.WmfHeader.NoParameters); - Assert.Equal(1737, header.WmfHeader.Size); - Assert.Equal((int)MetafileType.Wmf, header.WmfHeader.Type); - Assert.Equal(0x300, header.WmfHeader.Version); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/PropertyItemTests.cs b/src/System.Drawing.Common/tests/Imaging/PropertyItemTests.cs deleted file mode 100644 index 2a4fb076865..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/PropertyItemTests.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -public class PropertyItemTests -{ - private const int PropertyTagLuminanceTable = 0x5090; - - [Theory] - [InlineData(1)] - [InlineData(0)] - [InlineData(-1)] - public void Id_Set_GetReturnsExpected(int value) - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - PropertyItem item = bitmap.GetPropertyItem(PropertyTagLuminanceTable); - item.Id = value; - Assert.Equal(value, item.Id); - } - - [Theory] - [InlineData(1)] - [InlineData(0)] - [InlineData(-1)] - public void Len_Set_GetReturnsExpected(int value) - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - PropertyItem item = bitmap.GetPropertyItem(PropertyTagLuminanceTable); - item.Len = value; - Assert.Equal(value, item.Len); - } - - [Theory] - [InlineData(1)] - [InlineData(0)] - [InlineData(-1)] - public void Type_Set_GetReturnsExpected(short value) - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - PropertyItem item = bitmap.GetPropertyItem(PropertyTagLuminanceTable); - item.Type = value; - Assert.Equal(value, item.Type); - } - - public static IEnumerable Value_Set_TestData() - { - yield return new object[] { null }; - yield return new object[] { Array.Empty() }; - yield return new object[] { new byte[] { 1, 2, 3 } }; - } - - [Theory] - [MemberData(nameof(Value_Set_TestData))] - public void Value_Set_GetReturnsExpected(byte[] value) - { - using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("nature24bits.jpg")); - PropertyItem item = bitmap.GetPropertyItem(PropertyTagLuminanceTable); - item.Value = value; - Assert.Same(value, item.Value); - } - - public static IEnumerable Properties_TestData() - { - yield return new object[] { int.MaxValue, int.MaxValue, short.MaxValue, new byte[1] { 0 } }; - yield return new object[] { int.MinValue, int.MinValue, short.MinValue, new byte[2] { 1, 1} }; - yield return new object[] { 0, 0, 0, new byte[0] }; - } - - [Theory] - [MemberData(nameof(Properties_TestData))] - public void Properties_SetValues_ReturnsExpected(int id, int len, short type, byte[] value) - { - using var image = new Bitmap(Helpers.GetTestBitmapPath("16x16_nonindexed_24bit.png")); - using Image clone = (Image)image.Clone(); - - PropertyItem[] propItems = clone.PropertyItems; - PropertyItem propItem = propItems[0]; - Assert.Equal(771, propItem.Id); - Assert.Equal(1, propItem.Len); - Assert.Equal(1, propItem.Type); - Assert.Equal(new byte[1] { 0 }, propItem.Value); - - propItem.Id = id; - propItem.Len = len; - propItem.Type = type; - propItem.Value = value; - - Assert.Equal(id, propItem.Id); - Assert.Equal(len, propItem.Len); - Assert.Equal(type, propItem.Type); - Assert.Equal(value, propItem.Value); - } -} diff --git a/src/System.Drawing.Common/tests/Imaging/WmfPlaceableFileHeaderTests.cs b/src/System.Drawing.Common/tests/Imaging/WmfPlaceableFileHeaderTests.cs deleted file mode 100644 index 529cc637294..00000000000 --- a/src/System.Drawing.Common/tests/Imaging/WmfPlaceableFileHeaderTests.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Imaging.Tests; - -public class WmfPlaceableFileHeaderTests -{ - [Fact] - public void Ctor_Default() - { - WmfPlaceableFileHeader fileHeader = new WmfPlaceableFileHeader(); - Assert.Equal(0, fileHeader.BboxBottom); - Assert.Equal(0, fileHeader.BboxLeft); - Assert.Equal(0, fileHeader.BboxRight); - Assert.Equal(0, fileHeader.BboxTop); - Assert.Equal(0, fileHeader.Checksum); - Assert.Equal(0, fileHeader.Hmf); - Assert.Equal(0, fileHeader.Inch); - Assert.Equal(unchecked((int)0x9aC6CDD7), fileHeader.Key); - Assert.Equal(0, fileHeader.Reserved); - } - - [Theory] - [InlineData(short.MaxValue)] - [InlineData(0)] - [InlineData(short.MinValue)] - public void ShortProperties_SetValues_ReturnsExpected(short value) - { - WmfPlaceableFileHeader fileHeader = new WmfPlaceableFileHeader(); - fileHeader.BboxBottom = value; - fileHeader.BboxLeft = value; - fileHeader.BboxRight = value; - fileHeader.BboxTop = value; - fileHeader.Checksum = value; - fileHeader.Hmf = value; - fileHeader.Inch = value; - fileHeader.Key = value; - fileHeader.Reserved = value; - Assert.Equal(value, fileHeader.BboxBottom); - Assert.Equal(value, fileHeader.BboxLeft); - Assert.Equal(value, fileHeader.BboxRight); - Assert.Equal(value, fileHeader.BboxTop); - Assert.Equal(value, fileHeader.Checksum); - Assert.Equal(value, fileHeader.Hmf); - Assert.Equal(value, fileHeader.Inch); - Assert.Equal(value, fileHeader.Key); - Assert.Equal(value, fileHeader.Reserved); - } - - [Theory] - [InlineData(int.MaxValue)] - [InlineData(0)] - [InlineData(int.MinValue)] - public void IntProperties_SetValues_ReturnsExpected(int value) - { - WmfPlaceableFileHeader fileHeader = new WmfPlaceableFileHeader(); - fileHeader.Key = value; - fileHeader.Reserved = value; - Assert.Equal(value, fileHeader.Key); - Assert.Equal(value, fileHeader.Reserved); - } -} diff --git a/src/System.Drawing.Common/tests/PenTests.cs b/src/System.Drawing.Common/tests/PenTests.cs deleted file mode 100644 index 389ca849cd9..00000000000 --- a/src/System.Drawing.Common/tests/PenTests.cs +++ /dev/null @@ -1,1385 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; -using System.Globalization; - -namespace System.Drawing.Tests; - -public class PenTests -{ - public static IEnumerable Ctor_Brush_TestData() - { - yield return new object[] { new SolidBrush(Color.Red), PenType.SolidColor }; - yield return new object[] { new HatchBrush(HatchStyle.BackwardDiagonal, Color.Red), PenType.HatchFill }; - yield return new object[] { new LinearGradientBrush(new Point(0, 0), new Point(0, 2), Color.Purple, Color.Plum), PenType.LinearGradient }; - yield return new object[] { new TextureBrush(new Bitmap(1, 1)), PenType.TextureFill }; - yield return new object[] { new PathGradientBrush(new Point[] { new Point(1, 2), new Point(2, 3) }), PenType.PathGradient }; - } - - [Theory] - [MemberData(nameof(Ctor_Brush_TestData))] - public void Ctor_Brush(T brush, PenType penType) where T : Brush - { - using (brush) - using (var pen = new Pen(brush)) - { - VerifyPen(pen, penType, expectedWidth: 1); - } - } - - public static IEnumerable Ctor_Brush_Width_TestData() - { - foreach (object[] data in Ctor_Brush_TestData()) - { - yield return new object[] { data[0], 10, data[1] }; - } - - // Issue on Non-English Windows with brush width < 1. See https://github.com/dotnet/runtime/issues/60480 - if (Environment.OSVersion.Platform != PlatformID.Win32NT || CultureInfo.InstalledUICulture.TwoLetterISOLanguageName == "en") - { - yield return new object[] { new SolidBrush(Color.Red), 0, PenType.SolidColor }; - - // GDI+ No longer allows negative pen width values (Windows PR6441324) - // yield return new object[] { new SolidBrush(Color.Red), -1, PenType.SolidColor }; - // yield return new object[] { new SolidBrush(Color.Red), float.NegativeInfinity, PenType.SolidColor }; - } - - yield return new object[] { new SolidBrush(Color.Red), float.PositiveInfinity, PenType.SolidColor }; - yield return new object[] { new SolidBrush(Color.Red), float.NaN, PenType.SolidColor }; - yield return new object[] { new SolidBrush(Color.Red), float.MaxValue, PenType.SolidColor }; - } - - [Theory] - [MemberData(nameof(Ctor_Brush_Width_TestData))] - public void Ctor_Brush_Width(T brush, float width, PenType expectedPenType) where T : Brush - { - using (brush) - using (var pen = new Pen(brush, width)) - { - VerifyPen(pen, expectedPenType, width); - } - } - - [Fact] - public void Ctor_Brush_MakesClone() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - brush.Color = Color.Blue; - Assert.Equal(Color.FromArgb(Color.Red.ToArgb()), pen.Color); - Assert.Equal(pen.Color, Assert.IsType(pen.Brush).Color); - } - } - - [Fact] - public void Ctor_NullBrush_ThrowsArgumentNullException() - { - AssertExtensions.Throws("brush", () => new Pen(null)); - AssertExtensions.Throws("brush", () => new Pen(null, 0)); - } - - [Fact] - public void Ctor_DisposedBrush_ThrowsArgumentException() - { - var brush = new SolidBrush(Color.Red); - brush.Dispose(); - - AssertExtensions.Throws(null, () => new Pen(brush)); - AssertExtensions.Throws(null, () => new Pen(brush, 10)); - } - - [Fact] - public void Ctor_Color() - { - using (var pen = new Pen(Color.Red)) - { - VerifyPen(pen, PenType.SolidColor, 1); - Assert.Equal(Color.Red, pen.Color); - } - } - - [Theory] - // GDI+ No longer allows negative pen width values (Windows PR6441324) - // [InlineData(-1)] - // [InlineData(float.NegativeInfinity)] - [InlineData(0)] - [InlineData(1)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NaN)] - public void Ctor_Color_Width(float width) - { - using (var pen = new Pen(Color.Red, width)) - { - VerifyPen(pen, PenType.SolidColor, width); - Assert.Equal(Color.Red, pen.Color); - } - } - - [Theory] - [InlineData(PenAlignment.Center)] - [InlineData(PenAlignment.Inset)] - [InlineData(PenAlignment.Left)] - [InlineData(PenAlignment.Outset)] - [InlineData(PenAlignment.Right)] - public void Alignment_SetValid_GetReturnsExpected(PenAlignment alignment) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.Alignment = alignment; - Assert.Equal(alignment, pen.Alignment); - } - } - - [Theory] - [InlineData(PenAlignment.Center - 1)] - [InlineData(PenAlignment.Right + 1)] - public void Alignment_SetInvalid_ThrowsInvalidEnumArgumentException(PenAlignment alignment) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - Assert.ThrowsAny(() => pen.Alignment = alignment); - } - } - - [Fact] - public void Alignment_GetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.Alignment); - AssertExtensions.Throws(null, () => pen.Alignment = PenAlignment.Center); - } - } - - [Theory] - [MemberData(nameof(Ctor_Brush_TestData))] - public void Brush_SetValid_GetReturnsExpected(T brush, PenType penType) where T : Brush - { - using (var pen = new Pen(Color.Red)) - { - pen.Brush = brush; - Assert.IsType(pen.Brush); - Assert.Equal(penType, pen.PenType); - } - } - - [Fact] - public void Brush_SetCustomBrush_ThrowsArgumentException() - { - using (var pen = new Pen(Color.Red)) - { - AssertExtensions.Throws(null, () => pen.Brush = new SubBrush()); - } - } - - public class SubBrush : Brush - { - public override object Clone() => this; - } - - [Fact] - public void Brush_SetNullBrush_ThrowsArgumentNullException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws("value", () => pen.Brush = null); - } - } - - [Fact] - public void Brush_SetDisposedBrush_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - brush.Dispose(); - - AssertExtensions.Throws(null, () => pen.Brush = brush); - } - } - - [Fact] - public void Brush_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.Brush); - AssertExtensions.Throws(null, () => pen.Brush = brush); - } - } - - public static IEnumerable Clone_TestData() - { - using (var brush = new SolidBrush(Color.Red)) - { - yield return new object[] { new Pen(brush) }; - } - } - - [Theory] - [MemberData(nameof(Clone_TestData))] - public void Clone_Invoke_ReturnsExpected(Pen pen) - { - using (pen) - { - Pen clone = Assert.IsType(pen.Clone()); - Assert.NotSame(pen, clone); - - Assert.Equal(pen.Color, clone.Color); - Assert.Equal(((SolidBrush)pen.Brush).Color, ((SolidBrush)clone.Brush).Color); - Assert.Equal(pen.DashOffset, clone.DashOffset); - Assert.Equal(pen.DashStyle, clone.DashStyle); - Assert.Equal(pen.EndCap, clone.EndCap); - Assert.Equal(pen.StartCap, clone.StartCap); - Assert.Equal(pen.Width, clone.Width); - } - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.Clone()); - } - } - - [Fact] - public void Color_SolidBrush_ReturnsExpected() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - Assert.Equal(Color.FromArgb(Color.Red.ToArgb()), pen.Color); - } - } - - [Fact] - public void Color_HatchBrush_ThrowsArgumentException() - { - using (var brush = new HatchBrush(HatchStyle.BackwardDiagonal, Color.Red)) - using (var pen = new Pen(brush)) - { - ValidateInitialPenColorState(pen); - } - } - - [Fact] - public void Color_LinearGradientBrush_ThrowsArgumentException() - { - using (var brush = new LinearGradientBrush(Point.Empty, new Point(1, 2), Color.Blue, Color.Red)) - using (var pen = new Pen(brush)) - { - ValidateInitialPenColorState(pen); - } - } - - private void ValidateInitialPenColorState(Pen pen) - { - AssertExtensions.Throws(null, () => pen.Color); - } - - [Theory] - [MemberData(nameof(Ctor_Brush_TestData))] - public void Color_Set_GetReturnsExpected(Brush brush, PenType penType) - { - _ = penType; - using (brush) - using (var pen = new Pen(brush)) - { - pen.Color = Color.Red; - Assert.Equal(Color.Red, pen.Color); - - pen.Color = Color.Red; - Assert.Equal(Color.Red, pen.Color); - } - } - - [Fact] - public void Color_GetSetWhenDisposedWithoutBrush_Success() - { - var pen = new Pen(Color.Red); - - pen.Dispose(); - Assert.Equal(Color.Red, pen.Color); - - pen.Color = Color.Red; - Assert.Equal(Color.Red, pen.Color); - - AssertExtensions.Throws(null, () => pen.Color = Color.Black); - } - - [Fact] - public void Color_GetSetWhenDisposedWithBrush_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.Color); - AssertExtensions.Throws(null, () => pen.Color = Color.Red); - } - } - - [Theory] - [InlineData(new float[] { 0, 0 })] - [InlineData(new float[] { 1, 1 })] - [InlineData(new float[] { float.NaN, 0 })] - public void CompoundArray_SetValidPattern_GetReturnsExpected(float[] compoundArray) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.CompoundArray = compoundArray; - Assert.Equal(compoundArray, pen.CompoundArray); - - // CompoundArray should be a clone of the original. - compoundArray[0] = 10; - Assert.NotEqual(compoundArray, pen.CompoundArray); - } - } - - [Fact] - public void CompoundArray_SetNullPattern_ThrowsNullReferenceException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - Assert.Throws(() => pen.CompoundArray = null); - } - } - - [Fact] - public void CompoundArray_SetEmptyPattern_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws(null, () => pen.CompoundArray = new float[0]); - } - } - - [Theory] - [InlineData(new float[] { -1, 0 })] - [InlineData(new float[] { float.NegativeInfinity, 0 })] - [InlineData(new float[] { float.PositiveInfinity, 0 })] - [InlineData(new float[] { float.MaxValue, 0 })] - [InlineData(new float[] { 1024, 0 })] - [InlineData(new float[] { 2, 2 })] - [InlineData(new float[] { 1 })] - [InlineData(new float[] { 1, 2, 3 })] - public void CompoundArray_SetInvalidPattern_ThrowsArgumentException(float[] compoundArray) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws(null, () => pen.CompoundArray = compoundArray); - } - } - - [Fact] - public void CompoundArray_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.CompoundArray); - AssertExtensions.Throws(null, () => pen.CompoundArray = new float[] { 1 }); - } - } - - [Fact] - public void CustomEndCap_SetValid_GetReturnsExpected() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (var fillPath = new GraphicsPath()) - using (var strokePath = new GraphicsPath()) - using (var lineCap = new CustomLineCap(fillPath, strokePath)) - { - lineCap.BaseInset = 100; - pen.CustomEndCap = lineCap; - Assert.Equal(100, pen.CustomEndCap.BaseInset); - - // The CustomLineCap should be cloned. - lineCap.BaseInset = 10; - Assert.Equal(100, pen.CustomEndCap.BaseInset); - } - } - - [Fact] - public void CustomEndCap_SetNull_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws(null, () => pen.CustomEndCap = null); - } - } - - [Fact] - public void CustomEndCap_SetDisposedLineCap_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (var fillPath = new GraphicsPath()) - using (var strokePath = new GraphicsPath()) - { - var lineCap = new CustomLineCap(fillPath, strokePath); - lineCap.Dispose(); - - AssertExtensions.Throws(null, () => pen.CustomEndCap = lineCap); - } - } - - [Fact] - public void CustomEndCap_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var fillPath = new GraphicsPath()) - using (var strokePath = new GraphicsPath()) - using (var lineCap = new CustomLineCap(fillPath, strokePath)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.CustomEndCap); - AssertExtensions.Throws(null, () => pen.CustomEndCap = lineCap); - } - } - - [Fact] - public void CustomStartCap_SetValid_GetReturnsExpected() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (var fillPath = new GraphicsPath()) - using (var strokePath = new GraphicsPath()) - using (var lineCap = new CustomLineCap(fillPath, strokePath)) - { - lineCap.BaseInset = 100; - pen.CustomStartCap = lineCap; - Assert.Equal(100, pen.CustomStartCap.BaseInset); - - // The CustomLineCap should be cloned. - lineCap.BaseInset = 10; - Assert.Equal(100, pen.CustomStartCap.BaseInset); - } - } - - [Fact] - public void CustomStartCap_SetNull_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws(null, () => pen.CustomStartCap = null); - } - } - - [Fact] - public void CustomStartCap_SetDisposedLineCap_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (var fillPath = new GraphicsPath()) - using (var strokePath = new GraphicsPath()) - { - var lineCap = new CustomLineCap(fillPath, strokePath); - lineCap.Dispose(); - - AssertExtensions.Throws(null, () => pen.CustomStartCap = lineCap); - } - } - - [Fact] - public void CustomStartCap_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var fillPath = new GraphicsPath()) - using (var strokePath = new GraphicsPath()) - using (var lineCap = new CustomLineCap(fillPath, strokePath)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.CustomStartCap); - AssertExtensions.Throws(null, () => pen.CustomStartCap = lineCap); - } - } - - [Theory] - [InlineData(DashCap.Flat)] - [InlineData(DashCap.Round)] - [InlineData(DashCap.Triangle)] - public void DashCap_SetValid_GetReturnsExpected(DashCap dashCap) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.DashCap = dashCap; - Assert.Equal(dashCap, pen.DashCap); - } - } - - [Theory] - [InlineData(DashCap.Flat - 1)] - [InlineData(DashCap.Round - 1)] - [InlineData(DashCap.Triangle + 1)] - public void DashCap_SetInvalid_ThrowsInvalidEnumArgumentException(DashCap dashCap) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - Assert.ThrowsAny(() => pen.DashCap = dashCap); - } - } - - [Fact] - public void DashCap_GetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.DashCap); - AssertExtensions.Throws(null, () => pen.DashCap = DashCap.Triangle); - } - } - - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(10)] - [InlineData(float.NegativeInfinity)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NaN)] - public void DashOffset_Set_GetReturnsExpected(float dashOffset) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.DashOffset = dashOffset; - Assert.Equal(dashOffset, pen.DashOffset); - } - } - - [Fact] - public void DashOffset_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.DashOffset); - AssertExtensions.Throws(null, () => pen.DashOffset = 10); - } - } - - [Theory] - [InlineData(new float[] { 1 })] - [InlineData(new float[] { 1, 1 })] - [InlineData(new float[] { float.MaxValue, float.NaN, float.PositiveInfinity })] - [InlineData(new float[] { float.MaxValue, float.NaN })] - public void DashPattern_SetValidPattern_GetReturnsExpected(float[] pattern) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.DashPattern = pattern; - Assert.Equal(pattern, pen.DashPattern); - Assert.Equal(DashStyle.Custom, pen.DashStyle); - - // DashPattern should be a clone of the original. - pattern[0] = 10; - Assert.NotEqual(pattern, pen.DashPattern); - } - } - - [Fact] - public void DashPattern_SetNullPattern_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws(null, () => pen.DashPattern = null); - } - } - - [Fact] - public void DashPattern_SetEmptyPattern_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws(null, () => pen.DashPattern = new float[0]); - } - } - - [Theory] - [InlineData(new float[] { -1 })] - [InlineData(new float[] { 0 })] - [InlineData(new float[] { 1, -1 })] - [InlineData(new float[] { float.NegativeInfinity })] - public void DashPattern_SetInvalidPattern_ThrowsArgumentException(float[] pattern) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws(null, () => pen.DashPattern = pattern); - } - } - - [Fact] - public void DashPattern_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.DashPattern); - AssertExtensions.Throws(null, () => pen.DashPattern = new float[] { 1 }); - } - } - - [Theory] - [InlineData(DashStyle.Dash, new float[] { 3, 1 })] - [InlineData(DashStyle.DashDot, new float[] { 3, 1, 1, 1 })] - [InlineData(DashStyle.DashDotDot, new float[] { 3, 1, 1, 1, 1, 1 })] - [InlineData(DashStyle.Dot, new float[] { 1, 1 })] - [InlineData(DashStyle.Solid, null)] - [InlineData(DashStyle.Custom, new float[] { 1 })] - public void DashStyle_SetValid_GetReturnsExpected(DashStyle dashStyle, float[] expectedDashPattern) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.DashStyle = dashStyle; - Assert.Equal(dashStyle, pen.DashStyle); - - if (expectedDashPattern == null) - { - Assert.Throws(() => pen.DashPattern); - } - else - { - Assert.Equal(expectedDashPattern, pen.DashPattern); - } - } - } - - [Fact] - public void DashStyle_SetCustomWithDashCount_DoeNotChangePattern() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.DashStyle = DashStyle.Dash; - pen.DashStyle = DashStyle.Custom; - - Assert.Equal(DashStyle.Custom, pen.DashStyle); - Assert.Equal(new float[] { 3, 1 }, pen.DashPattern); - } - } - - [Theory] - [InlineData(DashStyle.Solid - 1)] - [InlineData(DashStyle.Custom + 1)] - public void DashStyle_SetInvalid_ThrowsInvalidEnumArgumentException(DashStyle dashStyle) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - Assert.ThrowsAny(() => pen.DashStyle = dashStyle); - } - } - - [Fact] - public void DashStyle_GetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.DashStyle); - AssertExtensions.Throws(null, () => pen.DashStyle = DashStyle.Dash); - } - } - - public static IEnumerable LineCap_Valid_TestData() - { - yield return new object[] { LineCap.Flat }; - yield return new object[] { LineCap.Square }; - yield return new object[] { LineCap.Round }; - yield return new object[] { LineCap.Triangle }; - yield return new object[] { LineCap.NoAnchor }; - yield return new object[] { LineCap.SquareAnchor }; - yield return new object[] { LineCap.RoundAnchor }; - yield return new object[] { LineCap.DiamondAnchor }; - yield return new object[] { LineCap.ArrowAnchor }; - yield return new object[] { LineCap.AnchorMask }; - yield return new object[] { LineCap.Custom }; - } - - [Theory] - [MemberData(nameof(LineCap_Valid_TestData))] - public void EndCap_SetValid_GetReturnsExpected(LineCap lineCap) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.EndCap = lineCap; - Assert.Equal(lineCap, pen.EndCap); - } - } - - public static IEnumerable LineCap_Invalid_TestData() - { - yield return new object[] { LineCap.Flat - 1 }; - yield return new object[] { LineCap.Triangle + 1 }; - yield return new object[] { LineCap.ArrowAnchor + 1 }; - yield return new object[] { LineCap.AnchorMask + 1 }; - yield return new object[] { LineCap.Custom + 1 }; - } - - [Theory] - [MemberData(nameof(LineCap_Invalid_TestData))] - public void EndCap_SetInvalid_ThrowsInvalidEnumArgumentException(LineCap lineCap) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - Assert.ThrowsAny(() => pen.EndCap = lineCap); - } - } - - [Fact] - public void EndCap_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.EndCap); - AssertExtensions.Throws(null, () => pen.EndCap = LineCap.ArrowAnchor); - } - } - - [Theory] - [InlineData(LineJoin.Bevel)] - [InlineData(LineJoin.Miter)] - [InlineData(LineJoin.MiterClipped)] - [InlineData(LineJoin.Round)] - public void LineJoin_SetValid_GetReturnsExpected(LineJoin lineJoin) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.LineJoin = lineJoin; - Assert.Equal(lineJoin, pen.LineJoin); - } - } - - [Theory] - [InlineData(LineJoin.Miter - 1)] - [InlineData(LineJoin.MiterClipped + 1)] - public void LineJoin_SetInvalid_ThrowsInvalidEnumArgumentException(LineJoin lineJoin) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - Assert.ThrowsAny(() => pen.LineJoin = lineJoin); - } - } - - [Fact] - public void LineJoin_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.LineJoin); - AssertExtensions.Throws(null, () => pen.LineJoin = LineJoin.Miter); - } - } - - [Theory] - [InlineData(-1, 1)] - [InlineData(0, 1)] - [InlineData(10, 10)] - [InlineData(float.NegativeInfinity, 1)] - [InlineData(float.PositiveInfinity, float.PositiveInfinity)] - [InlineData(float.NaN, float.NaN)] - public void MiterLimit_Set_GetReturnsExpected(float miterLimit, float expectedMiterLimit) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.MiterLimit = miterLimit; - Assert.Equal(expectedMiterLimit, pen.MiterLimit); - } - } - - [Fact] - public void MiterLimit_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.MiterLimit); - AssertExtensions.Throws(null, () => pen.MiterLimit = 10); - } - } - - public static IEnumerable MultiplyTransform_TestData() - { - yield return new object[] { new Matrix(), new Matrix(1, 2, 3, 4, 5, 6), MatrixOrder.Prepend }; - yield return new object[] { new Matrix(), new Matrix(1, 2, 3, 4, 5, 6), MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), new Matrix(2, 3, 4, 5, 6, 7), MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), new Matrix(2, 3, 4, 5, 6, 7), MatrixOrder.Append }; - } - - [Theory] - [MemberData(nameof(MultiplyTransform_TestData))] - public void MultiplyTransform_Matrix_SetsTransformToExpected(Matrix originalTransform, Matrix matrix, MatrixOrder matrixOrder) - { - try - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (Matrix expected = originalTransform.Clone()) - { - expected.Multiply(matrix, matrixOrder); - pen.Transform = originalTransform; - - if (matrixOrder == MatrixOrder.Prepend) - { - Pen clone = (Pen)pen.Clone(); - clone.MultiplyTransform(matrix); - Assert.Equal(expected, clone.Transform); - } - - pen.MultiplyTransform(matrix, matrixOrder); - Assert.Equal(expected, pen.Transform); - } - } - finally - { - originalTransform.Dispose(); - matrix.Dispose(); - } - } - - [Fact] - public void MultiplyTransform_NullMatrix_ThrowsArgumentNullException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - Assert.Throws(() => pen.MultiplyTransform(null)); - Assert.Throws(() => pen.MultiplyTransform(null, MatrixOrder.Prepend)); - } - } - - [Fact] - public void MultiplyTransform_NotInvertibleMatrix_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (var matrix = new Matrix(123, 24, 82, 16, 47, 30)) - { - AssertExtensions.Throws(null, () => pen.MultiplyTransform(matrix)); - AssertExtensions.Throws(null, () => pen.MultiplyTransform(matrix, MatrixOrder.Prepend)); - } - } - - [Fact] - public void MultiplyTransform_DisposedMatrix_Nop() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - pen.Transform = transform; - - var matrix = new Matrix(); - matrix.Dispose(); - - pen.MultiplyTransform(matrix); - pen.MultiplyTransform(matrix, MatrixOrder.Append); - - Assert.Equal(transform, pen.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void MultiplyTransform_InvalidOrder_Nop(MatrixOrder matrixOrder) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - using (var matrix = new Matrix()) - { - pen.Transform = transform; - - pen.MultiplyTransform(matrix, matrixOrder); - Assert.Equal(transform, pen.Transform); - } - } - - [Fact] - public void MultiplyTransform_Disposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var matrix = new Matrix()) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.MultiplyTransform(matrix)); - AssertExtensions.Throws(null, () => pen.MultiplyTransform(matrix, MatrixOrder.Prepend)); - } - } - - [Fact] - public void ResetTransform_Invoke_SetsTransformToZero() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - using (var matrix = new Matrix()) - { - pen.Transform = transform; - pen.ResetTransform(); - Assert.Equal(matrix, pen.Transform); - - pen.ResetTransform(); - Assert.Equal(matrix, pen.Transform); - } - } - - [Fact] - public void ResetTransform_Disposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var matrix = new Matrix()) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.ResetTransform()); - } - } - public static IEnumerable RotateTransform_TestData() - { - yield return new object[] { new Matrix(), 90, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(), 90, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 360, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 360, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -45, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -45, MatrixOrder.Append }; - } - - [Theory] - [MemberData(nameof(RotateTransform_TestData))] - public void RotateTransform_Invoke_SetsTransformToExpected(Matrix originalTransform, float angle, MatrixOrder matrixOrder) - { - using (originalTransform) - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (Matrix expected = originalTransform.Clone()) - { - expected.Rotate(angle, matrixOrder); - pen.Transform = originalTransform; - - if (matrixOrder == MatrixOrder.Prepend) - { - Pen clone = (Pen)pen.Clone(); - clone.RotateTransform(angle); - Assert.Equal(expected, clone.Transform); - } - - pen.RotateTransform(angle, matrixOrder); - Assert.Equal(expected, pen.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void RotateTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder matrixOrder) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws(null, () => pen.RotateTransform(10, matrixOrder)); - } - } - - [Fact] - public void RotateTransform_Disposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var matrix = new Matrix()) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.RotateTransform(1)); - AssertExtensions.Throws(null, () => pen.RotateTransform(1, MatrixOrder.Prepend)); - } - } - - public static IEnumerable ScaleTransform_TestData() - { - yield return new object[] { new Matrix(), 2, 3, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(), 2, 3, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, 0, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, 0, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 1, 1, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 1, 1, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -2, -3, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -2, -3, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0.5, 0.75, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0.5, 0.75, MatrixOrder.Append }; - } - - [Theory] - [MemberData(nameof(ScaleTransform_TestData))] - public void ScaleTransform_Invoke_SetsTransformToExpected(Matrix originalTransform, float scaleX, float scaleY, MatrixOrder matrixOrder) - { - using (originalTransform) - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (Matrix expected = originalTransform.Clone()) - { - expected.Scale(scaleX, scaleY, matrixOrder); - pen.Transform = originalTransform; - - if (matrixOrder == MatrixOrder.Prepend) - { - Pen clone = (Pen)pen.Clone(); - clone.ScaleTransform(scaleX, scaleY); - Assert.Equal(expected, clone.Transform); - } - - pen.ScaleTransform(scaleX, scaleY, matrixOrder); - Assert.Equal(expected, pen.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void ScaleTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder matrixOrder) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws(null, () => pen.ScaleTransform(1, 2, matrixOrder)); - } - } - - [Fact] - public void ScaleTransform_Disposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var matrix = new Matrix()) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.ScaleTransform(1, 2)); - AssertExtensions.Throws(null, () => pen.ScaleTransform(1, 2, MatrixOrder.Prepend)); - } - } - - [Theory] - [InlineData(LineCap.Flat, LineCap.Round, DashCap.Triangle)] - [InlineData(LineCap.Flat - 1, LineCap.Flat - 1, DashCap.Flat - 1)] - [InlineData((LineCap)int.MaxValue, (LineCap)int.MaxValue, (DashCap)int.MaxValue)] - public void SetLineCap_Invoke_Success(LineCap startCap, LineCap endCap, DashCap dashCap) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - // Make sure that if DashCap is invalid then it is reset to Flat. - if (Enum.IsDefined(typeof(DashCap), dashCap)) - { - pen.DashCap = DashCap.Round; - } - - pen.SetLineCap(startCap, endCap, dashCap); - Assert.Equal(startCap, pen.StartCap); - Assert.Equal(endCap, pen.EndCap); - Assert.Equal(Enum.IsDefined(typeof(DashCap), dashCap) ? dashCap : DashCap.Flat, pen.DashCap); - } - } - - [Fact] - public void SetLineCap_Disposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.SetLineCap(LineCap.AnchorMask, LineCap.ArrowAnchor, DashCap.Flat)); - } - } - - [Theory] - [MemberData(nameof(LineCap_Valid_TestData))] - public void StartCap_SetValid_GetReturnsExpected(LineCap lineCap) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.StartCap = lineCap; - Assert.Equal(lineCap, pen.StartCap); - } - } - - [Theory] - [MemberData(nameof(LineCap_Invalid_TestData))] - public void StartCap_SetInvalid_ThrowsInvalidEnumArgumentException(LineCap lineCap) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - Assert.ThrowsAny(() => pen.StartCap = lineCap); - } - } - - [Fact] - public void StartCap_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.StartCap); - AssertExtensions.Throws(null, () => pen.StartCap = LineCap.ArrowAnchor); - } - } - - [Fact] - public void Transform_SetValid_GetReturnsExpected() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (var matrix = new Matrix(1, 2, 3, 4, 5,6 )) - using (var expected = new Matrix(1, 2, 3, 4, 5, 6)) - { - pen.Transform = matrix; - Assert.Equal(matrix, pen.Transform); - - // The Matrix should be cloned. - matrix.Translate(1, 2); - Assert.Equal(expected, pen.Transform); - } - } - - [Fact] - public void Transform_SetNull_ThrowsArgumentNullException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws("value", () => pen.Transform = null); - } - } - - [Fact] - public void Transform_SetNotInvertible_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (var matrix = new Matrix(123, 24, 82, 16, 47, 30)) - { - AssertExtensions.Throws(null, () => pen.Transform = matrix); - } - } - - [Fact] - public void Transform_SetDisposedLineCap_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - var matrix = new Matrix(); - matrix.Dispose(); - - AssertExtensions.Throws(null, () => pen.Transform = matrix); - } - } - - [Fact] - public void Transform_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var matrix = new Matrix()) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.Transform); - AssertExtensions.Throws(null, () => pen.Transform = matrix); - } - } - - public static IEnumerable TranslateTransform_TestData() - { - yield return new object[] { new Matrix(), 2, 3, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(), 2, 3, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, 0, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, 0, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 1, 1, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 1, 1, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -2, -3, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -2, -3, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0.5, 0.75, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0.5, 0.75, MatrixOrder.Append }; - } - - [Theory] - [MemberData(nameof(TranslateTransform_TestData))] - public void TranslateTransform_Invoke_SetsTransformToExpected(Matrix originalTransform, float dX, float dY, MatrixOrder matrixOrder) - { - using (originalTransform) - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - using (Matrix expected = originalTransform.Clone()) - { - expected.Translate(dX, dY, matrixOrder); - pen.Transform = originalTransform; - - if (matrixOrder == MatrixOrder.Prepend) - { - Pen clone = (Pen)pen.Clone(); - clone.TranslateTransform(dX, dY); - Assert.Equal(expected, clone.Transform); - } - - pen.TranslateTransform(dX, dY, matrixOrder); - Assert.Equal(expected, pen.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void TranslateTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder matrixOrder) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - AssertExtensions.Throws(null, () => pen.TranslateTransform(1, 2, matrixOrder)); - } - } - - [Fact] - public void TranslateTransform_Disposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - using (var matrix = new Matrix()) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.TranslateTransform(1, 2)); - AssertExtensions.Throws(null, () => pen.TranslateTransform(1, 2, MatrixOrder.Prepend)); - } - } - - [Theory] - [InlineData(-10)] - [InlineData(0)] - [InlineData(10)] - [InlineData(float.NegativeInfinity)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NaN)] - public void Width_Set_GetReturnsExpected(float value) - { - using (var brush = new SolidBrush(Color.Red)) - using (var pen = new Pen(brush)) - { - pen.Width = value; - Assert.Equal(value, pen.Width); - } - } - - [Fact] - public void Width_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var brush = new SolidBrush(Color.Red)) - { - var pen = new Pen(brush); - pen.Dispose(); - - AssertExtensions.Throws(null, () => pen.Width); - AssertExtensions.Throws(null, () => pen.Width = 10); - } - } - - private void VerifyPen(Pen pen, PenType expectedPenType, float expectedWidth) where T : Brush - { - Assert.Equal(PenAlignment.Center, pen.Alignment); - - Assert.IsType(pen.Brush); - - Assert.Empty(pen.CompoundArray); - - AssertExtensions.Throws(null, () => pen.CustomEndCap); - AssertExtensions.Throws(null, () => pen.CustomStartCap); - - Assert.Equal(DashCap.Flat, pen.DashCap); - Assert.Equal(0, pen.DashOffset); - - Assert.Throws(() => pen.DashPattern); - - Assert.Equal(DashStyle.Solid, pen.DashStyle); - Assert.Equal(LineCap.Flat, pen.EndCap); - Assert.Equal(LineJoin.Miter, pen.LineJoin); - Assert.Equal(10, pen.MiterLimit); - Assert.Equal(expectedPenType, pen.PenType); - Assert.Equal(LineCap.Flat, pen.StartCap); - - using (var matrix = new Matrix()) - { - Assert.Equal(new Matrix(), pen.Transform); - } - Assert.Equal(expectedWidth, pen.Width); - } -} diff --git a/src/System.Drawing.Common/tests/PensTests.cs b/src/System.Drawing.Common/tests/PensTests.cs deleted file mode 100644 index 4ba1f4a094c..00000000000 --- a/src/System.Drawing.Common/tests/PensTests.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; - -namespace System.Drawing.Tests; - -public class PensTests -{ - public static IEnumerable Pens_TestData() - { - yield return Pen(() => Pens.AliceBlue, Color.AliceBlue); - yield return Pen(() => Pens.AntiqueWhite, Color.AntiqueWhite); - yield return Pen(() => Pens.Aqua, Color.Aqua); - yield return Pen(() => Pens.Aquamarine, Color.Aquamarine); - yield return Pen(() => Pens.Azure, Color.Azure); - yield return Pen(() => Pens.Beige, Color.Beige); - yield return Pen(() => Pens.Bisque, Color.Bisque); - yield return Pen(() => Pens.Black, Color.Black); - yield return Pen(() => Pens.BlanchedAlmond, Color.BlanchedAlmond); - yield return Pen(() => Pens.Blue, Color.Blue); - yield return Pen(() => Pens.BlueViolet, Color.BlueViolet); - yield return Pen(() => Pens.Brown, Color.Brown); - yield return Pen(() => Pens.BurlyWood, Color.BurlyWood); - yield return Pen(() => Pens.CadetBlue, Color.CadetBlue); - yield return Pen(() => Pens.Chartreuse, Color.Chartreuse); - yield return Pen(() => Pens.Chocolate, Color.Chocolate); - yield return Pen(() => Pens.Coral, Color.Coral); - yield return Pen(() => Pens.CornflowerBlue, Color.CornflowerBlue); - yield return Pen(() => Pens.Cornsilk, Color.Cornsilk); - yield return Pen(() => Pens.Crimson, Color.Crimson); - yield return Pen(() => Pens.Cyan, Color.Cyan); - yield return Pen(() => Pens.DarkBlue, Color.DarkBlue); - yield return Pen(() => Pens.DarkCyan, Color.DarkCyan); - yield return Pen(() => Pens.DarkGoldenrod, Color.DarkGoldenrod); - yield return Pen(() => Pens.DarkGray, Color.DarkGray); - yield return Pen(() => Pens.DarkGreen, Color.DarkGreen); - yield return Pen(() => Pens.DarkKhaki, Color.DarkKhaki); - yield return Pen(() => Pens.DarkMagenta, Color.DarkMagenta); - yield return Pen(() => Pens.DarkOliveGreen, Color.DarkOliveGreen); - yield return Pen(() => Pens.DarkOrange, Color.DarkOrange); - yield return Pen(() => Pens.DarkOrchid, Color.DarkOrchid); - yield return Pen(() => Pens.DarkRed, Color.DarkRed); - yield return Pen(() => Pens.DarkSalmon, Color.DarkSalmon); - yield return Pen(() => Pens.DarkSeaGreen, Color.DarkSeaGreen); - yield return Pen(() => Pens.DarkSlateBlue, Color.DarkSlateBlue); - yield return Pen(() => Pens.DarkSlateGray, Color.DarkSlateGray); - yield return Pen(() => Pens.DarkTurquoise, Color.DarkTurquoise); - yield return Pen(() => Pens.DarkViolet, Color.DarkViolet); - yield return Pen(() => Pens.DeepPink, Color.DeepPink); - yield return Pen(() => Pens.DeepSkyBlue, Color.DeepSkyBlue); - yield return Pen(() => Pens.DimGray, Color.DimGray); - yield return Pen(() => Pens.DodgerBlue, Color.DodgerBlue); - yield return Pen(() => Pens.Firebrick, Color.Firebrick); - yield return Pen(() => Pens.FloralWhite, Color.FloralWhite); - yield return Pen(() => Pens.ForestGreen, Color.ForestGreen); - yield return Pen(() => Pens.Fuchsia, Color.Fuchsia); - yield return Pen(() => Pens.Gainsboro, Color.Gainsboro); - yield return Pen(() => Pens.GhostWhite, Color.GhostWhite); - yield return Pen(() => Pens.Gold, Color.Gold); - yield return Pen(() => Pens.Goldenrod, Color.Goldenrod); - yield return Pen(() => Pens.Gray, Color.Gray); - yield return Pen(() => Pens.Green, Color.Green); - yield return Pen(() => Pens.GreenYellow, Color.GreenYellow); - yield return Pen(() => Pens.Honeydew, Color.Honeydew); - yield return Pen(() => Pens.HotPink, Color.HotPink); - yield return Pen(() => Pens.IndianRed, Color.IndianRed); - yield return Pen(() => Pens.Indigo, Color.Indigo); - yield return Pen(() => Pens.Ivory, Color.Ivory); - yield return Pen(() => Pens.Khaki, Color.Khaki); - yield return Pen(() => Pens.Lavender, Color.Lavender); - yield return Pen(() => Pens.LavenderBlush, Color.LavenderBlush); - yield return Pen(() => Pens.LawnGreen, Color.LawnGreen); - yield return Pen(() => Pens.LemonChiffon, Color.LemonChiffon); - yield return Pen(() => Pens.LightBlue, Color.LightBlue); - yield return Pen(() => Pens.LightCoral, Color.LightCoral); - yield return Pen(() => Pens.LightCyan, Color.LightCyan); - yield return Pen(() => Pens.LightGoldenrodYellow, Color.LightGoldenrodYellow); - yield return Pen(() => Pens.LightGray, Color.LightGray); - yield return Pen(() => Pens.LightGreen, Color.LightGreen); - yield return Pen(() => Pens.LightPink, Color.LightPink); - yield return Pen(() => Pens.LightSalmon, Color.LightSalmon); - yield return Pen(() => Pens.LightSeaGreen, Color.LightSeaGreen); - yield return Pen(() => Pens.LightSkyBlue, Color.LightSkyBlue); - yield return Pen(() => Pens.LightSlateGray, Color.LightSlateGray); - yield return Pen(() => Pens.LightSteelBlue, Color.LightSteelBlue); - yield return Pen(() => Pens.LightYellow, Color.LightYellow); - yield return Pen(() => Pens.Lime, Color.Lime); - yield return Pen(() => Pens.LimeGreen, Color.LimeGreen); - yield return Pen(() => Pens.Linen, Color.Linen); - yield return Pen(() => Pens.Magenta, Color.Magenta); - yield return Pen(() => Pens.Maroon, Color.Maroon); - yield return Pen(() => Pens.MediumAquamarine, Color.MediumAquamarine); - yield return Pen(() => Pens.MediumBlue, Color.MediumBlue); - yield return Pen(() => Pens.MediumOrchid, Color.MediumOrchid); - yield return Pen(() => Pens.MediumPurple, Color.MediumPurple); - yield return Pen(() => Pens.MediumSeaGreen, Color.MediumSeaGreen); - yield return Pen(() => Pens.MediumSlateBlue, Color.MediumSlateBlue); - yield return Pen(() => Pens.MediumSpringGreen, Color.MediumSpringGreen); - yield return Pen(() => Pens.MediumTurquoise, Color.MediumTurquoise); - yield return Pen(() => Pens.MediumVioletRed, Color.MediumVioletRed); - yield return Pen(() => Pens.MidnightBlue, Color.MidnightBlue); - yield return Pen(() => Pens.MintCream, Color.MintCream); - yield return Pen(() => Pens.MistyRose, Color.MistyRose); - yield return Pen(() => Pens.Moccasin, Color.Moccasin); - yield return Pen(() => Pens.NavajoWhite, Color.NavajoWhite); - yield return Pen(() => Pens.Navy, Color.Navy); - yield return Pen(() => Pens.OldLace, Color.OldLace); - yield return Pen(() => Pens.Olive, Color.Olive); - yield return Pen(() => Pens.OliveDrab, Color.OliveDrab); - yield return Pen(() => Pens.Orange, Color.Orange); - yield return Pen(() => Pens.OrangeRed, Color.OrangeRed); - yield return Pen(() => Pens.Orchid, Color.Orchid); - yield return Pen(() => Pens.PaleGoldenrod, Color.PaleGoldenrod); - yield return Pen(() => Pens.PaleGreen, Color.PaleGreen); - yield return Pen(() => Pens.PaleTurquoise, Color.PaleTurquoise); - yield return Pen(() => Pens.PaleVioletRed, Color.PaleVioletRed); - yield return Pen(() => Pens.PapayaWhip, Color.PapayaWhip); - yield return Pen(() => Pens.PeachPuff, Color.PeachPuff); - yield return Pen(() => Pens.Peru, Color.Peru); - yield return Pen(() => Pens.Pink, Color.Pink); - yield return Pen(() => Pens.Plum, Color.Plum); - yield return Pen(() => Pens.PowderBlue, Color.PowderBlue); - yield return Pen(() => Pens.Purple, Color.Purple); - yield return Pen(() => Pens.Red, Color.Red); - yield return Pen(() => Pens.RosyBrown, Color.RosyBrown); - yield return Pen(() => Pens.RoyalBlue, Color.RoyalBlue); - yield return Pen(() => Pens.SaddleBrown, Color.SaddleBrown); - yield return Pen(() => Pens.Salmon, Color.Salmon); - yield return Pen(() => Pens.SandyBrown, Color.SandyBrown); - yield return Pen(() => Pens.SeaGreen, Color.SeaGreen); - yield return Pen(() => Pens.SeaShell, Color.SeaShell); - yield return Pen(() => Pens.Sienna, Color.Sienna); - yield return Pen(() => Pens.Silver, Color.Silver); - yield return Pen(() => Pens.SkyBlue, Color.SkyBlue); - yield return Pen(() => Pens.SlateBlue, Color.SlateBlue); - yield return Pen(() => Pens.SlateGray, Color.SlateGray); - yield return Pen(() => Pens.Snow, Color.Snow); - yield return Pen(() => Pens.SpringGreen, Color.SpringGreen); - yield return Pen(() => Pens.SteelBlue, Color.SteelBlue); - yield return Pen(() => Pens.Tan, Color.Tan); - yield return Pen(() => Pens.Teal, Color.Teal); - yield return Pen(() => Pens.Thistle, Color.Thistle); - yield return Pen(() => Pens.Tomato, Color.Tomato); - yield return Pen(() => Pens.Transparent, Color.Transparent); - yield return Pen(() => Pens.Turquoise, Color.Turquoise); - yield return Pen(() => Pens.Violet, Color.Violet); - yield return Pen(() => Pens.Wheat, Color.Wheat); - yield return Pen(() => Pens.White, Color.White); - yield return Pen(() => Pens.WhiteSmoke, Color.WhiteSmoke); - yield return Pen(() => Pens.Yellow, Color.Yellow); - yield return Pen(() => Pens.YellowGreen, Color.YellowGreen); - } - - public static object[] Pen(Func getPen, Color expectedColor) => new object[] { getPen, expectedColor }; - - [Theory] - [MemberData(nameof(Pens_TestData))] - public void Pens_Get_ReturnsExpected(Func getPen, Color expectedColor) - { - Pen pen = getPen(); - Assert.Equal(expectedColor, pen.Color); - Assert.Equal(PenType.SolidColor, pen.PenType); - AssertExtensions.Throws(null, () => pen.Color = Color.AliceBlue); - - Assert.Same(pen, getPen()); - } -} diff --git a/src/System.Drawing.Common/tests/Printing/MarginsTests.cs b/src/System.Drawing.Common/tests/Printing/MarginsTests.cs deleted file mode 100644 index 2847548673b..00000000000 --- a/src/System.Drawing.Common/tests/Printing/MarginsTests.cs +++ /dev/null @@ -1,246 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Authors: -// Sebastien Pouliot -// -// Copyright (C) 2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -namespace System.Drawing.Printing.Tests; - -public class MarginsTests -{ - [Fact] - public void Ctor_Default() - { - var margins = new Margins(); - Assert.Equal(100, margins.Left); - Assert.Equal(100, margins.Top); - Assert.Equal(100, margins.Right); - Assert.Equal(100, margins.Bottom); - } - - [Theory] - [InlineData(int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue)] - [InlineData(0, 1, 2, 3)] - [InlineData(0, 0, 0, 0)] - public void Ctor_Bounds(int left, int right, int top, int bottom) - { - var margins = new Margins(left, right, top, bottom); - Assert.Equal(left, margins.Left); - Assert.Equal(right, margins.Right); - Assert.Equal(top, margins.Top); - Assert.Equal(bottom, margins.Bottom); - } - - [Fact] - public void Ctor_NegativeLeft_ThrowsArgumentOutOfRangeException() - { - AssertExtensions.Throws("left", null, () => new Margins(-1, 2, 3, 4)); - } - - [Fact] - public void Ctor_NegativeRight_ThrowsArgumentOutOfRangeException() - { - AssertExtensions.Throws("right", null, () => new Margins(1, -1, 3, 4)); - } - - [Fact] - public void Ctor_NegativeTop_ThrowsArgumentOutOfRangeException() - { - AssertExtensions.Throws("top", null, () => new Margins(1, 2, -1, 4)); - } - - [Fact] - public void Ctor_NegativeBottom_ThrowsArgumentOutOfRangeException() - { - AssertExtensions.Throws("bottom", null, () => new Margins(1, 2, 3, -1)); - } - - public static IEnumerable Equals_Object_TestData() - { - var margins = new Margins(1, 2, 3, 4); - yield return new object[] { margins, margins, true }; - yield return new object[] { margins, new Margins(1, 2, 3, 4), true }; - yield return new object[] { margins, new Margins(2, 2, 3, 4), false }; - yield return new object[] { margins, new Margins(1, 3, 3, 4), false }; - yield return new object[] { margins, new Margins(1, 2, 4, 4), false }; - yield return new object[] { margins, new Margins(1, 2, 3, 5), false }; - - yield return new object[] { margins, new object(), false }; - yield return new object[] { margins, null, false }; - } - - [Theory] - [MemberData(nameof(Equals_Object_TestData))] - public void Equals_InvokeObject_ReturnsExpected(Margins margins, object obj, bool expected) - { - Assert.Equal(expected, margins.Equals(obj)); - if (obj is Margins) - { - Assert.Equal(expected, margins.GetHashCode().Equals(obj.GetHashCode())); - } - } - - public static IEnumerable Equals_Margin_TestData() - { - var margins = new Margins(1, 2, 3, 4); - yield return new object[] { margins, margins, true }; - yield return new object[] { margins, new Margins(1, 2, 3, 4), true }; - yield return new object[] { margins, new Margins(2, 2, 3, 4), false }; - yield return new object[] { margins, new Margins(1, 3, 3, 4), false }; - yield return new object[] { margins, new Margins(1, 2, 4, 4), false }; - yield return new object[] { margins, new Margins(1, 2, 3, 5), false }; - - yield return new object[] { null, null, true }; - yield return new object[] { null, new Margins(1, 2, 3, 4), false }; - yield return new object[] { new Margins(1, 2, 3, 4), null, false }; - } - - [Theory] - [MemberData(nameof(Equals_Margin_TestData))] - public void Equals_InvokeMargin_ReturnsExpected(Margins margins1, Margins margins2, bool expected) - { - Assert.Equal(expected, margins1 == margins2); - Assert.Equal(!expected, margins1 != margins2); - } - - public static IEnumerable ToString_TestData() - { - yield return new object[] { new Margins(), "[Margins Left=100 Right=100 Top=100 Bottom=100]" }; - yield return new object[] { new Margins(1, 2, 3, 4), "[Margins Left=1 Right=2 Top=3 Bottom=4]" }; - } - - [Theory] - [MemberData(nameof(ToString_TestData))] - public void ToString_Invoke_ReturnsExpected(Margins margins, string expected) - { - Assert.Equal(expected, margins.ToString()); - } - - [Fact] - public void Clone_Invoke_ReturnsExpected() - { - var margins = new Margins(1, 2, 3, 4); - Margins clonedMargins = Assert.IsType(margins.Clone()); - Assert.NotSame(margins, clonedMargins); - Assert.Equal(1, clonedMargins.Left); - Assert.Equal(2, clonedMargins.Right); - Assert.Equal(3, clonedMargins.Top); - Assert.Equal(4, clonedMargins.Bottom); - } - - public static IEnumerable Bounds_Set_TestData() - { - yield return new object[] { 0 }; - yield return new object[] { 10 }; - yield return new object[] { int.MaxValue }; - } - - [Theory] - [MemberData(nameof(Bounds_Set_TestData))] - public void Left_Set_GetReturnsExpected(int value) - { - var margins = new Margins - { - Left = value - }; - Assert.Equal(value, margins.Left); - - // Set same. - margins.Left = value; - Assert.Equal(value, margins.Left); - } - - [Fact] - public void Left_SetNegative_ThrowsArgumentOutOfRangeException() - { - var margins = new Margins(); - AssertExtensions.Throws("value", null, () => margins.Left = -1); - } - - [Theory] - [MemberData(nameof(Bounds_Set_TestData))] - public void Right_Set_GetReturnsExpected(int value) - { - var margins = new Margins - { - Right = value - }; - Assert.Equal(value, margins.Right); - - // Set same. - margins.Right = value; - Assert.Equal(value, margins.Right); - } - - [Fact] - public void Right_SetNegative_ThrowsArgumentOutOfRangeException() - { - var margins = new Margins(); - AssertExtensions.Throws("value", null, () => margins.Right = -1); - } - - [Theory] - [MemberData(nameof(Bounds_Set_TestData))] - public void Top_Set_GetReturnsExpected(int value) - { - var margins = new Margins - { - Top = value - }; - Assert.Equal(value, margins.Top); - - // Set same. - margins.Top = value; - Assert.Equal(value, margins.Top); - } - - [Fact] - public void Top_SetNegative_ThrowsArgumentOutOfRangeException() - { - var margins = new Margins(); - AssertExtensions.Throws("value", null, () => margins.Top = -1); - } - - [Theory] - [MemberData(nameof(Bounds_Set_TestData))] - public void Bottom_Set_GetReturnsExpected(int value) - { - var margins = new Margins - { - Bottom = value - }; - Assert.Equal(value, margins.Bottom); - - // Set same. - margins.Bottom = value; - Assert.Equal(value, margins.Bottom); - } - - [Fact] - public void Bottom_SetNegative_ThrowsArgumentOutOfRangeException() - { - var margins = new Margins(); - AssertExtensions.Throws("value", null, () => margins.Bottom = -1); - } -} diff --git a/src/System.Drawing.Common/tests/Printing/PageSettingsTests.cs b/src/System.Drawing.Common/tests/Printing/PageSettingsTests.cs deleted file mode 100644 index 6020b8f96dd..00000000000 --- a/src/System.Drawing.Common/tests/Printing/PageSettingsTests.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// Author: -// -// Jordi Mas i Hernandez (jordi@ximian.com) -// - -namespace System.Drawing.Printing.Tests; - -public class PageSettingsTests -{ - [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void Clone_Success() - { - PageSettings ps = new PageSettings(); - ps.Color = false; - ps.Landscape = true; - ps.Margins = new Margins(120, 130, 140, 150); - ps.PaperSize = new PaperSize("My Custom Size", 222, 333); - PageSettings clone = (PageSettings)ps.Clone(); - - Assert.Equal(ps.Color, clone.Color); - Assert.Equal(ps.Landscape, clone.Landscape); - Assert.Equal(ps.Margins, clone.Margins); - Assert.Same(ps.PrinterSettings, clone.PrinterSettings); - - // PaperSize - Assert.Equal(ps.PaperSize.PaperName, clone.PaperSize.PaperName); - Assert.Equal(ps.PaperSize.Width, clone.PaperSize.Width); - Assert.Equal(ps.PaperSize.Height, clone.PaperSize.Height); - Assert.Equal(ps.PaperSize.Kind, clone.PaperSize.Kind); - - // PrinterResolution - Assert.Equal(ps.PrinterResolution.X, clone.PrinterResolution.X); - Assert.Equal(ps.PrinterResolution.Y, clone.PrinterResolution.Y); - Assert.Equal(ps.PrinterResolution.Kind, clone.PrinterResolution.Kind); - - // PaperSource - Assert.Equal(ps.PaperSource.Kind, clone.PaperSource.Kind); - Assert.Equal(ps.PaperSource.SourceName, clone.PaperSource.SourceName); - } -} diff --git a/src/System.Drawing.Common/tests/Printing/PaperSizeTests.cs b/src/System.Drawing.Common/tests/Printing/PaperSizeTests.cs deleted file mode 100644 index 68b7a97cda9..00000000000 --- a/src/System.Drawing.Common/tests/Printing/PaperSizeTests.cs +++ /dev/null @@ -1,230 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Copyright (C) 2009 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// Author: -// Andy Hume -// - -namespace System.Drawing.Printing.Tests; - -public class PaperSizeTests -{ - [Fact] - public void Ctor_Default() - { - var size = new PaperSize(); - Assert.Equal(PaperKind.Custom, size.Kind); - Assert.Equal(0, size.Height); - Assert.Empty(size.PaperName); - Assert.Equal(0, size.RawKind); - Assert.Equal(0, size.Width); - } - - [Theory] - [InlineData(null, -1, -2)] - [InlineData("", 0, 0)] - [InlineData("name", 100, 200)] - public void Ctor_String_Int_Int(string name, int width, int height) - { - var size = new PaperSize(name, width, height); - Assert.Equal(PaperKind.Custom, size.Kind); - Assert.Equal(height, size.Height); - Assert.Equal(name, size.PaperName); - Assert.Equal(0, size.RawKind); - Assert.Equal(width, size.Width); - } - - public static IEnumerable RawKind_TestData() - { - yield return new object[] { (int)PaperKind.A4 }; - yield return new object[] { (int)PaperKind.JapaneseEnvelopeKakuNumber3 }; - yield return new object[] { (int)PaperKind.Custom }; - yield return new object[] { 999999 }; - yield return new object[] { int.MaxValue }; - yield return new object[] { -1 }; - yield return new object[] { int.MinValue }; - yield return new object[] { 2 }; - yield return new object[] { 1 + (int)PaperKind.PrcEnvelopeNumber10Rotated }; - } - - public static IEnumerable Height_Set_TestData() - { - foreach (object[] testData in RawKind_TestData()) - { - yield return new object[] { testData[0], -1 }; - yield return new object[] { testData[0], 0 }; - yield return new object[] { testData[0], 100 }; - } - } - - [Theory] - [MemberData(nameof(Height_Set_TestData))] - public void Height_Set_GetReturnsExpected(int rawKind, int value) - { - var size = new PaperSize - { - RawKind = rawKind, - Height = value - }; - Assert.Equal(value, size.Height); - - // Set same. - size.Height = value; - Assert.Equal(value, size.Height); - } - - public static IEnumerable NonCustomRawKind_TestData() - { - yield return new object[] { (int)PaperKind.A4 }; - yield return new object[] { (int)PaperKind.JapaneseEnvelopeKakuNumber3 }; - yield return new object[] { 999999 }; - yield return new object[] { int.MaxValue }; - yield return new object[] { -1 }; - yield return new object[] { int.MinValue }; - yield return new object[] { 1 + (int)PaperKind.PrcEnvelopeNumber10Rotated }; - } - - [Theory] - [MemberData(nameof(NonCustomRawKind_TestData))] - public void Height_SetNonCustomKindConstructor_ThrowsArgumentException(int rawKind) - { - var size = new PaperSize("name", 100, 200) - { - RawKind = rawKind - }; - AssertExtensions.Throws("value", null, () => size.Height = 1); - } - - public static IEnumerable PaperName_Set_TestData() - { - foreach (object[] testData in RawKind_TestData()) - { - yield return new object[] { testData[0], null }; - yield return new object[] { testData[0], string.Empty }; - yield return new object[] { testData[0], "name" }; - } - } - - [Theory] - [MemberData(nameof(PaperName_Set_TestData))] - public void PaperName_Set_GetReturnsExpected(int rawKind, string value) - { - var size = new PaperSize - { - RawKind = rawKind, - PaperName = value - }; - Assert.Equal(value, size.PaperName); - - // Set same. - size.PaperName = value; - Assert.Equal(value, size.PaperName); - } - - [Theory] - [MemberData(nameof(NonCustomRawKind_TestData))] - public void PaperName_SetNonCustomKindConstructor_ThrowsArgumentException(int rawKind) - { - var size = new PaperSize("name", 100, 200) - { - RawKind = rawKind - }; - AssertExtensions.Throws("value", null, () => size.PaperName = "name"); - } - - [Theory] - [InlineData((int)PaperKind.Custom, PaperKind.Custom)] - [InlineData((int)PaperKind.A4, PaperKind.A4)] - [InlineData((int)PaperKind.JapaneseEnvelopeKakuNumber3, PaperKind.JapaneseEnvelopeKakuNumber3)] - [InlineData(999999, PaperKind.Custom)] - [InlineData(int.MaxValue, PaperKind.Custom)] - [InlineData(1 + (int)PaperKind.PrcEnvelopeNumber10Rotated, PaperKind.Custom)] - [InlineData(-1, (PaperKind)(-1))] - [InlineData(int.MinValue, (PaperKind)int.MinValue)] - public void RawKind_Set_GetReturnsExpected(int value, PaperKind expectedKind) - { - var size = new PaperSize - { - RawKind = value - }; - Assert.Equal(value, size.RawKind); - Assert.Equal(expectedKind, size.Kind); - - // Set same. - size.RawKind = value; - Assert.Equal(value, size.RawKind); - Assert.Equal(expectedKind, size.Kind); - } - - public static IEnumerable Width_Set_TestData() - { - foreach (object[] testData in RawKind_TestData()) - { - yield return new object[] { testData[0], -1 }; - yield return new object[] { testData[0], 0 }; - yield return new object[] { testData[0], 100 }; - } - } - - [Theory] - [MemberData(nameof(Width_Set_TestData))] - public void Width_Set_GetReturnsExpected(int rawKind, int value) - { - var size = new PaperSize - { - RawKind = rawKind, - Width = value - }; - Assert.Equal(value, size.Width); - - // Set same. - size.Width = value; - Assert.Equal(value, size.Width); - } - - [Theory] - [MemberData(nameof(NonCustomRawKind_TestData))] - public void Width_SetNonCustomKindConstructor_ThrowsArgumentException(int rawKind) - { - var size = new PaperSize("name", 100, 200) - { - RawKind = rawKind - }; - AssertExtensions.Throws("value", null, () => size.Width = 1); - } - - public static IEnumerable ToString_TestData() - { - yield return new object[] { new PaperSize(), "[PaperSize Kind=Custom Height=0 Width=0]" }; - yield return new object[] { new PaperSize("name", 1, 2), "[PaperSize name Kind=Custom Height=2 Width=1]" }; - yield return new object[] { new PaperSize("name", -1, -2), "[PaperSize name Kind=Custom Height=-2 Width=-1]" }; - } - - [Theory] - [MemberData(nameof(ToString_TestData))] - public void ToString_Invoke_ReturnsExpected(PaperSize size, string expected) - { - Assert.Equal(expected, size.ToString()); - } -} diff --git a/src/System.Drawing.Common/tests/Printing/PaperSourceTests.cs b/src/System.Drawing.Common/tests/Printing/PaperSourceTests.cs deleted file mode 100644 index f0a84bcb425..00000000000 --- a/src/System.Drawing.Common/tests/Printing/PaperSourceTests.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2009 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// Author: -// Andy Hume -// - -namespace System.Drawing.Printing.Tests; - -public class PaperSourceTests -{ - [Fact] - public void Ctor_Default() - { - var source = new PaperSource(); - Assert.Equal(PaperSourceKind.Custom, source.Kind); - Assert.Equal((int)PaperSourceKind.Custom, source.RawKind); - Assert.Empty(source.SourceName); - } - - [Theory] - [InlineData((int)PaperSourceKind.Custom, PaperSourceKind.Custom)] - [InlineData((int)PaperSourceKind.Upper, PaperSourceKind.Upper)] - [InlineData((int)PaperSourceKind.TractorFeed, PaperSourceKind.TractorFeed)] - [InlineData((int)PaperSourceKind.SmallFormat, PaperSourceKind.SmallFormat)] - [InlineData((int)PaperSourceKind.Middle, PaperSourceKind.Middle)] - [InlineData((int)PaperSourceKind.ManualFeed, PaperSourceKind.ManualFeed)] - [InlineData((int)PaperSourceKind.Manual, PaperSourceKind.Manual)] - [InlineData((int)PaperSourceKind.Lower, PaperSourceKind.Lower)] - [InlineData((int)PaperSourceKind.LargeFormat, PaperSourceKind.LargeFormat)] - [InlineData((int)PaperSourceKind.LargeCapacity, PaperSourceKind.LargeCapacity)] - [InlineData((int)PaperSourceKind.FormSource, PaperSourceKind.FormSource)] - [InlineData((int)PaperSourceKind.Envelope, PaperSourceKind.Envelope)] - [InlineData((int)PaperSourceKind.Cassette, PaperSourceKind.Cassette)] - [InlineData((int)PaperSourceKind.AutomaticFeed, PaperSourceKind.AutomaticFeed)] - [InlineData(int.MaxValue, PaperSourceKind.Custom)] - [InlineData(int.MinValue, (PaperSourceKind)int.MinValue)] - [InlineData(0, (PaperSourceKind)0)] - [InlineData(256, PaperSourceKind.Custom)] - public void RawKind_Set_GetReturnsExpected(int value, PaperSourceKind expectedKind) - { - var source = new PaperSource - { - RawKind = value - }; - Assert.Equal(value, source.RawKind); - Assert.Equal(expectedKind, source.Kind); - - // Set same. - source.RawKind = value; - Assert.Equal(value, source.RawKind); - Assert.Equal(expectedKind, source.Kind); - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("sourceName")] - public void SourceName_Set_GetReturnsExpected(string value) - { - var source = new PaperSource - { - SourceName = value - }; - Assert.Equal(value, source.SourceName); - - // Set same. - source.SourceName = value; - Assert.Equal(value, source.SourceName); - } -} diff --git a/src/System.Drawing.Common/tests/Printing/PreviewPrintControllerTests.cs b/src/System.Drawing.Common/tests/Printing/PreviewPrintControllerTests.cs deleted file mode 100644 index 2aef7a3b73d..00000000000 --- a/src/System.Drawing.Common/tests/Printing/PreviewPrintControllerTests.cs +++ /dev/null @@ -1,139 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Printing.Tests; - -public class PreviewPrintControllerTests -{ - [Fact] - public void Ctor_Default() - { - var controller = new PreviewPrintController(); - Assert.True(controller.IsPreview); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void OnStartPage_InvokeWithPrint_ReturnsNull() - { - using (var document = new PrintDocument()) - { - var controller = new PreviewPrintController(); - controller.OnStartPrint(document, new PrintEventArgs()); - - var printEventArgs = new PrintPageEventArgs(null, Rectangle.Empty, Rectangle.Empty, new PageSettings()); - Assert.NotNull(controller.OnStartPage(document, printEventArgs)); - - // Call OnEndPage. - controller.OnEndPage(document, printEventArgs); - - // Call EndPrint. - controller.OnEndPrint(document, new PrintEventArgs()); - } - } - - [Fact] - public void OnStartPage_InvokeNullDocument_ThrowsNullReferenceException() - { - var controller = new PreviewPrintController(); - var e = new PrintPageEventArgs(null, Rectangle.Empty, Rectangle.Empty, null); - Assert.Throws(() => controller.OnStartPage(null, e)); - } - - [Fact] - public void OnStartPage_InvokeNullEventArgs_ThrowsNullReferenceException() - { - using (var document = new PrintDocument()) - { - var controller = new PreviewPrintController(); - Assert.Throws(() => controller.OnStartPage(document, null)); - } - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void OnStartPage_InvokeNullEventArgsPageSettings_ReturnsNull() - { - using (var document = new PrintDocument()) - { - var controller = new PreviewPrintController(); - controller.OnStartPrint(document, new PrintEventArgs()); - - var printEventArgs = new PrintPageEventArgs(null, Rectangle.Empty, Rectangle.Empty, null); - Assert.Throws(() => controller.OnStartPage(document, printEventArgs)); - } - } - - [Fact] - public void OnStartPage_PrintNotStarted_ThrowsNullReferenceException() - { - using (var document = new PrintDocument()) - { - var controller = new PreviewPrintController(); - var e = new PrintPageEventArgs(null, Rectangle.Empty, Rectangle.Empty, null); - Assert.Throws(() => controller.OnStartPage(document, e)); - } - } - - [Fact] - public void OnEndPage_InvokeWithoutStarting_Nop() - { - using (var document = new PrintDocument()) - { - var controller = new PreviewPrintController(); - controller.OnEndPage(document, new PrintPageEventArgs(null, Rectangle.Empty, Rectangle.Empty, null)); - controller.OnEndPage(null, null); - } - } - - public static IEnumerable PrintEventArgs_TestData() - { - yield return new object[] { null }; - yield return new object[] { new PrintEventArgs() }; - } - - [ConditionalTheory(Helpers.AnyInstalledPrinters)] - [MemberData(nameof(PrintEventArgs_TestData))] - public void OnStartPrint_InvokeWithDocument_Success(PrintEventArgs e) - { - using (var document = new PrintDocument()) - { - var controller = new PreviewPrintController(); - controller.OnStartPrint(document, e); - - // Call OnEndPrint - controller.OnEndPrint(document, e); - } - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void OnStartPrint_InvokeMultipleTimes_Success() - { - using (var document = new PrintDocument()) - { - var controller = new PreviewPrintController(); - controller.OnStartPrint(document, new PrintEventArgs()); - controller.OnStartPrint(document, new PrintEventArgs()); - - // Call OnEndPrint - controller.OnEndPrint(document, new PrintEventArgs()); - } - } - - [Fact] - public void OnStartPrint_InvokeNullDocument_ThrowsNullReferenceException() - { - var controller = new PreviewPrintController(); - Assert.Throws(() => controller.OnStartPrint(null, new PrintEventArgs())); - } - - [Theory] - [MemberData(nameof(PrintEventArgs_TestData))] - public void OnEndPrint_InvokeWithoutStarting_Nop(PrintEventArgs e) - { - using (var document = new PrintDocument()) - { - var controller = new PreviewPrintController(); - controller.OnEndPrint(document, e); - controller.OnEndPrint(null, e); - } - } -} diff --git a/src/System.Drawing.Common/tests/Printing/PrintControllerTests.cs b/src/System.Drawing.Common/tests/Printing/PrintControllerTests.cs deleted file mode 100644 index 343f37c24a8..00000000000 --- a/src/System.Drawing.Common/tests/Printing/PrintControllerTests.cs +++ /dev/null @@ -1,113 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Printing.Tests; - -public class PrintControllerTests -{ - [Fact] - public void Ctor_Default() - { - var controller = new SubPrintController(); - Assert.False(controller.IsPreview); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void OnStartPage_InvokeWithPrint_ReturnsNull() - { - using (var document = new PrintDocument()) - { - var controller = new SubPrintController(); - controller.OnStartPrint(document, new PrintEventArgs()); - - var printEventArgs = new PrintPageEventArgs(null, Rectangle.Empty, Rectangle.Empty, null); - Assert.Null(controller.OnStartPage(document, printEventArgs)); - - // Call OnEndPage. - controller.OnEndPage(document, printEventArgs); - - // Call EndPrint. - controller.OnEndPrint(document, new PrintEventArgs()); - } - } - - [Fact] - public void OnStartPage_Invoke_ReturnsNull() - { - using (var document = new PrintDocument()) - { - var controller = new SubPrintController(); - Assert.Null(controller.OnStartPage(document, new PrintPageEventArgs(null, Rectangle.Empty, Rectangle.Empty, null))); - Assert.Null(controller.OnStartPage(null, null)); - } - } - - [Fact] - public void OnEndPage_InvokeWithoutStarting_Nop() - { - using (var document = new PrintDocument()) - { - var controller = new SubPrintController(); - controller.OnEndPage(document, new PrintPageEventArgs(null, Rectangle.Empty, Rectangle.Empty, null)); - controller.OnEndPage(null, null); - } - } - - public static IEnumerable PrintEventArgs_TestData() - { - yield return new object[] { null }; - yield return new object[] { new PrintEventArgs() }; - } - - [Theory] - [MemberData(nameof(PrintEventArgs_TestData))] - public void OnStartPrint_InvokeWithDocument_Success(PrintEventArgs e) - { - using (var document = new PrintDocument()) - { - var controller = new SubPrintController(); - controller.OnStartPrint(document, e); - - // Call OnEndPrint - controller.OnEndPrint(document, e); - } - } - - [Theory] - [MemberData(nameof(PrintEventArgs_TestData))] - public void OnStartPrint_InvokeWithDocumentSeveralTimes_Success(PrintEventArgs e) - { - using (var document = new PrintDocument()) - { - var controller = new SubPrintController(); - controller.OnStartPrint(document, e); - controller.OnStartPrint(document, e); - - // Call OnEndPrint - controller.OnEndPrint(document, e); - } - } - - [Fact] - public void OnStartPrint_InvokeNullDocument_ThrowsNullReferenceException() - { - var controller = new SubPrintController(); - Assert.Throws(() => controller.OnStartPrint(null, new PrintEventArgs())); - } - - [Theory] - [MemberData(nameof(PrintEventArgs_TestData))] - public void OnEndPrint_InvokeWithoutStarting_Nop(PrintEventArgs e) - { - using (var document = new PrintDocument()) - { - var controller = new SubPrintController(); - controller.OnEndPrint(document, e); - controller.OnEndPrint(null, e); - } - } - - private class SubPrintController : PrintController - { - } -} diff --git a/src/System.Drawing.Common/tests/Printing/PrintDocumentTests.cs b/src/System.Drawing.Common/tests/Printing/PrintDocumentTests.cs deleted file mode 100644 index 9af2b3e48e7..00000000000 --- a/src/System.Drawing.Common/tests/Printing/PrintDocumentTests.cs +++ /dev/null @@ -1,317 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2005-2006 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace System.Drawing.Printing.Tests; - -public class PrintDocumentTests : FileCleanupTestBase -{ - private readonly PageSettings _pageSettings = new() - { - PaperSize = new PaperSize() - { - RawKind = (int)PaperKind.A3 - } - }; - - [ConditionalFact(Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void Ctor_Default_Success() - { - using (var document = new PrintDocument()) - { - Assert.Equal("document", document.DocumentName); - Assert.False(document.OriginAtMargins); - AssertDefaultPageSettings(document.DefaultPageSettings); - } - } - - [ConditionalFact(Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void DefaultPageSettings_SetValue_ReturnsExpected() - { - using (var document = new PrintDocument()) - { - document.DefaultPageSettings = null; - Assert.IsAssignableFrom(document.DefaultPageSettings); - - document.DefaultPageSettings = _pageSettings; - Assert.Equal(_pageSettings.PaperSize.Kind, _pageSettings.PaperSize.Kind); - } - } - - [Fact] - [ActiveIssue("https://github.com/dotnet/winforms/issues/8812")] - public void DefaultPageSettings_Null_ReturnsExpected() - { - using (var document = new PrintDocument()) - { - document.DefaultPageSettings = null; - AssertDefaultPageSettings(document.DefaultPageSettings); - } - } - - [Theory] - [InlineData("")] - [InlineData("newDocument")] - public void DocumentName_SetValue_ReturnsExpected(string documentName) - { - using (var document = new PrintDocument()) - { - document.DocumentName = documentName; - Assert.Equal(documentName, document.DocumentName); - } - } - - [Fact] - public void DocumentName_Null_ReturnsExpected() - { - using (var document = new PrintDocument()) - { - document.DocumentName = null; - Assert.Equal(string.Empty, document.DocumentName); - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void OriginAtMargins_SetValue_ReturnsExpected(bool originAtMargins) - { - using (var document = new PrintDocument()) - { - document.OriginAtMargins = originAtMargins; - Assert.Equal(originAtMargins, document.OriginAtMargins); - } - } - - [Fact] - public void PrintController_SetValue_ReturnsExpected() - { - using (var document = new PrintDocument()) - { - document.PrintController = null; - Assert.NotNull(document.PrintController); - - var printController = new StandardPrintController(); - document.PrintController = printController; - Assert.Same(printController, document.PrintController); - } - } - - [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void PrinterSettings_SetValue_ReturnsExpected() - { - using (var document = new PrintDocument()) - { - document.PrinterSettings = null; - Assert.IsAssignableFrom(document.PrinterSettings); - - var printerSettings = new PrinterSettings(); - document.PrinterSettings = printerSettings; - Assert.Same(printerSettings, document.PrinterSettings); - Assert.Equal( - document.PrinterSettings.DefaultPageSettings.PaperSize.Kind, - document.DefaultPageSettings.PaperSize.Kind); - - document.DefaultPageSettings = _pageSettings; - document.PrinterSettings = printerSettings; - Assert.Equal( - _pageSettings.PaperSize.Kind, - document.DefaultPageSettings.PaperSize.Kind); - } - } - - [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void BeginPrint_SetValue_ReturnsExpected() - { - bool flag = false; - var beginPrintHandler = new PrintEventHandler((sender, e) => flag = true); - - using (var document = new PrintDocument()) - { - document.PrintController = new TestPrintController(); - document.BeginPrint += beginPrintHandler; - document.Print(); - Assert.True(flag); - - flag = false; - document.BeginPrint -= beginPrintHandler; - document.Print(); - Assert.False(flag); - } - } - - [ActiveIssue("https://github.com/dotnet/winforms/issues/8815")] - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void EndPrint_SetValue_ReturnsExpected() - { - bool flag = false; - var endPrintHandler = new PrintEventHandler((sender, e) => flag = true); - - using (var document = new PrintDocument()) - { - document.PrintController = new TestPrintController(); - document.EndPrint += endPrintHandler; - document.Print(); - Assert.True(flag); - - flag = false; - document.EndPrint -= endPrintHandler; - document.Print(); - Assert.False(flag); - } - } - - [ConditionalFact(nameof(CanPrintToPdf))] - public void Print_DefaultPrintController_Success() - { - bool endPrintCalled = false; - var endPrintHandler = new PrintEventHandler((sender, e) => endPrintCalled = true); - using (var document = new PrintDocument()) - { - document.PrinterSettings.PrinterName = PrintToPdfPrinterName; - document.PrinterSettings.PrintFileName = GetTestFilePath(); - document.PrinterSettings.PrintToFile = true; - document.EndPrint += endPrintHandler; - document.Print(); - document.EndPrint -= endPrintHandler; - } - - // File may not have finished saving to disk when Print returns, - // so we check for EndPrint being called instead of file existence. - Assert.True(endPrintCalled); - } - - [ActiveIssue("https://github.com/dotnet/winforms/issues/8815")] - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void PrintPage_SetValue_ReturnsExpected() - { - bool flag = false; - var printPageHandler = new PrintPageEventHandler((sender, e) => flag = true); - - using (var document = new PrintDocument()) - { - document.PrintController = new TestPrintController(); - document.PrintPage += printPageHandler; - document.Print(); - Assert.True(flag); - - flag = false; - document.PrintPage -= printPageHandler; - document.Print(); - Assert.False(flag); - } - } - - [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void QueryPageSettings_SetValue_ReturnsExpected() - { - bool flag = false; - var queryPageSettingsHandler = new QueryPageSettingsEventHandler((sender, e) => flag = true); - - using (var document = new PrintDocument()) - { - document.PrintController = new TestPrintController(); - document.QueryPageSettings += queryPageSettingsHandler; - document.Print(); - Assert.True(flag); - - flag = false; - document.QueryPageSettings -= queryPageSettingsHandler; - document.Print(); - Assert.False(flag); - } - } - - [Fact] - public void ToString_ReturnsExpected() - { - using (var document = new PrintDocument()) - { - var expected = $"[PrintDocument {document.DocumentName}]"; - Assert.Equal(expected, document.ToString()); - } - } - - private void AssertDefaultPageSettings(PageSettings pageSettings) - { - // A4 and Letter are both common default sizes for systems to have. - switch (pageSettings.PaperSize.Kind) - { - case PaperKind.A4: - Assert.Equal(new Rectangle(0, 0, 827, 1169), pageSettings.Bounds); - break; - - case PaperKind.Letter: - Assert.Equal(new Rectangle(0, 0, 850, 1100), pageSettings.Bounds); - break; - } - - Assert.True(Enum.IsDefined(typeof(PrinterResolutionKind), pageSettings.PrinterResolution.Kind)); - Assert.True(pageSettings.PrinterSettings.IsDefaultPrinter); - } - - private const string PrintToPdfPrinterName = "Microsoft Print to PDF"; - private static bool CanPrintToPdf() - { - if (!PlatformDetection.IsWindows || !PlatformDetection.IsDrawingSupported) - return false; - - foreach (string name in PrinterSettings.InstalledPrinters) - { - if (name == PrintToPdfPrinterName) - { - return true; - } - } - - return false; - } - - private class TestPrintController : PrintController - { - public override Graphics OnStartPage(PrintDocument document, PrintPageEventArgs e) - { - using (var bitmap = new Bitmap(20, 20)) - { - return Graphics.FromImage(bitmap); - } - } - - public override void OnStartPrint(PrintDocument document, PrintEventArgs e) - { - base.OnStartPrint(document, e); - } - - public override void OnEndPrint(PrintDocument document, PrintEventArgs e) - { - base.OnEndPrint(document, e); - } - - public override void OnEndPage(PrintDocument document, PrintPageEventArgs e) - { - base.OnEndPage(document, e); - e.Graphics.Dispose(); - } - } -} diff --git a/src/System.Drawing.Common/tests/Printing/PrinterResolutionTests.cs b/src/System.Drawing.Common/tests/Printing/PrinterResolutionTests.cs deleted file mode 100644 index 97795834a9a..00000000000 --- a/src/System.Drawing.Common/tests/Printing/PrinterResolutionTests.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; - -namespace System.Drawing.Printing.Tests; - -public class PrinterResolutionTests -{ - [Fact] - public void Ctor_Default() - { - var resolution = new PrinterResolution(); - Assert.Equal(PrinterResolutionKind.Custom, resolution.Kind); - Assert.Equal(0, resolution.X); - Assert.Equal(0, resolution.Y); - } - - [Theory] - [InlineData(int.MaxValue)] - [InlineData(1)] - [InlineData(0)] - [InlineData(-1)] - [InlineData(int.MinValue)] - public void X_Value_ReturnsExpected(int value) - { - var resolution = new PrinterResolution - { - X = value - }; - Assert.Equal(value, resolution.X); - - // Set same. - resolution.X = value; - Assert.Equal(value, resolution.X); - } - - [Theory] - [InlineData(int.MaxValue)] - [InlineData(1)] - [InlineData(0)] - [InlineData(-1)] - [InlineData(int.MinValue)] - public void Y_Value_ReturnsExpected(int value) - { - var resolution = new PrinterResolution - { - Y = value - }; - Assert.Equal(value, resolution.Y); - - // Set same. - resolution.Y = value; - Assert.Equal(value, resolution.Y); - } - - [Theory] - [InlineData(PrinterResolutionKind.Custom)] - [InlineData(PrinterResolutionKind.Draft)] - [InlineData(PrinterResolutionKind.High)] - [InlineData(PrinterResolutionKind.Low)] - [InlineData(PrinterResolutionKind.Medium)] - public void Kind_Set_GetReturnsExpected(PrinterResolutionKind value) - { - var resolution = new PrinterResolution - { - Kind = value - }; - Assert.Equal(value, resolution.Kind); - - // Set same. - resolution.Kind = value; - Assert.Equal(value, resolution.Kind); - } - - [Theory] - [InlineData(PrinterResolutionKind.Custom + 1)] - [InlineData(PrinterResolutionKind.High - 1)] - public void Kind_SetInvalid_ThrowsInvalidEnumArgumentException(PrinterResolutionKind value) - { - var resolution = new PrinterResolution(); - Assert.Throws("value", () => resolution.Kind = value); - } - - public static IEnumerable ToString_TestData() - { - yield return new object[] { new PrinterResolution(), "[PrinterResolution X=0 Y=0]" }; - yield return new object[] { new PrinterResolution { X = -1, Y = -2}, "[PrinterResolution X=-1 Y=-2]" }; - yield return new object[] { new PrinterResolution { Kind = PrinterResolutionKind.High }, "[PrinterResolution High]" }; - yield return new object[] { new PrinterResolution { X = 1, Y = 2, Kind = PrinterResolutionKind.High }, "[PrinterResolution High]" }; - } - - [Theory] - [MemberData(nameof(ToString_TestData))] - public void ToString_Invoke_ReturnsExpected(PrinterResolution resolution, string expected) - { - Assert.Equal(expected, resolution.ToString()); - } -} diff --git a/src/System.Drawing.Common/tests/Printing/PrinterSettingsTests.cs b/src/System.Drawing.Common/tests/Printing/PrinterSettingsTests.cs deleted file mode 100644 index 0b1f25d7e0a..00000000000 --- a/src/System.Drawing.Common/tests/Printing/PrinterSettingsTests.cs +++ /dev/null @@ -1,626 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Authors: -// Sebastien Pouliot -// -// Copyright (C) 2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -using System.Drawing.Imaging; -using System.Globalization; - -namespace System.Drawing.Printing.Tests; - -public class PrinterSettingsTests -{ - [Fact] - public void Ctor_Default_Success() - { - var printerSettings = new PrinterSettings(); - Assert.NotNull(printerSettings.DefaultPageSettings); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void CanDuplex_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - bool canDuplex = printerSettings.CanDuplex; - } - - [Fact] - public void Copies_Default_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - int copies = printerSettings.Copies; - } - - [Theory] - [InlineData(0)] - [InlineData(short.MaxValue)] - public void Copies_SetValue_ReturnsExpected(short copies) - { - var printerSettings = new PrinterSettings() - { - Copies = copies - }; - - Assert.Equal(copies, printerSettings.Copies); - } - - [Theory] - [InlineData(-1)] - [InlineData(short.MinValue)] - public void Copies_SetValue_ThrowsArgumentException(short copies) - { - var printerSettings = new PrinterSettings(); - AssertExtensions.Throws(null, () => printerSettings.Copies = copies); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void Collate_Default_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - bool collate = printerSettings.Collate; - } - - [Fact] - public void Collate_SetValue_ReturnsExpected() - { - var printerSettings = new PrinterSettings() - { - Collate = false - }; - - Assert.False(printerSettings.Collate); - } - - [Fact] - public void DefaultPageSettings_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - Assert.NotNull(printerSettings.DefaultPageSettings); - } - - [Theory] - [InlineData(Duplex.Simplex)] - [InlineData(Duplex.Vertical)] - [InlineData(Duplex.Horizontal)] - public void Duplex_SetValue_ReturnsExpected(Duplex duplex) - { - var printerSettings = new PrinterSettings() - { - Duplex = duplex - }; - - Assert.Equal(duplex, printerSettings.Duplex); - } - - [Theory] - [InlineData(Duplex.Default - 1)] - [InlineData(Duplex.Horizontal + 1)] - [InlineData((Duplex)int.MaxValue)] - [InlineData((Duplex)int.MinValue)] - public void Duplex_Invalid_ThrowsInvalidEnumArgumentException(Duplex duplex) - { - var printerSettings = new PrinterSettings(); - Assert.ThrowsAny(() => printerSettings.Duplex = duplex); - } - - [Fact] - public void FromPage_Default_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - - Assert.Equal(0, printerSettings.FromPage); - } - - [Theory] - [InlineData(1)] - [InlineData(int.MaxValue)] - public void FromPage_SetValue_ReturnsExpected(int pageNumber) - { - var printerSettings = new PrinterSettings() - { - FromPage = pageNumber - }; - - Assert.Equal(pageNumber, printerSettings.FromPage); - } - - [Theory] - [InlineData(-1)] - [InlineData(int.MinValue)] - public void FromPage_Invalid_ThrowsArgumentException(int pageNumber) - { - var printerSettings = new PrinterSettings(); - AssertExtensions.Throws(null, () => printerSettings.FromPage = pageNumber); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void Static_InstalledPrinters_ReturnsExpected() - { - Assert.NotNull(PrinterSettings.InstalledPrinters); - } - - [Fact] - public void IsDefaultPrinter_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - Assert.True(printerSettings.IsDefaultPrinter); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void IsPlotter_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - Assert.False(printerSettings.IsPlotter); - } - - [Fact] - public void IsValid_ReturnsExpected() - { - var printerSettings = new PrinterSettings() - { - PrinterName = "Invalid Printer" - }; - - Assert.False(printerSettings.IsValid); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void LandscapeAngle_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - int[] validValues = new[] { -90, 0, 90, 270 }; - Assert.True(validValues.Contains(printerSettings.LandscapeAngle), $"PrinterSettings.LandscapeAngle ({printerSettings.LandscapeAngle}) must be 0, 90, or 270 degrees."); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void MaximumCopies_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - Assert.True(printerSettings.MaximumCopies >= 0, $"PrinterSettings.MaximumCopies ({printerSettings.MaximumCopies}) should not be negative."); - } - - [Fact] - public void MaximumPage_Default_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - - Assert.Equal(9999, printerSettings.MaximumPage); - } - - [Theory] - [InlineData(20)] - [InlineData(int.MaxValue)] - public void MaximumPage_SetValue_ReturnsExpected(int maximumPage) - { - var printerSettings = new PrinterSettings() - { - MaximumPage = maximumPage - }; - - Assert.Equal(maximumPage, printerSettings.MaximumPage); - } - - [Theory] - [InlineData(-1)] - [InlineData(int.MinValue)] - public void MaximumPage_Invalid_ThrowsArgumentException(int maximumPage) - { - var printerSettings = new PrinterSettings(); - AssertExtensions.Throws(null, () => printerSettings.MaximumPage = maximumPage); - } - - [Fact] - public void MinimumPage_Default_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - Assert.Equal(0, printerSettings.MinimumPage); - } - - [Theory] - [InlineData(20)] - [InlineData(int.MaxValue)] - public void MinimumPage_SetValue_ReturnsExpected(int minimumPage) - { - var printerSettings = new PrinterSettings() - { - MinimumPage = minimumPage - }; - - Assert.Equal(minimumPage, printerSettings.MinimumPage); - } - - [Theory] - [InlineData(-1)] - [InlineData(int.MinValue)] - public void MinimumPage_Invalid_ThrowsArgumentException(int minimumPage) - { - var printerSettings = new PrinterSettings(); - AssertExtensions.Throws(null, () => printerSettings.MinimumPage = minimumPage); - } - - [Fact] - public void PrintFileName_SetValue_ReturnsExpected() - { - var printFileName = "fileName"; - var printerSettings = new PrinterSettings() - { - PrintFileName = printFileName - }; - - Assert.Equal(printFileName, printerSettings.PrintFileName); - } - - [Fact] - public void PrintFileName_Null_ThrowsArgumentNullException() - { - var printerSettings = new PrinterSettings(); - AssertExtensions.Throws(null, () => printerSettings.PrintFileName = null); - } - - [Fact] - public void PrintFileName_Empty_ThrowsArgumentNullException() - { - var printerSettings = new PrinterSettings(); - AssertExtensions.Throws(string.Empty, () => printerSettings.PrintFileName = string.Empty); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void PaperSizes_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - Assert.NotNull(printerSettings.PaperSizes); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void PaperSources_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - Assert.NotNull(printerSettings.PaperSources); - } - - [Theory] - [InlineData(PrintRange.AllPages)] - [InlineData(PrintRange.CurrentPage)] - [InlineData(PrintRange.Selection)] - [InlineData(PrintRange.SomePages)] - public void PrintRange_SetValue_ReturnsExpected(PrintRange printRange) - { - var printerSettings = new PrinterSettings() - { - PrintRange = printRange - }; - - Assert.Equal(printRange, printerSettings.PrintRange); - } - - [Theory] - [InlineData(PrintRange.AllPages - 1)] - [InlineData(PrintRange.SomePages + 1)] - [InlineData((PrintRange)int.MaxValue)] - [InlineData((PrintRange)int.MinValue)] - public void PrintRange_Invalid_ThrowsInvalidEnumArgumentException(PrintRange printRange) - { - var printerSettings = new PrinterSettings(); - Assert.ThrowsAny(() => printerSettings.PrintRange = printRange); - } - - [Fact] - public void PrintToFile_SetValue_ReturnsExpected() - { - var printToFile = true; - var printerSettings = new PrinterSettings() - { - PrintToFile = printToFile - }; - - Assert.Equal(printToFile, printerSettings.PrintToFile); - } - - [Theory] - [InlineData("")] - [InlineData("My printer")] - public void PrinterName_SetValue_ReturnsExpected(string printerName) - { - var printerSettings = new PrinterSettings() - { - PrinterName = printerName - }; - - Assert.Equal(printerName, printerSettings.PrinterName); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void PrinterName_Null_ReturnsExpected() - { - var printerSettings = new PrinterSettings() - { - PrinterName = null - }; - - Assert.NotNull(printerSettings.PrinterName); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters)] - public void PrinterResolutions_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - Assert.NotNull(printerSettings.PrinterResolutions); - } - - public static IEnumerable IsDirectPrintingSupported_ImageFormatSupported_TestData() - { - yield return new object[] { ImageFormat.Jpeg }; - yield return new object[] { ImageFormat.Png }; - } - - [ConditionalTheory(Helpers.AnyInstalledPrinters)] - [MemberData(nameof(IsDirectPrintingSupported_ImageFormatSupported_TestData))] - public void IsDirectPrintingSupported_ImageFormatSupported_ReturnsExpected(ImageFormat imageFormat) - { - var printerSettings = new PrinterSettings(); - bool supported = printerSettings.IsDirectPrintingSupported(imageFormat); - } - - public static IEnumerable IsDirectPrintingSupported_ImageFormatNotSupported_TestData() - { - yield return new object[] { ImageFormat.Emf }; - yield return new object[] { ImageFormat.Exif }; - yield return new object[] { ImageFormat.Gif }; - yield return new object[] { ImageFormat.Icon }; - yield return new object[] { ImageFormat.MemoryBmp }; - yield return new object[] { ImageFormat.Tiff }; - yield return new object[] { ImageFormat.Wmf }; - yield return new object[] { ImageFormat.Bmp }; - } - - [Theory] - [MemberData(nameof(IsDirectPrintingSupported_ImageFormatNotSupported_TestData))] - public void IsDirectPrintingSupported_ImageFormatNotSupported_ReturnsExpected(ImageFormat imageFormat) - { - var printerSettings = new PrinterSettings(); - Assert.False(printerSettings.IsDirectPrintingSupported(imageFormat)); - } - - [Fact] - public void IsDirectPrintingSupported_ImageNotSupported_ReturnsExpected() - { - using (var bitmap = new Bitmap(10, 10)) - { - var printerSettings = new PrinterSettings(); - Assert.False(printerSettings.IsDirectPrintingSupported(bitmap)); - } - } - - [ConditionalFact(typeof(PrinterSettingsTests), nameof(CanTestSetHdevmode_IntPtr_Success))] - public void SupportsColor_ReturnsExpected() - { - // XPS and PDF printers support color. - // docs.microsoft.com/en-us/windows-hardware/drivers/print/improved-color-printing - var printerSettings = new PrinterSettings() { PrinterName = GetNameOfTestPrinterSuitableForDevModeTesting() }; - Assert.True(printerSettings.SupportsColor); - } - - [Theory] - [InlineData(20)] - [InlineData(int.MaxValue)] - public void ToPage_SetValue_ReturnsExpected(int toPage) - { - var printerSettings = new PrinterSettings() - { - ToPage = toPage - }; - - Assert.Equal(toPage, printerSettings.ToPage); - } - - [Theory] - [InlineData(-1)] - [InlineData(int.MinValue)] - public void ToPage_Invalid_ThrowsArgumentException(int toPage) - { - var printerSettings = new PrinterSettings(); - AssertExtensions.Throws(null, () => printerSettings.ToPage = toPage); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void Clone_Success() - { - var printerSettings = new PrinterSettings(); - PrinterSettings clone = Assert.IsAssignableFrom(printerSettings.Clone()); - Assert.False(ReferenceEquals(clone, printerSettings)); - } - - [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void CreateMeasurementGraphics_Default_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - using (Graphics graphic = printerSettings.CreateMeasurementGraphics()) - { - Assert.NotNull(graphic); - Assert.Equal((double)printerSettings.DefaultPageSettings.Bounds.X, graphic.VisibleClipBounds.X, 0); - Assert.Equal((double)printerSettings.DefaultPageSettings.Bounds.Y, graphic.VisibleClipBounds.Y, 0); - Assert.Equal((double)printerSettings.DefaultPageSettings.PrintableArea.Height, graphic.VisibleClipBounds.Height, 0); - Assert.Equal((double)printerSettings.DefaultPageSettings.PrintableArea.Width, graphic.VisibleClipBounds.Width, 0); - } - } - - [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void CreateMeasurementGraphics_Bool_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - using (Graphics graphic = printerSettings.CreateMeasurementGraphics(true)) - { - Assert.NotNull(graphic); - Assert.Equal((double)printerSettings.DefaultPageSettings.PrintableArea.Height, graphic.VisibleClipBounds.Height, 0); - Assert.Equal((double)printerSettings.DefaultPageSettings.PrintableArea.Width, graphic.VisibleClipBounds.Width, 0); - } - } - - [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void CreateMeasurementGraphics_PageSettings_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - var pageSettings = new PageSettings(); - using (Graphics graphic = printerSettings.CreateMeasurementGraphics(pageSettings)) - { - Assert.NotNull(graphic); - Assert.Equal((double)printerSettings.DefaultPageSettings.Bounds.X, graphic.VisibleClipBounds.X, 0); - Assert.Equal((double)printerSettings.DefaultPageSettings.Bounds.Y, graphic.VisibleClipBounds.Y, 0); - Assert.Equal((double)printerSettings.DefaultPageSettings.PrintableArea.Height, graphic.VisibleClipBounds.Height, 0); - Assert.Equal((double)printerSettings.DefaultPageSettings.PrintableArea.Width, graphic.VisibleClipBounds.Width, 0); - } - } - - [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void CreateMeasurementGraphics_PageSettingsBool_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - var pageSettings = new PageSettings(); - using (Graphics graphic = printerSettings.CreateMeasurementGraphics(pageSettings, true)) - { - Assert.NotNull(graphic); - Assert.Equal((double)printerSettings.DefaultPageSettings.PrintableArea.Height, graphic.VisibleClipBounds.Height, 0); - Assert.Equal((double)printerSettings.DefaultPageSettings.PrintableArea.Width, graphic.VisibleClipBounds.Width, 0); - } - } - - [ConditionalFact(Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/winforms/issues/8816 - public void CreateMeasurementGraphics_Null_ThrowsNullReferenceException() - { - var printerSettings = new PrinterSettings(); - Assert.Throws(() => printerSettings.CreateMeasurementGraphics(null)); - Assert.Throws(() => printerSettings.CreateMeasurementGraphics(null, true)); - } - - [Fact] - public void GetHdevmode_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - IntPtr handle = IntPtr.Zero; - - handle = printerSettings.GetHdevmode(); - Assert.NotEqual(IntPtr.Zero, handle); - } - - [Fact] - public void GetHdevmode_PageSettings_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - var pageSettings = new PageSettings(); - IntPtr handle = IntPtr.Zero; - - handle = printerSettings.GetHdevmode(pageSettings); - Assert.NotEqual(IntPtr.Zero, handle); - } - - [Fact] - public void GetHdevmode_Null_ThrowsNullReferenceException() - { - var printerSettings = new PrinterSettings(); - Assert.Throws(() => printerSettings.GetHdevmode(null)); - } - - [Fact] - public void GetHdevnames_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - IntPtr handle = IntPtr.Zero; - - handle = printerSettings.GetHdevnames(); - Assert.NotEqual(IntPtr.Zero, handle); - } - - [ConditionalFact(typeof(PrinterSettingsTests), nameof(CanTestSetHdevmode_IntPtr_Success))] - public void SetHdevmode_IntPtr_Success() - { - string printerName = GetNameOfTestPrinterSuitableForDevModeTesting(); - var printerSettings = new PrinterSettings() { PrinterName = printerName, Copies = 3 }; - var newPrinterSettings = new PrinterSettings() { PrinterName = printerName, Copies = 6 }; - - IntPtr handle = printerSettings.GetHdevmode(); - newPrinterSettings.SetHdevmode(handle); - Assert.Equal(printerSettings.Copies, newPrinterSettings.Copies); - Assert.Equal(printerSettings.Collate, newPrinterSettings.Collate); - Assert.Equal(printerSettings.Duplex, newPrinterSettings.Duplex); - } - - public static bool CanTestSetHdevmode_IntPtr_Success => GetNameOfTestPrinterSuitableForDevModeTesting() != null; - - private static string GetNameOfTestPrinterSuitableForDevModeTesting() - { - foreach (string candidate in s_TestPrinterNames) - { - PrinterSettings printerSettings = new PrinterSettings() { PrinterName = candidate }; - if (printerSettings.IsValid) - return candidate; - } - return null; - } - - private static readonly string[] s_TestPrinterNames = - { - // Our method of testing some apis requires a printer that supports multi-copy printing, collating, color and duplex settings. Not all printers - // support these so rather than trust the machine running the test to have configured such a printer as the default, use the name of - // a known compliant printer that ships with Windows 10. - "Microsoft Print to PDF", - "Microsoft XPS Document Writer", // Backup for older Windows - }; - - [Fact] - public void GetHdevmode_Zero_ThrowsArgumentException() - { - var printerSettings = new PrinterSettings(); - AssertExtensions.Throws(null, () => printerSettings.SetHdevmode(IntPtr.Zero)); - } - - [Fact] - public void SetHdevnames_IntPtr_Success() - { - var printerSettings = new PrinterSettings(); - var newPrinterSettings = new PrinterSettings(); - IntPtr handle = printerSettings.GetHdevnames(); - newPrinterSettings.SetHdevnames(handle); - Assert.Equal(newPrinterSettings.PrinterName, printerSettings.PrinterName); - } - - [Fact] - public void ToString_ReturnsExpected() - { - var printerSettings = new PrinterSettings(); - var expected = "[PrinterSettings " - + printerSettings.PrinterName - + " Copies=" + printerSettings.Copies.ToString(CultureInfo.InvariantCulture) - + " Collate=" + printerSettings.Collate.ToString(CultureInfo.InvariantCulture) - + " Duplex=" + printerSettings.Duplex.ToString() - + " FromPage=" + printerSettings.FromPage.ToString(CultureInfo.InvariantCulture) - + " LandscapeAngle=" + printerSettings.LandscapeAngle.ToString(CultureInfo.InvariantCulture) - + " MaximumCopies=" + printerSettings.MaximumCopies.ToString(CultureInfo.InvariantCulture) - + " OutputPort=" + printerSettings.PrintFileName.ToString(CultureInfo.InvariantCulture) - + " ToPage=" + printerSettings.ToPage.ToString(CultureInfo.InvariantCulture) - + "]"; - - Assert.Equal(expected, printerSettings.ToString()); - } -} diff --git a/src/System.Drawing.Common/tests/Printing/PrinterUnitConvertTests.cs b/src/System.Drawing.Common/tests/Printing/PrinterUnitConvertTests.cs deleted file mode 100644 index abd4531f330..00000000000 --- a/src/System.Drawing.Common/tests/Printing/PrinterUnitConvertTests.cs +++ /dev/null @@ -1,148 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// Author: -// -// Jordi Mas i Hernandez (jordi@ximian.com) -// - -namespace System.Drawing.Printing.Tests; - -public class PrinterUnitConvertTests -{ - [Theory] - [InlineData(PrinterUnit.Display, PrinterUnit.Display, 100)] - [InlineData(PrinterUnit.Display, PrinterUnit.HundredthsOfAMillimeter, 2540)] - [InlineData(PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter, 254)] - [InlineData(PrinterUnit.Display, PrinterUnit.ThousandthsOfAnInch, 1000)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.Display, 4)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.HundredthsOfAMillimeter, 100)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.TenthsOfAMillimeter, 10)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch, 39)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display, 39)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.HundredthsOfAMillimeter, 1000)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.TenthsOfAMillimeter, 100)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch, 394)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.Display, 10)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.HundredthsOfAMillimeter, 254)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.TenthsOfAMillimeter, 25)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.ThousandthsOfAnInch, 100)] - public void Convert_Int_ReturnsExpected(PrinterUnit fromUnit, PrinterUnit toUnit, int expectedResult) - { - var converted = PrinterUnitConvert.Convert(100, fromUnit, toUnit); - Assert.Equal(expectedResult, converted); - } - - [Theory] - [InlineData(PrinterUnit.Display, PrinterUnit.Display, 100, 1000)] - [InlineData(PrinterUnit.Display, PrinterUnit.HundredthsOfAMillimeter, 2540, 25400)] - [InlineData(PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter, 254, 2540)] - [InlineData(PrinterUnit.Display, PrinterUnit.ThousandthsOfAnInch, 1000, 10000)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.Display, 4, 39)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.HundredthsOfAMillimeter, 100, 1000)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.TenthsOfAMillimeter, 10, 100)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch, 39, 394)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display, 39, 394)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.HundredthsOfAMillimeter, 1000, 10000)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.TenthsOfAMillimeter, 100, 1000)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch, 394, 3937)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.Display, 10, 100)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.HundredthsOfAMillimeter, 254, 2540)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.TenthsOfAMillimeter, 25, 254)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.ThousandthsOfAnInch, 100, 1000)] - public void Convert_Point_ReturnsExpected(PrinterUnit fromUnit, PrinterUnit toUnit, int expectedX, int expectedY) - { - var converted = PrinterUnitConvert.Convert(new Point(100, 1000), fromUnit, toUnit); - Assert.Equal(new Point(expectedX, expectedY), converted); - } - - [Theory] - [InlineData(PrinterUnit.Display, PrinterUnit.Display, 100, 1000)] - [InlineData(PrinterUnit.Display, PrinterUnit.HundredthsOfAMillimeter, 2540, 25400)] - [InlineData(PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter, 254, 2540)] - [InlineData(PrinterUnit.Display, PrinterUnit.ThousandthsOfAnInch, 1000, 10000)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.Display, 4, 39)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.HundredthsOfAMillimeter, 100, 1000)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.TenthsOfAMillimeter, 10, 100)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch, 39, 394)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display, 39, 394)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.HundredthsOfAMillimeter, 1000, 10000)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.TenthsOfAMillimeter, 100, 1000)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch, 394, 3937)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.Display, 10, 100)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.HundredthsOfAMillimeter, 254, 2540)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.TenthsOfAMillimeter, 25, 254)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.ThousandthsOfAnInch, 100, 1000)] - public void Convert_Rectangle_ReturnsExpected(PrinterUnit fromUnit, PrinterUnit toUnit, int expectedLeftValue, int expectedRightValue) - { - var converted = PrinterUnitConvert.Convert(new Rectangle(100, 1000, 100, 1000), fromUnit, toUnit); - Assert.Equal(new Rectangle(expectedLeftValue, expectedRightValue, expectedLeftValue, expectedRightValue), converted); - } - - [Theory] - [InlineData(PrinterUnit.Display, PrinterUnit.Display, 100, 1000)] - [InlineData(PrinterUnit.Display, PrinterUnit.HundredthsOfAMillimeter, 2540, 25400)] - [InlineData(PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter, 254, 2540)] - [InlineData(PrinterUnit.Display, PrinterUnit.ThousandthsOfAnInch, 1000, 10000)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.Display, 4, 39)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.HundredthsOfAMillimeter, 100, 1000)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.TenthsOfAMillimeter, 10, 100)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch, 39, 394)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display, 39, 394)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.HundredthsOfAMillimeter, 1000, 10000)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.TenthsOfAMillimeter, 100, 1000)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch, 394, 3937)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.Display, 10, 100)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.HundredthsOfAMillimeter, 254, 2540)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.TenthsOfAMillimeter, 25, 254)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.ThousandthsOfAnInch, 100, 1000)] - public void Convert_Size_ReturnsExpected(PrinterUnit fromUnit, PrinterUnit toUnit, int expectedX, int expectedY) - { - var converted = PrinterUnitConvert.Convert(new Size(100, 1000), fromUnit, toUnit); - Assert.Equal(new Size(expectedX, expectedY), converted); - } - - [Theory] - [InlineData(PrinterUnit.Display, PrinterUnit.Display, 100, 1000, 100, 1000)] - [InlineData(PrinterUnit.Display, PrinterUnit.HundredthsOfAMillimeter, 2540, 25400, 2540, 25400)] - [InlineData(PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter, 254, 2540, 254, 2540)] - [InlineData(PrinterUnit.Display, PrinterUnit.ThousandthsOfAnInch, 1000, 10000, 1000, 10000)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.Display, 4, 39, 4, 39)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.HundredthsOfAMillimeter, 100, 1000, 100, 1000)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.TenthsOfAMillimeter, 10, 100, 10, 100)] - [InlineData(PrinterUnit.HundredthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch, 39, 394, 39, 394)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display, 39, 394, 39, 394)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.HundredthsOfAMillimeter, 1000, 10000, 1000, 10000)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.TenthsOfAMillimeter, 100, 1000, 100, 1000)] - [InlineData(PrinterUnit.TenthsOfAMillimeter, PrinterUnit.ThousandthsOfAnInch, 394, 3937, 394, 3937)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.Display, 10, 100, 10, 100)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.HundredthsOfAMillimeter, 254, 2540, 254, 2540)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.TenthsOfAMillimeter, 25, 254, 25, 254)] - [InlineData(PrinterUnit.ThousandthsOfAnInch, PrinterUnit.ThousandthsOfAnInch, 100, 1000, 100, 1000)] - public void Convert_Margins_ReturnsExpected(PrinterUnit fromUnit, PrinterUnit toUnit, int expectedLeft, int expectedRight, int expectedTop, int expectedBottom) - { - var converted = PrinterUnitConvert.Convert(new Margins(100, 1000, 100, 1000), fromUnit, toUnit); - Assert.Equal(new Margins(expectedLeft, expectedRight, expectedTop, expectedBottom), converted); - } -} diff --git a/src/System.Drawing.Common/tests/RegionTests.cs b/src/System.Drawing.Common/tests/RegionTests.cs deleted file mode 100644 index 9f9ecabaccb..00000000000 --- a/src/System.Drawing.Common/tests/RegionTests.cs +++ /dev/null @@ -1,2381 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Copyright (C) 2004-2008 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -using System.Drawing.Drawing2D; -using System.Runtime.InteropServices; - -namespace System.Drawing.Tests; - -public class RegionTests -{ - private static readonly Graphics s_graphic = Graphics.FromImage(new Bitmap(1, 1)); - - private static Region CreateDisposedRegion() - { - var region = new Region(); - region.Dispose(); - return region; - } - - [Fact] - public void Ctor_Default() - { - using (var region = new Region()) - { - Assert.False(region.IsEmpty(s_graphic)); - Assert.True(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF(-4194304, -4194304, 8388608, 8388608), region.GetBounds(s_graphic)); - } - } - - [Theory] - [InlineData(-1, -2, -3, -4, true)] - [InlineData(0, 0, 0, 0, true)] - [InlineData(1, 2, 3, 4, false)] - public void Ctor_Rectangle(int x, int y, int width, int height, bool isEmpty) - { - var rectangle = new Rectangle(x, y, width, height); - - using (var region = new Region(rectangle)) - { - Assert.Equal(isEmpty, region.IsEmpty(s_graphic)); - Assert.False(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF(x, y, width, height), region.GetBounds(s_graphic)); - } - } - - [Theory] - [InlineData(1, 2, 3, float.NegativeInfinity, true)] - [InlineData(-1, -2, -3, -4, true)] - [InlineData(0, 0, 0, 0, true)] - [InlineData(1, 2, 3, 4, false)] - [InlineData(float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, true)] - public void Ctor_RectangleF(float x, float y, float width, float height, bool isEmpty) - { - var rectangle = new RectangleF(x, y, width, height); - - using (var region = new Region(rectangle)) - { - Assert.Equal(isEmpty, region.IsEmpty(s_graphic)); - Assert.False(region.IsInfinite(s_graphic)); - Assert.Equal(rectangle, region.GetBounds(s_graphic)); - } - } - - public static IEnumerable Region_TestData() - { - yield return new object[] { new Region() }; - yield return new object[] { new Region(new Rectangle(0, 0, 0, 0)) }; - yield return new object[] { new Region(new Rectangle(1, 2, 3, 4)) }; - } - - [Theory] - [MemberData(nameof(Region_TestData))] - public void Ctor_RegionData(Region region) - { - using (region) - { - using (var otherRegion = new Region(region.GetRegionData())) - using (var matrix = new Matrix()) - { - Assert.Equal(region.GetBounds(s_graphic), otherRegion.GetBounds(s_graphic)); - Assert.Equal(region.GetRegionScans(matrix), otherRegion.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Ctor_RegionDataOfRegionWithPath_Success() - { - using (var graphicsPath = new GraphicsPath()) - { - graphicsPath.AddRectangle(new Rectangle(1, 2, 3, 4)); - - using (var region = new Region(graphicsPath)) - { - Ctor_RegionData(region); - } - } - } - - [Fact] - public void Ctor_RegionDataOfRegionWithRegionData_Success() - { - using (var region = new Region(new Rectangle(1, 2, 3, 4))) - using (var other = new Region(region.GetRegionData())) - { - Ctor_RegionData(other); - } - } - - [Fact] - public void Ctor_NullRegionData_ThrowsArgumentNullException() - { - AssertExtensions.Throws("rgnData", () => new Region((RegionData)null)); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(7)] - [InlineData(256)] - public void Ctor_InvalidRegionData_ThrowsExternalException(int dataLength) - { - using (var region = new Region()) - { - RegionData regionData = region.GetRegionData(); - regionData.Data = new byte[dataLength]; - Assert.Throws(() => new Region(regionData)); - } - } - - [Fact] - public void Ctor_EmptyGraphicsPath_ThrowsExternalException() - { - using (var graphicsPath = new GraphicsPath()) - using (var region = new Region(graphicsPath)) - { - RegionData regionData = region.GetRegionData(); - Assert.Throws(() => new Region(regionData)); - } - } - - [Fact] - public void Ctor_NullDataInRegionData_ThrowsNullReferenceException() - { - using (var region = new Region()) - { - RegionData regionData = region.GetRegionData(); - regionData.Data = null; - Assert.Throws(() => new Region(regionData)); - } - } - - [Fact] - public void Ctor_GraphicsPath() - { - using (var graphicsPath = new GraphicsPath()) - { - graphicsPath.AddRectangle(new Rectangle(1, 2, 3, 4)); - graphicsPath.AddRectangle(new Rectangle(4, 5, 6, 7)); - - using (var region = new Region(graphicsPath)) - using (var matrix = new Matrix()) - { - Assert.Equal(new RectangleF[] - { - new RectangleF(1, 2, 3, 3), - new RectangleF(1, 5, 9, 1), - new RectangleF(4, 6, 6, 6) - }, region.GetRegionScans(matrix)); - Assert.Equal(new RectangleF(1, 2, 9, 10), region.GetBounds(s_graphic)); - } - } - } - - [Fact] - public void Ctor_EmptyGraphicsPath() - { - using (var graphicsPath = new GraphicsPath()) - using (var region = new Region(graphicsPath)) - using (var matrix = new Matrix()) - { - Assert.True(region.IsEmpty(s_graphic)); - Assert.Empty(region.GetRegionScans(matrix)); - } - } - - public static IEnumerable Ctor_InfiniteGraphicsPath_TestData() - { - var path1 = new GraphicsPath(); - path1.AddRectangle(new Rectangle(-4194304, -4194304, 8388608, 8388608)); - yield return new object[] { path1, true }; - - var path2 = new GraphicsPath(); - path2.AddRectangle(new Rectangle(-4194304, -4194304, 8388608, 8388608)); - path2.AddRectangle(Rectangle.Empty); - yield return new object[] { path2, true }; - - var path3 = new GraphicsPath(); - path3.AddRectangle(new Rectangle(-4194304, -4194304, 8388608, 8388608)); - path3.AddRectangle(new Rectangle(1, 2, 3, 4)); - yield return new object[] { path3, false }; - - var path4 = new GraphicsPath(); - path4.AddCurve(new Point[] { new Point(-4194304, -4194304), new Point(4194304, 4194304) }); - yield return new object[] { path4, false }; - - var path5 = new GraphicsPath(); - path5.AddPolygon(new Point[] { new Point(-4194304, -4194304), new Point(-4194304, 4194304), new Point(4194304, 4194304), new Point(4194304, -4194304) }); - yield return new object[] { path5, true }; - - var path6 = new GraphicsPath(); - path6.AddPolygon(new Point[] { new Point(-4194304, -4194304), new Point(-4194304, 4194304), new Point(4194304, 4194304), new Point(4194304, -4194304), new Point(-4194304, -4194304) }); - yield return new object[] { path6, true }; - } - - [Theory] - [MemberData(nameof(Ctor_InfiniteGraphicsPath_TestData))] - public void Ctor_InfiniteGraphicsPath_IsInfinite(GraphicsPath path, bool isInfinite) - { - using (path) - using (var region = new Region(path)) - { - Assert.Equal(isInfinite, region.IsInfinite(s_graphic)); - } - } - - [Fact] - public void Ctor_GraphicsPathTooLarge_SetsToEmpty() - { - using (var path = new GraphicsPath()) - { - path.AddCurve(new Point[] { new Point(-4194304, -4194304), new Point(4194304, 4194304) }); - - using (var region = new Region(path)) - using (var matrix = new Matrix()) - { - Assert.Empty(region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Ctor_NullGraphicsPath_ThrowsArgumentNullException() - { - AssertExtensions.Throws("path", () => new Region((GraphicsPath)null)); - } - - [Fact] - public void Ctor_DisposedGraphicsPath_ThrowsArgumentException() - { - var path = new GraphicsPath(); - path.Dispose(); - - AssertExtensions.Throws(null, () => new Region(path)); - } - - [Theory] - [MemberData(nameof(Region_TestData))] - public void Clone(Region region) - { - using (region) - using (Region clone = Assert.IsType(region.Clone())) - using (var matrix = new Matrix()) - { - Assert.NotSame(region, clone); - - Assert.Equal(region.GetBounds(s_graphic), clone.GetBounds(s_graphic)); - Assert.Equal(region.GetRegionScans(matrix), clone.GetRegionScans(matrix)); - } - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedRegion().Clone()); - } - - public static IEnumerable Complement_TestData() - { - yield return new object[] - { - new Region(new RectangleF(10, 10, 100, 100)), - new RectangleF[] { new RectangleF(40, 60, 100, 20) }, - new RectangleF[] { new RectangleF(110, 60, 30, 20) } - }; - - yield return new object[] - { - new Region(new RectangleF(70, 10, 100, 100)), - new RectangleF[] { new RectangleF(40, 60, 100, 20) }, - new RectangleF[] { new RectangleF(40, 60, 30, 20) } - }; - - yield return new object[] - { - new Region(new RectangleF(40, 100, 100, 100)), - new RectangleF[] { new RectangleF(70, 80, 50, 40) }, - new RectangleF[] { new RectangleF(70, 80, 50, 20) } - }; - - yield return new object[] - { - new Region(new RectangleF(40, 10, 100, 100)), - new RectangleF[] { new RectangleF(70, 80, 50, 40) }, - new RectangleF[] { new RectangleF(70, 110, 50, 10) } - }; - - yield return new object[] - { - new Region(new RectangleF(30, 30, 80, 80)), - new RectangleF[] - { - new RectangleF(45, 45, 200, 200), - new RectangleF(160, 260, 10, 10), - new RectangleF(170, 260, 10, 10), - }, - new RectangleF[] { new RectangleF(170, 260, 10, 10) } - }; - - yield return new object[] - { - new Region(), - new RectangleF[] { RectangleF.Empty }, - new RectangleF[0] - }; - - yield return new object[] - { - new Region(), - new RectangleF[] { new RectangleF(1, 2, 3, 4) }, - new RectangleF[0] - }; - } - - [Theory] - [MemberData(nameof(Complement_TestData))] - public void Complement_Region_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - using (var other = new Region(rect)) - { - region.Complement(other); - } - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Complement_UnionRegion_Success() - { - using (var region = new Region(new Rectangle(20, 20, 20, 20))) - using (var other = new Region(new Rectangle(20, 80, 20, 10))) - using (var matrix = new Matrix()) - { - other.Union(new Rectangle(60, 60, 30, 10)); - - region.Complement(other); - Assert.Equal(new RectangleF[] - { - new RectangleF(60, 60, 30, 10), - new RectangleF(20, 80, 20, 10) - }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Complement_InfiniteAndWithIntersectRegion_Success() - { - using (var region = new Region()) - using (var matrix = new Matrix()) - { - region.Intersect(new Rectangle(5, 5, -10, -10)); - region.Complement(new Rectangle(-5, -5, 12, 12)); - - Assert.False(region.IsEmpty(s_graphic)); - Assert.False(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF[] - { - new RectangleF(5, -5, 2, 10), - new RectangleF(-5, 5, 12, 2) - }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Complement_InfiniteRegion_Success() - { - using (var region = new Region(new Rectangle(1, 2, 3, 4))) - using (var matrix = new Matrix()) - using (var other = new Region()) - { - region.Complement(other); - - Assert.Equal(new RectangleF[] - { - new RectangleF(-4194304, -4194304, 8388608, 4194306), - new RectangleF(-4194304, 2, 4194305, 4), - new RectangleF(4, 2, 4194300, 4), - new RectangleF(-4194304, 6, 8388608, 4194298) - }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Complement_NullRegion_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("region", () => region.Complement((Region)null)); - } - } - - [Fact] - public void Complement_DisposedRegion_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new Region().Complement(CreateDisposedRegion())); - } - - [Fact] - public void Complement_SameRegion_ThrowsInvalidOperationException() - { - using (var region = new Region()) - { - Assert.Throws(() => region.Complement(region)); - } - } - - [Theory] - [MemberData(nameof(Complement_TestData))] - public void Complement_Rectangle_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - region.Complement(new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height)); - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Theory] - [MemberData(nameof(Complement_TestData))] - public void Complement_RectangleF_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - region.Complement(rect); - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Theory] - [MemberData(nameof(Complement_TestData))] - public void Complement_GraphicsPath_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - using (var path = new GraphicsPath()) - { - path.AddRectangle(rect); - region.Complement(path); - } - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Complement_GraphicsPathWithMultipleRectangles_Success() - { - var rect1 = new Rectangle(20, 30, 60, 80); - var rect2 = new Rectangle(50, 40, 60, 80); - - using (Graphics graphics = Graphics.FromImage(new Bitmap(600, 800))) - using (var region1 = new Region(rect1)) - using (var region2 = new Region(rect2)) - using (var matrix = new Matrix()) - { - graphics.DrawRectangle(Pens.Green, rect1); - graphics.DrawRectangle(Pens.Red, rect2); - - region1.Complement(region2); - graphics.FillRegion(Brushes.Blue, region1); - graphics.DrawRectangles(Pens.Yellow, region1.GetRegionScans(matrix)); - - Assert.Equal(new RectangleF[] - { - new RectangleF(80, 40, 30, 70), - new RectangleF(50, 110, 60, 10) - }, region1.GetRegionScans(matrix)); - } - } - - [Fact] - public void Complement_EmptyPathWithInfiniteRegion_MakesEmpty() - { - using (var region = new Region()) - using (var graphicsPath = new GraphicsPath()) - { - region.Complement(graphicsPath); - Assert.True(region.IsEmpty(s_graphic)); - } - } - - [Fact] - public void Complement_NullGraphicsPath_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("path", () => region.Complement((GraphicsPath)null)); - } - } - - [Fact] - public void Complement_Disposed_ThrowsArgumentException() - { - Region disposedRegion = CreateDisposedRegion(); - - using (var graphicPath = new GraphicsPath()) - using (var other = new Region()) - { - AssertExtensions.Throws(null, () => disposedRegion.Complement(graphicPath)); - AssertExtensions.Throws(null, () => disposedRegion.Complement(new Rectangle())); - AssertExtensions.Throws(null, () => disposedRegion.Complement(new RectangleF())); - AssertExtensions.Throws(null, () => disposedRegion.Complement(disposedRegion)); - } - } - - public static IEnumerable Equals_TestData() - { - static Region Empty() - { - var emptyRegion = new Region(); - emptyRegion.MakeEmpty(); - return emptyRegion; - } - - var createdRegion = new Region(); - yield return new object[] { createdRegion, createdRegion, true }; - yield return new object[] { new Region(), new Region(), true }; - yield return new object[] { new Region(), Empty(), false }; - yield return new object[] { new Region(), new Region(new Rectangle(1, 2, 3, 4)), false }; - - yield return new object[] { Empty(), Empty(), true }; - yield return new object[] { Empty(), new Region(new Rectangle(0, 0, 0, 0)), true }; - yield return new object[] { Empty(), new Region(new Rectangle(1, 2, 3, 3)), false }; - - yield return new object[] { new Region(new Rectangle(1, 2, 3, 4)), new Region(new Rectangle(1, 2, 3, 4)), true }; - yield return new object[] { new Region(new Rectangle(1, 2, 3, 4)), new Region(new RectangleF(1, 2, 3, 4)), true }; - yield return new object[] { new Region(new Rectangle(1, 2, 3, 4)), new Region(new Rectangle(2, 2, 3, 4)), false }; - yield return new object[] { new Region(new Rectangle(1, 2, 3, 4)), new Region(new Rectangle(1, 3, 3, 4)), false }; - yield return new object[] { new Region(new Rectangle(1, 2, 3, 4)), new Region(new Rectangle(1, 2, 4, 4)), false }; - yield return new object[] { new Region(new Rectangle(1, 2, 3, 4)), new Region(new Rectangle(1, 2, 3, 5)), false }; - - var graphics1 = new GraphicsPath(); - graphics1.AddRectangle(new Rectangle(1, 2, 3, 4)); - - var graphics2 = new GraphicsPath(); - graphics2.AddRectangle(new Rectangle(1, 2, 3, 4)); - - var graphics3 = new GraphicsPath(); - graphics3.AddRectangle(new Rectangle(2, 2, 3, 4)); - - var graphics4 = new GraphicsPath(); - graphics4.AddRectangle(new Rectangle(1, 3, 3, 4)); - - var graphics5 = new GraphicsPath(); - graphics5.AddRectangle(new Rectangle(1, 2, 4, 4)); - - var graphics6 = new GraphicsPath(); - graphics6.AddRectangle(new Rectangle(1, 2, 3, 5)); - - yield return new object[] { new Region(graphics1), new Region(graphics1), true }; - yield return new object[] { new Region(graphics1), new Region(graphics2), true }; - yield return new object[] { new Region(graphics1), new Region(graphics3), false }; - yield return new object[] { new Region(graphics1), new Region(graphics4), false }; - yield return new object[] { new Region(graphics1), new Region(graphics5), false }; - yield return new object[] { new Region(graphics1), new Region(graphics6), false }; - } - - [Theory] - [MemberData(nameof(Equals_TestData))] - public void Equals_Valid_ReturnsExpected(Region region, Region other, bool expected) - { - using (region) - using (other) - { - Assert.Equal(expected, region.Equals(other, s_graphic)); - } - } - - [Fact] - public void Equals_NullRegion_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("region", () => region.Equals(null, s_graphic)); - } - } - - [Fact] - public void Equals_NullGraphics_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("g", () => region.Equals(region, null)); - } - } - - [Fact] - public void Equals_DisposedGraphics_ThrowsArgumentException() - { - using (var region = new Region()) - using (var other = new Region()) - using (var image = new Bitmap(10, 10)) - { - var graphics = Graphics.FromImage(image); - graphics.Dispose(); - AssertExtensions.Throws(null, () => region.Equals(region, graphics)); - } - } - - [Fact] - public void Equals_Disposed_ThrowsArgumentException() - { - Region disposedRegion = CreateDisposedRegion(); - - AssertExtensions.Throws(null, () => disposedRegion.Equals(new Region(), s_graphic)); - AssertExtensions.Throws(null, () => new Region().Equals(disposedRegion, s_graphic)); - } - - public static IEnumerable Exclude_TestData() - { - yield return new object[] - { - new Region(new Rectangle(500, 30, 60, 80)), - new RectangleF[] { new RectangleF(500, 30, 60, 80) }, - new RectangleF[0] - }; - - yield return new object[] - { - new Region(new Rectangle(500, 30, 60, 80)), - new RectangleF[] { RectangleF.Empty }, - new RectangleF[] { new RectangleF(500, 30, 60, 80) } - }; - - yield return new object[] - { - new Region(), - new RectangleF[] { new RectangleF(520, 40, 60, 80) }, - new RectangleF[] - { - new RectangleF(-4194304, -4194304, 8388608, 4194344), - new RectangleF(-4194304, 40, 4194824, 80), - new RectangleF(580, 40, 4193724, 80), - new RectangleF(-4194304, 120, 8388608, 4194184) - } - }; - - yield return new object[] - { - new Region(), - new RectangleF[] { RectangleF.Empty }, - new RectangleF[] { new Rectangle(-4194304, -4194304, 8388608, 8388608) } - }; - - // Intersecting from the right. - yield return new object[] - { - new Region(new Rectangle(10, 10, 100, 100)), - new RectangleF[] { new RectangleF(40, 60, 100, 20) }, - new RectangleF[] - { - new RectangleF(10, 10, 100, 50), - new RectangleF(10, 60, 30, 20), - new RectangleF(10, 80, 100, 30) - } - }; - - // Intersecting from the left. - yield return new object[] - { - new Region(new Rectangle(70, 10, 100, 100)), - new RectangleF[] { new RectangleF(40, 60, 100, 20) }, - new RectangleF[] - { - new RectangleF(70, 10, 100, 50), - new RectangleF(140, 60, 30, 20), - new RectangleF(70, 80, 100, 30) - } - }; - - // Intersecting from the top. - yield return new object[] - { - new Region(new Rectangle(40, 100, 100, 100)), - new RectangleF[] { new RectangleF(70, 80, 50, 40) }, - new RectangleF[] - { - new RectangleF(40, 100, 30, 20), - new RectangleF(120, 100, 20, 20), - new RectangleF(40, 120, 100, 80) - } - }; - - // Intersecting from the bottom. - yield return new object[] - { - new Region(new Rectangle(40, 10, 100, 100)), - new RectangleF[] { new RectangleF(70, 80, 50, 40) }, - new RectangleF[] - { - new RectangleF(40, 10, 100, 70), - new RectangleF(40, 80, 30, 30), - new RectangleF(120, 80, 20, 30) - } - }; - - // Multiple regions. - yield return new object[] - { - new Region(new Rectangle(30, 30, 80, 80)), - new RectangleF[] - { - new RectangleF(45, 45, 200, 200), - new RectangleF(160, 260, 10, 10), - new RectangleF(170, 260, 10, 10) - }, - new RectangleF[] - { - new RectangleF(30, 30, 80, 15), - new RectangleF(30, 45, 15, 65) - } - }; - - // Intersecting from the top with a larger rect. - yield return new object[] - { - new Region(new Rectangle(50, 100, 100, 100)), - new RectangleF[] { new RectangleF(30, 70, 150, 40) }, - new RectangleF[] { new RectangleF(50, 110, 100, 90) } - }; - - // Intersecting from the right with a larger rect. - yield return new object[] - { - new Region(new Rectangle(70, 60, 100, 70)), - new RectangleF[] { new RectangleF(40, 10, 100, 150) }, - new RectangleF[] { new RectangleF(140, 60, 30, 70) } - }; - - // Intersecting from the left with a larger rect. - yield return new object[] - { - new Region(new Rectangle(70, 60, 100, 70)), - new RectangleF[] { new RectangleF(100, 10, 100, 150) }, - new RectangleF[] { new RectangleF(70, 60, 30, 70) } - }; - - // Intersecting from the bottom with a larger rect. - yield return new object[] - { - new Region(new Rectangle(20, 20, 100, 100)), - new RectangleF[] { new RectangleF(10, 80, 140, 150) }, - new RectangleF[] { new RectangleF(20, 20, 100, 60) } - }; - - yield return new object[] - { - new Region(new Rectangle(130, 30, 60, 80)), - new RectangleF[] { new RectangleF(170, 40, 60, 80) }, - new RectangleF[] - { - new RectangleF(130, 30, 60, 10), - new RectangleF(130, 40, 40, 70) - } - }; - } - - [Theory] - [MemberData(nameof(Exclude_TestData))] - public void Exclude_Region_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - using (var other = new Region(rect)) - { - region.Exclude(other); - } - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Exclude_UnionRegion_Success() - { - using (var region = new Region(new RectangleF(20, 20, 20, 20))) - using (var union = new Region(new RectangleF(20, 80, 20, 10))) - using (var matrix = new Matrix()) - { - union.Union(new RectangleF(60, 60, 30, 10)); - region.Exclude(union); - Assert.Equal(new RectangleF[] { new RectangleF(20, 20, 20, 20) }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Exclude_InfiniteRegion_Success() - { - using (var region = new Region(new Rectangle(1, 2, 3, 4))) - using (var other = new Region()) - using (var matrix = new Matrix()) - { - region.Exclude(other); - Assert.Equal(new RectangleF[0], region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Exclude_NullRegion_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("region", () => region.Exclude((Region)null)); - } - } - - [Fact] - public void Exclude_DisposedRegion_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new Region().Exclude(CreateDisposedRegion())); - } - - [Fact] - public void Exclude_SameRegion_ThrowsInvalidOperationException() - { - using (var region = new Region()) - { - Assert.Throws(() => region.Exclude(region)); - } - } - - [Theory] - [MemberData(nameof(Exclude_TestData))] - public void Exclude_Rectangle_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - region.Exclude(new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height)); - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Theory] - [MemberData(nameof(Exclude_TestData))] - public void Exclude_RectangleF_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - region.Exclude(rect); - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Theory] - [MemberData(nameof(Exclude_TestData))] - public void Exclude_GraphicsPath_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - using (var path = new GraphicsPath()) - { - path.AddRectangle(rect); - region.Exclude(path); - } - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Exclude_EmptyPathWithInfiniteRegion_MakesInfinite() - { - using (var region = new Region()) - using (var graphicsPath = new GraphicsPath()) - { - region.Exclude(graphicsPath); - Assert.True(region.IsInfinite(s_graphic)); - } - } - - [Fact] - public void Exclude_NullGraphicsPath_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("path", () => region.Exclude((GraphicsPath)null)); - } - } - - [Fact] - public void Exclude_Disposed_ThrowsArgumentException() - { - Region disposedRegion = CreateDisposedRegion(); - - using (var graphicsPath = new GraphicsPath()) - using (var other = new Region()) - { - AssertExtensions.Throws(null, () => disposedRegion.Exclude(graphicsPath)); - AssertExtensions.Throws(null, () => disposedRegion.Exclude(new Rectangle())); - AssertExtensions.Throws(null, () => disposedRegion.Exclude(new RectangleF())); - AssertExtensions.Throws(null, () => disposedRegion.Exclude(other)); - } - } - - [Fact] - public void FromHrgn_ValidHrgn_ReturnsExpected() - { - using (var region = new Region(new Rectangle(1, 2, 3, 4))) - { - IntPtr handle1 = region.GetHrgn(s_graphic); - IntPtr handle2 = region.GetHrgn(s_graphic); - Assert.NotEqual(IntPtr.Zero, handle1); - Assert.NotEqual(handle1, handle2); - - Region newRegion = Region.FromHrgn(handle1); - IntPtr handle3 = newRegion.GetHrgn(s_graphic); - Assert.NotEqual(handle3, handle1); - Assert.Equal(new RectangleF(1, 2, 3, 4), newRegion.GetBounds(s_graphic)); - - region.ReleaseHrgn(handle1); - region.ReleaseHrgn(handle2); - newRegion.ReleaseHrgn(handle3); - } - } - - [Fact] - public void FromHrgn_ZeroHrgn_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => Region.FromHrgn(IntPtr.Zero)); - } - - [Fact] - public void GetHrgn_Infinite_ReturnsZero() - { - using (var region = new Region(new Rectangle(1, 2, 3, 4))) - { - IntPtr handle = region.GetHrgn(s_graphic); - Assert.NotEqual(IntPtr.Zero, handle); - region.ReleaseHrgn(handle); - - region.MakeInfinite(); - Assert.Equal(IntPtr.Zero, region.GetHrgn(s_graphic)); - } - } - - [Fact] - public void GetHrgn_Empty_ReturnsNonZero() - { - using (var region = new Region()) - { - Assert.Equal(IntPtr.Zero, region.GetHrgn(s_graphic)); - - region.MakeEmpty(); - IntPtr handle = region.GetHrgn(s_graphic); - Assert.NotEqual(IntPtr.Zero, handle); - region.ReleaseHrgn(handle); - } - } - - [Fact] - public void GetHrgn_NullGraphics_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("g", () => region.GetHrgn(null)); - } - } - - [Fact] - public void GetHrgn_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedRegion().GetHrgn(s_graphic)); - } - - [Fact] - public void ReleaseHrgn_ZeroHandle_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("regionHandle", () => region.ReleaseHrgn(IntPtr.Zero)); - } - } - - [Fact] - public void GetBounds_NullGraphics_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("g", () => region.GetBounds(null)); - } - } - - [Fact] - public void GetBounds_DisposedGraphics_ThrowsArgumentException() - { - using (var region = new Region()) - using (var image = new Bitmap(10, 10)) - { - var graphics = Graphics.FromImage(image); - graphics.Dispose(); - AssertExtensions.Throws(null, () => region.GetBounds(graphics)); - } - } - - [Fact] - public void GetBounds_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedRegion().GetBounds(s_graphic)); - } - - [Fact] - public void GetRegionData_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedRegion().GetRegionData()); - } - - [Fact] - public void GetRegionScans_CustomMatrix_TransformsRegionScans() - { - using (var matrix = new Matrix()) - using (var region = new Region(new Rectangle(1, 2, 3, 4))) - using (var emptyMatrix = new Matrix()) - { - matrix.Translate(10, 11); - matrix.Scale(5, 6); - - Assert.Equal(new RectangleF[] { new RectangleF(1, 2, 3, 4) }, region.GetRegionScans(emptyMatrix)); - Assert.Equal(new RectangleF[] { new RectangleF(15, 23, 15, 24) }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void GetRegionScans_NullMatrix_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("matrix", () => region.GetRegionScans(null)); - } - } - - [Fact] - public void GetRegionScans_Disposed_ThrowsArgumentException() - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => CreateDisposedRegion().GetRegionScans(matrix)); - } - } - - [Fact] - public void GetRegionScans_DisposedMatrix_ThrowsArgumentException() - { - using (var region = new Region()) - { - var matrix = new Matrix(); - matrix.Dispose(); - AssertExtensions.Throws(null, () => region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Intersect_SmallerRect_Success() - { - using (var clipRegion = new Region()) - using (var matrix = new Matrix()) - { - Rectangle smaller = new Rectangle(5, 5, -10, -10); - - clipRegion.Intersect(smaller); - Assert.False(clipRegion.IsEmpty(s_graphic)); - Assert.False(clipRegion.IsInfinite(s_graphic)); - - RectangleF[] rects = clipRegion.GetRegionScans(matrix); - Assert.Equal(1, rects.Length); - Assert.Equal(new RectangleF(-5, -5, 10, 10), rects[0]); - } - } - - public static IEnumerable Intersect_TestData() - { - yield return new object[] - { - new Region(new Rectangle(500, 30, 60, 80)), - new RectangleF[] { new RectangleF(500, 30, 60, 80) }, - new RectangleF[] { new RectangleF(500, 30, 60, 80) } - }; - yield return new object[] - { - new Region(new Rectangle(0, 0, 0, 0)), - new RectangleF[] { new RectangleF(500, 30, 60, 80) }, - new RectangleF[0] - }; - - yield return new object[] - { - new Region(new Rectangle(500, 30, 60, 80)), - new RectangleF[] { RectangleF.Empty }, - new RectangleF[0] - }; - - yield return new object[] - { - new Region(), - new RectangleF[] { new RectangleF(520, 40, 60, 80) }, - new RectangleF[] { new Rectangle(520, 40, 60, 80) } - }; - - yield return new object[] - { - new Region(), - new RectangleF[] { RectangleF.Empty }, - new RectangleF[0] - }; - - yield return new object[] - { - new Region(new RectangleF(260, 30, 60, 80)), - new RectangleF[] { new RectangleF(290, 40, 60, 90) }, - new RectangleF[] { new RectangleF(290, 40, 30, 70) } - }; - - yield return new object[] - { - new Region(new RectangleF(20, 330, 40, 50)), - new RectangleF[] - { - new RectangleF(50, 340, 40, 50), - new RectangleF(70, 360, 30, 50), - new RectangleF(80, 400, 30, 10) - }, - new RectangleF[0] - }; - } - - [Theory] - [MemberData(nameof(Intersect_TestData))] - public void Intersect_Region_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - using (var rectangleRegion = new Region(rect)) - { - region.Intersect(rectangleRegion); - } - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Intersect_InfiniteRegion_Success() - { - using (var region = new Region(new Rectangle(1, 2, 3, 4))) - using (var matrix = new Matrix()) - using (var infiniteRegion = new Region()) - { - region.Intersect(infiniteRegion); - - Assert.Equal(new RectangleF[] { new Rectangle(1, 2, 3, 4) }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Intersect_NullRegion_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("region", () => region.Intersect((Region)null)); - } - } - - [Fact] - public void Intersect_DisposedRegion_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => new Region().Intersect(CreateDisposedRegion())); - } - - [Fact] - public void Intersect_SameRegion_ThrowsInvalidOperationException() - { - using (var region = new Region()) - { - Assert.Throws(() => region.Intersect(region)); - } - } - - [Theory] - [MemberData(nameof(Intersect_TestData))] - public void Intersect_Rectangle_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - region.Intersect(new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height)); - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Intersect_InfiniteRegionWithSmallerRectangle_Success() - { - using (var region = new Region()) - using (var matrix = new Matrix()) - { - region.Intersect(new Rectangle(5, 5, -10, -10)); - - Assert.False(region.IsEmpty(s_graphic)); - Assert.False(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF[] { new RectangleF(-5, -5, 10, 10) }, region.GetRegionScans(matrix)); - } - } - - [Theory] - [MemberData(nameof(Intersect_TestData))] - public void Intersect_RectangleF_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - region.Intersect(rect); - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Intersect_InfiniteRegionWithSmallerRectangleF_Success() - { - using (var region = new Region()) - using (var matrix = new Matrix()) - { - region.Intersect(new RectangleF(5, 5, -10, -10)); - - Assert.False(region.IsEmpty(s_graphic)); - Assert.False(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF[] { new RectangleF(-5, -5, 10, 10) }, region.GetRegionScans(matrix)); - } - } - - [Theory] - [MemberData(nameof(Intersect_TestData))] - public void Intersect_GraphicsPath_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - using (var path = new GraphicsPath()) - { - path.AddRectangle(rect); - region.Intersect(path); - } - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Intersect_EmptyPathWithInfiniteRegion_MakesEmpty() - { - using (var region = new Region()) - using (var graphicsPath = new GraphicsPath()) - { - region.Intersect(graphicsPath); - Assert.True(region.IsEmpty(s_graphic)); - } - } - - [Fact] - public void Intersect_NullGraphicsPath_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("path", () => region.Intersect((GraphicsPath)null)); - } - } - - [Fact] - public void Intersect_Disposed_ThrowsArgumentException() - { - Region disposedRegion = CreateDisposedRegion(); - - using (var graphicsPath = new GraphicsPath()) - using (var other = new Region()) - { - AssertExtensions.Throws(null, () => disposedRegion.Intersect(graphicsPath)); - AssertExtensions.Throws(null, () => disposedRegion.Intersect(new Rectangle())); - AssertExtensions.Throws(null, () => disposedRegion.Intersect(new RectangleF())); - AssertExtensions.Throws(null, () => disposedRegion.Intersect(other)); - } - } - - [Fact] - public void IsEmpty_NullGraphics_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("g", () => region.IsEmpty(null)); - } - } - - [Fact] - public void IsEmpty_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedRegion().IsEmpty(s_graphic)); - } - - [Fact] - public void IsInfinite_NullGraphics_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("g", () => region.IsInfinite(null)); - } - } - - [Fact] - public void IsInfinite_DisposedGraphics_ThrowsArgumentException() - { - using (var region = new Region()) - using (var image = new Bitmap(10, 10)) - { - var graphics = Graphics.FromImage(image); - graphics.Dispose(); - AssertExtensions.Throws(null, () => region.IsInfinite(graphics)); - } - } - - [Fact] - public void IsInfinite_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedRegion().IsInfinite(s_graphic)); - } - - public static IEnumerable IsVisible_Rectangle_TestData() - { - var infiniteExclude = new Region(); - infiniteExclude.Exclude(new Rectangle(387, 292, 189, 133)); - infiniteExclude.Exclude(new Rectangle(387, 66, 189, 133)); - - yield return new object[] { infiniteExclude, new Rectangle(66, 292, 189, 133), true }; - yield return new object[] { new Region(), Rectangle.Empty, false }; - - yield return new object[] { new Region(new Rectangle(0, 0, 10, 10)), new Rectangle(0, 0, 0, 1), false }; - yield return new object[] { new Region(new Rectangle(500, 30, 60, 80)), new Rectangle(500, 30, 60, 80), true }; - yield return new object[] { new Region(new Rectangle(500, 30, 60, 80)), new Rectangle(520, 40, 60, 80), true }; - - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Rectangle(1, 1, 2, 1), true }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Rectangle(1, 1, 2, 2), true }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Rectangle(1, 1, 10, 10), true }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Rectangle(1, 1, 1, 1), true }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Rectangle(2, 2, 1, 1), false }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Rectangle(0, 0, 1, 1), false }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Rectangle(3, 3, 1, 1), false }; - } - - [Theory] - [MemberData(nameof(IsVisible_Rectangle_TestData))] - public void IsVisible_Rectangle_ReturnsExpected(Region region, Rectangle rectangle, bool expected) - { - using (region) - using (var image = new Bitmap(10, 10)) - { - var disposedGraphics = Graphics.FromImage(image); - disposedGraphics.Dispose(); - - Assert.Equal(expected, region.IsVisible(rectangle)); - Assert.Equal(expected, region.IsVisible((RectangleF)rectangle)); - Assert.Equal(expected, region.IsVisible(rectangle, s_graphic)); - Assert.Equal(expected, region.IsVisible(rectangle, disposedGraphics)); - Assert.Equal(expected, region.IsVisible(rectangle, null)); - Assert.Equal(expected, region.IsVisible((RectangleF)rectangle, s_graphic)); - Assert.Equal(expected, region.IsVisible((RectangleF)rectangle, disposedGraphics)); - Assert.Equal(expected, region.IsVisible((RectangleF)rectangle, null)); - - Assert.Equal(expected, region.IsVisible(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height)); - Assert.Equal(expected, region.IsVisible((float)rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height)); - Assert.Equal(expected, region.IsVisible(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, s_graphic)); - Assert.Equal(expected, region.IsVisible(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, disposedGraphics)); - Assert.Equal(expected, region.IsVisible(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, null)); - Assert.Equal(expected, region.IsVisible((float)rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, s_graphic)); - Assert.Equal(expected, region.IsVisible((float)rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, disposedGraphics)); - Assert.Equal(expected, region.IsVisible((float)rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, null)); - } - } - - public static IEnumerable IsVisible_Point_TestData() - { - var infiniteExclude = new Region(); - infiniteExclude.Exclude(new Rectangle(387, 292, 189, 133)); - infiniteExclude.Exclude(new Rectangle(387, 66, 189, 133)); - - yield return new object[] { infiniteExclude, new Point(66, 292), true }; - yield return new object[] { new Region(), Point.Empty, true }; - - yield return new object[] { new Region(new Rectangle(500, 30, 60, 80)), new Point(500, 29), false }; - yield return new object[] { new Region(new Rectangle(500, 30, 60, 80)), new Point(500, 30), true }; - - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Point(0, 1), false }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Point(1, 0), false }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Point(2, 0), false }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Point(3, 0), false }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Point(1, 1), true }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Point(2, 1), true }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Point(3, 1), false }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Point(0, 2), false }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Point(2, 2), false }; - yield return new object[] { new Region(new Rectangle(1, 1, 2, 1)), new Point(3, 2), false }; - } - - [Theory] - [MemberData(nameof(IsVisible_Point_TestData))] - public void IsVisible_Point_ReturnsExpected(Region region, Point point, bool expected) - { - using (region) - using (var image = new Bitmap(10, 10)) - { - var disposedGraphics = Graphics.FromImage(image); - disposedGraphics.Dispose(); - - Assert.Equal(expected, region.IsVisible(point)); - Assert.Equal(expected, region.IsVisible((PointF)point)); - Assert.Equal(expected, region.IsVisible(point, s_graphic)); - Assert.Equal(expected, region.IsVisible(point, disposedGraphics)); - Assert.Equal(expected, region.IsVisible(point, null)); - Assert.Equal(expected, region.IsVisible((PointF)point, s_graphic)); - Assert.Equal(expected, region.IsVisible((PointF)point, disposedGraphics)); - Assert.Equal(expected, region.IsVisible((PointF)point, null)); - - Assert.Equal(expected, region.IsVisible(point.X, point.Y)); - Assert.Equal(expected, region.IsVisible(point.X, point.Y, s_graphic)); - Assert.Equal(expected, region.IsVisible(point.X, point.Y, disposedGraphics)); - Assert.Equal(expected, region.IsVisible(point.X, point.Y, null)); - - Assert.Equal(expected, region.IsVisible(point.X, point.Y, s_graphic)); - Assert.Equal(expected, region.IsVisible(point.X, point.Y, disposedGraphics)); - Assert.Equal(expected, region.IsVisible(point.X, point.Y, null)); - Assert.Equal(expected, region.IsVisible((float)point.X, point.Y, s_graphic)); - Assert.Equal(expected, region.IsVisible((float)point.X, point.Y, disposedGraphics)); - Assert.Equal(expected, region.IsVisible((float)point.X, point.Y, null)); - } - } - - [Fact] - public void IsVisible_Disposed_ThrowsArgumentException() - { - Region disposedRegion = CreateDisposedRegion(); - - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(1f, 2f)); - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(new PointF(1, 2))); - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(new Point(1, 2))); - - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(1f, 2f, s_graphic)); - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(new PointF(1, 2), s_graphic)); - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(new Point(1, 2), s_graphic)); - - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(1f, 2f, 3f, 4f)); - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(new Rectangle(1, 2, 3, 4))); - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(new RectangleF(1, 2, 3, 4))); - - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(1f, 2f, 3f, 4f, s_graphic)); - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(new Rectangle(1, 2, 3, 4), s_graphic)); - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(new RectangleF(1, 2, 3, 4), s_graphic)); - - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(1, 2, s_graphic)); - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(1, 2, 3, 4)); - AssertExtensions.Throws(null, () => disposedRegion.IsVisible(1, 2, 3, 4, s_graphic)); - } - - [Theory] - [MemberData(nameof(Region_TestData))] - public void MakeEmpty_NonEmpty_Success(Region region) - { - using (region) - { - region.MakeEmpty(); - Assert.True(region.IsEmpty(s_graphic)); - Assert.False(region.IsInfinite(s_graphic)); - Assert.Equal(RectangleF.Empty, region.GetBounds(s_graphic)); - - using (var matrix = new Matrix()) - { - Assert.Empty(region.GetRegionScans(matrix)); - } - - region.MakeEmpty(); - Assert.True(region.IsEmpty(s_graphic)); - } - } - - [Fact] - public void MakeEmpty_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedRegion().MakeEmpty()); - } - - [Theory] - [MemberData(nameof(Region_TestData))] - public void MakeInfinite_NonInfinity_Success(Region region) - { - using (region) - { - region.MakeInfinite(); - Assert.False(region.IsEmpty(s_graphic)); - Assert.True(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF(-4194304, -4194304, 8388608, 8388608), region.GetBounds(s_graphic)); - - region.MakeInfinite(); - Assert.False(region.IsEmpty(s_graphic)); - Assert.True(region.IsInfinite(s_graphic)); - } - } - - [Fact] - public void MakeInfinite_Disposed_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => CreateDisposedRegion().MakeInfinite()); - } - - public static IEnumerable Union_TestData() - { - yield return new object[] - { - new Region(new Rectangle(500, 30, 60, 80)), - new RectangleF[] { new RectangleF(500, 30, 60, 80) }, - new RectangleF[] { new RectangleF(500, 30, 60, 80) } - }; - - yield return new object[] - { - new Region(new Rectangle(500, 30, 60, 80)), - new RectangleF[] { RectangleF.Empty }, - new RectangleF[] { new RectangleF(500, 30, 60, 80) } - }; - - yield return new object[] - { - new Region(new Rectangle(500, 30, 60, 80)), - new RectangleF[] { new RectangleF(520, 30, 60, 80) }, - new RectangleF[] { new RectangleF(500, 30, 80, 80) } - }; - - yield return new object[] - { - new Region(new Rectangle(500, 30, 60, 80)), - new RectangleF[] { new RectangleF(520, 40, 60, 80) }, - new RectangleF[] - { - new RectangleF(500, 30, 60, 10), - new RectangleF(500, 40, 80, 70), - new RectangleF(520, 110, 60, 10), - } - }; - - yield return new object[] - { - new Region(), - new RectangleF[] { new RectangleF(520, 40, 60, 80) }, - new RectangleF[] { new Rectangle(-4194304, -4194304, 8388608, 8388608) } - }; - - yield return new object[] - { - new Region(), - new RectangleF[] { RectangleF.Empty }, - new RectangleF[] { new Rectangle(-4194304, -4194304, 8388608, 8388608) } - }; - - // No intersecting rects. - yield return new object[] - { - new Region(new Rectangle(20, 20, 20, 20)), - new RectangleF[] - { - new RectangleF(20, 80, 20, 10), - new RectangleF(60, 60, 30, 10) - }, - new RectangleF[] - { - new RectangleF(20, 20, 20, 20), - new RectangleF(60, 60, 30, 10), - new RectangleF(20, 80, 20, 10) - } - }; - - yield return new object[] - { - new Region(new Rectangle(20, 180, 40, 50)), - new RectangleF[] - { - new RectangleF(50, 190, 40, 50), - new RectangleF(70, 210, 30, 50) - }, - new RectangleF[] - { - new RectangleF(20, 180, 40, 10), - new RectangleF(20, 190, 70, 20), - new RectangleF(20, 210, 80, 20), - new RectangleF(50, 230, 50, 10), - new RectangleF(70, 240, 30, 20) - } - }; - - yield return new object[] - { - new Region(new Rectangle(20, 330, 40, 50)), - new RectangleF[] - { - new RectangleF(50, 340, 40, 50), - new RectangleF(70, 360, 30, 50), - new RectangleF(80, 400, 30, 10) - }, - new RectangleF[] - { - new RectangleF(20, 330, 40, 10), - new RectangleF(20, 340, 70, 20), - new RectangleF(20, 360, 80, 20), - new RectangleF(50, 380, 50, 10), - new RectangleF(70, 390, 30, 10), - new RectangleF(70, 400, 40, 10) - } - }; - - yield return new object[] - { - new Region(new Rectangle(10, 20, 50, 50)), - new RectangleF[] - { - new RectangleF(100, 100, 60, 60), - new RectangleF(200, 200, 80, 80) - }, - new RectangleF[] - { - new RectangleF(10, 20, 50, 50), - new RectangleF(100, 100, 60, 60), - new RectangleF(200, 200, 80, 80) - } - }; - - // Intersecting from the right. - yield return new object[] - { - new Region(new Rectangle(10, 10, 100, 100)), - new RectangleF[] { new RectangleF(40, 60, 100, 20) }, - new RectangleF[] - { - new RectangleF(10, 10, 100, 50), - new RectangleF(10, 60, 130, 20), - new RectangleF(10, 80, 100, 30) - } - }; - - // Intersecting from the left. - yield return new object[] - { - new Region(new Rectangle(70, 10, 100, 100)), - new RectangleF[] { new RectangleF(40, 60, 100, 20) }, - new RectangleF[] - { - new RectangleF(70, 10, 100, 50), - new RectangleF(40, 60, 130, 20), - new RectangleF(70, 80, 100, 30) - } - }; - - // Intersecting from the top. - yield return new object[] - { - new Region(new Rectangle(40, 100, 100, 100)), - new RectangleF[] { new RectangleF(70, 80, 50, 40) }, - new RectangleF[] - { - new RectangleF(70, 80, 50, 20), - new RectangleF(40, 100, 100, 100) - } - }; - - // Intersecting from the bottom. - yield return new object[] - { - new Region(new Rectangle(40, 10, 100, 100)), - new RectangleF[] { new RectangleF(70, 80, 50, 40) }, - new RectangleF[] - { - new RectangleF(40, 10, 100, 100), - new RectangleF(70, 110, 50, 10) - } - }; - - // Multiple regions separated by 0 pixels. - yield return new object[] - { - new Region(new Rectangle(30, 30, 80, 80)), - new RectangleF[] - { - new RectangleF(45, 45, 200, 200), - new RectangleF(160, 260, 10, 10), - new RectangleF(170, 260, 10, 10) - }, - new RectangleF[] - { - new RectangleF(30, 30, 80, 15), - new RectangleF(30, 45, 215, 65), - new RectangleF(45, 110, 200, 135), - new RectangleF(160, 260, 20, 10) - } - }; - } - - [Theory] - [MemberData(nameof(Union_TestData))] - public void Union_Region_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - using (var other = new Region(rect)) - { - region.Union(other); - } - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Union_InfiniteRegion_Success() - { - using (var region = new Region(new Rectangle(1, 2, 3, 4))) - using (var other = new Region()) - using (var matrix = new Matrix()) - { - region.Union(other); - - Assert.Equal(new RectangleF[] { new Rectangle(-4194304, -4194304, 8388608, 8388608) }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Union_NullRegion_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("region", () => region.Union((Region)null)); - } - } - - [Fact] - public void Union_DisposedRegion_ThrowsArgumentException() - { - using (var region = new Region()) - { - AssertExtensions.Throws(null, () => region.Union(CreateDisposedRegion())); - } - } - - [Fact] - public void Union_SameRegion_ThrowsInvalidOperationException() - { - using (var region = new Region()) - { - Assert.Throws(() => region.Union(region)); - } - } - - [Theory] - [MemberData(nameof(Union_TestData))] - public void Union_Rectangle_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - region.Union(new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height)); - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Theory] - [MemberData(nameof(Union_TestData))] - public void Union_RectangleF_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - region.Union(rect); - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Theory] - [MemberData(nameof(Union_TestData))] - public void Union_GraphicsPath_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - using (var path = new GraphicsPath()) - { - path.AddRectangle(rect); - region.Union(path); - } - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Union_EmptyPathWithInfiniteRegion_MakesInfinite() - { - using (var region = new Region()) - using (var graphicsPath = new GraphicsPath()) - { - region.Union(graphicsPath); - Assert.True(region.IsInfinite(s_graphic)); - } - } - - [Fact] - public void Union_NullGraphicsPath_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("path", () => region.Union((GraphicsPath)null)); - } - } - - [Fact] - public void Union_Disposed_ThrowsArgumentException() - { - Region disposedRegion = CreateDisposedRegion(); - - using (var graphicsPath = new GraphicsPath()) - using (var other = new Region()) - { - AssertExtensions.Throws(null, () => disposedRegion.Union(graphicsPath)); - AssertExtensions.Throws(null, () => disposedRegion.Union(new Rectangle())); - AssertExtensions.Throws(null, () => disposedRegion.Union(new RectangleF())); - AssertExtensions.Throws(null, () => disposedRegion.Union(disposedRegion)); - } - } - - [Fact] - public void Transform_EmptyMatrix_Nop() - { - using (var region = new Region(new RectangleF(1, 2, 3, 4))) - using (var matrix = new Matrix()) - { - region.Transform(matrix); - Assert.Equal(new RectangleF[] { new RectangleF(1, 2, 3, 4) }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Transform_CustomMatrix_Success() - { - using (var region = new Region(new RectangleF(1, 2, 3, 4))) - using (var matrix = new Matrix()) - using (var emptyMatrix = new Matrix()) - { - matrix.Translate(10, 11); - matrix.Scale(5, 6); - - region.Transform(matrix); - Assert.Equal(new RectangleF[] { new RectangleF(15, 23, 15, 24) }, region.GetRegionScans(emptyMatrix)); - } - } - - [Theory] - [InlineData(0, 0, 0)] - [InlineData(2, 2, 0)] - [InlineData(0.5, 0.5, 0)] - [InlineData(1, 1, 45)] - public void Transform_Infinity_Nop(float scaleX, float scaleY, int angle) - { - using (var region = new Region()) - using (var matrix = new Matrix()) - using (var emptyMatrix = new Matrix()) - { - matrix.Translate(10, 11); - matrix.Scale(scaleX, scaleY); - matrix.Rotate(angle); - - region.Transform(matrix); - Assert.True(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF[] { new RectangleF(-4194304, -4194304, 8388608, 8388608) }, region.GetRegionScans(emptyMatrix)); - } - } - - [Fact] - public void Transform_InfinityIntersectScale_Success() - { - using (var region = new Region()) - using (var matrix = new Matrix()) - using (var emptyMatrix = new Matrix()) - { - matrix.Scale(2, 0.5f); - - region.Intersect(new Rectangle(-10, -10, 20, 20)); - region.Transform(matrix); - Assert.False(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF[] { new RectangleF(-20, -5, 40, 10) }, region.GetRegionScans(emptyMatrix)); - } - } - - [Fact] - public void Transform_InfinityIntersectTransform_Success() - { - using (var region = new Region()) - using (var matrix = new Matrix(2, 0, 0, 0.5f, 10, 10)) - using (var emptyMatrix = new Matrix()) - { - region.Intersect(new Rectangle(-10, -10, 20, 20)); - region.Transform(matrix); - - Assert.False(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF[] { new RectangleF(-10, 5, 40, 10) }, region.GetRegionScans(emptyMatrix)); - } - } - - [Fact] - public void Transform_NullMatrix_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("matrix", () => region.Transform(null)); - } - } - - [Fact] - public void Transform_Disposed_ThrowsArgumentException() - { - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => CreateDisposedRegion().Transform(matrix)); - } - } - - [Theory] - [InlineData(0, 0)] - [InlineData(2, 3)] - [InlineData(-2, -3)] - public void Translate_Int_Success(float dx, float dy) - { - using (var region = new Region(new RectangleF(1, 2, 3, 4))) - using (var matrix = new Matrix()) - { - region.Translate(dx, dy); - Assert.Equal(new RectangleF[] { new RectangleF(1 + dx, 2 + dy, 3, 4) }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Translate_IntInfinityIntersect_Success() - { - using (var region = new Region()) - using (var matrix = new Matrix()) - { - region.Intersect(new Rectangle(-10, -10, 20, 20)); - region.Translate(10, 10); - - Assert.False(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF[] { new RectangleF(0, 0, 20, 20) }, region.GetRegionScans(matrix)); - } - } - - [Theory] - [InlineData(0, 0)] - [InlineData(2, 3)] - public void Translate_Float_Success(int dx, int dy) - { - using (var region = new Region(new RectangleF(1, 2, 3, 4))) - using (var matrix = new Matrix()) - { - region.Translate(dx, dy); - Assert.Equal(new RectangleF[] { new RectangleF(1 + dx, 2 + dy, 3, 4) }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Translate_FloatInfinityIntersect_Success() - { - using (var region = new Region()) - using (var matrix = new Matrix()) - { - region.Intersect(new Rectangle(-10, -10, 20, 20)); - region.Translate(10f, 10f); - - Assert.False(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF[] { new RectangleF(0, 0, 20, 20) }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Translate_Infinity_Nop() - { - using (var region = new Region()) - using (var matrix = new Matrix()) - { - region.Translate(10, 10); - region.Translate(10f, 10f); - - Assert.True(region.IsInfinite(s_graphic)); - Assert.Equal(new RectangleF[] { new RectangleF(-4194304, -4194304, 8388608, 8388608) }, region.GetRegionScans(matrix)); - } - } - - [Theory] - [InlineData(float.MaxValue)] - [InlineData(float.MinValue)] - [InlineData(float.NaN)] - [InlineData(float.PositiveInfinity)] - [InlineData(float.NegativeInfinity)] - public void Translate_InvalidFloatValue_EmptiesRegion(float f) - { - using (var region = new Region(new RectangleF(1, 2, 3, 4))) - using (var matrix = new Matrix()) - { - region.Translate(f, 0); - - Assert.True(region.IsEmpty(s_graphic)); - Assert.False(region.IsInfinite(s_graphic)); - Assert.Empty(region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Translate_Disposed_ThrowsArgumentException() - { - Region disposedRegion = CreateDisposedRegion(); - - AssertExtensions.Throws(null, () => disposedRegion.Translate(1, 2)); - AssertExtensions.Throws(null, () => disposedRegion.Translate(1f, 2f)); - } - - public static IEnumerable Xor_TestData() - { - yield return new object[] - { - new Region(new RectangleF(500, 30, 60, 80)), - new RectangleF[] { new RectangleF(500, 30, 60, 80) }, - new RectangleF[0] - }; - - yield return new object[] - { - new Region(new RectangleF(500, 30, 60, 80)), - new RectangleF[] { RectangleF.Empty }, - new RectangleF[] { new RectangleF(500, 30, 60, 80) } - }; - - yield return new object[] - { - new Region(new RectangleF(0, 0, 0, 0)), - new RectangleF[] { new RectangleF(500, 30, 60, 80) }, - new RectangleF[] { new RectangleF(500, 30, 60, 80) } - }; - - yield return new object[] - { - new Region(), - new RectangleF[] { new RectangleF(520, 40, 60, 80) }, - new RectangleF[] - { - new RectangleF(-4194304, -4194304, 8388608, 4194344), - new RectangleF(-4194304, 40, 4194824, 80), - new RectangleF(580, 40, 4193724, 80), - new RectangleF(-4194304, 120, 8388608, 4194184) - } - }; - - yield return new object[] - { - new Region(), - new RectangleF[] { RectangleF.Empty }, - new RectangleF[] { new Rectangle(-4194304, -4194304, 8388608, 8388608) } - }; - - yield return new object[] - { - new Region(new RectangleF(380, 30, 60, 80)), - new RectangleF[] { new RectangleF(410, 40, 60, 80) }, - new RectangleF[] - { - new RectangleF(380, 30, 60, 10), - new RectangleF(380, 40, 30, 70), - new RectangleF(440, 40, 30, 70), - new RectangleF(410, 110, 60, 10) - } - }; - } - - [Theory] - [MemberData(nameof(Xor_TestData))] - public void Xor_Region_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - using (var other = new Region(rect)) - { - region.Xor(other); - } - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Xor_InfiniteRegion_Success() - { - using (var region = new Region(new Rectangle(1, 2, 3, 4))) - using (var other = new Region()) - using (var matrix = new Matrix()) - { - region.Xor(other); - - Assert.Equal(new RectangleF[] - { - new RectangleF(-4194304, -4194304, 8388608, 4194306), - new RectangleF(-4194304, 2, 4194305, 4), - new RectangleF(4, 2, 4194300, 4), - new RectangleF(-4194304, 6, 8388608, 4194298) - }, region.GetRegionScans(matrix)); - } - } - - [Fact] - public void Xor_NullRegion_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("region", () => region.Xor((Region)null)); - } - } - - [Fact] - public void Xor_DisposedRegion_ThrowsArgumentException() - { - using (var region = new Region()) - { - AssertExtensions.Throws(null, () => region.Xor(CreateDisposedRegion())); - } - } - - [Fact] - public void Xor_SameRegion_ThrowsInvalidOperationException() - { - using (var region = new Region()) - { - Assert.Throws(() => region.Xor(region)); - } - } - - [Theory] - [MemberData(nameof(Xor_TestData))] - public void Xor_Rectangle_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - region.Xor(new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height)); - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Theory] - [MemberData(nameof(Xor_TestData))] - public void Xor_RectangleF_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - region.Xor(rect); - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Theory] - [MemberData(nameof(Xor_TestData))] - public void Xor_GraphicsPath_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) - { - using (region) - { - foreach (RectangleF rect in rectangles) - { - using (var path = new GraphicsPath()) - { - path.AddRectangle(rect); - region.Xor(path); - } - } - - using (var matrix = new Matrix()) - { - Assert.Equal(expectedScans, region.GetRegionScans(matrix)); - } - } - } - - [Fact] - public void Xor_EmptyPathWithInfiniteRegion_MakesInfinite() - { - using (var region = new Region()) - using (var graphicsPath = new GraphicsPath()) - { - region.Xor(graphicsPath); - Assert.True(region.IsInfinite(s_graphic)); - } - } - - [Fact] - public void Xor_NullGraphicsPath_ThrowsArgumentNullException() - { - using (var region = new Region()) - { - AssertExtensions.Throws("path", () => region.Xor((GraphicsPath)null)); - } - } - - [Fact] - public void Xor_Disposed_ThrowsArgumentException() - { - Region disposedRegion = CreateDisposedRegion(); - - using (var graphicsPath = new GraphicsPath()) - using (var other = new Region()) - { - AssertExtensions.Throws(null, () => disposedRegion.Xor(graphicsPath)); - AssertExtensions.Throws(null, () => disposedRegion.Xor(new Rectangle())); - AssertExtensions.Throws(null, () => disposedRegion.Xor(new RectangleF())); - AssertExtensions.Throws(null, () => disposedRegion.Xor(other)); - } - } -} diff --git a/src/System.Drawing.Common/tests/SolidBrushTests.cs b/src/System.Drawing.Common/tests/SolidBrushTests.cs deleted file mode 100644 index 03102d662c4..00000000000 --- a/src/System.Drawing.Common/tests/SolidBrushTests.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class SolidBrushTests -{ - public static IEnumerable Colors_TestData() - { - yield return new object[] { new Color(), Color.FromArgb(0) }; - yield return new object[] { Color.PapayaWhip, Color.PapayaWhip }; - } - - [Theory] - [MemberData(nameof(Colors_TestData))] - public void Ctor_Color(Color color, Color expectedColor) - { - var brush = new SolidBrush(color); - Assert.Equal(expectedColor, brush.Color); - } - - [Fact] - public void Clone_Color_ReturnsClone() - { - var brush = new SolidBrush(Color.PeachPuff); - SolidBrush clone = Assert.IsType(brush.Clone()); - - Assert.NotSame(clone, brush); - Assert.Equal(brush.Color.ToArgb(), clone.Color.ToArgb()); - - // Known colors are not preserved across clones. - Assert.NotEqual(Color.PeachPuff, clone.Color); - - // Modifying the original brush should not modify the clone. - brush.Color = Color.PapayaWhip; - Assert.NotEqual(Color.PapayaWhip, clone.Color); - } - - [Fact] - public void Clone_ImmutableColor_ReturnsMutableClone() - { - SolidBrush brush = Assert.IsType(Brushes.Bisque); - SolidBrush clone = Assert.IsType(brush.Clone()); - - clone.Color = SystemColors.AppWorkspace; - Assert.Equal(SystemColors.AppWorkspace, clone.Color); - Assert.Equal(Color.Bisque, brush.Color); - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - var brush = new SolidBrush(Color.LavenderBlush); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Clone()); - } - - [Fact] - public void Color_EmptyAndGetDisposed_ThrowsArgumentException() - { - var brush = new SolidBrush(new Color()); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Color); - } - - [Fact] - public void Color_NonEmptyAndGetDisposed_ReturnsExpected() - { - var brush = new SolidBrush(Color.Aquamarine); - brush.Dispose(); - - Assert.Equal(Color.Aquamarine, brush.Color); - } - - [Fact] - public void Color_SetValid_GetReturnsExpected() - { - var brush = new SolidBrush(Color.Goldenrod) { Color = Color.GhostWhite }; - Assert.Equal(Color.GhostWhite, brush.Color); - } - - [Fact] - public void Color_SetDisposed_ThrowsArgumentException() - { - var brush = new SolidBrush(new Color()); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Color = Color.WhiteSmoke); - } - - [Fact] - public void Color_SetImmutable_ThrowsArgumentException() - { - SolidBrush brush = Assert.IsType(SystemBrushes.ActiveBorder); - AssertExtensions.Throws(null, () => brush.Color = Color.AntiqueWhite); - } - - [Fact] - public void Dispose_MultipleTimes_Success() - { - var brush = new SolidBrush(Color.Plum); - brush.Dispose(); - brush.Dispose(); - } - - [Fact] - public void Dispose_SetImmutable_ThrowsArgumentException() - { - SolidBrush brush = Assert.IsType(SystemBrushes.ActiveBorder); - AssertExtensions.Throws(null, () => brush.Dispose()); - } -} diff --git a/src/System.Drawing.Common/tests/StringFormatTests.cs b/src/System.Drawing.Common/tests/StringFormatTests.cs deleted file mode 100644 index 17820389de7..00000000000 --- a/src/System.Drawing.Common/tests/StringFormatTests.cs +++ /dev/null @@ -1,481 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Text; - -namespace System.Drawing.Tests; - -public class StringFormatTests -{ - private const int RandomLanguageCode = 10; - private const int EnglishLanguageCode = 2057; - - [Fact] - public void Ctor_Default() - { - using (var format = new StringFormat()) - { - Assert.Equal(StringAlignment.Near, format.Alignment); - Assert.Equal(0, format.DigitSubstitutionLanguage); - Assert.Equal(StringDigitSubstitute.User, format.DigitSubstitutionMethod); - Assert.Equal((StringFormatFlags)0, format.FormatFlags); - Assert.Equal(HotkeyPrefix.None, format.HotkeyPrefix); - Assert.Equal(StringAlignment.Near, format.LineAlignment); - Assert.Equal(StringTrimming.Character, format.Trimming); - } - } - - [Theory] - [InlineData(StringFormatFlags.DirectionRightToLeft | StringFormatFlags.DirectionVertical)] - [InlineData((StringFormatFlags)(-1))] - public void Ctor_Options(StringFormatFlags options) - { - using (var format = new StringFormat(options)) - { - Assert.Equal(StringAlignment.Near, format.Alignment); - Assert.Equal(0, format.DigitSubstitutionLanguage); - Assert.Equal(StringDigitSubstitute.User, format.DigitSubstitutionMethod); - Assert.Equal(options, format.FormatFlags); - Assert.Equal(HotkeyPrefix.None, format.HotkeyPrefix); - Assert.Equal(StringAlignment.Near, format.LineAlignment); - Assert.Equal(StringTrimming.Character, format.Trimming); - } - } - - [Theory] - [InlineData(StringFormatFlags.DirectionRightToLeft | StringFormatFlags.DirectionVertical, RandomLanguageCode)] - [InlineData(StringFormatFlags.NoClip, EnglishLanguageCode)] - [InlineData((StringFormatFlags)(-1), -1)] - public void Ctor_Options_Language(StringFormatFlags options, int language) - { - using (var format = new StringFormat(options, language)) - { - Assert.Equal(StringAlignment.Near, format.Alignment); - Assert.Equal(0, format.DigitSubstitutionLanguage); - Assert.Equal(StringDigitSubstitute.User, format.DigitSubstitutionMethod); - Assert.Equal(options, format.FormatFlags); - Assert.Equal(HotkeyPrefix.None, format.HotkeyPrefix); - Assert.Equal(StringAlignment.Near, format.LineAlignment); - Assert.Equal(StringTrimming.Character, format.Trimming); - } - } - - [Fact] - public void Ctor_Format() - { - using (var original = new StringFormat(StringFormatFlags.NoClip, EnglishLanguageCode)) - using (var format = new StringFormat(original)) - { - Assert.Equal(StringAlignment.Near, format.Alignment); - Assert.Equal(0, format.DigitSubstitutionLanguage); - Assert.Equal(StringDigitSubstitute.User, format.DigitSubstitutionMethod); - Assert.Equal(StringFormatFlags.NoClip, format.FormatFlags); - Assert.Equal(HotkeyPrefix.None, format.HotkeyPrefix); - Assert.Equal(StringAlignment.Near, format.LineAlignment); - Assert.Equal(StringTrimming.Character, format.Trimming); - - // The new format is a clone. - original.FormatFlags = StringFormatFlags.NoFontFallback; - Assert.Equal(StringFormatFlags.NoClip, format.FormatFlags); - } - } - - [Fact] - public void Ctor_NullFormat_ThrowsArgumentNullException() - { - AssertExtensions.Throws("format", () => new StringFormat(null)); - } - - [Fact] - public void Ctor_DisposedFormat_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => new StringFormat(format)); - } - - [Fact] - public void Dispose_MultipleTimes_Success() - { - var format = new StringFormat(); - format.Dispose(); - format.Dispose(); - } - - [Fact] - public void Clone_Valid_Success() - { - using (var original = new StringFormat(StringFormatFlags.NoClip, EnglishLanguageCode)) - using (StringFormat format = Assert.IsType(original.Clone())) - { - Assert.Equal(StringAlignment.Near, format.Alignment); - Assert.Equal(0, format.DigitSubstitutionLanguage); - Assert.Equal(StringDigitSubstitute.User, format.DigitSubstitutionMethod); - Assert.Equal(StringFormatFlags.NoClip, format.FormatFlags); - Assert.Equal(HotkeyPrefix.None, format.HotkeyPrefix); - Assert.Equal(StringAlignment.Near, format.LineAlignment); - Assert.Equal(StringTrimming.Character, format.Trimming); - - // The new format is a clone. - original.FormatFlags = StringFormatFlags.NoFontFallback; - Assert.Equal(StringFormatFlags.NoClip, format.FormatFlags); - } - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.Clone()); - } - - [Theory] - [InlineData(0, StringDigitSubstitute.None, 0)] - [InlineData(EnglishLanguageCode, StringDigitSubstitute.Traditional, EnglishLanguageCode)] - [InlineData(int.MaxValue, StringDigitSubstitute.Traditional + 1, 65535)] - [InlineData(-1, StringDigitSubstitute.User - 1, 65535)] - public void SetDigitSubstitution_Invoke_SetsProperties(int language, StringDigitSubstitute substitute, int expectedLanguage) - { - using (var format = new StringFormat()) - { - format.SetDigitSubstitution(language, substitute); - Assert.Equal(expectedLanguage, format.DigitSubstitutionLanguage); - Assert.Equal(substitute, format.DigitSubstitutionMethod); - } - } - - [Fact] - public void SetDigitSubstitution_Disposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.SetDigitSubstitution(0, StringDigitSubstitute.None)); - } - - [Theory] - [InlineData(0, new float[0])] - [InlineData(10, new float[] { 1, 2.3f, 4, float.PositiveInfinity, float.NaN })] - public void SetTabStops_GetTabStops_ReturnsExpected(float firstTabOffset, float[] tabStops) - { - using (var format = new StringFormat()) - { - format.SetTabStops(firstTabOffset, tabStops); - - Assert.Equal(tabStops, format.GetTabStops(out float actualFirstTabOffset)); - Assert.Equal(firstTabOffset, actualFirstTabOffset); - } - } - - [Fact] - public void SetTabStops_NullTabStops_ThrowsNullReferenceException() - { - using (var format = new StringFormat()) - { - Assert.Throws(() => format.SetTabStops(0, null)); - } - } - - [Fact] - public void SetTabStops_NegativeFirstTabOffset_ThrowsArgumentException() - { - using (var format = new StringFormat()) - { - AssertExtensions.Throws(null, () => format.SetTabStops(-1, new float[0])); - } - } - - [Fact] - public void SetTabStops_NegativeInfinityInTabStops_ThrowsNotImplementedException() - { - using (var format = new StringFormat()) - { - Assert.Throws(() => format.SetTabStops(0, new float[] { float.NegativeInfinity })); - } - } - - [Fact] - public void SetTabStops_Disposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.SetTabStops(0, new float[0])); - } - - [Fact] - public void GetTabStops_Disposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.GetTabStops(out float firstTabOffset)); - } - - public static IEnumerable SetMeasurableCharacterRanges_TestData() - { - yield return new object[] { new CharacterRange[0] }; - yield return new object[] { new CharacterRange[] { new CharacterRange(1, 2) } }; - yield return new object[] { new CharacterRange[] { new CharacterRange(-1, -1) } }; - yield return new object[] { new CharacterRange[32] }; - } - - [Theory] - [MemberData(nameof(SetMeasurableCharacterRanges_TestData))] - public void SetMeasurableCharacterRanges_Valid_Success(CharacterRange[] ranges) - { - using (var format = new StringFormat()) - { - format.SetMeasurableCharacterRanges(ranges); - } - } - - [Fact] - public void SetMeasurableCharacterRanges_NullRanges_ThrowsNullReferenceException() - { - using (var format = new StringFormat()) - { - Assert.Throws(() => format.SetMeasurableCharacterRanges(null)); - } - } - - [Fact] - public void SetMeasurableCharacterRanges_RangesTooLarge_ThrowsOverflowException() - { - using (var format = new StringFormat()) - { - Assert.Throws(() => format.SetMeasurableCharacterRanges(new CharacterRange[33])); - } - } - - [Fact] - public void SetMeasurableCharacterRanges_Disposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.SetMeasurableCharacterRanges(new CharacterRange[0])); - } - - [Theory] - [InlineData(StringAlignment.Center)] - [InlineData(StringAlignment.Far)] - [InlineData(StringAlignment.Near)] - public void Alignment_SetValid_GetReturnsExpected(StringAlignment alignment) - { - using (var format = new StringFormat { Alignment = alignment }) - { - Assert.Equal(alignment, format.Alignment); - } - } - - [Theory] - [InlineData(StringAlignment.Near - 1)] - [InlineData(StringAlignment.Far + 1)] - public void Alignment_SetInvalid_ThrowsInvalidEnumArgumentException(StringAlignment alignment) - { - using (var format = new StringFormat()) - { - Assert.ThrowsAny(() => format.Alignment = alignment); - } - } - - [Fact] - public void Alignment_GetSetWhenDisposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.Alignment); - AssertExtensions.Throws(null, () => format.Alignment = StringAlignment.Center); - } - - [Fact] - public void DigitSubstitutionMethod_GetSetWhenDisposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.DigitSubstitutionMethod); - } - - [Fact] - public void DigitSubstitutionLanguage_GetSetWhenDisposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.DigitSubstitutionLanguage); - } - - [Theory] - [InlineData(StringFormatFlags.DirectionRightToLeft)] - [InlineData((StringFormatFlags)int.MinValue)] - [InlineData((StringFormatFlags)int.MaxValue)] - public void FormatFlags_Set_GetReturnsExpected(StringFormatFlags formatFlags) - { - using (var format = new StringFormat { FormatFlags = formatFlags }) - { - Assert.Equal(formatFlags, format.FormatFlags); - } - } - - [Fact] - public void FormatFlags_GetSetWhenDisposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.FormatFlags); - AssertExtensions.Throws(null, () => format.FormatFlags = StringFormatFlags.NoClip); - } - - [Theory] - [InlineData(StringAlignment.Center)] - [InlineData(StringAlignment.Far)] - [InlineData(StringAlignment.Near)] - public void LineAlignment_SetValid_GetReturnsExpected(StringAlignment alignment) - { - using (var format = new StringFormat { LineAlignment = alignment }) - { - Assert.Equal(alignment, format.LineAlignment); - } - } - - [Theory] - [InlineData(StringAlignment.Near - 1)] - [InlineData(StringAlignment.Far + 1)] - public void LineAlignment_SetInvalid_ThrowsInvalidEnumArgumentException(StringAlignment alignment) - { - using (var format = new StringFormat()) - { - Assert.ThrowsAny(() => format.LineAlignment = alignment); - } - } - - [Fact] - public void LineAlignment_GetSetWhenDisposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.LineAlignment); - AssertExtensions.Throws(null, () => format.LineAlignment = StringAlignment.Center); - } - - [Theory] - [InlineData(HotkeyPrefix.Hide)] - [InlineData(HotkeyPrefix.None)] - [InlineData(HotkeyPrefix.Show)] - public void HotKeyPrefix_SetValid_GetReturnsExpected(HotkeyPrefix prefix) - { - using (var format = new StringFormat { HotkeyPrefix = prefix }) - { - Assert.Equal(prefix, format.HotkeyPrefix); - } - } - - [Theory] - [InlineData(HotkeyPrefix.None - 1)] - [InlineData(HotkeyPrefix.Hide + 1)] - public void HotKeyPrefix_SetInvalid_ThrowsInvalidEnumArgumentException(HotkeyPrefix prefix) - { - using (var format = new StringFormat()) - { - Assert.ThrowsAny(() => format.HotkeyPrefix = prefix); - } - } - - [Fact] - public void HotkeyPrefix_GetSetWhenDisposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.HotkeyPrefix); - AssertExtensions.Throws(null, () => format.HotkeyPrefix = HotkeyPrefix.Hide); - } - - [Theory] - [InlineData(StringTrimming.Word)] - public void Trimming_SetValid_GetReturnsExpected(StringTrimming trimming) - { - using (var format = new StringFormat { Trimming = trimming }) - { - Assert.Equal(trimming, format.Trimming); - } - } - - [Theory] - [InlineData(StringTrimming.None - 1)] - [InlineData(StringTrimming.EllipsisPath + 1)] - public void Trimming_SetInvalid_ThrowsInvalidEnumArgumentException(StringTrimming trimming) - { - using (var format = new StringFormat()) - { - Assert.ThrowsAny(() => format.Trimming = trimming); - } - } - - [Fact] - public void Trimming_GetSetWhenDisposed_ThrowsArgumentException() - { - var format = new StringFormat(); - format.Dispose(); - - - AssertExtensions.Throws(null, () => format.Trimming); - AssertExtensions.Throws(null, () => format.Trimming = StringTrimming.Word); - } - - [Fact] - public void GenericDefault_Get_ReturnsExpected() - { - StringFormat format = StringFormat.GenericDefault; - Assert.NotSame(format, StringFormat.GenericDefault); - - Assert.Equal(StringAlignment.Near, format.Alignment); - Assert.Equal(0, format.DigitSubstitutionLanguage); - Assert.Equal(StringDigitSubstitute.User, format.DigitSubstitutionMethod); - Assert.Equal((StringFormatFlags)0, format.FormatFlags); - Assert.Equal(HotkeyPrefix.None, format.HotkeyPrefix); - Assert.Equal(StringAlignment.Near, format.LineAlignment); - Assert.Equal(StringTrimming.Character, format.Trimming); - } - - [Fact] - public void GenericTypographic_Get_ReturnsExpected() - { - StringFormat format = StringFormat.GenericTypographic; - Assert.NotSame(format, StringFormat.GenericTypographic); - - Assert.Equal(StringAlignment.Near, format.Alignment); - Assert.Equal(0, format.DigitSubstitutionLanguage); - Assert.Equal(StringDigitSubstitute.User, format.DigitSubstitutionMethod); - Assert.Equal(StringFormatFlags.FitBlackBox | StringFormatFlags.LineLimit | StringFormatFlags.NoClip, format.FormatFlags); - Assert.Equal(HotkeyPrefix.None, format.HotkeyPrefix); - Assert.Equal(StringAlignment.Near, format.LineAlignment); - Assert.Equal(StringTrimming.None, format.Trimming); - } - - [Fact] - public void ToString_Flags_ReturnsExpected() - { - using (var format = new StringFormat(StringFormatFlags.DirectionVertical)) - { - Assert.Equal("[StringFormat, FormatFlags=DirectionVertical]", format.ToString()); - } - } - - [Fact] - public void ToString_Disposed_ThrowsArgumentException() - { - var format = new StringFormat(StringFormatFlags.DirectionVertical); - format.Dispose(); - - AssertExtensions.Throws(null, () => format.ToString()); - } -} diff --git a/src/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj b/src/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj deleted file mode 100644 index 856bcf159dc..00000000000 --- a/src/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj +++ /dev/null @@ -1,141 +0,0 @@ - - - - true - annotations - - $(NoWarn);CA1825;CA5351;CA1850 - $(NoWarn);IDE0090 - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - System.Drawing.Tests.48x48_multiple_entries_4bit.ico - - - System.Drawing.Tests.bitmap_173x183_indexed_8bit.bmp - - - System.Drawing.Tests.empty.file - - - System.Drawing.Tests.invalid.ico - - - System.Drawing.Tests.Icon_toolboxBitmapAttributeTest - - - - - - - - - - - - - - - - diff --git a/src/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs b/src/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs deleted file mode 100644 index 083f7a4ef7a..00000000000 --- a/src/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs +++ /dev/null @@ -1,248 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design.Serialization; -using System.Drawing.Text; -using System.Globalization; -using static System.Drawing.FontConverter; - -namespace System.ComponentModel.TypeConverterTests; - -public class FontNameConverterTest -{ - [Fact] - public void TestConvertFrom() - { - FontConverter.FontNameConverter converter = new FontConverter.FontNameConverter(); - // returns "Times" under Linux and "Times New Roman" under Windows - if (PlatformDetection.IsWindows) - { - Assert.Equal("Times New Roman", converter.ConvertFrom("Times") as string); - } - else - { - Assert.Equal("Times", converter.ConvertFrom("Times") as string); - } - Assert.True(converter.GetStandardValuesSupported(), "standard values supported"); - Assert.False(converter.GetStandardValuesExclusive(), "standard values exclusive"); - } - - [Fact] - public void ExTestConvertFrom_ThrowsNotSupportedException() - { - FontConverter.FontNameConverter converter = new FontConverter.FontNameConverter(); - Assert.Throws(() => converter.ConvertFrom(null)); - Assert.Throws(() => converter.ConvertFrom(1)); - } -} - -public class FontConverterTest -{ - public static char s_separator = CultureInfo.CurrentCulture.TextInfo.ListSeparator[0]; - - [Theory] - [MemberData(nameof(TestConvertFormData))] - public void TestConvertFrom(string input, string expectedName, float expectedSize, GraphicsUnit expectedUnits, FontStyle expectedFontStyle) - { - FontConverter converter = new FontConverter(); - Font font = (Font)converter.ConvertFrom(input); - - // Unix fonts - Assert.Equal(expectedName, font.Name); - Assert.Equal(expectedSize, font.Size); - Assert.Equal(expectedUnits, font.Unit); - Assert.Equal(expectedFontStyle, font.Style); - } - - [Theory] - [MemberData(nameof(ArgumentExceptionFontConverterData))] - public void InvalidInputThrowsArgumentException(string input, string paramName, string netfxParamName) - { - FontConverter converter = new FontConverter(); - AssertExtensions.Throws(paramName, netfxParamName, () => converter.ConvertFrom(input)); - } - - [Theory] - [MemberData(nameof(InvalidEnumArgumentExceptionFontConverterData))] - public void InvalidInputThrowsInvalidEnumArgumentException(string input, string paramName) - { - FontConverter converter = new FontConverter(); - Assert.Throws(paramName, () => converter.ConvertFrom(input)); - } - - [Fact] - public void EmptyStringInput() - { - FontConverter converter = new FontConverter(); - Font font = (Font)converter.ConvertFrom(string.Empty); - Assert.Null(font); - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBuiltWithAggressiveTrimming))] - public void GetFontPropsSorted() - { - // The order provided since .NET Framework - string[] expectedPropNames = new[] - { - nameof(Font.Name), - nameof(Font.Size), - nameof(Font.Unit), - nameof(Font.Bold), - nameof(Font.GdiCharSet), - nameof(Font.GdiVerticalFont), - nameof(Font.Italic), - nameof(Font.Strikeout), - nameof(Font.Underline), - }; - - FontConverter converter = new FontConverter(); - Font font = new($"Courier New", 8.25f, FontStyle.Regular, GraphicsUnit.Point); - - PropertyDescriptorCollection props = converter.GetProperties(font); - string[] propNames = new string[props.Count]; - - int index = 0; - foreach (PropertyDescriptor prop in props) - { - propNames[index++] = prop.DisplayName; - } - - Assert.True(propNames.SequenceEqual(expectedPropNames)); - } - - [Theory] - [MemberData(nameof(InstanceDescriptorTestData))] - public void ConvertToInstanceDescriptor(Font font, int expectedArguments) - { - try - { - FontConverter converter = new(); - InstanceDescriptor descriptor = (InstanceDescriptor)converter.ConvertTo(font, typeof(InstanceDescriptor)); - Assert.Equal(expectedArguments, descriptor.Arguments.Count); - using Font newFont = (Font)descriptor.Invoke(); - Assert.Equal(font.Name, newFont.Name); - Assert.Equal(font.Size, newFont.Size); - Assert.Equal(font.Style, newFont.Style); - Assert.Equal(font.Unit, newFont.Unit); - Assert.Equal(font.GdiCharSet, newFont.GdiCharSet); - Assert.Equal(font.GdiVerticalFont, newFont.GdiVerticalFont); - } - finally - { - font.Dispose(); - } - } - - public static TheoryData InstanceDescriptorTestData => new() - { - { new Font("Arial", 12.0f), 2 }, - { new Font("Arial", 12.0f, FontStyle.Regular), 2 }, - { new Font("Courier", 8.0f, FontStyle.Italic), 3 }, - { new Font("Courier", 1.0f, FontStyle.Regular, GraphicsUnit.Point), 2 }, - { new Font("Courier", 1.0f, FontStyle.Regular, GraphicsUnit.Inch), 4 }, - { new Font("Courier", 1.0f, FontStyle.Regular, GraphicsUnit.Pixel, gdiCharSet: 2 /* SYMBOL_CHARSET */), 5 }, - { new Font("Courier", 1.0f, FontStyle.Regular, GraphicsUnit.Point, gdiCharSet: 1 /* DEFAULT_CHARSET */), 2 }, - { new Font("Courier", 1.0f, FontStyle.Regular, GraphicsUnit.Pixel, gdiCharSet: 1 /* DEFAULT_CHARSET */, gdiVerticalFont: true), 6 }, - }; - - public static TheoryData TestConvertFormData() - { - var data = - new TheoryData() - { - { $"Courier New", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, - { $"Courier New{s_separator} 11", "Courier New", 11f, GraphicsUnit.Point, FontStyle.Regular }, - { $"Arial{s_separator} 11px", "Arial", 11f, GraphicsUnit.Pixel, FontStyle.Regular }, - { $"Courier New{s_separator} 11 px", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Regular }, - { $"Courier New{s_separator} 11 px{s_separator} style=Regular", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Regular }, - { $"Courier New{s_separator} style=Bold", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Bold }, - { $"Courier New{s_separator} 11 px{s_separator} style=Bold{s_separator} Italic", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic }, - { $"Courier New{s_separator} 11 px{s_separator} style=Regular, Italic", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Regular | FontStyle.Italic }, - { $"Courier New{s_separator} 11 px{s_separator} style=Bold{s_separator} Italic{s_separator} Strikeout", "Courier New", 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout }, - { $"Arial{s_separator} 11 px{s_separator} style=Bold, Italic, Strikeout", "Arial", 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout }, - { $"11px", "Microsoft Sans Serif", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, - { $"Style=Bold", "Microsoft Sans Serif", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, - { $"arIAL{s_separator} 10{s_separator} style=bold", "Arial", 10f, GraphicsUnit.Point, FontStyle.Bold }, - { $"Arial{s_separator} 10{s_separator}", "Arial", 10f, GraphicsUnit.Point, FontStyle.Regular }, - { $"Arial{s_separator}", "Arial", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, - { $"Arial{s_separator} 10{s_separator} style=12", "Arial", 10f, GraphicsUnit.Point, FontStyle.Underline | FontStyle.Strikeout }, - { $"Courier New{s_separator} Style=Bold", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Bold }, // FullFramework style keyword is case sensitive. - { $"11px{s_separator} Style=Bold", "Microsoft Sans Serif", 8.25f, GraphicsUnit.Point, FontStyle.Bold} - }; - - // FullFramework disregards all arguments if the font name is an empty string. - // Empty string is not an installed font on Windows 7, windows 8 and some versions of windows 10. - if (EmptyFontPresent) - { - data.Add($"{s_separator} 10{s_separator} style=bold", "", 10f, GraphicsUnit.Point, FontStyle.Bold); - } - else - { - data.Add($"{s_separator} 10{s_separator} style=bold", "Microsoft Sans Serif", 10f, GraphicsUnit.Point, FontStyle.Bold); - } - - return data; - } - - private static bool EmptyFontPresent - { - get - { - using (var installedFonts = new InstalledFontCollection()) - { - return installedFonts.Families.Select(t => t.Name).Contains(string.Empty); - } - } - } - - public static TheoryData ArgumentExceptionFontConverterData() => new() - { - { $"Courier New{s_separator} 11 px{s_separator} type=Bold{s_separator} Italic", "units", null }, - { $"Courier New{s_separator} {s_separator} Style=Bold", "value", null }, - { $"Courier New{s_separator} 11{s_separator} Style=", "value", null }, - { $"Courier New{s_separator} 11{s_separator} Style=RandomEnum", null, null }, - { $"Arial{s_separator} 10{s_separator} style=bold{s_separator}", "value", null }, - { $"Arial{s_separator} 10{s_separator} style=null", null, null }, - { $"Arial{s_separator} 10{s_separator} style=abc#", null, null }, - { $"Arial{s_separator} 10{s_separator} style=##", null, null }, - { $"Arial{s_separator} 10display{s_separator} style=bold", null, null }, - { $"Arial{s_separator} 10style{s_separator} style=bold", "units", null }, - }; - - public static TheoryData InvalidEnumArgumentExceptionFontConverterData() => new() - { - { $"Arial{s_separator} 10{s_separator} style=56", "style" }, - { $"Arial{s_separator} 10{s_separator} style=-1", "style" }, - }; -} - -public class FontUnitConverterTest -{ - [Fact] - public void GetStandardValuesTest() - { - FontUnitConverter converter = new FontUnitConverter(); - var values = converter.GetStandardValues(); - Assert.Equal(6, values.Count); // The six supported values of Graphics unit: World, Pixel, Point, Inch, Document, Millimeter. - - foreach (var item in values) - { - Assert.NotEqual(GraphicsUnit.Display, (GraphicsUnit)item); - } - } - - [Theory] - [InlineData("Display", GraphicsUnit.Display)] - [InlineData("Document", GraphicsUnit.Document)] - [InlineData("Inch", GraphicsUnit.Inch)] - [InlineData("Millimeter", GraphicsUnit.Millimeter)] - [InlineData("Pixel", GraphicsUnit.Pixel)] - [InlineData("Point", GraphicsUnit.Point)] - [InlineData("World", GraphicsUnit.World)] - public void CanConvertFrom(string input, GraphicsUnit expected) - { - FontUnitConverter converter = new FontUnitConverter(); - GraphicsUnit value = (GraphicsUnit)converter.ConvertFrom(input); - Assert.Equal(expected, value); - } -} diff --git a/src/System.Drawing.Common/tests/System/Drawing/IconConverterTests.cs b/src/System.Drawing.Common/tests/System/Drawing/IconConverterTests.cs deleted file mode 100644 index 1d843b08456..00000000000 --- a/src/System.Drawing.Common/tests/System/Drawing/IconConverterTests.cs +++ /dev/null @@ -1,180 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Imaging; -using System.Globalization; - -namespace System.ComponentModel.TypeConverterTests; - -// On IoT: "Unable to find an entry point named 'CreateIconFromResourceEx'" -[ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsIoTCore))] -public class IconConverterTest -{ - private readonly Icon _icon; - private readonly IconConverter _icoConv; - private readonly IconConverter _icoConvFrmTD; - private readonly string _iconStr; - private readonly byte[] _iconBytes; - - public IconConverterTest() - { - _icon = new Icon(Path.Combine("bitmaps", "TestIcon.ico")); - _iconStr = _icon.ToString(); - - using (MemoryStream destStream = new MemoryStream()) - { - _icon.Save(destStream); - _iconBytes = destStream.ToArray(); - } - - _icoConv = new IconConverter(); - _icoConvFrmTD = (IconConverter)TypeDescriptor.GetConverter(_icon); - } - - [Fact] - public void TestCanConvertFrom() - { - Assert.True(_icoConv.CanConvertFrom(typeof(byte[])), "byte[] (no context)"); - Assert.True(_icoConv.CanConvertFrom(null, typeof(byte[])), "byte[]"); - Assert.True(_icoConv.CanConvertFrom(null, _iconBytes.GetType()), "_iconBytes.GetType()"); - Assert.False(_icoConv.CanConvertFrom(null, typeof(string)), "string"); - Assert.False(_icoConv.CanConvertFrom(null, typeof(Rectangle)), "Rectangle"); - Assert.False(_icoConv.CanConvertFrom(null, typeof(Point)), "Point"); - Assert.False(_icoConv.CanConvertFrom(null, typeof(PointF)), "PointF"); - Assert.False(_icoConv.CanConvertFrom(null, typeof(Size)), "Size"); - Assert.False(_icoConv.CanConvertFrom(null, typeof(SizeF)), "SizeF"); - Assert.False(_icoConv.CanConvertFrom(null, typeof(object)), "object"); - Assert.False(_icoConv.CanConvertFrom(null, typeof(int)), "int"); - Assert.False(_icoConv.CanConvertFrom(null, typeof(Metafile)), "Metafile"); - - Assert.True(_icoConvFrmTD.CanConvertFrom(typeof(byte[])), "TD byte[] (no context)"); - Assert.True(_icoConvFrmTD.CanConvertFrom(null, typeof(byte[])), "TD byte[]"); - Assert.True(_icoConvFrmTD.CanConvertFrom(null, _iconBytes.GetType()), "TD _iconBytes.GetType()"); - Assert.False(_icoConvFrmTD.CanConvertFrom(null, typeof(string)), "TD string"); - Assert.False(_icoConvFrmTD.CanConvertFrom(null, typeof(Rectangle)), "TD Rectangle"); - Assert.False(_icoConvFrmTD.CanConvertFrom(null, typeof(Point)), "TD Point"); - Assert.False(_icoConvFrmTD.CanConvertFrom(null, typeof(PointF)), "TD PointF"); - Assert.False(_icoConvFrmTD.CanConvertFrom(null, typeof(Size)), "TD Size"); - Assert.False(_icoConvFrmTD.CanConvertFrom(null, typeof(SizeF)), "TD SizeF"); - Assert.False(_icoConvFrmTD.CanConvertFrom(null, typeof(object)), "TD object"); - Assert.False(_icoConvFrmTD.CanConvertFrom(null, typeof(int)), "TD int"); - Assert.False(_icoConvFrmTD.CanConvertFrom(null, typeof(Metafile)), "TD Metafile"); - } - - [Fact] - public void TestCanConvertTo() - { - Assert.True(_icoConv.CanConvertTo(typeof(string)), "string (no context)"); - Assert.True(_icoConv.CanConvertTo(null, typeof(string)), "string"); - Assert.True(_icoConv.CanConvertTo(null, _iconStr.GetType()), "_iconStr.GetType()"); - Assert.True(_icoConv.CanConvertTo(typeof(byte[])), "byte[] (no context)"); - Assert.True(_icoConv.CanConvertTo(null, typeof(byte[])), "byte[]"); - Assert.True(_icoConv.CanConvertTo(null, _iconBytes.GetType()), "_iconBytes.GetType()"); - Assert.True(_icoConv.CanConvertTo(typeof(Image)), "Image (no context)"); - Assert.True(_icoConv.CanConvertTo(null, typeof(Image)), "Image"); - Assert.True(_icoConv.CanConvertTo(typeof(Bitmap)), "Bitmap (no context)"); - Assert.True(_icoConv.CanConvertTo(null, typeof(Bitmap)), "Bitmap"); - Assert.False(_icoConv.CanConvertTo(null, typeof(Rectangle)), "Rectangle"); - Assert.False(_icoConv.CanConvertTo(null, typeof(Point)), "Point"); - Assert.False(_icoConv.CanConvertTo(null, typeof(PointF)), "PointF"); - Assert.False(_icoConv.CanConvertTo(null, typeof(Size)), "Size"); - Assert.False(_icoConv.CanConvertTo(null, typeof(SizeF)), "SizeF"); - Assert.False(_icoConv.CanConvertTo(null, typeof(object)), "object"); - Assert.False(_icoConv.CanConvertTo(null, typeof(int)), "int"); - - Assert.True(_icoConvFrmTD.CanConvertTo(typeof(string)), "TD string (no context)"); - Assert.True(_icoConvFrmTD.CanConvertTo(null, typeof(string)), "TD string"); - Assert.True(_icoConvFrmTD.CanConvertTo(null, _iconStr.GetType()), "TD _iconStr.GetType()"); - Assert.True(_icoConvFrmTD.CanConvertTo(typeof(byte[])), "TD byte[] (no context)"); - Assert.True(_icoConvFrmTD.CanConvertTo(null, typeof(byte[])), "TD byte[]"); - Assert.True(_icoConvFrmTD.CanConvertTo(null, _iconBytes.GetType()), "TD _iconBytes.GetType()"); - Assert.True(_icoConvFrmTD.CanConvertTo(typeof(Image)), "TD Image (no context)"); - Assert.True(_icoConvFrmTD.CanConvertTo(null, typeof(Image)), "TD Image"); - Assert.True(_icoConvFrmTD.CanConvertTo(typeof(Bitmap)), "TD Bitmap (no context)"); - Assert.True(_icoConvFrmTD.CanConvertTo(null, typeof(Bitmap)), "TD Bitmap"); - Assert.False(_icoConvFrmTD.CanConvertTo(null, typeof(Rectangle)), "TD Rectangle"); - Assert.False(_icoConvFrmTD.CanConvertTo(null, typeof(Point)), "TD Point"); - Assert.False(_icoConvFrmTD.CanConvertTo(null, typeof(PointF)), "TD PointF"); - Assert.False(_icoConvFrmTD.CanConvertTo(null, typeof(Size)), "TD Size"); - Assert.False(_icoConvFrmTD.CanConvertTo(null, typeof(SizeF)), "TD SizeF"); - Assert.False(_icoConvFrmTD.CanConvertTo(null, typeof(object)), "TD object"); - Assert.False(_icoConvFrmTD.CanConvertTo(null, typeof(int)), "TD int"); - } - - [Fact] - public void TestConvertFrom() - { - Icon newIcon = (Icon)_icoConv.ConvertFrom(null, CultureInfo.InvariantCulture, _iconBytes); - - Assert.Equal(_icon.Height, newIcon.Height); - Assert.Equal(_icon.Width, newIcon.Width); - - Assert.Throws(() => _icoConv.ConvertFrom("System.Drawing.String")); - Assert.Throws(() => _icoConv.ConvertFrom(null, CultureInfo.InvariantCulture, "System.Drawing.String")); - Assert.Throws(() => _icoConv.ConvertFrom(null, CultureInfo.InvariantCulture, new Bitmap(20, 20))); - Assert.Throws(() => _icoConv.ConvertFrom(null, CultureInfo.InvariantCulture, new Point(10, 10))); - Assert.Throws(() => _icoConv.ConvertFrom(null, CultureInfo.InvariantCulture, new SizeF(10, 10))); - Assert.Throws(() => _icoConv.ConvertFrom(null, CultureInfo.InvariantCulture, new object())); - - - newIcon = (Icon)_icoConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, _iconBytes); - - Assert.Equal(_icon.Height, newIcon.Height); - Assert.Equal(_icon.Width, newIcon.Width); - - Assert.Throws(() => _icoConvFrmTD.ConvertFrom("System.Drawing.String")); - Assert.Throws(() => _icoConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, "System.Drawing.String")); - Assert.Throws(() => _icoConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, new Bitmap(20, 20))); - Assert.Throws(() => _icoConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, new Point(10, 10))); - Assert.Throws(() => _icoConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, new SizeF(10, 10))); - Assert.Throws(() => _icoConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, new object())); - } - - [Fact] - public void TestConvertTo() - { - Assert.Equal(_iconStr, (string)_icoConv.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(string))); - Assert.Equal(_iconStr, (string)_icoConv.ConvertTo(_icon, typeof(string))); - - byte[] newIconBytes = (byte[])_icoConv.ConvertTo(null, CultureInfo.InvariantCulture, _icon, _iconBytes.GetType()); - Assert.Equal(_iconBytes, newIconBytes); - - newIconBytes = (byte[])_icoConv.ConvertTo(_icon, _iconBytes.GetType()); - Assert.Equal(_iconBytes, newIconBytes); - - Assert.Throws(() => _icoConv.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(Rectangle))); - Assert.Throws(() => _icoConv.ConvertTo(null, CultureInfo.InvariantCulture, _icon, _icon.GetType())); - Assert.Throws(() => _icoConv.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(Size))); - Assert.Throws(() => _icoConv.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(Point))); - Assert.Throws(() => _icoConv.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(Metafile))); - Assert.Throws(() => _icoConv.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(object))); - Assert.Throws(() => _icoConv.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(int))); - - Assert.Equal(_iconStr, (string)_icoConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(string))); - Assert.Equal(_iconStr, (string)_icoConvFrmTD.ConvertTo(_icon, typeof(string))); - - - newIconBytes = (byte[])_icoConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _icon, _iconBytes.GetType()); - Assert.Equal(_iconBytes, newIconBytes); - - newIconBytes = (byte[])_icoConvFrmTD.ConvertTo(_icon, _iconBytes.GetType()); - Assert.Equal(_iconBytes, newIconBytes); - - Assert.Throws(() => _icoConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(Rectangle))); - Assert.Throws(() => _icoConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _icon, _icon.GetType())); - Assert.Throws(() => _icoConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(Size))); - Assert.Throws(() => _icoConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(Point))); - Assert.Throws(() => _icoConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(Metafile))); - Assert.Throws(() => _icoConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(object))); - Assert.Throws(() => _icoConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _icon, typeof(int))); - - using (new ThreadCultureChange(CultureInfo.CreateSpecificCulture("fr-FR"), CultureInfo.InvariantCulture)) - { - Assert.Equal("(none)", (string)_icoConv.ConvertTo(null, typeof(string))); - Assert.Equal("(none)", (string)_icoConv.ConvertTo(null, CultureInfo.CreateSpecificCulture("ru-RU"), null, typeof(string))); - - Assert.Equal("(none)", (string)_icoConvFrmTD.ConvertTo(null, typeof(string))); - Assert.Equal("(none)", (string)_icoConvFrmTD.ConvertTo(null, CultureInfo.CreateSpecificCulture("de-DE"), null, typeof(string))); - } - } -} diff --git a/src/System.Drawing.Common/tests/System/Drawing/ImageAnimator.ManualTests.cs b/src/System.Drawing.Common/tests/System/Drawing/ImageAnimator.ManualTests.cs deleted file mode 100644 index 1c6c0d1761b..00000000000 --- a/src/System.Drawing.Common/tests/System/Drawing/ImageAnimator.ManualTests.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Imaging; - -namespace System.Drawing.Tests; - -public class ImageAnimatorManualTests -{ - public static string OutputFolder = Path.Combine(Environment.CurrentDirectory, "ImageAnimatorManualTests", DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")); - - [Fact(Skip = "Manual Test")] - public void AnimateAndCaptureFrames() - { - // This test animates the test gifs that we have and waits 60 seconds - // for the animations to progress. As the frame change events occur, we - // capture snapshots of the current frame, essentially extracting the - // frames from the GIF. - - // The animation should progress at the expected pace to stay synchronized - // with the wall clock, and the animated timer images show the time duration - // within the image itself, so this can be manually verified for accuracy. - - // The captured frames are stored in the `artifacts/bin/System.Drawing.Common.Tests` - // folder for each configuration, and then under an `ImageAnimatorManualTests` folder - // with a timestamped folder under that. Each animation image gets its own folder too. - - string[] images = new string[] - { - "animated-timer-1fps-repeat-2.gif", - "animated-timer-1fps-repeat-infinite.gif", - "animated-timer-10fps-repeat-2.gif", - "animated-timer-10fps-repeat-infinite.gif", - "animated-timer-100fps-repeat-2.gif", - "animated-timer-100fps-repeat-infinite.gif", - "animated-timer-0-delay-all-frames.gif", - }; - - Dictionary handlers = new(); - Dictionary frameIndexes = new(); - Dictionary bitmaps = new(); - - Stopwatch stopwatch = new(); - - foreach (var imageName in images) - { - string testOutputFolder = Path.Combine(OutputFolder, Path.GetFileNameWithoutExtension(imageName)); - Directory.CreateDirectory(testOutputFolder); - frameIndexes[imageName] = 0; - - handlers[imageName] = new EventHandler(new Action((object o, EventArgs e) => - { - Bitmap animation = (Bitmap)o; - ImageAnimator.UpdateFrames(animation); - - // We save captures using jpg so that: - // a) The images don't get saved as animated gifs again, and just a single frame is saved - // b) Saving pngs in this test on Linux was leading to sporadic GDI+ errors; Jpeg is more reliable - string timestamp = stopwatch.ElapsedMilliseconds.ToString("000000"); - animation.Save(Path.Combine(testOutputFolder, $"{++frameIndexes[imageName]}_{timestamp}.jpg"), ImageFormat.Jpeg); - })); - - bitmaps[imageName] = new Bitmap(Helpers.GetTestBitmapPath(imageName)); - ImageAnimator.Animate(bitmaps[imageName], handlers[imageName]); - } - - stopwatch.Start(); - Thread.Sleep(60_000); - - foreach (var imageName in images) - { - ImageAnimator.StopAnimate(bitmaps[imageName], handlers[imageName]); - bitmaps[imageName].Dispose(); - } - } -} diff --git a/src/System.Drawing.Common/tests/System/Drawing/ImageAnimatorTests.cs b/src/System.Drawing.Common/tests/System/Drawing/ImageAnimatorTests.cs deleted file mode 100644 index 9d5701f0e89..00000000000 --- a/src/System.Drawing.Common/tests/System/Drawing/ImageAnimatorTests.cs +++ /dev/null @@ -1,149 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class ImageAnimatorTests -{ - [Fact] - public void UpdateFrames_Succeeds_WithNothingAnimating() - { - ImageAnimator.UpdateFrames(); - } - - [Theory] - [InlineData("1bit.png")] - [InlineData("48x48_one_entry_1bit.ico")] - [InlineData("81773-interlaced.gif")] - public void CanAnimate_ReturnsFalse_ForNonAnimatedImages(string imageName) - { - using (var image = new Bitmap(Helpers.GetTestBitmapPath(imageName))) - { - Assert.False(ImageAnimator.CanAnimate(image)); - } - } - - [Fact] - public void Animate_Succeeds_ForNonAnimatedImages_WithNothingAnimating() - { - var image = new Bitmap(Helpers.GetTestBitmapPath("1bit.png")); - ImageAnimator.Animate(image, (object o, EventArgs e) => { }); - } - - [Fact] - public void Animate_Succeeds_ForNonAnimatedImages_WithCurrentAnimations() - { - var animatedImage = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-2.gif")); - ImageAnimator.Animate(animatedImage, (object o, EventArgs e) => { }); - - var image = new Bitmap(Helpers.GetTestBitmapPath("1bit.png")); - ImageAnimator.Animate(image, (object o, EventArgs e) => { }); - } - - [Fact] - public void UpdateFrames_Succeeds_ForNonAnimatedImages_WithNothingAnimating() - { - var image = new Bitmap(Helpers.GetTestBitmapPath("1bit.png")); - ImageAnimator.UpdateFrames(image); - } - - [Fact] - public void UpdateFrames_Succeeds_ForNonAnimatedImages_WithCurrentAnimations() - { - var animatedImage = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-2.gif")); - ImageAnimator.Animate(animatedImage, (object o, EventArgs e) => { }); - - var image = new Bitmap(Helpers.GetTestBitmapPath("1bit.png")); - ImageAnimator.UpdateFrames(image); - } - - [Fact] - public void StopAnimate_Succeeds_ForNonAnimatedImages_WithNothingAnimating() - { - var image = new Bitmap(Helpers.GetTestBitmapPath("1bit.png")); - ImageAnimator.StopAnimate(image, (object o, EventArgs e) => { }); - } - - [Fact] - public void StopAnimate_Succeeds_ForNonAnimatedImages_WithCurrentAnimations() - { - var animatedImage = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-2.gif")); - ImageAnimator.Animate(animatedImage, (object o, EventArgs e) => { }); - - var image = new Bitmap(Helpers.GetTestBitmapPath("1bit.png")); - ImageAnimator.StopAnimate(image, (object o, EventArgs e) => { }); - } - - [Theory] - [InlineData("animated-timer-1fps-repeat-2.gif")] - [InlineData("animated-timer-1fps-repeat-infinite.gif")] - [InlineData("animated-timer-10fps-repeat-2.gif")] - [InlineData("animated-timer-10fps-repeat-infinite.gif")] - [InlineData("animated-timer-100fps-repeat-2.gif")] - [InlineData("animated-timer-100fps-repeat-infinite.gif")] - public void CanAnimate_ReturnsTrue_ForAnimatedImages(string imageName) - { - using (var image = new Bitmap(Helpers.GetTestBitmapPath(imageName))) - { - Assert.True(ImageAnimator.CanAnimate(image)); - } - } - - [Fact] - public void Animate_Succeeds_ForAnimatedImages_WithNothingAnimating() - { - var image = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-2.gif")); - ImageAnimator.Animate(image, (object o, EventArgs e) => { }); - } - - [Fact] - public void Animate_Succeeds_ForAnimatedImages_WithCurrentAnimations() - { - var animatedImage = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-2.gif")); - ImageAnimator.Animate(animatedImage, (object o, EventArgs e) => { }); - - var image = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-infinite.gif")); - ImageAnimator.Animate(image, (object o, EventArgs e) => { }); - } - - [Fact] - public void UpdateFrames_Succeeds_ForAnimatedImages_WithNothingAnimating() - { - var animatedImage = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-2.gif")); - ImageAnimator.UpdateFrames(animatedImage); - } - - [Fact] - public void UpdateFrames_Succeeds_WithCurrentAnimations() - { - var animatedImage = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-2.gif")); - ImageAnimator.Animate(animatedImage, (object o, EventArgs e) => { }); - ImageAnimator.UpdateFrames(); - } - - [Fact] - public void UpdateFrames_Succeeds_ForAnimatedImages_WithCurrentAnimations() - { - var animatedImage = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-2.gif")); - ImageAnimator.Animate(animatedImage, (object o, EventArgs e) => { }); - ImageAnimator.UpdateFrames(animatedImage); - } - - [Fact] - public void StopAnimate_Succeeds_ForAnimatedImages_WithNothingAnimating() - { - var image = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-2.gif")); - ImageAnimator.StopAnimate(image, (object o, EventArgs e) => { }); - } - - [Fact] - public void StopAnimate_Succeeds_ForAnimatedImages_WithCurrentAnimations() - { - var animatedImage = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-2.gif")); - ImageAnimator.Animate(animatedImage, (object o, EventArgs e) => { }); - - var image = new Bitmap(Helpers.GetTestBitmapPath("animated-timer-100fps-repeat-infinite.gif")); - ImageAnimator.StopAnimate(animatedImage, (object o, EventArgs e) => { }); - ImageAnimator.StopAnimate(image, (object o, EventArgs e) => { }); - } -} diff --git a/src/System.Drawing.Common/tests/System/Drawing/ImageConverterTests.cs b/src/System.Drawing.Common/tests/System/Drawing/ImageConverterTests.cs deleted file mode 100644 index fd4da940049..00000000000 --- a/src/System.Drawing.Common/tests/System/Drawing/ImageConverterTests.cs +++ /dev/null @@ -1,262 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Imaging; -using System.Globalization; - -namespace System.ComponentModel.TypeConverterTests; - -public class ImageConverterTest -{ - private readonly Image _image; - private readonly ImageConverter _imgConv; - private readonly ImageConverter _imgConvFrmTD; - private readonly string _imageStr; - private readonly byte[] _imageBytes; - - public ImageConverterTest() - { - _image = Image.FromFile(Path.Combine("bitmaps", "TestImage.bmp")); - _imageStr = _image.ToString(); - - using (MemoryStream destStream = new MemoryStream()) - { - _image.Save(destStream, _image.RawFormat); - _imageBytes = destStream.ToArray(); - } - - _imgConv = new ImageConverter(); - _imgConvFrmTD = (ImageConverter)TypeDescriptor.GetConverter(_image); - } - - [Theory] - [InlineData("48x48_multiple_entries_4bit.ico")] - [InlineData("256x256_seven_entries_multiple_bits.ico")] - [InlineData("pngwithheight_icon.ico")] - public void ImageConverterFromIconTest(string name) - { - using (var icon = new Icon(Helpers.GetTestBitmapPath(name))) - { - Bitmap IconBitmap = (Bitmap)_imgConv.ConvertFrom(icon); - Assert.NotNull(IconBitmap); - Assert.Equal(32, IconBitmap.Width); - Assert.Equal(32, IconBitmap.Height); - Assert.Equal(new Size(32, 32), IconBitmap.Size); - } - } - - [Fact] - public void ImageWithOleHeader() - { - string path = Path.Combine("bitmaps", "TestImageWithOleHeader.bmp"); - using (FileStream fileStream = File.Open(path, FileMode.Open)) - { - using (var ms = new MemoryStream()) - { - fileStream.CopyTo(ms); - var converter = new ImageConverter(); - object image = converter.ConvertFrom(ms.ToArray()); - Assert.NotNull(image); - } - } - } - - [Fact] - public void TestCanConvertFrom() - { - Assert.True(_imgConv.CanConvertFrom(typeof(byte[])), "byte[] (no context)"); - Assert.True(_imgConv.CanConvertFrom(null, typeof(byte[])), "byte[]"); - Assert.True(_imgConv.CanConvertFrom(null, _imageBytes.GetType()), "_imageBytes.GetType()"); - Assert.True(_imgConv.CanConvertFrom(typeof(Icon)), "Icon (no context)"); - Assert.True(_imgConv.CanConvertFrom(null, typeof(Icon)), "Icon"); - Assert.False(_imgConv.CanConvertFrom(null, typeof(string)), "string"); - Assert.False(_imgConv.CanConvertFrom(null, typeof(Rectangle)), "Rectangle"); - Assert.False(_imgConv.CanConvertFrom(null, typeof(Point)), "Point"); - Assert.False(_imgConv.CanConvertFrom(null, typeof(PointF)), "PointF"); - Assert.False(_imgConv.CanConvertFrom(null, typeof(Size)), "Size"); - Assert.False(_imgConv.CanConvertFrom(null, typeof(SizeF)), "SizeF"); - Assert.False(_imgConv.CanConvertFrom(null, typeof(object)), "object"); - Assert.False(_imgConv.CanConvertFrom(null, typeof(int)), "int"); - Assert.False(_imgConv.CanConvertFrom(null, typeof(Metafile)), "Mefafile"); - - Assert.True(_imgConvFrmTD.CanConvertFrom(typeof(byte[])), "TD byte[] (no context)"); - Assert.True(_imgConvFrmTD.CanConvertFrom(null, typeof(byte[])), "TD byte[]"); - Assert.True(_imgConvFrmTD.CanConvertFrom(null, _imageBytes.GetType()), "TD _imageBytes.GetType()"); - Assert.False(_imgConvFrmTD.CanConvertFrom(null, typeof(string)), "TD string"); - Assert.False(_imgConvFrmTD.CanConvertFrom(null, typeof(Rectangle)), "TD Rectangle"); - Assert.False(_imgConvFrmTD.CanConvertFrom(null, typeof(Point)), "TD Point"); - Assert.False(_imgConvFrmTD.CanConvertFrom(null, typeof(PointF)), "TD PointF"); - Assert.False(_imgConvFrmTD.CanConvertFrom(null, typeof(Size)), "TD Size"); - Assert.False(_imgConvFrmTD.CanConvertFrom(null, typeof(SizeF)), "TD SizeF"); - Assert.False(_imgConvFrmTD.CanConvertFrom(null, typeof(object)), "TD object"); - Assert.False(_imgConvFrmTD.CanConvertFrom(null, typeof(int)), "TD int"); - Assert.False(_imgConvFrmTD.CanConvertFrom(null, typeof(Metafile)), "TD Metafile"); - } - - [Fact] - public void TestCanConvertTo() - { - Assert.True(_imgConv.CanConvertTo(typeof(string)), "stirng (no context)"); - Assert.True(_imgConv.CanConvertTo(null, typeof(string)), "string"); - Assert.True(_imgConv.CanConvertTo(null, _imageStr.GetType()), "_imageStr.GetType()"); - Assert.True(_imgConv.CanConvertTo(typeof(byte[])), "byte[] (no context)"); - Assert.True(_imgConv.CanConvertTo(null, typeof(byte[])), "byte[]"); - Assert.True(_imgConv.CanConvertTo(null, _imageBytes.GetType()), "_imageBytes.GetType()"); - Assert.False(_imgConv.CanConvertTo(null, typeof(Rectangle)), "Rectangle"); - Assert.False(_imgConv.CanConvertTo(null, typeof(Point)), "Point"); - Assert.False(_imgConv.CanConvertTo(null, typeof(PointF)), "PointF"); - Assert.False(_imgConv.CanConvertTo(null, typeof(Size)), "Size"); - Assert.False(_imgConv.CanConvertTo(null, typeof(SizeF)), "SizeF"); - Assert.False(_imgConv.CanConvertTo(null, typeof(object)), "object"); - Assert.False(_imgConv.CanConvertTo(null, typeof(int)), "int"); - - Assert.True(_imgConvFrmTD.CanConvertTo(typeof(string)), "TD string (no context)"); - Assert.True(_imgConvFrmTD.CanConvertTo(null, typeof(string)), "TD string"); - Assert.True(_imgConvFrmTD.CanConvertTo(null, _imageStr.GetType()), "TD _imageStr.GetType()"); - Assert.True(_imgConvFrmTD.CanConvertTo(typeof(byte[])), "TD byte[] (no context)"); - Assert.True(_imgConvFrmTD.CanConvertTo(null, typeof(byte[])), "TD byte[]"); - Assert.True(_imgConvFrmTD.CanConvertTo(null, _imageBytes.GetType()), "TD _imageBytes.GetType()"); - Assert.False(_imgConvFrmTD.CanConvertTo(null, typeof(Rectangle)), "TD Rectangle"); - Assert.False(_imgConvFrmTD.CanConvertTo(null, typeof(Point)), "TD Point"); - Assert.False(_imgConvFrmTD.CanConvertTo(null, typeof(PointF)), "TD PointF"); - Assert.False(_imgConvFrmTD.CanConvertTo(null, typeof(Size)), "TD Size"); - Assert.False(_imgConvFrmTD.CanConvertTo(null, typeof(SizeF)), "TD SizeF"); - Assert.False(_imgConvFrmTD.CanConvertTo(null, typeof(object)), "TD object"); - Assert.False(_imgConvFrmTD.CanConvertTo(null, typeof(int)), "TD int"); - } - - [Fact] - public void ConvertFrom() - { - Image newImage = (Image)_imgConv.ConvertFrom(null, CultureInfo.InvariantCulture, _imageBytes); - - Assert.Equal(_image.Height, newImage.Height); - Assert.Equal(_image.Width, newImage.Width); - - newImage = (Image)_imgConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, _imageBytes); - - Assert.Equal(_image.Height, newImage.Height); - Assert.Equal(_image.Width, newImage.Width); - } - - [Fact] - public void ConvertFrom_ThrowsNotSupportedException() - { - Assert.Throws(() => _imgConv.ConvertFrom("System.Drawing.String")); - Assert.Throws(() => _imgConv.ConvertFrom(null, CultureInfo.InvariantCulture, "System.Drawing.String")); - Assert.Throws(() => _imgConv.ConvertFrom(null, CultureInfo.InvariantCulture, new Bitmap(20, 20))); - Assert.Throws(() => _imgConv.ConvertFrom(null, CultureInfo.InvariantCulture, new Point(10, 10))); - Assert.Throws(() => _imgConv.ConvertFrom(null, CultureInfo.InvariantCulture, new SizeF(10, 10))); - Assert.Throws(() => _imgConv.ConvertFrom(null, CultureInfo.InvariantCulture, new object())); - - Assert.Throws(() => _imgConvFrmTD.ConvertFrom("System.Drawing.String")); - Assert.Throws(() => _imgConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, "System.Drawing.String")); - Assert.Throws(() => _imgConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, new Bitmap(20, 20))); - Assert.Throws(() => _imgConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, new Point(10, 10))); - Assert.Throws(() => _imgConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, new SizeF(10, 10))); - Assert.Throws(() => _imgConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, new object())); - } - - [Fact] - public void ConvertTo_String() - { - Assert.Equal(_imageStr, (string)_imgConv.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(string))); - Assert.Equal(_imageStr, (string)_imgConv.ConvertTo(_image, typeof(string))); - Assert.Equal(_imageStr, (string)_imgConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(string))); - Assert.Equal(_imageStr, (string)_imgConvFrmTD.ConvertTo(_image, typeof(string))); - - using (new ThreadCultureChange(CultureInfo.CreateSpecificCulture("fr-FR"), CultureInfo.InvariantCulture)) - { - Assert.Equal("(none)", (string)_imgConv.ConvertTo(null, typeof(string))); - Assert.Equal("(none)", (string)_imgConv.ConvertTo(null, CultureInfo.CreateSpecificCulture("ru-RU"), null, typeof(string))); - - Assert.Equal("(none)", (string)_imgConvFrmTD.ConvertTo(null, typeof(string))); - Assert.Equal("(none)", (string)_imgConvFrmTD.ConvertTo(null, CultureInfo.CreateSpecificCulture("de-DE"), null, typeof(string))); - } - } - - [Fact] - public void ConvertTo_ByteArray() - { - byte[] newImageBytes = (byte[])_imgConv.ConvertTo(null, CultureInfo.InvariantCulture, _image, _imageBytes.GetType()); - Assert.Equal(_imageBytes, newImageBytes); - - newImageBytes = (byte[])_imgConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _image, _imageBytes.GetType()); - Assert.Equal(_imageBytes, newImageBytes); - - newImageBytes = (byte[])_imgConvFrmTD.ConvertTo(_image, _imageBytes.GetType()); - Assert.Equal(_imageBytes, newImageBytes); - } - - [Fact] - public void ConvertTo_FromBitmapToByteArray() - { - Bitmap value = new Bitmap(64, 64); - ImageConverter converter = new ImageConverter(); - byte[] converted = (byte[])converter.ConvertTo(value, typeof(byte[])); - Assert.NotNull(converted); - } - - [Fact] - public void ConvertTo_ThrowsNotSupportedException() - { - Assert.Throws(() => _imgConv.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(Rectangle))); - Assert.Throws(() => _imgConv.ConvertTo(null, CultureInfo.InvariantCulture, _image, _image.GetType())); - Assert.Throws(() => _imgConv.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(Size))); - Assert.Throws(() => _imgConv.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(Bitmap))); - Assert.Throws(() => _imgConv.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(Point))); - Assert.Throws(() => _imgConv.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(Metafile))); - Assert.Throws(() => _imgConv.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(object))); - Assert.Throws(() => _imgConv.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(int))); - - Assert.Throws(() => _imgConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(Rectangle))); - Assert.Throws(() => _imgConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _image, _image.GetType())); - Assert.Throws(() => _imgConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(Size))); - Assert.Throws(() => _imgConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(Bitmap))); - Assert.Throws(() => _imgConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(Point))); - Assert.Throws(() => _imgConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(Metafile))); - Assert.Throws(() => _imgConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(object))); - Assert.Throws(() => _imgConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _image, typeof(int))); - } - - [Fact] - public void TestGetPropertiesSupported() - { - Assert.True(_imgConv.GetPropertiesSupported(), "GetPropertiesSupported()"); - Assert.True(_imgConv.GetPropertiesSupported(null), "GetPropertiesSupported(null)"); - } - - [Fact] - public void TestGetProperties() - { - const int allPropertiesCount = 14; // Count of all properties in Image class. - const int browsablePropertiesCount = 7; // Count of browsable properties in Image class (BrowsableAttribute.Yes). - - PropertyDescriptorCollection propsColl; - - // Internally calls TypeDescriptor.GetProperties(typeof(Image), null), which returns all properties. - propsColl = _imgConv.GetProperties(null, _image, null); - Assert.Equal(allPropertiesCount, propsColl.Count); - - // Internally calls TypeDescriptor.GetProperties(typeof(Image), new Attribute[] { BrowsableAttribute.Yes }). - propsColl = _imgConv.GetProperties(null, _image); - Assert.Equal(browsablePropertiesCount, propsColl.Count); - propsColl = _imgConv.GetProperties(_image); - Assert.Equal(browsablePropertiesCount, propsColl.Count); - - - // Returns all properties of Image class. - propsColl = TypeDescriptor.GetProperties(typeof(Image)); - Assert.Equal(allPropertiesCount, propsColl.Count); - - // Internally calls TypeDescriptor.GetProperties(typeof(Image), null), which returns all properties. - propsColl = _imgConvFrmTD.GetProperties(null, _image, null); - Assert.Equal(allPropertiesCount, propsColl.Count); - - // Internally calls TypeDescriptor.GetProperties(typeof(Image), new Attribute[] { BrowsableAttribute.Yes }). - propsColl = _imgConvFrmTD.GetProperties(null, _image); - Assert.Equal(browsablePropertiesCount, propsColl.Count); - propsColl = _imgConvFrmTD.GetProperties(_image); - Assert.Equal(browsablePropertiesCount, propsColl.Count); - } -} diff --git a/src/System.Drawing.Common/tests/System/Drawing/ImageFormatConverterTests.cs b/src/System.Drawing.Common/tests/System/Drawing/ImageFormatConverterTests.cs deleted file mode 100644 index 09858c3d54f..00000000000 --- a/src/System.Drawing.Common/tests/System/Drawing/ImageFormatConverterTests.cs +++ /dev/null @@ -1,249 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Drawing.Imaging; -using System.Globalization; - -namespace System.ComponentModel.TypeConverterTests; - -public class ImageFormatConverterTest -{ - private readonly ImageFormat _imageFmt; - private readonly ImageFormatConverter _imgFmtConv; - private readonly ImageFormatConverter _imgFmtConvFrmTD; - private readonly string _imageFmtStr; - - public ImageFormatConverterTest() - { - _imageFmt = ImageFormat.Bmp; - _imageFmtStr = _imageFmt.ToString(); - - _imgFmtConv = new ImageFormatConverter(); - _imgFmtConvFrmTD = (ImageFormatConverter)TypeDescriptor.GetConverter(_imageFmt); - } - - [Fact] - public void TestCanConvertFrom() - { - Assert.True(_imgFmtConv.CanConvertFrom(typeof(string)), "string (no context)"); - Assert.True(_imgFmtConv.CanConvertFrom(null, typeof(string)), "string"); - Assert.False(_imgFmtConv.CanConvertFrom(null, typeof(ImageFormat)), "ImageFormat"); - Assert.False(_imgFmtConv.CanConvertFrom(null, typeof(Guid)), "Guid"); - Assert.False(_imgFmtConv.CanConvertFrom(null, typeof(object)), "object"); - Assert.False(_imgFmtConv.CanConvertFrom(null, typeof(int)), "int"); - - Assert.True(_imgFmtConvFrmTD.CanConvertFrom(typeof(string)), "TD string (no context)"); - Assert.True(_imgFmtConvFrmTD.CanConvertFrom(null, typeof(string)), "TD string"); - Assert.False(_imgFmtConvFrmTD.CanConvertFrom(null, typeof(ImageFormat)), "TD ImageFormat"); - Assert.False(_imgFmtConvFrmTD.CanConvertFrom(null, typeof(Guid)), "TD Guid"); - Assert.False(_imgFmtConvFrmTD.CanConvertFrom(null, typeof(object)), "TD object"); - Assert.False(_imgFmtConvFrmTD.CanConvertFrom(null, typeof(int)), "TD int"); - } - - [Fact] - public void TestCanConvertTo() - { - Assert.True(_imgFmtConv.CanConvertTo(typeof(string)), "string (no context)"); - Assert.True(_imgFmtConv.CanConvertTo(null, typeof(string)), "string"); - Assert.False(_imgFmtConv.CanConvertTo(null, typeof(ImageFormat)), "ImageFormat"); - Assert.False(_imgFmtConv.CanConvertTo(null, typeof(Guid)), "Guid"); - Assert.False(_imgFmtConv.CanConvertTo(null, typeof(object)), "object"); - Assert.False(_imgFmtConv.CanConvertTo(null, typeof(int)), "int"); - - Assert.True(_imgFmtConvFrmTD.CanConvertTo(typeof(string)), "TD string (no context)"); - Assert.True(_imgFmtConvFrmTD.CanConvertTo(null, typeof(string)), "TD string"); - Assert.False(_imgFmtConvFrmTD.CanConvertTo(null, typeof(ImageFormat)), "TD ImageFormat"); - Assert.False(_imgFmtConvFrmTD.CanConvertTo(null, typeof(Guid)), "TD Guid"); - Assert.False(_imgFmtConvFrmTD.CanConvertTo(null, typeof(object)), "TD object"); - Assert.False(_imgFmtConvFrmTD.CanConvertTo(null, typeof(int)), "TD int"); - } - - [Fact] - public void TestConvertFrom_ImageFormatToString() - { - Assert.Equal(_imageFmt, (ImageFormat)_imgFmtConv.ConvertFrom(null, CultureInfo.InvariantCulture, ImageFormat.Bmp.ToString())); - Assert.Equal(_imageFmt, (ImageFormat)_imgFmtConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, ImageFormat.Bmp.ToString())); - } - - [Fact] - public void TestConvertFrom_ThrowsNotSupportedException() - { - Assert.Throws(() => _imgFmtConv.ConvertFrom(null, CultureInfo.InvariantCulture, ImageFormat.Bmp)); - Assert.Throws(() => _imgFmtConv.ConvertFrom(null, CultureInfo.InvariantCulture, ImageFormat.Bmp.Guid)); - Assert.Throws(() => _imgFmtConv.ConvertFrom(null, CultureInfo.InvariantCulture, new object())); - Assert.Throws(() => _imgFmtConv.ConvertFrom(null, CultureInfo.InvariantCulture, 10)); - - Assert.Throws(() => _imgFmtConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, ImageFormat.Bmp)); - Assert.Throws(() => _imgFmtConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, ImageFormat.Bmp.Guid)); - Assert.Throws(() => _imgFmtConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, new object())); - Assert.Throws(() => _imgFmtConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, 10)); - } - - private ImageFormat ConvertFromName(string imgFormatName) - { - return (ImageFormat)_imgFmtConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, imgFormatName); - } - - [Fact] - public void ConvertFrom_ShortName() - { - Assert.Equal(ImageFormat.Bmp, ConvertFromName("Bmp")); - Assert.Equal(ImageFormat.Emf, ConvertFromName("Emf")); - Assert.Equal(ImageFormat.Exif, ConvertFromName("Exif")); - Assert.Equal(ImageFormat.Gif, ConvertFromName("Gif")); - Assert.Equal(ImageFormat.Tiff, ConvertFromName("Tiff")); - Assert.Equal(ImageFormat.Png, ConvertFromName("Png")); - Assert.Equal(ImageFormat.MemoryBmp, ConvertFromName("MemoryBmp")); - Assert.Equal(ImageFormat.Icon, ConvertFromName("Icon")); - Assert.Equal(ImageFormat.Jpeg, ConvertFromName("Jpeg")); - Assert.Equal(ImageFormat.Wmf, ConvertFromName("Wmf")); -#if NET - Assert.Equal(ImageFormat.Heif, ConvertFromName("Heif")); - Assert.Equal(ImageFormat.Webp, ConvertFromName("Webp")); -#endif - } - - [Fact] - public void ConvertFrom_LongName() - { - Guid testGuid = Guid.NewGuid(); - ImageFormat imageformat = ConvertFromName($"[ImageFormat: {testGuid}]"); - Assert.Equal(testGuid, imageformat.Guid); - } - - [Fact] - public void ConvertFrom_ThrowsFormatExceptionOnInvalidFormatString() - { - Assert.Throws(() => _imgFmtConv.ConvertFrom("System.Drawing.String")); - Assert.Throws(() => _imgFmtConv.ConvertFrom(null, CultureInfo.InvariantCulture, "System.Drawing.String")); - Assert.Throws(() => _imgFmtConv.ConvertFrom("[ImageFormat: abcdefgh-ijkl-mnop-qrst-uvwxyz012345]")); - - Assert.Throws(() => _imgFmtConvFrmTD.ConvertFrom("System.Drawing.String")); - Assert.Throws(() => _imgFmtConvFrmTD.ConvertFrom(null, CultureInfo.InvariantCulture, "System.Drawing.String")); - Assert.Throws(() => _imgFmtConvFrmTD.ConvertFrom("[ImageFormat: abcdefgh-ijkl-mnop-qrst-uvwxyz012345]")); - } - - [Fact] - public void TestConvertTo_String() - { - Assert.Equal(_imageFmtStr, (string)_imgFmtConv.ConvertTo(null, CultureInfo.InvariantCulture, _imageFmt, typeof(string))); - Assert.Equal(_imageFmtStr, (string)_imgFmtConv.ConvertTo(_imageFmt, typeof(string))); - - Assert.Equal(_imageFmtStr, (string)_imgFmtConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _imageFmt, typeof(string))); - Assert.Equal(_imageFmtStr, (string)_imgFmtConvFrmTD.ConvertTo(_imageFmt, typeof(string))); - - Assert.Equal(string.Empty, (string)_imgFmtConv.ConvertTo(null, typeof(string))); - Assert.Equal(string.Empty, (string)_imgFmtConv.ConvertTo(null, CultureInfo.CreateSpecificCulture("ru-RU"), null, typeof(string))); - - Assert.Equal(string.Empty, (string)_imgFmtConvFrmTD.ConvertTo(null, typeof(string))); - Assert.Equal(string.Empty, (string)_imgFmtConvFrmTD.ConvertTo(null, CultureInfo.CreateSpecificCulture("de-DE"), null, typeof(string))); - } - - [Fact] - public void TestConvertTo_ThrowsNotSupportedException() - { - Assert.Throws(() => _imgFmtConv.ConvertTo(null, CultureInfo.InvariantCulture, _imageFmt, typeof(ImageFormat))); - Assert.Throws(() => _imgFmtConv.ConvertTo(null, CultureInfo.InvariantCulture, _imageFmt, typeof(Guid))); - Assert.Throws(() => _imgFmtConv.ConvertTo(null, CultureInfo.InvariantCulture, _imageFmt, typeof(object))); - Assert.Throws(() => _imgFmtConv.ConvertTo(null, CultureInfo.InvariantCulture, _imageFmt, typeof(int))); - - Assert.Throws(() => _imgFmtConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _imageFmt, typeof(ImageFormat))); - Assert.Throws(() => _imgFmtConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _imageFmt, typeof(Guid))); - Assert.Throws(() => _imgFmtConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _imageFmt, typeof(object))); - Assert.Throws(() => _imgFmtConvFrmTD.ConvertTo(null, CultureInfo.InvariantCulture, _imageFmt, typeof(int))); - } - - [Fact] - public void GetStandardValuesSupported() - { - Assert.True(_imgFmtConv.GetStandardValuesSupported(), "GetStandardValuesSupported()"); - Assert.True(_imgFmtConv.GetStandardValuesSupported(null), "GetStandardValuesSupported(null)"); - } - - private void CheckStandardValues(ICollection values) - { - bool memorybmp = false; - bool bmp = false; - bool emf = false; - bool wmf = false; - bool gif = false; - bool jpeg = false; - bool png = false; - bool tiff = false; - bool exif = false; - bool icon = false; -#if NET - bool heif = false; - bool webp = false; -#endif - - foreach (ImageFormat iformat in values) - { - switch (iformat.Guid.ToString()) - { - case "b96b3caa-0728-11d3-9d7b-0000f81ef32e": - memorybmp = true; - break; - case "b96b3cab-0728-11d3-9d7b-0000f81ef32e": - bmp = true; - break; - case "b96b3cac-0728-11d3-9d7b-0000f81ef32e": - emf = true; - break; - case "b96b3cad-0728-11d3-9d7b-0000f81ef32e": - wmf = true; - break; - case "b96b3cb0-0728-11d3-9d7b-0000f81ef32e": - gif = true; - break; - case "b96b3cae-0728-11d3-9d7b-0000f81ef32e": - jpeg = true; - break; - case "b96b3caf-0728-11d3-9d7b-0000f81ef32e": - png = true; - break; - case "b96b3cb1-0728-11d3-9d7b-0000f81ef32e": - tiff = true; - break; - case "b96b3cb2-0728-11d3-9d7b-0000f81ef32e": - exif = true; - break; - case "b96b3cb5-0728-11d3-9d7b-0000f81ef32e": - icon = true; - break; -#if NET - case "b96b3cb6-0728-11d3-9d7b-0000f81ef32e": - heif = true; - break; - case "b96b3cb7-0728-11d3-9d7b-0000f81ef32e": - webp = true; - break; -#endif - default: - throw new InvalidOperationException($"Unknown GUID {iformat.Guid}."); - } - } - Assert.True(memorybmp, "MemoryBMP"); - Assert.True(bmp, "Bmp"); - Assert.True(emf, "Emf"); - Assert.True(wmf, "Wmf"); - Assert.True(gif, "Gif"); - Assert.True(jpeg, "Jpeg"); - Assert.True(png, "Png"); - Assert.True(tiff, "Tiff"); - Assert.True(exif, "Exif"); - Assert.True(icon, "Icon"); -#if NET - Assert.True(heif, "Heif"); - Assert.True(webp, "Webp"); -#endif - } - - [Fact] - public void GetStandardValues() - { - CheckStandardValues(_imgFmtConv.GetStandardValues()); - CheckStandardValues(_imgFmtConv.GetStandardValues(null)); - } -} diff --git a/src/System.Drawing.Common/tests/System/Drawing/Printing/MarginsConverterTests.cs b/src/System.Drawing.Common/tests/System/Drawing/Printing/MarginsConverterTests.cs deleted file mode 100644 index c5846ebcd2f..00000000000 --- a/src/System.Drawing.Common/tests/System/Drawing/Printing/MarginsConverterTests.cs +++ /dev/null @@ -1,154 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace System.Drawing.Printing.Tests; - -public class MarginsConverterTests -{ - [Fact] - public void CanConvertFrom() - { - MarginsConverter mc = new MarginsConverter(); - - // try once with then once without context - for (var context = new MyTypeDescriptorContext(); context != null; context = null) - { - Assert.True(mc.CanConvertFrom(context, typeof(string))); - Assert.False(mc.CanConvertFrom(context, typeof(Guid))); - Assert.False(mc.CanConvertFrom(context, typeof(object))); - Assert.False(mc.CanConvertFrom(context, typeof(int))); - } - } - - [Fact] - public void CanConvertTo() - { - MarginsConverter mc = new MarginsConverter(); - - // try once with then once without context - for (var context = new MyTypeDescriptorContext(); context != null; context = null) - { - Assert.True(mc.CanConvertTo(context, typeof(string))); - Assert.False(mc.CanConvertTo(context, typeof(Guid))); - Assert.False(mc.CanConvertTo(context, typeof(object))); - Assert.False(mc.CanConvertTo(context, typeof(int))); - } - } - - [Fact] - public void CreateInstance() - { - MarginsConverter mc = new MarginsConverter(); - MyTypeDescriptorContext context = new MyTypeDescriptorContext(); - - IDictionary values = new Dictionary(); - values.Add("Left", 1); - values.Add("Right", 2); - values.Add("Top", 3); - Assert.Throws(() => mc.CreateInstance(context, values)); - values.Add("Bottom", 4); - - object result = mc.CreateInstance(context, values); - Assert.NotNull(result); - - Assert.IsType(result); - Margins margins = result as Margins; - Assert.Equal(1, margins.Left); - Assert.Equal(2, margins.Right); - Assert.Equal(3, margins.Top); - Assert.Equal(4, margins.Bottom); - } - - [Fact] - public void GetCreateInstanceSupported() - { - MarginsConverter mc = new MarginsConverter(); - Assert.True(mc.GetCreateInstanceSupported(null)); - Assert.True(mc.GetCreateInstanceSupported(new MyTypeDescriptorContext())); - } - - [Fact] - public void ConvertFrom() - { - MarginsConverter mc = new MarginsConverter(); - CultureInfo culture = CultureInfo.InvariantCulture; - - // try once with then once without context - for (var context = new MyTypeDescriptorContext(); context != null; context = null) - { - object result; - Assert.Equal(',', culture.TextInfo.ListSeparator[0]); - AssertExtensions.Throws(() => mc.ConvertFrom(context, culture, "1;2;3;4")); - result = mc.ConvertFrom(context, culture, "1,2,3,4"); - Assert.IsType(result); - Margins margins = result as Margins; - Assert.Equal(1, margins.Left); - Assert.Equal(2, margins.Right); - Assert.Equal(3, margins.Top); - Assert.Equal(4, margins.Bottom); - } - } - - [Fact] - public void ConvertFrom_Throws() - { - MarginsConverter mc = new MarginsConverter(); - CultureInfo culture = CultureInfo.InvariantCulture; - - // try once with then once without context - for (var context = new MyTypeDescriptorContext(); context != null; context = null) - { - Assert.Throws(() => mc.ConvertFrom(context, null, null)); - Assert.Throws(() => mc.ConvertFrom(context, culture, null)); - Assert.Throws(() => mc.ConvertFrom(context, culture, Guid.NewGuid())); - AssertExtensions.Throws(() => mc.ConvertFrom(context, null, "wrong string format")); - AssertExtensions.Throws(() => mc.ConvertFrom(context, culture, "wrong string format")); - } - } - - [Fact] - public void ConvertTo() - { - MarginsConverter mc = new MarginsConverter(); - Guid guid = Guid.NewGuid(); - CultureInfo culture = CultureInfo.InvariantCulture; - Margins margins = new Margins() { Left = 1, Right = 2, Top = 3, Bottom = 4 }; - - // try once with then once without context - for (var context = new MyTypeDescriptorContext(); context != null; context = null) - { - Assert.Equal("1;2;3;4", mc.ConvertTo(context, culture, "1;2;3;4", typeof(string))); - - object converted = mc.ConvertTo(context, culture, margins, typeof(string)); - Assert.IsType(converted); - Assert.Equal(',', culture.TextInfo.ListSeparator[0]); - Assert.Equal("1, 2, 3, 4", converted); - - converted = mc.ConvertTo(context, culture, margins, typeof(InstanceDescriptor)); - Assert.IsType(converted); - Assert.Equal(new object[] { 1, 2, 3, 4 }, ((InstanceDescriptor)converted).Arguments); - - Assert.Throws(() => mc.ConvertTo(context, culture, new object(), typeof(object))); - Assert.Throws(() => mc.ConvertTo(context, culture, 12, typeof(int))); - Assert.Throws(() => mc.ConvertTo(context, culture, guid, typeof(Guid))); - - Assert.Equal(string.Empty, (string)mc.ConvertTo(null, typeof(string))); - Assert.Equal(string.Empty, (string)mc.ConvertTo(context, CultureInfo.CreateSpecificCulture("ru-RU"), null, typeof(string))); - } - } - - private class MyTypeDescriptorContext : ITypeDescriptorContext - { - public IContainer Container => null; - public object Instance { get { return null; } } - public PropertyDescriptor PropertyDescriptor { get { return null; } } - public bool OnComponentChanging() { return true; } - public void OnComponentChanged() { } - public object GetService(Type serviceType) { return null; } - } -} diff --git a/src/System.Drawing.Common/tests/SystemBrushesTests.cs b/src/System.Drawing.Common/tests/SystemBrushesTests.cs deleted file mode 100644 index 208a2feaeb3..00000000000 --- a/src/System.Drawing.Common/tests/SystemBrushesTests.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class SystemBrushesTests -{ - public static IEnumerable SystemBrushes_TestData() - { - yield return Brush(() => SystemBrushes.ActiveBorder, SystemColors.ActiveBorder); - yield return Brush(() => SystemBrushes.ActiveCaption, SystemColors.ActiveCaption); - yield return Brush(() => SystemBrushes.ActiveCaptionText, SystemColors.ActiveCaptionText); - yield return Brush(() => SystemBrushes.AppWorkspace, SystemColors.AppWorkspace); - yield return Brush(() => SystemBrushes.ButtonFace, SystemColors.ButtonFace); - yield return Brush(() => SystemBrushes.ButtonHighlight, SystemColors.ButtonHighlight); - yield return Brush(() => SystemBrushes.ButtonShadow, SystemColors.ButtonShadow); - yield return Brush(() => SystemBrushes.Control, SystemColors.Control); - yield return Brush(() => SystemBrushes.ControlDark, SystemColors.ControlDark); - yield return Brush(() => SystemBrushes.ControlDarkDark, SystemColors.ControlDarkDark); - yield return Brush(() => SystemBrushes.ControlLight, SystemColors.ControlLight); - yield return Brush(() => SystemBrushes.ControlLightLight, SystemColors.ControlLightLight); - yield return Brush(() => SystemBrushes.ControlText, SystemColors.ControlText); - yield return Brush(() => SystemBrushes.Desktop, SystemColors.Desktop); - yield return Brush(() => SystemBrushes.GradientActiveCaption, SystemColors.GradientActiveCaption); - yield return Brush(() => SystemBrushes.GradientInactiveCaption, SystemColors.GradientInactiveCaption); - yield return Brush(() => SystemBrushes.GrayText, SystemColors.GrayText); - yield return Brush(() => SystemBrushes.Highlight, SystemColors.Highlight); - yield return Brush(() => SystemBrushes.HighlightText, SystemColors.HighlightText); - yield return Brush(() => SystemBrushes.HotTrack, SystemColors.HotTrack); - yield return Brush(() => SystemBrushes.InactiveBorder, SystemColors.InactiveBorder); - yield return Brush(() => SystemBrushes.InactiveCaption, SystemColors.InactiveCaption); - yield return Brush(() => SystemBrushes.InactiveCaptionText, SystemColors.InactiveCaptionText); - yield return Brush(() => SystemBrushes.Info, SystemColors.Info); - yield return Brush(() => SystemBrushes.InfoText, SystemColors.InfoText); - yield return Brush(() => SystemBrushes.Menu, SystemColors.Menu); - yield return Brush(() => SystemBrushes.MenuBar, SystemColors.MenuBar); - yield return Brush(() => SystemBrushes.MenuHighlight, SystemColors.MenuHighlight); - yield return Brush(() => SystemBrushes.MenuText, SystemColors.MenuText); - yield return Brush(() => SystemBrushes.ScrollBar, SystemColors.ScrollBar); - yield return Brush(() => SystemBrushes.Window, SystemColors.Window); - yield return Brush(() => SystemBrushes.WindowFrame, SystemColors.WindowFrame); - yield return Brush(() => SystemBrushes.WindowText, SystemColors.WindowText); - } - - public static object[] Brush(Func getBrush, Color expectedColor) => new object[] { getBrush, expectedColor }; - - [Theory] - [MemberData(nameof(SystemBrushes_TestData))] - public void SystemBrushes_Get_ReturnsExpected(Func getBrush, Color expectedColor) - { - SolidBrush brush = Assert.IsType(getBrush()); - Assert.Equal(expectedColor, brush.Color); - AssertExtensions.Throws(null, () => brush.Color = Color.Red); - - Assert.Same(brush, getBrush()); - } - - [Fact] - public void FromSystemColor_NotSystemColor_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => SystemBrushes.FromSystemColor(Color.Blue)); - } -} diff --git a/src/System.Drawing.Common/tests/SystemFontsTests.cs b/src/System.Drawing.Common/tests/SystemFontsTests.cs deleted file mode 100644 index 4ba71824aa1..00000000000 --- a/src/System.Drawing.Common/tests/SystemFontsTests.cs +++ /dev/null @@ -1,172 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; - -namespace System.Drawing.Tests; - -public class SystemFontsTests -{ - public static IEnumerable SystemFonts_TestData() - { - yield return new object[] { (Func)(() => SystemFonts.CaptionFont) }; - yield return new object[] { (Func)(() => SystemFonts.IconTitleFont) }; - yield return new object[] { (Func)(() => SystemFonts.MenuFont) }; - yield return new object[] { (Func)(() => SystemFonts.MessageBoxFont) }; - yield return new object[] { (Func)(() => SystemFonts.SmallCaptionFont) }; - yield return new object[] { (Func)(() => SystemFonts.StatusFont) }; - } - - [Theory] - [MemberData(nameof(SystemFonts_TestData))] - public void SystemFont_Get_ReturnsExpected(Func getFont) - { - using (Font font = getFont()) - using (Font otherFont = getFont()) - { - Assert.NotNull(font); - Assert.NotNull(otherFont); - Assert.NotSame(font, otherFont); - - // Assert.Equal on a font will use the native handle to assert equality, which is not always guaranteed. - Assert.Equal(font.Name, otherFont.Name); - } - } - - public static IEnumerable SystemFonts_WindowsNames_TestData() - { - int userLangId = GetUserDefaultLCID(); - SystemFontList fonts; - - switch (userLangId & 0x3ff) - { - case 0x11: // ja-JP (Japanese) - fonts = new SystemFontList("Yu Gothic UI"); - break; - case 0x5C: // chr-Cher-US (Cherokee) - fonts = new SystemFontList("Gadugi"); - break; - case 0x12: // ko-KR (Korean) - fonts = new SystemFontList("\ub9d1\uc740\x20\uace0\ub515"); - break; - case 0x4: // zh-TW (Traditional Chinese, Taiwan) or zh-CN (Simplified Chinese, PRC) - // Although the primary language ID is the same, the fonts are different - // So we have to determine by the full language ID - // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/70feba9f-294e-491e-b6eb-56532684c37f - // Assuming this doc is correct AND the font only differs by whether it's traditional or not it should work - switch (userLangId & 0xFFFF) - { - case 0x0004: // zh-Hans - case 0x7804: // zh - case 0x0804: // zh-CN - case 0x1004: // zh-SG - fonts = new SystemFontList("Microsoft JhengHei UI"); - break; - case 0x7C04: // zh-Hant - case 0x0C04: // zh-HK - case 0x1404: // zh-MO - case 0x0404: // zh-TW - fonts = new SystemFontList("Microsoft YaHei UI"); - break; - default: - throw new InvalidOperationException("The primary language ID is Chinese, however it was not able to" + - $" determine the user locale from the LCID with value: {userLangId & 0xFFFF:X4}."); - } - break; - case 0x1E: // th-TH - case 0x54: // lo-LA - case 0x53: // km-KH - fonts = new SystemFontList("Leelawadee UI"); - break; - case 0x4A: // te-IN - case 0x49: // ta-IN - case 0x5B: // si-LK - case 0x48: // or-IN - case 0x4E: // mr-IN - case 0x4C: // ml-IN - case 0x57: // kok-IN - case 0x45: // bn-BD - case 0x4D: // as-IN - fonts = new SystemFontList("Nirmala UI"); - break; - case 0x5E: // am-ET - fonts = new SystemFontList("Ebrima"); - break; - default: // For now we assume everything else uses Segoe UI - // If there's other failure reported we can add it - fonts = new SystemFontList("Segoe UI"); - break; - } - - return fonts.ToTestData(); - } - - [Theory] - [MemberData(nameof(SystemFonts_WindowsNames_TestData))] - public void SystemFont_Get_ReturnsExpected_WindowsNames(Func getFont, string systemFontName, string windowsFontName) - { - using (Font font = getFont()) - using (Font otherFont = getFont()) - using (Font fontFromName = SystemFonts.GetFontByName(systemFontName)) - { - Assert.NotSame(font, otherFont); - Assert.Equal(font, otherFont); - Assert.Equal(font, fontFromName); - - Assert.Equal(systemFontName, font.SystemFontName); - - // Windows 8 updated some system fonts. - if (!PlatformDetection.IsWindows7) - { - Assert.Equal(windowsFontName, font.Name); - } - } - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("captionfont")] - public void GetFontByName_NoSuchName_ReturnsNull(string systemFontName) - { - Assert.Null(SystemFonts.GetFontByName(systemFontName)); - } - - [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)] - internal static extern int GetUserDefaultLCID(); - - // Do not test DefaultFont and DialogFont, as we can't reliably determine from LCID - // https://github.com/dotnet/runtime/issues/28830#issuecomment-473556522 - class SystemFontList - { - public SystemFontList(string c_it_m_mb_scFonts) - { - CaptionFont = c_it_m_mb_scFonts; - IconTitleFont = c_it_m_mb_scFonts; - MenuFont = c_it_m_mb_scFonts; - MessageBoxFont = c_it_m_mb_scFonts; - SmallCaptionFont = c_it_m_mb_scFonts; - StatusFont = c_it_m_mb_scFonts; - } - - public string CaptionFont { get; set; } - public string IconTitleFont { get; set; } - public string MenuFont { get; set; } - public string MessageBoxFont { get; set; } - public string SmallCaptionFont { get; set; } - public string StatusFont { get; set; } - - public IEnumerable ToTestData() - { - return new [] - { - new object[] {(Func)(() => SystemFonts.CaptionFont), nameof(CaptionFont), CaptionFont}, - new object[] {(Func)(() => SystemFonts.IconTitleFont), nameof(IconTitleFont), IconTitleFont}, - new object[] {(Func)(() => SystemFonts.MenuFont), nameof(MenuFont), MenuFont}, - new object[] {(Func)(() => SystemFonts.MessageBoxFont), nameof(MessageBoxFont), MessageBoxFont}, - new object[] {(Func)(() => SystemFonts.SmallCaptionFont), nameof(SmallCaptionFont), SmallCaptionFont}, - new object[] {(Func)(() => SystemFonts.StatusFont), nameof(StatusFont), StatusFont} - }; - } - } -} diff --git a/src/System.Drawing.Common/tests/SystemIconsTests.cs b/src/System.Drawing.Common/tests/SystemIconsTests.cs deleted file mode 100644 index 26c84b6edee..00000000000 --- a/src/System.Drawing.Common/tests/SystemIconsTests.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Tests; - -public class SystemIconsTests -{ - public static IEnumerable SystemIcons_TestData() - { - yield return Icon(() => SystemIcons.Application); - yield return Icon(() => SystemIcons.Asterisk); - yield return Icon(() => SystemIcons.Error); - yield return Icon(() => SystemIcons.Exclamation); - yield return Icon(() => SystemIcons.Hand); - yield return Icon(() => SystemIcons.Information); - yield return Icon(() => SystemIcons.Question); - yield return Icon(() => SystemIcons.Shield); - yield return Icon(() => SystemIcons.Warning); - yield return Icon(() => SystemIcons.WinLogo); - } - - public static object[] Icon(Func getIcon) => new object[] { getIcon }; - - [Theory] - [MemberData(nameof(SystemIcons_TestData))] - public void SystemIcons_Get_ReturnsExpected(Func getIcon) - { - Icon icon = getIcon(); - Assert.Same(icon, getIcon()); - } - - [Theory] - [EnumData] - public void SystemIcons_GetStockIcon(StockIconId stockIcon) - { - using Icon icon = SystemIcons.GetStockIcon(stockIcon); - Assert.NotNull(icon); - } - - [Fact] - public void SystemIcons_GetStockIcon_BySize() - { - using Icon icon = SystemIcons.GetStockIcon(StockIconId.Lock, size: 256); - Assert.NotNull(icon); - Assert.Equal(256, icon.Width); - Assert.Equal(256, icon.Height); - } - - [Fact] - public void SystemIcons_GetStockIcon_InvalidId_ThrowsArgumentException() - { - Assert.Throws(() => SystemIcons.GetStockIcon((StockIconId)(-1))); - } - - public static TheoryData StockIconOptions_TestData => new() - { - StockIconOptions.LinkOverlay, - StockIconOptions.Selected, - StockIconOptions.ShellIconSize, - StockIconOptions.SmallIcon, - StockIconOptions.LinkOverlay | StockIconOptions.Selected | StockIconOptions.ShellIconSize | StockIconOptions.SmallIcon, - }; - - [Theory] - [MemberData(nameof(StockIconOptions_TestData))] - public void SystemIcons_GetStockIcon_Options(StockIconOptions options) - { - using Icon icon = SystemIcons.GetStockIcon(StockIconId.Shield, options); - Assert.NotNull(icon); - } -} diff --git a/src/System.Drawing.Common/tests/SystemPensTest.cs b/src/System.Drawing.Common/tests/SystemPensTest.cs deleted file mode 100644 index 9afb2aeb4f5..00000000000 --- a/src/System.Drawing.Common/tests/SystemPensTest.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; - -namespace System.Drawing.Tests; - -public class SystemPensTests -{ - public static IEnumerable SystemPens_TestData() - { - yield return Pen(() => SystemPens.ActiveBorder, SystemColors.ActiveBorder); - yield return Pen(() => SystemPens.ActiveCaption, SystemColors.ActiveCaption); - yield return Pen(() => SystemPens.ActiveCaptionText, SystemColors.ActiveCaptionText); - yield return Pen(() => SystemPens.AppWorkspace, SystemColors.AppWorkspace); - yield return Pen(() => SystemPens.ButtonFace, SystemColors.ButtonFace); - yield return Pen(() => SystemPens.ButtonHighlight, SystemColors.ButtonHighlight); - yield return Pen(() => SystemPens.ButtonShadow, SystemColors.ButtonShadow); - yield return Pen(() => SystemPens.Control, SystemColors.Control); - yield return Pen(() => SystemPens.ControlDark, SystemColors.ControlDark); - yield return Pen(() => SystemPens.ControlDarkDark, SystemColors.ControlDarkDark); - yield return Pen(() => SystemPens.ControlLight, SystemColors.ControlLight); - yield return Pen(() => SystemPens.ControlLightLight, SystemColors.ControlLightLight); - yield return Pen(() => SystemPens.ControlText, SystemColors.ControlText); - yield return Pen(() => SystemPens.Desktop, SystemColors.Desktop); - yield return Pen(() => SystemPens.GradientActiveCaption, SystemColors.GradientActiveCaption); - yield return Pen(() => SystemPens.GradientInactiveCaption, SystemColors.GradientInactiveCaption); - yield return Pen(() => SystemPens.GrayText, SystemColors.GrayText); - yield return Pen(() => SystemPens.Highlight, SystemColors.Highlight); - yield return Pen(() => SystemPens.HighlightText, SystemColors.HighlightText); - yield return Pen(() => SystemPens.HotTrack, SystemColors.HotTrack); - yield return Pen(() => SystemPens.InactiveBorder, SystemColors.InactiveBorder); - yield return Pen(() => SystemPens.InactiveCaption, SystemColors.InactiveCaption); - yield return Pen(() => SystemPens.InactiveCaptionText, SystemColors.InactiveCaptionText); - yield return Pen(() => SystemPens.Info, SystemColors.Info); - yield return Pen(() => SystemPens.InfoText, SystemColors.InfoText); - yield return Pen(() => SystemPens.Menu, SystemColors.Menu); - yield return Pen(() => SystemPens.MenuBar, SystemColors.MenuBar); - yield return Pen(() => SystemPens.MenuHighlight, SystemColors.MenuHighlight); - yield return Pen(() => SystemPens.MenuText, SystemColors.MenuText); - yield return Pen(() => SystemPens.ScrollBar, SystemColors.ScrollBar); - yield return Pen(() => SystemPens.Window, SystemColors.Window); - yield return Pen(() => SystemPens.WindowFrame, SystemColors.WindowFrame); - yield return Pen(() => SystemPens.WindowText, SystemColors.WindowText); - } - - public static object[] Pen(Func getPen, Color expectedColor) => new object[] { getPen, expectedColor }; - - [Theory] - [MemberData(nameof(SystemPens_TestData))] - public void SystemPens_Get_ReturnsExpected(Func getPen, Color expectedColor) - { - Pen pen = getPen(); - Assert.Equal(expectedColor, pen.Color); - Assert.Equal(PenType.SolidColor, pen.PenType); - Assert.Same(pen, getPen()); - - AssertExtensions.Throws(null, () => pen.Dispose()); - AssertExtensions.Throws(null, () => pen.SetLineCap(LineCap.ArrowAnchor, LineCap.Custom, DashCap.Round)); - - AssertExtensions.Throws(null, () => pen.Alignment = PenAlignment.Center); - AssertExtensions.Throws(null, () => pen.Brush = null); - AssertExtensions.Throws(null, () => pen.Color = Color.AliceBlue); - AssertExtensions.Throws(null, () => pen.CompoundArray = null); - AssertExtensions.Throws(null, () => pen.CustomEndCap = null); - AssertExtensions.Throws(null, () => pen.CustomStartCap = null); - AssertExtensions.Throws(null, () => pen.DashCap = DashCap.Flat); - AssertExtensions.Throws(null, () => pen.DashStyle = DashStyle.Custom); - AssertExtensions.Throws(null, () => pen.DashOffset = 10); - AssertExtensions.Throws(null, () => pen.DashPattern = null); - AssertExtensions.Throws(null, () => pen.EndCap = LineCap.RoundAnchor); - AssertExtensions.Throws(null, () => pen.LineJoin = LineJoin.MiterClipped); - AssertExtensions.Throws(null, () => pen.MiterLimit = 10); - AssertExtensions.Throws(null, () => pen.StartCap = LineCap.RoundAnchor); - using (var matrix = new Matrix()) - { - AssertExtensions.Throws(null, () => pen.Transform = matrix); - } - AssertExtensions.Throws(null, () => pen.Width = 10); - } - - [Fact] - public void FromSystemColor_NotSystemColor_ThrowsArgumentException() - { - AssertExtensions.Throws(null, () => SystemPens.FromSystemColor(Color.Blue)); - } -} diff --git a/src/System.Drawing.Common/tests/Text/InstalledFontCollectionTests.cs b/src/System.Drawing.Common/tests/Text/InstalledFontCollectionTests.cs deleted file mode 100644 index 6c16f2a3e6d..00000000000 --- a/src/System.Drawing.Common/tests/Text/InstalledFontCollectionTests.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Text.Tests; - -[ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported))] -public class InstalledFontCollectionTests -{ - [Fact] - public void Ctor_Default() - { - using (var fontCollection = new InstalledFontCollection()) - { - Assert.NotEmpty(fontCollection.Families); - } - } - - [Fact] - public void Families_GetWhenDisposed_ReturnsNonEmpty() - { - var fontCollection = new InstalledFontCollection(); - fontCollection.Dispose(); - - Assert.NotEmpty(fontCollection.Families); - } - - [Fact] - public void Dispose_MultipleTimes_Nop() - { - var fontCollection = new InstalledFontCollection(); - fontCollection.Dispose(); - fontCollection.Dispose(); - } -} diff --git a/src/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs b/src/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs deleted file mode 100644 index 82f2fdea9bc..00000000000 --- a/src/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs +++ /dev/null @@ -1,237 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; - -namespace System.Drawing.Text.Tests; - -public class PrivateFontCollectionTests -{ - [Fact] - public void Ctor_Default() - { - using (var fontCollection = new PrivateFontCollection()) - { - Assert.Empty(fontCollection.Families); - } - } - - [Fact] - public void AddFontFile_AbsolutePath_Success() - { - // GDI+ on Windows 7 incorrectly throws a FileNotFoundException. - if (PlatformDetection.IsWindows7) - { - return; - } - - using (var fontCollection = new PrivateFontCollection()) - { - fontCollection.AddFontFile(Helpers.GetTestBitmapPath("empty.file")); - fontCollection.AddFontFile(Helpers.GetTestFontPath("CodeNewRoman.otf")); - - FontFamily fontFamily = Assert.Single(fontCollection.Families); - Assert.Equal("Code New Roman", fontFamily.Name); - } - } - - [Fact] - public void AddFontFile_RelativePath_Success() - { - // GDI+ on Windows 7 incorrectly throws a FileNotFoundException. - if (PlatformDetection.IsWindows7) - { - return; - } - - using (var fontCollection = new PrivateFontCollection()) - { - string relativePath = Path.Combine("fonts", "CodeNewRoman.ttf"); - fontCollection.AddFontFile(relativePath); - - FontFamily fontFamily = Assert.Single(fontCollection.Families); - Assert.Equal("Code New Roman", fontFamily.Name); - } - } - - [Fact] - public void AddFontFile_SamePathMultipleTimes_FamiliesContainsOnlyOneFont() - { - // GDI+ on Windows 7 incorrectly throws a FileNotFoundException. - if (PlatformDetection.IsWindows7) - { - return; - } - - using (var fontCollection = new PrivateFontCollection()) - { - fontCollection.AddFontFile(Helpers.GetTestFontPath("CodeNewRoman.ttf")); - fontCollection.AddFontFile(Helpers.GetTestFontPath("CodeNewRoman.ttf")); - - FontFamily fontFamily = Assert.Single(fontCollection.Families); - Assert.Equal("Code New Roman", fontFamily.Name); - } - } - - [Fact] - public void AddFontFile_SameNameMultipleTimes_FamiliesContainsFirstFontOnly() - { - // GDI+ on Windows 7 incorrectly throws a FileNotFoundException. - if (PlatformDetection.IsWindows7) - { - return; - } - - using (var fontCollection = new PrivateFontCollection()) - { - fontCollection.AddFontFile(Helpers.GetTestFontPath("CodeNewRoman.ttf")); - fontCollection.AddFontFile(Helpers.GetTestFontPath("CodeNewRoman.otf")); - - // Verify that the first file is used by checking that it contains metadata - // associated with CodeNewRoman.ttf. - const int FrenchLCID = 1036; - FontFamily fontFamily = Assert.Single(fontCollection.Families); - Assert.Equal("Code New Roman", fontFamily.Name); - Assert.Equal("Bonjour", fontFamily.GetName(FrenchLCID)); - } - } - - [Fact] - public void AddFontFile_NullFileName_ThrowsArgumentNullException() - { - using (var fontCollection = new PrivateFontCollection()) - { - AssertExtensions.Throws("filename", "path", () => fontCollection.AddFontFile(null)); - } - } - - [Fact] - public void AddFontFile_InvalidPath_ThrowsArgumentException() - { - using (var fontCollection = new PrivateFontCollection()) - { - AssertExtensions.Throws("path", null, () => fontCollection.AddFontFile(string.Empty)); - } - } - - [Fact] - public void AddFontFile_NoSuchFilePath_ThrowsFileNotFoundException() - { - using (var fontCollection = new PrivateFontCollection()) - { - Assert.Throws(() => fontCollection.AddFontFile("fileName")); - } - } - - [Fact] - public void AddFontFile_LongFilePath_ThrowsException() - { - using var fontCollection = new PrivateFontCollection(); - Assert.Throws( - () => fontCollection.AddFontFile(new string('a', 261))); - } - - [Fact] - public void AddFontFile_Directory_ThrowsFileNotFoundException() - { - using (var fontCollection = new PrivateFontCollection()) - { - AssertExtensions.Throws(() => fontCollection.AddFontFile(AppContext.BaseDirectory)); - } - } - - [Fact] - public void AddFontFile_Disposed_ThrowsArgumentException() - { - var fontCollection = new PrivateFontCollection(); - fontCollection.Dispose(); - - AssertExtensions.Throws(null, () => fontCollection.AddFontFile("fileName")); - } - - [Fact] - public void AddMemoryFont_ValidMemory_Success() - { - using (var fontCollection = new PrivateFontCollection()) - { - byte[] data = File.ReadAllBytes(Helpers.GetTestFontPath("CodeNewRoman.otf")); - - IntPtr fontBuffer = Marshal.AllocCoTaskMem(data.Length); - try - { - Marshal.Copy(data, 0, fontBuffer, data.Length); - fontCollection.AddMemoryFont(fontBuffer, data.Length); - - FontFamily font = Assert.Single(fontCollection.Families); - Assert.Equal("Code New Roman", font.Name); - } - finally - { - Marshal.FreeCoTaskMem(fontBuffer); - } - } - } - - [Fact] - public void AddMemoryFont_ZeroMemory_ThrowsArgumentException() - { - using (var fontCollection = new PrivateFontCollection()) - { - AssertExtensions.Throws(null, () => fontCollection.AddMemoryFont(IntPtr.Zero, 100)); - } - } - - [Theory] - [InlineData(0)] - [InlineData(-1)] - public void AddMemoryFont_InvalidLength_ThrowsArgumentException(int length) - { - // GDI+ on Windows 7 incorrectly throws a FileNotFoundException. - if (PlatformDetection.IsWindows) - { - return; - } - - using (var fontCollection = new PrivateFontCollection()) - { - byte[] data = File.ReadAllBytes(Helpers.GetTestFontPath("CodeNewRoman.otf")); - - IntPtr fontBuffer = Marshal.AllocCoTaskMem(data.Length); - try - { - Marshal.Copy(data, 0, fontBuffer, data.Length); - AssertExtensions.Throws(null, () => fontCollection.AddMemoryFont(fontBuffer, length)); - } - finally - { - Marshal.FreeCoTaskMem(fontBuffer); - } - } - } - - [Fact] - public void AddMemoryFont_Disposed_ThrowsArgumentException() - { - var fontCollection = new PrivateFontCollection(); - fontCollection.Dispose(); - - AssertExtensions.Throws(null, () => fontCollection.AddMemoryFont((IntPtr)10, 100)); - } - - [Fact] - public void Families_GetWhenDisposed_ThrowsArgumentException() - { - var fontCollection = new PrivateFontCollection(); - fontCollection.Dispose(); - - AssertExtensions.Throws(null, () => fontCollection.Families); - } - - [Fact] - public void Dispose_MultipleTimes_Nop() - { - var fontCollection = new PrivateFontCollection(); - fontCollection.Dispose(); - fontCollection.Dispose(); - } -} diff --git a/src/System.Drawing.Common/tests/TextureBrushTests.cs b/src/System.Drawing.Common/tests/TextureBrushTests.cs deleted file mode 100644 index 35bcd32821d..00000000000 --- a/src/System.Drawing.Common/tests/TextureBrushTests.cs +++ /dev/null @@ -1,898 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; - -namespace System.Drawing.Tests; - -public class TextureBrushTests -{ - public static IEnumerable Ctor_Bitmap_TestData() - { - yield return new object[] { new Bitmap(10, 10), PixelFormat.Format32bppPArgb, new Size(10, 10) }; - yield return new object[] { new Metafile(Helpers.GetTestBitmapPath("telescope_01.wmf")), PixelFormat.Format32bppArgb, new Size(490, 654) }; - } - - [Theory] - [MemberData(nameof(Ctor_Bitmap_TestData))] - public void Ctor_Bitmap(Image bitmap, PixelFormat expectedPixelFormat, Size expectedSize) - { - try - { - using (var brush = new TextureBrush(bitmap)) - using (var matrix = new Matrix()) - { - Bitmap brushImage = Assert.IsType(brush.Image); - Assert.NotSame(bitmap, brushImage); - Assert.Equal(expectedPixelFormat, brushImage.PixelFormat); - Assert.Equal(expectedSize, brushImage.Size); - Assert.Equal(matrix, brush.Transform); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - } - } - finally - { - bitmap.Dispose(); - } - } - - [Fact] - public void Ctor_BitmapFromIconHandle_Success() - { - using (var icon = new Icon(Helpers.GetTestBitmapPath("10x16_one_entry_32bit.ico"))) - using (var image = Bitmap.FromHicon(icon.Handle)) - { - Ctor_Bitmap(image, PixelFormat.Format32bppPArgb, new Size(11, 22)); - } - } - - public static IEnumerable Ctor_Image_WrapMode_TestData() - { - foreach (object[] data in Ctor_Bitmap_TestData()) - { - yield return new object[] { ((Image)data[0]).Clone(), WrapMode.Clamp, data[1], data[2] }; - yield return new object[] { ((Image)data[0]).Clone(), WrapMode.Tile, data[1], data[2] }; - yield return new object[] { ((Image)data[0]).Clone(), WrapMode.TileFlipX, data[1], data[2] }; - yield return new object[] { ((Image)data[0]).Clone(), WrapMode.TileFlipXY, data[1], data[2] }; - yield return new object[] { ((Image)data[0]).Clone(), WrapMode.TileFlipY, data[1], data[2] }; - } - } - - [Theory] - [MemberData(nameof(Ctor_Image_WrapMode_TestData))] - public void Ctor_Image_WrapMode(Image image, WrapMode wrapMode, PixelFormat expectedPixelFormat, Size expectedSize) - { - try - { - using (var brush = new TextureBrush(image, wrapMode)) - using (var matrix = new Matrix()) - { - Bitmap brushImage = Assert.IsType(brush.Image); - Assert.NotSame(image, brushImage); - Assert.Equal(expectedPixelFormat, brushImage.PixelFormat); - Assert.Equal(expectedSize, brushImage.Size); - Assert.Equal(matrix, brush.Transform); - Assert.Equal(wrapMode, brush.WrapMode); - } - } - finally - { - image.Dispose(); - } - } - - public static IEnumerable Ctor_Image_Rectangle_TestData() - { - yield return new object[] { new Bitmap(10, 10), new Rectangle(0, 0, 10, 10) }; - yield return new object[] { new Bitmap(10, 10), new Rectangle(5, 5, 5, 5) }; - } - - [Theory] - [MemberData(nameof(Ctor_Image_Rectangle_TestData))] - public void Ctor_Image_Rectangle(Image image, Rectangle rectangle) - { - try - { - using (var brush = new TextureBrush(image, rectangle)) - using (var matrix = new Matrix()) - { - Bitmap brushImage = Assert.IsType(brush.Image); - Assert.NotSame(image, brushImage); - Assert.Equal(PixelFormat.Format32bppPArgb, brushImage.PixelFormat); - Assert.Equal(rectangle.Size, brushImage.Size); - Assert.Equal(matrix, brush.Transform); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - } - } - finally - { - image.Dispose(); - } - } - - [Theory] - [MemberData(nameof(Ctor_Image_Rectangle_TestData))] - public void Ctor_Image_RectangleF(Image image, Rectangle rectangle) - { - try - { - using (var brush = new TextureBrush(image, (RectangleF)rectangle)) - using (var matrix = new Matrix()) - { - Bitmap brushImage = Assert.IsType(brush.Image); - Assert.NotSame(image, brushImage); - Assert.Equal(PixelFormat.Format32bppPArgb, brushImage.PixelFormat); - Assert.Equal(rectangle.Size, brushImage.Size); - Assert.Equal(matrix, brush.Transform); - Assert.Equal(WrapMode.Tile, brush.WrapMode); - } - } - finally - { - image.Dispose(); - } - } - - public static IEnumerable Ctor_Image_WrapMode_Rectangle_TestData() - { - foreach (object[] data in Ctor_Image_Rectangle_TestData()) - { - yield return new object[] { ((Image)data[0]).Clone(), WrapMode.Clamp, data[1] }; - yield return new object[] { ((Image)data[0]).Clone(), WrapMode.Tile, data[1] }; - yield return new object[] { ((Image)data[0]).Clone(), WrapMode.TileFlipX, data[1] }; - yield return new object[] { ((Image)data[0]).Clone(), WrapMode.TileFlipXY, data[1] }; - yield return new object[] { ((Image)data[0]).Clone(), WrapMode.TileFlipY, data[1] }; - } - } - - [Theory] - [MemberData(nameof(Ctor_Image_WrapMode_Rectangle_TestData))] - public void Ctor_Image_WrapMode_Rectangle(Image image, WrapMode wrapMode, Rectangle rectangle) - { - try - { - using (var brush = new TextureBrush(image, wrapMode, rectangle)) - using (var matrix = new Matrix()) - { - Bitmap brushImage = Assert.IsType(brush.Image); - Assert.NotSame(image, brushImage); - Assert.Equal(PixelFormat.Format32bppPArgb, brushImage.PixelFormat); - Assert.Equal(rectangle.Size, brushImage.Size); - Assert.Equal(matrix, brush.Transform); - Assert.Equal(wrapMode, brush.WrapMode); - } - } - finally - { - image.Dispose(); - } - } - - [Theory] - [MemberData(nameof(Ctor_Image_WrapMode_Rectangle_TestData))] - public void Ctor_Image_WrapMode_RectangleF(Image image, WrapMode wrapMode, Rectangle rectangle) - { - try - { - using (var brush = new TextureBrush(image, wrapMode, (RectangleF)rectangle)) - using (var matrix = new Matrix()) - { - Bitmap brushImage = Assert.IsType(brush.Image); - Assert.NotSame(image, brushImage); - Assert.Equal(PixelFormat.Format32bppPArgb, brushImage.PixelFormat); - Assert.Equal(rectangle.Size, brushImage.Size); - Assert.Equal(matrix, brush.Transform); - Assert.Equal(wrapMode, brush.WrapMode); - } - } - finally - { - image.Dispose(); - } - } - - public static IEnumerable Ctor_Image_Rectangle_ImageAttributes_TestData() - { - foreach (object[] data in Ctor_Image_Rectangle_TestData()) - { - yield return new object[] { ((Image)data[0]).Clone(), data[1], null, WrapMode.Tile }; - yield return new object[] { ((Image)data[0]).Clone(), data[1], new ImageAttributes(), WrapMode.Clamp }; - - var customWrapMode = new ImageAttributes(); - customWrapMode.SetWrapMode(WrapMode.TileFlipXY); - yield return new object[] { ((Image)data[0]).Clone(), data[1], customWrapMode, WrapMode.TileFlipXY }; - } - } - - [Theory] - [MemberData(nameof(Ctor_Image_Rectangle_ImageAttributes_TestData))] - public void Ctor_Image_Rectangle_ImageAttributes(Image image, Rectangle rectangle, ImageAttributes attributes, WrapMode expectedWrapMode) - { - try - { - using (var brush = new TextureBrush(image, rectangle, attributes)) - using (var matrix = new Matrix()) - { - Bitmap brushImage = Assert.IsType(brush.Image); - Assert.NotSame(image, brushImage); - Assert.Equal(PixelFormat.Format32bppPArgb, brushImage.PixelFormat); - Assert.Equal(rectangle.Size, brushImage.Size); - Assert.Equal(matrix, brush.Transform); - Assert.Equal(expectedWrapMode, brush.WrapMode); - } - } - finally - { - image.Dispose(); - attributes?.Dispose(); - } - } - - [Theory] - [MemberData(nameof(Ctor_Image_Rectangle_ImageAttributes_TestData))] - public void Ctor_Image_RectangleF_ImageAttributes(Image image, Rectangle rectangle, ImageAttributes attributes, WrapMode expectedWrapMode) - { - try - { - using (var brush = new TextureBrush(image, (RectangleF)rectangle, attributes)) - using (var matrix = new Matrix()) - { - Bitmap brushImage = Assert.IsType(brush.Image); - Assert.NotSame(image, brushImage); - Assert.Equal(PixelFormat.Format32bppPArgb, brushImage.PixelFormat); - Assert.Equal(rectangle.Size, brushImage.Size); - Assert.Equal(matrix, brush.Transform); - Assert.Equal(expectedWrapMode, brush.WrapMode); - } - } - finally - { - image.Dispose(); - attributes?.Dispose(); - } - } - - [Fact] - public void Ctor_NullImage_ThrowsArgumentNullException() - { - AssertExtensions.Throws("image", () => new TextureBrush(null)); - AssertExtensions.Throws("image", () => new TextureBrush(null, WrapMode.Tile)); - AssertExtensions.Throws("image", () => new TextureBrush(null, RectangleF.Empty)); - AssertExtensions.Throws("image", () => new TextureBrush(null, Rectangle.Empty)); - AssertExtensions.Throws("image", () => new TextureBrush(null, RectangleF.Empty, null)); - AssertExtensions.Throws("image", () => new TextureBrush(null, Rectangle.Empty, null)); - AssertExtensions.Throws("image", () => new TextureBrush(null, WrapMode.Tile, RectangleF.Empty)); - AssertExtensions.Throws("image", () => new TextureBrush(null, WrapMode.Tile, Rectangle.Empty)); - } - - [Fact] - public void Ctor_DisposedImage_ThrowsArgumentException() - { - var image = new Bitmap(10, 10); - image.Dispose(); - - AssertExtensions.Throws(null, () => new TextureBrush(image)); - AssertExtensions.Throws(null, () => new TextureBrush(image, WrapMode.Tile)); - AssertExtensions.Throws(null, () => new TextureBrush(image, RectangleF.Empty)); - AssertExtensions.Throws(null, () => new TextureBrush(image, Rectangle.Empty)); - AssertExtensions.Throws(null, () => new TextureBrush(image, RectangleF.Empty, null)); - AssertExtensions.Throws(null, () => new TextureBrush(image, Rectangle.Empty, null)); - AssertExtensions.Throws(null, () => new TextureBrush(image, WrapMode.Tile, RectangleF.Empty)); - AssertExtensions.Throws(null, () => new TextureBrush(image, WrapMode.Tile, Rectangle.Empty)); - } - - [Theory] - [InlineData(WrapMode.Tile - 1)] - [InlineData(WrapMode.Clamp + 1)] - public void Ctor_InvalidWrapMode_ThrowsInvalidEnumArgumentException(WrapMode wrapMode) - { - using (var image = new Bitmap(10, 10)) - { - Assert.ThrowsAny(() => new TextureBrush(image, wrapMode)); - Assert.ThrowsAny(() => new TextureBrush(image, wrapMode, RectangleF.Empty)); - Assert.ThrowsAny(() => new TextureBrush(image, wrapMode, Rectangle.Empty)); - } - } - - [Theory] - [InlineData(-1, 0, 1, 1)] - [InlineData(10, 0, 1, 1)] - [InlineData(5, 0, 6, 1)] - [InlineData(0, -1, 1, 1)] - [InlineData(0, 10, 1, 1)] - [InlineData(0, 5, 1, 6)] - [InlineData(0, 0, 1, 0)] - [InlineData(0, 0, 0, 1)] - public void Ctor_InvalidRectangle_ThrowsOutOfMemoryException(int x, int y, int width, int height) - { - var rectangle = new Rectangle(x, y, width, height); - using (var image = new Bitmap(10, 10)) - { - Assert.Throws(() => new TextureBrush(image, rectangle)); - Assert.Throws(() => new TextureBrush(image, (RectangleF)rectangle)); - Assert.Throws(() => new TextureBrush(image, WrapMode.Tile, rectangle)); - Assert.Throws(() => new TextureBrush(image, WrapMode.Tile, (RectangleF)rectangle)); - Assert.Throws(() => new TextureBrush(image, rectangle, null)); - Assert.Throws(() => new TextureBrush(image, (RectangleF)rectangle, null)); - } - } - - [Fact] - public void Clone_Invoke_Success() - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image, WrapMode.Clamp)) - { - TextureBrush clone = Assert.IsType(brush.Clone()); - Assert.NotSame(brush, clone); - - Assert.Equal(new Size(10, 10), brush.Image.Size); - Assert.Equal(WrapMode.Clamp, clone.WrapMode); - } - } - - [Fact] - public void Clone_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - var brush = new TextureBrush(image); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Clone()); - } - } - - [Fact] - public void Image_GetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - var brush = new TextureBrush(image); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Image); - } - } - - public static IEnumerable MultiplyTransform_TestData() - { - yield return new object[] { new Matrix(), new Matrix(1, 2, 3, 4, 5, 6), MatrixOrder.Prepend }; - yield return new object[] { new Matrix(), new Matrix(1, 2, 3, 4, 5, 6), MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), new Matrix(2, 3, 4, 5, 6, 7), MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), new Matrix(2, 3, 4, 5, 6, 7), MatrixOrder.Append }; - } - - [Theory] - [MemberData(nameof(MultiplyTransform_TestData))] - public void MultiplyTransform_Matrix_SetsTransformToExpected(Matrix originalTransform, Matrix matrix, MatrixOrder matrixOrder) - { - try - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - using (var expected = (Matrix)originalTransform.Clone()) - { - expected.Multiply(matrix, matrixOrder); - brush.Transform = originalTransform; - - if (matrixOrder == MatrixOrder.Prepend) - { - TextureBrush clone = (TextureBrush)brush.Clone(); - clone.MultiplyTransform(matrix); - Assert.Equal(expected, clone.Transform); - } - - brush.MultiplyTransform(matrix, matrixOrder); - Assert.Equal(expected, brush.Transform); - } - } - finally - { - originalTransform.Dispose(); - matrix.Dispose(); - } - } - - [Fact] - public void MultiplyTransform_NullMatrix_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - { - AssertExtensions.Throws("matrix", () => brush.MultiplyTransform(null)); - AssertExtensions.Throws("matrix", () => brush.MultiplyTransform(null, MatrixOrder.Prepend)); - } - } - - [Fact] - public void MultiplyTransform_NotInvertibleMatrix_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - using (var matrix = new Matrix(123, 24, 82, 16, 47, 30)) - { - AssertExtensions.Throws(null, () => brush.MultiplyTransform(matrix)); - AssertExtensions.Throws(null, () => brush.MultiplyTransform(matrix, MatrixOrder.Prepend)); - } - } - - [Fact] - public void MultiplyTransform_DisposedMatrix_Nop() - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - { - brush.Transform = transform; - - var matrix = new Matrix(); - matrix.Dispose(); - - brush.MultiplyTransform(matrix); - brush.MultiplyTransform(matrix, MatrixOrder.Append); - - Assert.Equal(transform, brush.Transform); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void MultiplyTransform_InvalidOrder_Nop(MatrixOrder matrixOrder) - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - using (var matrix = new Matrix()) - { - brush.Transform = transform; - - brush.MultiplyTransform(matrix, matrixOrder); - Assert.Equal(transform, brush.Transform); - } - } - - [Fact] - public void MultiplyTransform_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var matrix = new Matrix()) - { - var brush = new TextureBrush(image); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.MultiplyTransform(matrix)); - AssertExtensions.Throws(null, () => brush.MultiplyTransform(matrix, MatrixOrder.Prepend)); - } - } - - [Fact] - public void ResetTransform_Invoke_SetsTransformToZero() - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - using (var transform = new Matrix(1, 2, 3, 4, 5, 6)) - using (var matrix = new Matrix()) - { - brush.Transform = transform; - brush.ResetTransform(); - Assert.Equal(matrix, brush.Transform); - - brush.ResetTransform(); - Assert.Equal(matrix, brush.Transform); - } - } - - [Fact] - public void ResetTransform_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - var brush = new TextureBrush(image); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.ResetTransform()); - } - } - - public static IEnumerable RotateTransform_TestData() - { - yield return new object[] { new Matrix(), 90, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(), 90, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 360, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 360, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -45, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -45, MatrixOrder.Append }; - } - - [Theory] - [MemberData(nameof(RotateTransform_TestData))] - public void RotateTransform_Invoke_SetsTransformToExpected(Matrix originalTransform, float angle, MatrixOrder matrixOrder) - { - try - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - using (Matrix expected = originalTransform.Clone()) - { - expected.Rotate(angle, matrixOrder); - brush.Transform = originalTransform; - - if (matrixOrder == MatrixOrder.Prepend) - { - TextureBrush clone = (TextureBrush)brush.Clone(); - clone.RotateTransform(angle); - Assert.Equal(expected, clone.Transform); - } - - brush.RotateTransform(angle, matrixOrder); - Assert.Equal(expected, brush.Transform); - } - } - finally - { - originalTransform.Dispose(); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void RotateTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder matrixOrder) - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - { - AssertExtensions.Throws(null, () => brush.RotateTransform(10, matrixOrder)); - } - } - - [Fact] - public void RotateTransform_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var matrix = new Matrix()) - { - var brush = new TextureBrush(image); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.RotateTransform(1)); - AssertExtensions.Throws(null, () => brush.RotateTransform(1, MatrixOrder.Prepend)); - } - } - - public static IEnumerable ScaleTransform_TestData() - { - yield return new object[] { new Matrix(), 2, 3, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(), 2, 3, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, 0, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, 0, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 1, 1, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 1, 1, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -2, -3, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -2, -3, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0.5, 0.75, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0.5, 0.75, MatrixOrder.Append }; - } - - [Theory] - [MemberData(nameof(ScaleTransform_TestData))] - public void ScaleTransform_Invoke_SetsTransformToExpected(Matrix originalTransform, float scaleX, float scaleY, MatrixOrder matrixOrder) - { - try - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - using (Matrix expected = originalTransform.Clone()) - { - expected.Scale(scaleX, scaleY, matrixOrder); - brush.Transform = originalTransform; - - if (matrixOrder == MatrixOrder.Prepend) - { - TextureBrush clone = (TextureBrush)brush.Clone(); - clone.ScaleTransform(scaleX, scaleY); - Assert.Equal(expected, clone.Transform); - } - - brush.ScaleTransform(scaleX, scaleY, matrixOrder); - Assert.Equal(expected, brush.Transform); - } - } - finally - { - originalTransform.Dispose(); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void ScaleTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder matrixOrder) - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - { - AssertExtensions.Throws(null, () => brush.ScaleTransform(1, 2, matrixOrder)); - } - } - - [Fact] - public void ScaleTransform_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var matrix = new Matrix()) - { - var brush = new TextureBrush(image); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.ScaleTransform(1, 2)); - AssertExtensions.Throws(null, () => brush.ScaleTransform(1, 2, MatrixOrder.Prepend)); - } - } - - [Fact] - public void Transform_SetValid_GetReturnsExpected() - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - using (var matrix = new Matrix(1, 2, 3, 4, 5, 6)) - { - brush.Transform = matrix; - Assert.Equal(matrix, brush.Transform); - } - } - - [Fact] - public void Transform_SetNull_ThrowsArgumentNullException() - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - { - AssertExtensions.Throws("value", () => brush.Transform = null); - } - } - - [Fact] - public void Transform_SetDisposedMatrix_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - { - var matrix = new Matrix(); - matrix.Dispose(); - - AssertExtensions.Throws(null, () => brush.Transform = matrix); - } - } - - [Fact] - public void Transform_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var matrix = new Matrix()) - { - var brush = new TextureBrush(image); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.Transform); - AssertExtensions.Throws(null, () => brush.Transform = matrix); - } - } - - public static IEnumerable TranslateTransform_TestData() - { - yield return new object[] { new Matrix(), 2, 3, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(), 2, 3, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, 0, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0, 0, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 1, 1, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 1, 1, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -2, -3, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), -2, -3, MatrixOrder.Append }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0.5, 0.75, MatrixOrder.Prepend }; - yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), 0.5, 0.75, MatrixOrder.Append }; - } - - [Theory] - [MemberData(nameof(TranslateTransform_TestData))] - public void TranslateTransform_Invoke_SetsTransformToExpected(Matrix originalTransform, float dX, float dY, MatrixOrder matrixOrder) - { - try - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - using (Matrix expected = originalTransform.Clone()) - { - expected.Translate(dX, dY, matrixOrder); - brush.Transform = originalTransform; - - if (matrixOrder == MatrixOrder.Prepend) - { - TextureBrush clone = (TextureBrush)brush.Clone(); - clone.TranslateTransform(dX, dY); - Assert.Equal(expected, clone.Transform); - } - - brush.TranslateTransform(dX, dY, matrixOrder); - Assert.Equal(expected, brush.Transform); - } - } - finally - { - originalTransform.Dispose(); - } - } - - [Theory] - [InlineData(MatrixOrder.Prepend - 1)] - [InlineData(MatrixOrder.Append + 1)] - public void TranslateTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder matrixOrder) - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - { - AssertExtensions.Throws(null, () => brush.TranslateTransform(1, 2, matrixOrder)); - } - } - - [Fact] - public void TranslateTransform_Disposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - using (var matrix = new Matrix()) - { - var brush = new TextureBrush(image); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.TranslateTransform(1, 2)); - AssertExtensions.Throws(null, () => brush.TranslateTransform(1, 2, MatrixOrder.Prepend)); - } - } - - [Theory] - [InlineData(WrapMode.Clamp)] - [InlineData(WrapMode.Tile)] - [InlineData(WrapMode.TileFlipX)] - [InlineData(WrapMode.TileFlipXY)] - [InlineData(WrapMode.TileFlipY)] - public void WrapMode_SetValid_GetReturnsExpected(WrapMode wrapMode) - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - { - brush.WrapMode = wrapMode; - Assert.Equal(wrapMode, brush.WrapMode); - } - } - - [Theory] - [InlineData(WrapMode.Tile - 1)] - [InlineData(WrapMode.Clamp + 1)] - public void WrapMode_SetInvalid_ThrowsInvalidEnumArgumentException(WrapMode wrapMode) - { - using (var image = new Bitmap(10, 10)) - using (var brush = new TextureBrush(image)) - { - Assert.ThrowsAny(() => brush.WrapMode = wrapMode); - } - } - - [Fact] - public void WrapMode_GetSetWhenDisposed_ThrowsArgumentException() - { - using (var image = new Bitmap(10, 10)) - { - var brush = new TextureBrush(image); - brush.Dispose(); - - AssertExtensions.Throws(null, () => brush.WrapMode); - AssertExtensions.Throws(null, () => brush.WrapMode = WrapMode.Tile); - } - } - - [Fact] - public void WrapMode_Clamp_ReturnsExpected() - { - // R|G|_|_ - // B|Y|_|_ - // _|_|_|_ - // _|_|_|_ - Color empty = Color.FromArgb(0, 0, 0, 0); - VerifyFillRect(WrapMode.Clamp, new Color[][] - { - new Color[] { Color.Red, Color.Green, empty, empty }, - new Color[] { Color.Blue, Color.Yellow, empty, empty }, - new Color[] { empty, empty, empty, empty }, - new Color[] { empty, empty, empty, empty } - }); - } - - [Fact] - public void WrapMode_Tile_ReturnsExpected() - { - // R|G|R|G - // B|Y|B|Y - // R|G|R|G - // B|Y|B|Y - VerifyFillRect(WrapMode.Tile, new Color[][] - { - new Color[] { Color.Red, Color.Green, Color.Red, Color.Green }, - new Color[] { Color.Blue, Color.Yellow, Color.Blue, Color.Yellow }, - new Color[] { Color.Red, Color.Green, Color.Red, Color.Green }, - new Color[] { Color.Blue, Color.Yellow, Color.Blue, Color.Yellow } - }); - } - - [Fact] - public void WrapMode_TileFlipX_ReturnsExpected() - { - // R|G|G|R - // B|Y|Y|B - // R|G|G|R - // B|Y|Y|B - VerifyFillRect(WrapMode.TileFlipX, new Color[][] - { - new Color[] { Color.Red, Color.Green, Color.Green, Color.Red }, - new Color[] { Color.Blue, Color.Yellow, Color.Yellow, Color.Blue }, - new Color[] { Color.Red, Color.Green, Color.Green, Color.Red }, - new Color[] { Color.Blue, Color.Yellow, Color.Yellow, Color.Blue } - }); - } - - [Fact] - public void WrapMode_TileFlipY_ReturnsExpected() - { - // R|G|R|G - // B|Y|B|Y - // B|Y|B|Y - // R|G|R|G - VerifyFillRect(WrapMode.TileFlipY, new Color[][] - { - new Color[] { Color.Red, Color.Green, Color.Red, Color.Green }, - new Color[] { Color.Blue, Color.Yellow, Color.Blue, Color.Yellow }, - new Color[] { Color.Blue, Color.Yellow, Color.Blue, Color.Yellow }, - new Color[] { Color.Red, Color.Green, Color.Red, Color.Green } - }); - } - - [Fact] - public void WrapMode_TileFlipXY_ReturnsExpected() - { - // R|G|G|R - // B|Y|Y|B - // B|Y|Y|B - // R|G|G|R - VerifyFillRect(WrapMode.TileFlipXY, new Color[][] - { - new Color[] { Color.Red, Color.Green, Color.Green, Color.Red }, - new Color[] { Color.Blue, Color.Yellow, Color.Yellow, Color.Blue }, - new Color[] { Color.Blue, Color.Yellow, Color.Yellow, Color.Blue }, - new Color[] { Color.Red, Color.Green, Color.Green, Color.Red } - }); - } - - private static void VerifyFillRect(WrapMode wrapMode, Color[][] expectedColors) - { - using (var brushBitmap = new Bitmap(2, 2)) - { - brushBitmap.SetPixel(0, 0, Color.Red); - brushBitmap.SetPixel(1, 0, Color.Green); - brushBitmap.SetPixel(0, 1, Color.Blue); - brushBitmap.SetPixel(1, 1, Color.Yellow); - - using (var brush = new TextureBrush(brushBitmap, wrapMode)) - using (var targetImage = new Bitmap(4, 4)) - using (Graphics targetGraphics = Graphics.FromImage(targetImage)) - { - targetGraphics.FillRectangle(brush, new Rectangle(0, 0, 4, 4)); - - Helpers.VerifyBitmap(targetImage, expectedColors); - } - } - } -} diff --git a/src/System.Drawing.Common/tests/ToolboxBitmapAttributeTests.cs b/src/System.Drawing.Common/tests/ToolboxBitmapAttributeTests.cs deleted file mode 100644 index 7b9e3438920..00000000000 --- a/src/System.Drawing.Common/tests/ToolboxBitmapAttributeTests.cs +++ /dev/null @@ -1,192 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -#pragma warning disable CA1050 // Declare types in namespaces -public class ClassWithNoNamespace { } -#pragma warning restore CA1050 - -namespace System.Drawing.Tests -{ - public class bitmap_173x183_indexed_8bit { } - - public class Icon_toolboxBitmapAttributeTest { } - - public class ToolboxBitmapAttributeTests - { - private static Size DefaultSize = new(16, 16); - private void AssertDefaultSize(Image image) - { - Assert.Equal(DefaultSize, image.Size); - } - - public static IEnumerable Ctor_FileName_TestData() - { - yield return new object[] { null, new Size(0, 0) }; - yield return new object[] { Helpers.GetTestBitmapPath("bitmap_173x183_indexed_8bit.bmp"), new Size(173, 183) }; - yield return new object[] { Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"), new Size(16, 16) }; - yield return new object[] { Helpers.GetTestBitmapPath("invalid.ico"), new Size(0, 0) }; - } - - [Theory] - [MemberData(nameof(Ctor_FileName_TestData))] - public void Ctor_FileName(string fileName, Size size) - { - var attribute = new ToolboxBitmapAttribute(fileName); - - using (Image image = attribute.GetImage(null)) - { - if (size == Size.Empty) - { - AssertDefaultSize(image); - } - else - { - Assert.Equal(size, image.Size); - } - } - } - - [Theory] - [InlineData(null, -1, -1)] - [InlineData(typeof(ClassWithNoNamespace), -1, -1)] - [InlineData(typeof(bitmap_173x183_indexed_8bit), 173, 183)] - [InlineData(typeof(ToolboxBitmapAttributeTests), -1, -1)] - public void Ctor_Type(Type type, int width, int height) - { - var attribute = new ToolboxBitmapAttribute(type); - using (Image image = attribute.GetImage(type)) - { - if (width == -1 && height == -1) - { - AssertDefaultSize(image); - } - else - { - Assert.Equal(new Size(width, height), image.Size); - } - } - } - - [Theory] - [InlineData(null, null, -1, -1)] - [InlineData(null, "invalid.ico", -1, -1)] - [InlineData(typeof(ClassWithNoNamespace), null, -1, -1)] - [InlineData(typeof(ToolboxBitmapAttributeTests), "", -1, -1)] - [InlineData(typeof(ToolboxBitmapAttributeTests), null, -1, -1)] - [InlineData(typeof(ToolboxBitmapAttributeTests), "invalid.ico", -1, -1)] - [InlineData(typeof(ToolboxBitmapAttributeTests), "48x48_multiple_entries_4bit", 16, 16)] - [InlineData(typeof(ToolboxBitmapAttributeTests), "48x48_multiple_entries_4bit.ico", 16, 16)] - [InlineData(typeof(ToolboxBitmapAttributeTests), "empty.file", -1, -1)] - [InlineData(typeof(ToolboxBitmapAttributeTests), "bitmap_173x183_indexed_8bit", 173, 183)] - [InlineData(typeof(ToolboxBitmapAttributeTests), "bitmap_173x183_indexed_8bit.bmp", 173, 183)] - public void Ctor_Type_String(Type type, string fileName, int width, int height) - { - var attribute = new ToolboxBitmapAttribute(type, fileName); - - using (Image image = attribute.GetImage(type, fileName, false)) - { - if (width == -1 && height == -1) - { - AssertDefaultSize(image); - } - else - { - Assert.Equal(new Size(width, height), image.Size); - } - } - } - - [Theory] - [InlineData("bitmap_173x183_indexed_8bit.bmp", 173, 183)] - [InlineData("48x48_multiple_entries_4bit.ico", 16, 16)] - public void GetImage_TypeFileNameBool_ReturnsExpected(string fileName, int width, int height) - { - var attribute = new ToolboxBitmapAttribute((string)null); - using (Image image = attribute.GetImage(typeof(ToolboxBitmapAttributeTests), fileName, large: true)) - { - Assert.Equal(new Size(32, 32), image.Size); - } - - using (Image image = attribute.GetImage(typeof(ToolboxBitmapAttributeTests), fileName, large: false)) - { - Assert.Equal(new Size(width, height), image.Size); - } - } - - [Fact] - public void GetImage_NullComponent_ReturnsNull() - { - var attribute = new ToolboxBitmapAttribute((string)null); - Assert.Null(attribute.GetImage((object)null)); - Assert.Null(attribute.GetImage((object)null, true)); - } - - [Fact] - public void GetImage_Component_ReturnsExpected() - { - ToolboxBitmapAttribute attribute = new ToolboxBitmapAttribute((string)null); - - using (Image smallImage = attribute.GetImage(new bitmap_173x183_indexed_8bit(), large: false)) - { - Assert.Equal(new Size(173, 183), smallImage.Size); - - using (Image largeImage = attribute.GetImage(new bitmap_173x183_indexed_8bit(), large: true)) - { - Assert.Equal(new Size(32, 32), largeImage.Size); - } - } - } - - [Fact] - public void GetImage_Default_ReturnsExpected() - { - ToolboxBitmapAttribute attribute = ToolboxBitmapAttribute.Default; - - using (Image image = attribute.GetImage(typeof(ToolboxBitmapAttributeTests), "bitmap_173x183_indexed_8bit", large: true)) - { - Assert.Equal(new Size(32, 32), image.Size); - } - - using (Image image = attribute.GetImage(typeof(ToolboxBitmapAttributeTests), "bitmap_173x183_indexed_8bit", large: false)) - { - Assert.Equal(new Size(173, 183), image.Size); - } - } - - [Theory] - [InlineData(typeof(Icon_toolboxBitmapAttributeTest), 256, 256)] - public void GetImage_NoExtension(Type type, int width, int height) - { - var attribute = new ToolboxBitmapAttribute(type); - using (Image image = attribute.GetImage(type)) - { - if (width == -1 && height == -1) - { - AssertDefaultSize(image); - } - else - { - Assert.Equal(new Size(width, height), image.Size); - } - } - } - - public static IEnumerable Equals_TestData() - { - yield return new object[] { ToolboxBitmapAttribute.Default, ToolboxBitmapAttribute.Default, true }; - yield return new object[] { ToolboxBitmapAttribute.Default, new ToolboxBitmapAttribute(typeof(ToolboxBitmapAttribute), "bitmap_173x183_indexed_8bit"), true }; - - yield return new object[] { ToolboxBitmapAttribute.Default, new object(), false }; - yield return new object[] { ToolboxBitmapAttribute.Default, null, false }; - } - - [Theory] - [MemberData(nameof(Equals_TestData))] - public void Equals_Other_ReturnsExpected(ToolboxBitmapAttribute attribute, object other, bool expected) - { - Assert.Equal(expected, attribute.Equals(other)); - Assert.Equal(attribute.GetHashCode(), attribute.GetHashCode()); - } - } -} diff --git a/src/System.Drawing.Common/tests/TrimmingTests/IconSave.cs b/src/System.Drawing.Common/tests/TrimmingTests/IconSave.cs deleted file mode 100644 index 0e15a645c51..00000000000 --- a/src/System.Drawing.Common/tests/TrimmingTests/IconSave.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.IO; - -/// -/// Tests that Icon.Save works when the Icon is loaded from an IntPtr. -/// This causes COM to be used to save the Icon. -/// -class Program -{ - static int Main(string[] args) - { - Icon i = SystemIcons.WinLogo; - using MemoryStream stream = new(); - - i.Save(stream); - - // ensure something was written to the stream - if (stream.Position == 0) - { - return -1; - } - - return 100; - } -} diff --git a/src/System.Drawing.Common/tests/TrimmingTests/System.Drawing.Common.TrimmingTests.proj b/src/System.Drawing.Common/tests/TrimmingTests/System.Drawing.Common.TrimmingTests.proj deleted file mode 100644 index 71883b846cb..00000000000 --- a/src/System.Drawing.Common/tests/TrimmingTests/System.Drawing.Common.TrimmingTests.proj +++ /dev/null @@ -1,15 +0,0 @@ - - - - - System.Drawing.Common - - - - - - - - diff --git a/src/System.Drawing.Common/tests/default.rd.xml b/src/System.Drawing.Common/tests/default.rd.xml deleted file mode 100644 index c2aeeadaf8e..00000000000 --- a/src/System.Drawing.Common/tests/default.rd.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/BmpCodecTests.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/BmpCodecTests.cs deleted file mode 100644 index 741eeaa3881..00000000000 --- a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/BmpCodecTests.cs +++ /dev/null @@ -1,535 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// BMPCodec class testing unit -// -// Authors: -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sebastien Pouliot -// -// (C) 2004 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Drawing.Imaging; - -namespace MonoTests.System.Drawing.Imaging; - -public class BmpCodecTest -{ - /* Checks bitmap features on a known 1bbp bitmap */ - [Fact] - public void Bitmap1bitFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver1bit.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.Equal(PixelFormat.Format4bppIndexed, bmp.PixelFormat); - Assert.Equal(173, bmp.Width); - Assert.Equal(183, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(173, rect.Width); - Assert.Equal(183, rect.Height); - - Assert.Equal(173, bmp.Size.Width); - Assert.Equal(183, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap1bitPixels() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver1bit.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-1, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(0, 128).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(0, 160).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(32, 128).ToArgb()); - Assert.Equal(-8355712, bmp.GetPixel(32, 160).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-8355712, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-8355840, bmp.GetPixel(64, 128).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 160).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-8355712, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(96, 96).ToArgb()); - Assert.Equal(-8355840, bmp.GetPixel(96, 128).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(96, 160).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(128, 0).ToArgb()); - Assert.Equal(-8355712, bmp.GetPixel(128, 32).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(128, 64).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(128, 96).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 128).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(128, 160).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(160, 0).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(160, 32).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(160, 64).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(160, 96).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(160, 128).ToArgb()); - Assert.Equal(-8355712, bmp.GetPixel(160, 160).ToArgb()); - } - } - - /* Checks bitmap features on a known 8bbp bitmap */ - [Fact] - public void Bitmap8bitFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver8bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.Equal(PixelFormat.Format8bppIndexed, bmp.PixelFormat); - Assert.Equal(173, bmp.Width); - Assert.Equal(183, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(173, rect.Width); - Assert.Equal(183, rect.Height); - - Assert.Equal(173, bmp.Size.Width); - Assert.Equal(183, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap8bitPixels() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver8bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-1040, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-4137792, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-1040, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-1040, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-4137792, bmp.GetPixel(0, 128).ToArgb()); - Assert.Equal(-1040, bmp.GetPixel(0, 160).ToArgb()); - Assert.Equal(-4137792, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-4137792, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-1040, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-6250304, bmp.GetPixel(32, 128).ToArgb()); - Assert.Equal(-8355712, bmp.GetPixel(32, 160).ToArgb()); - Assert.Equal(-12566464, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-6258560, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-1040, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-8355776, bmp.GetPixel(64, 128).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 160).ToArgb()); - Assert.Equal(-4137792, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-8355712, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-12566464, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-2039680, bmp.GetPixel(96, 96).ToArgb()); - Assert.Equal(-4153280, bmp.GetPixel(96, 128).ToArgb()); - Assert.Equal(-12566464, bmp.GetPixel(96, 160).ToArgb()); - Assert.Equal(-1040, bmp.GetPixel(128, 0).ToArgb()); - Assert.Equal(-6258560, bmp.GetPixel(128, 32).ToArgb()); - Assert.Equal(-1040, bmp.GetPixel(128, 64).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(128, 96).ToArgb()); - Assert.Equal(-12566464, bmp.GetPixel(128, 128).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(128, 160).ToArgb()); - Assert.Equal(-4137792, bmp.GetPixel(160, 0).ToArgb()); - Assert.Equal(-1040, bmp.GetPixel(160, 32).ToArgb()); - Assert.Equal(-4144960, bmp.GetPixel(160, 64).ToArgb()); - Assert.Equal(-4137792, bmp.GetPixel(160, 96).ToArgb()); - Assert.Equal(-4137792, bmp.GetPixel(160, 128).ToArgb()); - Assert.Equal(-8355712, bmp.GetPixel(160, 160).ToArgb()); - } - } - - /* Checks bitmap features on a known 24-bits bitmap */ - [Fact] - public void Bitmap24bitFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.Equal(PixelFormat.Format24bppRgb, bmp.PixelFormat); - Assert.Equal(173, bmp.Width); - Assert.Equal(183, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(173, rect.Width); - Assert.Equal(183, rect.Height); - - Assert.Equal(173, bmp.Size.Width); - Assert.Equal(183, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap24bitPixels() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-1645353, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-461332, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-330005, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-2237489, bmp.GetPixel(0, 128).ToArgb()); - Assert.Equal(-1251105, bmp.GetPixel(0, 160).ToArgb()); - Assert.Equal(-3024947, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-2699070, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-2366734, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-4538413, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-6116681, bmp.GetPixel(32, 128).ToArgb()); - Assert.Equal(-7369076, bmp.GetPixel(32, 160).ToArgb()); - Assert.Equal(-13024729, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-7174020, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-51, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-16053503, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-8224431, bmp.GetPixel(64, 128).ToArgb()); - Assert.Equal(-16579326, bmp.GetPixel(64, 160).ToArgb()); - Assert.Equal(-2502457, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-9078395, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-12696508, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-70772, bmp.GetPixel(96, 96).ToArgb()); - Assert.Equal(-4346279, bmp.GetPixel(96, 128).ToArgb()); - Assert.Equal(-11583193, bmp.GetPixel(96, 160).ToArgb()); - Assert.Equal(-724763, bmp.GetPixel(128, 0).ToArgb()); - Assert.Equal(-7238268, bmp.GetPixel(128, 32).ToArgb()); - Assert.Equal(-2169612, bmp.GetPixel(128, 64).ToArgb()); - Assert.Equal(-3683883, bmp.GetPixel(128, 96).ToArgb()); - Assert.Equal(-12892867, bmp.GetPixel(128, 128).ToArgb()); - Assert.Equal(-3750464, bmp.GetPixel(128, 160).ToArgb()); - Assert.Equal(-3222844, bmp.GetPixel(160, 0).ToArgb()); - Assert.Equal(-65806, bmp.GetPixel(160, 32).ToArgb()); - Assert.Equal(-2961726, bmp.GetPixel(160, 64).ToArgb()); - Assert.Equal(-2435382, bmp.GetPixel(160, 96).ToArgb()); - Assert.Equal(-2501944, bmp.GetPixel(160, 128).ToArgb()); - Assert.Equal(-9211799, bmp.GetPixel(160, 160).ToArgb()); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void Bitmap24bitData() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - Assert.Equal(-3355456, bmp.GetPixel(163, 1).ToArgb()); - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(520, data.Stride); - Assert.Equal(183, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(217, *(scan + 0)); - Assert.Equal(192, *(scan + 1009)); - Assert.Equal(210, *(scan + 2018)); - Assert.Equal(196, *(scan + 3027)); - Assert.Equal(216, *(scan + 4036)); - Assert.Equal(215, *(scan + 5045)); - Assert.Equal(218, *(scan + 6054)); - Assert.Equal(218, *(scan + 7063)); - Assert.Equal(95, *(scan + 8072)); - Assert.Equal(9, *(scan + 9081)); - Assert.Equal(247, *(scan + 10090)); - Assert.Equal(161, *(scan + 11099)); - Assert.Equal(130, *(scan + 12108)); - Assert.Equal(131, *(scan + 13117)); - Assert.Equal(175, *(scan + 14126)); - Assert.Equal(217, *(scan + 15135)); - Assert.Equal(201, *(scan + 16144)); - Assert.Equal(183, *(scan + 17153)); - Assert.Equal(236, *(scan + 18162)); - Assert.Equal(242, *(scan + 19171)); - Assert.Equal(125, *(scan + 20180)); - Assert.Equal(193, *(scan + 21189)); - Assert.Equal(227, *(scan + 22198)); - Assert.Equal(44, *(scan + 23207)); - Assert.Equal(230, *(scan + 24216)); - Assert.Equal(224, *(scan + 25225)); - Assert.Equal(164, *(scan + 26234)); - Assert.Equal(43, *(scan + 27243)); - Assert.Equal(200, *(scan + 28252)); - Assert.Equal(255, *(scan + 29261)); - Assert.Equal(226, *(scan + 30270)); - Assert.Equal(230, *(scan + 31279)); - Assert.Equal(178, *(scan + 32288)); - Assert.Equal(224, *(scan + 33297)); - Assert.Equal(233, *(scan + 34306)); - Assert.Equal(212, *(scan + 35315)); - Assert.Equal(153, *(scan + 36324)); - Assert.Equal(143, *(scan + 37333)); - Assert.Equal(215, *(scan + 38342)); - Assert.Equal(116, *(scan + 39351)); - Assert.Equal(26, *(scan + 40360)); - Assert.Equal(28, *(scan + 41369)); - Assert.Equal(75, *(scan + 42378)); - Assert.Equal(50, *(scan + 43387)); - Assert.Equal(244, *(scan + 44396)); - Assert.Equal(191, *(scan + 45405)); - Assert.Equal(200, *(scan + 46414)); - Assert.Equal(197, *(scan + 47423)); - Assert.Equal(232, *(scan + 48432)); - Assert.Equal(186, *(scan + 49441)); - Assert.Equal(210, *(scan + 50450)); - Assert.Equal(215, *(scan + 51459)); - Assert.Equal(155, *(scan + 52468)); - Assert.Equal(56, *(scan + 53477)); - Assert.Equal(149, *(scan + 54486)); - Assert.Equal(137, *(scan + 55495)); - Assert.Equal(141, *(scan + 56504)); - Assert.Equal(36, *(scan + 57513)); - Assert.Equal(39, *(scan + 58522)); - Assert.Equal(25, *(scan + 59531)); - Assert.Equal(44, *(scan + 60540)); - Assert.Equal(12, *(scan + 61549)); - Assert.Equal(161, *(scan + 62558)); - Assert.Equal(179, *(scan + 63567)); - Assert.Equal(181, *(scan + 64576)); - Assert.Equal(165, *(scan + 65585)); - Assert.Equal(182, *(scan + 66594)); - Assert.Equal(186, *(scan + 67603)); - Assert.Equal(201, *(scan + 68612)); - Assert.Equal(49, *(scan + 69621)); - Assert.Equal(161, *(scan + 70630)); - Assert.Equal(140, *(scan + 71639)); - Assert.Equal(2, *(scan + 72648)); - Assert.Equal(15, *(scan + 73657)); - Assert.Equal(33, *(scan + 74666)); - Assert.Equal(17, *(scan + 75675)); - Assert.Equal(0, *(scan + 76684)); - Assert.Equal(47, *(scan + 77693)); - Assert.Equal(4, *(scan + 78702)); - Assert.Equal(142, *(scan + 79711)); - Assert.Equal(151, *(scan + 80720)); - Assert.Equal(124, *(scan + 81729)); - Assert.Equal(81, *(scan + 82738)); - Assert.Equal(214, *(scan + 83747)); - Assert.Equal(217, *(scan + 84756)); - Assert.Equal(30, *(scan + 85765)); - Assert.Equal(185, *(scan + 86774)); - Assert.Equal(200, *(scan + 87783)); - Assert.Equal(37, *(scan + 88792)); - Assert.Equal(2, *(scan + 89801)); - Assert.Equal(41, *(scan + 90810)); - Assert.Equal(16, *(scan + 91819)); - Assert.Equal(0, *(scan + 92828)); - Assert.Equal(146, *(scan + 93837)); - Assert.Equal(163, *(scan + 94846)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - /* Checks bitmap features on a known 32-bits bitmap (codec)*/ - [Fact] - public void Bitmap32bitFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver32bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.Equal(173, bmp.Width); - Assert.Equal(183, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(173, rect.Width); - Assert.Equal(183, rect.Height); - - Assert.Equal(173, bmp.Size.Width); - Assert.Equal(183, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap32bitPixels() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver32bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - Assert.Equal(PixelFormat.Format32bppRgb, bmp.PixelFormat); - // sampling values from a well known bitmap - Assert.Equal(-1579559, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-1645353, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-461332, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-330005, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-2237489, bmp.GetPixel(0, 128).ToArgb()); - Assert.Equal(-1251105, bmp.GetPixel(0, 160).ToArgb()); - Assert.Equal(-3024947, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-2699070, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-2366734, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-4538413, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-6116681, bmp.GetPixel(32, 128).ToArgb()); - Assert.Equal(-7369076, bmp.GetPixel(32, 160).ToArgb()); - Assert.Equal(-13024729, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-7174020, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-51, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-16053503, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-8224431, bmp.GetPixel(64, 128).ToArgb()); - Assert.Equal(-16579326, bmp.GetPixel(64, 160).ToArgb()); - Assert.Equal(-2502457, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-9078395, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-12696508, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-70772, bmp.GetPixel(96, 96).ToArgb()); - Assert.Equal(-4346279, bmp.GetPixel(96, 128).ToArgb()); - Assert.Equal(-11583193, bmp.GetPixel(96, 160).ToArgb()); - Assert.Equal(-724763, bmp.GetPixel(128, 0).ToArgb()); - Assert.Equal(-7238268, bmp.GetPixel(128, 32).ToArgb()); - Assert.Equal(-2169612, bmp.GetPixel(128, 64).ToArgb()); - Assert.Equal(-3683883, bmp.GetPixel(128, 96).ToArgb()); - Assert.Equal(-12892867, bmp.GetPixel(128, 128).ToArgb()); - Assert.Equal(-3750464, bmp.GetPixel(128, 160).ToArgb()); - Assert.Equal(-3222844, bmp.GetPixel(160, 0).ToArgb()); - Assert.Equal(-65806, bmp.GetPixel(160, 32).ToArgb()); - Assert.Equal(-2961726, bmp.GetPixel(160, 64).ToArgb()); - Assert.Equal(-2435382, bmp.GetPixel(160, 96).ToArgb()); - Assert.Equal(-2501944, bmp.GetPixel(160, 128).ToArgb()); - Assert.Equal(-9211799, bmp.GetPixel(160, 160).ToArgb()); - } - } - - private void Save(PixelFormat original, PixelFormat expected, bool colorCheck) - { - string sOutFile = $"linerect-{expected}.bmp"; - - // Save - Bitmap bmp = new Bitmap(100, 100, original); - Graphics gr = Graphics.FromImage(bmp); - - using (Pen p = new Pen(Color.BlueViolet, 2)) - { - gr.DrawLine(p, 10.0F, 10.0F, 90.0F, 90.0F); - gr.DrawRectangle(p, 10.0F, 10.0F, 80.0F, 80.0F); - } - - try - { - bmp.Save(sOutFile, ImageFormat.Bmp); - - // Load - using (Bitmap bmpLoad = new Bitmap(sOutFile)) - { - Assert.Equal(expected, bmpLoad.PixelFormat); - if (colorCheck) - { - Color color = bmpLoad.GetPixel(10, 10); - Assert.Equal(Color.FromArgb(255, 138, 43, 226), color); - } - } - } - finally - { - gr.Dispose(); - bmp.Dispose(); - try - { - File.Delete(sOutFile); - } - catch - { - } - } - } - - [Fact] - public void Save_24bppRgb() - { - Save(PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb, true); - } - - [Fact] - public void Save_32bppRgb() - { - Save(PixelFormat.Format32bppRgb, PixelFormat.Format32bppRgb, true); - } - - [Fact] - public void Save_32bppArgb() - { - Save(PixelFormat.Format32bppArgb, PixelFormat.Format32bppRgb, true); - } - - [Fact] - public void Save_32bppPArgb() - { - Save(PixelFormat.Format32bppPArgb, PixelFormat.Format32bppRgb, true); - } - - [Fact] - public void NonInvertedBitmap() - { - // regression check against http://bugzilla.ximian.com/show_bug.cgi?id=80751 - string sInFile = Helpers.GetTestBitmapPath("non-inverted.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.Equal(90, bmp.Width); - Assert.Equal(60, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(90, rect.Width); - Assert.Equal(60, rect.Height); - - Assert.Equal(90, bmp.Size.Width); - Assert.Equal(60, bmp.Size.Height); - - // sampling values from a well known bitmap - Assert.Equal(-16777216, bmp.GetPixel(12, 21).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(21, 37).ToArgb()); - } - } -} diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/GifCodecTests.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/GifCodecTests.cs deleted file mode 100644 index 5b1fb8f45b1..00000000000 --- a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/GifCodecTests.cs +++ /dev/null @@ -1,262 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// GIF Codec class testing unit -// -// Authors: -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sebastien Pouliot -// -// Copyright (C) 2006, 2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Drawing.Imaging; - -namespace MonoTests.System.Drawing.Imaging; - -public class GifCodecTest -{ - /* Checks bitmap features on a known 1bbp bitmap */ - private void Bitmap8bitsFeatures(string filename) - { - using (Bitmap bmp = new Bitmap(filename)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.Equal(PixelFormat.Format8bppIndexed, bmp.PixelFormat); - Assert.Equal(110, bmp.Width); - Assert.Equal(100, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(110, rect.Width); - Assert.Equal(100, rect.Height); - - Assert.Equal(110, bmp.Size.Width); - Assert.Equal(100, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap8bitsFeatures_Gif89() - { - Bitmap8bitsFeatures(Helpers.GetTestBitmapPath("nature24bits.gif")); - } - - [Fact] - public void Bitmap8bitsFeatures_Gif87() - { - Bitmap8bitsFeatures(Helpers.GetTestBitmapPath("nature24bits87.gif")); - } - - private void Bitmap8bitsPixels(string filename) - { - using (Bitmap bmp = new Bitmap(filename)) - { - // sampling values from a well known bitmap - Assert.Equal(-10644802, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-12630705, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-14537409, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-14672099, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-526863, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-10263970, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-10461317, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-9722415, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-131076, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-2702435, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-6325922, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-12411924, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-131076, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-7766649, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-11512986, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-12616230, bmp.GetPixel(96, 96).ToArgb()); - } - } - - [Fact] - public void Bitmap8bitsPixels_Gif89() - { - Bitmap8bitsPixels(Helpers.GetTestBitmapPath("nature24bits.gif")); - } - - [Fact] - public void Bitmap8bitsPixels_Gif87() - { - Bitmap8bitsPixels(Helpers.GetTestBitmapPath("nature24bits87.gif")); - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void Bitmap8bitsData() - { - string sInFile = Helpers.GetTestBitmapPath("nature24bits.gif"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(332, data.Stride); - Assert.Equal(100, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(190, *(scan + 0)); - Assert.Equal(217, *(scan + 1009)); - Assert.Equal(120, *(scan + 2018)); - Assert.Equal(253, *(scan + 3027)); - Assert.Equal(233, *(scan + 4036)); - Assert.Equal(176, *(scan + 5045)); - Assert.Equal(151, *(scan + 6054)); - Assert.Equal(220, *(scan + 7063)); - Assert.Equal(139, *(scan + 8072)); - Assert.Equal(121, *(scan + 9081)); - Assert.Equal(160, *(scan + 10090)); - Assert.Equal(92, *(scan + 11099)); - Assert.Equal(96, *(scan + 12108)); - Assert.Equal(64, *(scan + 13117)); - Assert.Equal(156, *(scan + 14126)); - Assert.Equal(68, *(scan + 15135)); - Assert.Equal(156, *(scan + 16144)); - Assert.Equal(84, *(scan + 17153)); - Assert.Equal(55, *(scan + 18162)); - Assert.Equal(68, *(scan + 19171)); - Assert.Equal(116, *(scan + 20180)); - Assert.Equal(61, *(scan + 21189)); - Assert.Equal(69, *(scan + 22198)); - Assert.Equal(75, *(scan + 23207)); - Assert.Equal(61, *(scan + 24216)); - Assert.Equal(66, *(scan + 25225)); - Assert.Equal(40, *(scan + 26234)); - Assert.Equal(55, *(scan + 27243)); - Assert.Equal(53, *(scan + 28252)); - Assert.Equal(215, *(scan + 29261)); - Assert.Equal(99, *(scan + 30270)); - Assert.Equal(67, *(scan + 31279)); - Assert.Equal(142, *(scan + 32288)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - [Fact] - public void Interlaced() - { - string sInFile = Helpers.GetTestBitmapPath("81773-interlaced.gif"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - for (int i = 0; i < 255; i++) - { - Color c = bmp.GetPixel(0, i); - Assert.Equal(255, c.A); - Assert.Equal(i, c.R); - Assert.Equal(i, c.G); - Assert.Equal(i, c.B); - } - } - } - - private void Save(PixelFormat original, PixelFormat expected, bool exactColorCheck) - { - string sOutFile = $"linerect-{expected}.gif"; - - // Save - Bitmap bmp = new Bitmap(100, 100, original); - Graphics gr = Graphics.FromImage(bmp); - - using (Pen p = new Pen(Color.Red, 2)) - { - gr.DrawLine(p, 10.0F, 10.0F, 90.0F, 90.0F); - gr.DrawRectangle(p, 10.0F, 10.0F, 80.0F, 80.0F); - } - - try - { - bmp.Save(sOutFile, ImageFormat.Gif); - - // Load - using (Bitmap bmpLoad = new Bitmap(sOutFile)) - { - Assert.Equal(expected, bmpLoad.PixelFormat); - Color color = bmpLoad.GetPixel(10, 10); - if (exactColorCheck) - { - Assert.Equal(Color.FromArgb(255, 255, 0, 0), color); - } - else - { - // FIXME: we don't save a pure red (F8 instead of FF) into the file so the color-check assert will fail - // this is due to libgif's QuantizeBuffer. An alternative would be to make our own that checks if less than 256 colors - // are used in the bitmap (or else use QuantizeBuffer). - Assert.Equal(255, color.A); - Assert.True(color.R >= 248); - Assert.Equal(0, color.G); - Assert.Equal(0, color.B); - } - } - } - finally - { - gr.Dispose(); - bmp.Dispose(); - try - { - File.Delete(sOutFile); - } - catch - { - } - } - } - - [Fact] - public void Save_24bppRgb() - { - Save(PixelFormat.Format24bppRgb, PixelFormat.Format8bppIndexed, false); - } - - [Fact] - public void Save_32bppRgb() - { - Save(PixelFormat.Format32bppRgb, PixelFormat.Format8bppIndexed, false); - } - - [Fact] - public void Save_32bppArgb() - { - Save(PixelFormat.Format32bppArgb, PixelFormat.Format8bppIndexed, false); - } - - [Fact] - public void Save_32bppPArgb() - { - Save(PixelFormat.Format32bppPArgb, PixelFormat.Format8bppIndexed, false); - } -} diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/IconCodecTests.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/IconCodecTests.cs deleted file mode 100644 index d53cfb2ae3c..00000000000 --- a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/IconCodecTests.cs +++ /dev/null @@ -1,1979 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// ICO Codec class testing unit -// -// Authors: -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sebastien Pouliot -// -// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Drawing.Imaging; - -namespace MonoTests.System.Drawing.Imaging; - -public class IconCodecTest -{ - [Fact] - public void Image16() - { - string sInFile = Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"); - using (Image image = Image.FromFile(sInFile)) - { - Assert.True(image.RawFormat.Equals(ImageFormat.Icon)); - // note that image is "promoted" to 32bits - Assert.Equal(PixelFormat.Format32bppArgb, image.PixelFormat); - Assert.Equal(73746, image.Flags); - - using (Bitmap bmp = new Bitmap(image)) - { - Assert.True(bmp.RawFormat.Equals(ImageFormat.MemoryBmp)); - Assert.Equal(PixelFormat.Format32bppArgb, bmp.PixelFormat); - Assert.Equal(2, bmp.Flags); - Assert.Equal(0, bmp.Palette.Entries.Length); - } - } - } - - [Fact] - public void Image16_PaletteEntries() - { - string sInFile = Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"); - using (Image image = Image.FromFile(sInFile)) - { - Assert.Equal(0, image.Palette.Entries.Length); - } - } - - // simley.ico has 48x48, 32x32 and 16x16 images (in that order) - [Fact] - public void Bitmap16Features() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.True(bmp.RawFormat.Equals(ImageFormat.Icon)); - // note that image is "promoted" to 32bits - Assert.Equal(PixelFormat.Format32bppArgb, bmp.PixelFormat); - Assert.Equal(73746, bmp.Flags); - - Assert.Equal(1, bmp.FrameDimensionsList.Length); - Assert.Equal(0, bmp.PropertyIdList.Length); - Assert.Equal(0, bmp.PropertyItems.Length); - Assert.Null(bmp.Tag); - Assert.Equal(96.0f, bmp.HorizontalResolution); - Assert.Equal(96.0f, bmp.VerticalResolution); - Assert.Equal(16, bmp.Width); - Assert.Equal(16, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(16, rect.Width); - Assert.Equal(16, rect.Height); - - Assert.Equal(16, bmp.Size.Width); - Assert.Equal(16, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap16Features_Palette_Entries() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - Assert.Equal(0, bmp.Palette.Entries.Length); - } - } - - [Fact] - public void Bitmap16Pixels() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(0, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 4).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 0).ToArgb()); - Assert.Equal(-256, bmp.GetPixel(4, 4).ToArgb()); - Assert.Equal(-256, bmp.GetPixel(4, 8).ToArgb()); - Assert.Equal(-8355840, bmp.GetPixel(4, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 0).ToArgb()); - Assert.Equal(-256, bmp.GetPixel(8, 4).ToArgb()); - Assert.Equal(-256, bmp.GetPixel(8, 8).ToArgb()); - Assert.Equal(-256, bmp.GetPixel(8, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 4).ToArgb()); - Assert.Equal(-8355840, bmp.GetPixel(12, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 12).ToArgb()); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void Bitmap16Data() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(16, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(0, *(scan + 0)); - Assert.Equal(0, *(scan + 13)); - Assert.Equal(0, *(scan + 26)); - Assert.Equal(0, *(scan + 39)); - Assert.Equal(0, *(scan + 52)); - Assert.Equal(0, *(scan + 65)); - Assert.Equal(0, *(scan + 78)); - Assert.Equal(0, *(scan + 91)); - Assert.Equal(0, *(scan + 104)); - Assert.Equal(0, *(scan + 117)); - Assert.Equal(0, *(scan + 130)); - Assert.Equal(0, *(scan + 143)); - Assert.Equal(0, *(scan + 156)); - Assert.Equal(255, *(scan + 169)); - Assert.Equal(0, *(scan + 182)); - Assert.Equal(0, *(scan + 195)); - Assert.Equal(255, *(scan + 208)); - Assert.Equal(255, *(scan + 221)); - Assert.Equal(0, *(scan + 234)); - Assert.Equal(128, *(scan + 247)); - Assert.Equal(0, *(scan + 260)); - Assert.Equal(0, *(scan + 273)); - Assert.Equal(0, *(scan + 286)); - Assert.Equal(255, *(scan + 299)); - Assert.Equal(0, *(scan + 312)); - Assert.Equal(128, *(scan + 325)); - Assert.Equal(0, *(scan + 338)); - Assert.Equal(0, *(scan + 351)); - Assert.Equal(255, *(scan + 364)); - Assert.Equal(0, *(scan + 377)); - Assert.Equal(0, *(scan + 390)); - Assert.Equal(255, *(scan + 403)); - Assert.Equal(255, *(scan + 416)); - Assert.Equal(0, *(scan + 429)); - Assert.Equal(255, *(scan + 442)); - Assert.Equal(0, *(scan + 455)); - Assert.Equal(0, *(scan + 468)); - Assert.Equal(0, *(scan + 481)); - Assert.Equal(255, *(scan + 494)); - Assert.Equal(0, *(scan + 507)); - Assert.Equal(0, *(scan + 520)); - Assert.Equal(0, *(scan + 533)); - Assert.Equal(0, *(scan + 546)); - Assert.Equal(255, *(scan + 559)); - Assert.Equal(0, *(scan + 572)); - Assert.Equal(0, *(scan + 585)); - Assert.Equal(255, *(scan + 598)); - Assert.Equal(0, *(scan + 611)); - Assert.Equal(0, *(scan + 624)); - Assert.Equal(0, *(scan + 637)); - Assert.Equal(128, *(scan + 650)); - Assert.Equal(0, *(scan + 663)); - Assert.Equal(0, *(scan + 676)); - Assert.Equal(0, *(scan + 689)); - Assert.Equal(0, *(scan + 702)); - Assert.Equal(0, *(scan + 715)); - Assert.Equal(0, *(scan + 728)); - Assert.Equal(0, *(scan + 741)); - Assert.Equal(0, *(scan + 754)); - Assert.Equal(0, *(scan + 767)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - // VisualPng.ico only has a 32x32 size available - [Fact] - public void Bitmap32Features() - { - string sInFile = Helpers.GetTestBitmapPath("VisualPng.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.True(bmp.RawFormat.Equals(ImageFormat.Icon)); - Assert.Equal(PixelFormat.Format32bppArgb, bmp.PixelFormat); - Assert.Equal(73746, bmp.Flags); - - Assert.Equal(1, bmp.FrameDimensionsList.Length); - Assert.Equal(0, bmp.PropertyIdList.Length); - Assert.Equal(0, bmp.PropertyItems.Length); - Assert.Null(bmp.Tag); - Assert.Equal(96.0f, bmp.HorizontalResolution); - Assert.Equal(96.0f, bmp.VerticalResolution); - Assert.Equal(32, bmp.Width); - Assert.Equal(32, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(32, rect.Width); - Assert.Equal(32, rect.Height); - - Assert.Equal(32, bmp.Size.Width); - Assert.Equal(32, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap32Features_PaletteEntries() - { - string sInFile = Helpers.GetTestBitmapPath("VisualPng.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - Assert.Equal(0, bmp.Palette.Entries.Length); - } - } - - [Fact] - public void Bitmap32Pixels() - { - string sInFile = Helpers.GetTestBitmapPath("VisualPng.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(0, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-8388608, bmp.GetPixel(0, 4).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 4).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 4).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 16).ToArgb()); - Assert.Equal(-65536, bmp.GetPixel(8, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 4).ToArgb()); - Assert.Equal(-8388608, bmp.GetPixel(12, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 16).ToArgb()); - Assert.Equal(-65536, bmp.GetPixel(12, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 4).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 20).ToArgb()); - Assert.Equal(-65536, bmp.GetPixel(16, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 4).ToArgb()); - Assert.Equal(-8388608, bmp.GetPixel(20, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 4).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(24, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 4).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 20).ToArgb()); - Assert.Equal(-8388608, bmp.GetPixel(28, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 28).ToArgb()); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void Bitmap32Data() - { - string sInFile = Helpers.GetTestBitmapPath("VisualPng.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(32, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(0, *(scan + 0)); - Assert.Equal(0, *(scan + 13)); - Assert.Equal(0, *(scan + 26)); - Assert.Equal(0, *(scan + 39)); - Assert.Equal(0, *(scan + 52)); - Assert.Equal(0, *(scan + 65)); - Assert.Equal(0, *(scan + 78)); - Assert.Equal(0, *(scan + 91)); - Assert.Equal(0, *(scan + 104)); - Assert.Equal(0, *(scan + 117)); - Assert.Equal(0, *(scan + 130)); - Assert.Equal(0, *(scan + 143)); - Assert.Equal(0, *(scan + 156)); - Assert.Equal(0, *(scan + 169)); - Assert.Equal(0, *(scan + 182)); - Assert.Equal(0, *(scan + 195)); - Assert.Equal(0, *(scan + 208)); - Assert.Equal(0, *(scan + 221)); - Assert.Equal(0, *(scan + 234)); - Assert.Equal(0, *(scan + 247)); - Assert.Equal(0, *(scan + 260)); - Assert.Equal(0, *(scan + 273)); - Assert.Equal(0, *(scan + 286)); - Assert.Equal(0, *(scan + 299)); - Assert.Equal(0, *(scan + 312)); - Assert.Equal(0, *(scan + 325)); - Assert.Equal(0, *(scan + 338)); - Assert.Equal(0, *(scan + 351)); - Assert.Equal(0, *(scan + 364)); - Assert.Equal(0, *(scan + 377)); - Assert.Equal(0, *(scan + 390)); - Assert.Equal(0, *(scan + 403)); - Assert.Equal(0, *(scan + 416)); - Assert.Equal(0, *(scan + 429)); - Assert.Equal(0, *(scan + 442)); - Assert.Equal(0, *(scan + 455)); - Assert.Equal(0, *(scan + 468)); - Assert.Equal(0, *(scan + 481)); - Assert.Equal(128, *(scan + 494)); - Assert.Equal(0, *(scan + 507)); - Assert.Equal(0, *(scan + 520)); - Assert.Equal(0, *(scan + 533)); - Assert.Equal(0, *(scan + 546)); - Assert.Equal(0, *(scan + 559)); - Assert.Equal(128, *(scan + 572)); - Assert.Equal(0, *(scan + 585)); - Assert.Equal(0, *(scan + 598)); - Assert.Equal(0, *(scan + 611)); - Assert.Equal(0, *(scan + 624)); - Assert.Equal(0, *(scan + 637)); - Assert.Equal(128, *(scan + 650)); - Assert.Equal(0, *(scan + 663)); - Assert.Equal(0, *(scan + 676)); - Assert.Equal(0, *(scan + 689)); - Assert.Equal(0, *(scan + 702)); - Assert.Equal(0, *(scan + 715)); - Assert.Equal(0, *(scan + 728)); - Assert.Equal(0, *(scan + 741)); - Assert.Equal(0, *(scan + 754)); - Assert.Equal(0, *(scan + 767)); - Assert.Equal(0, *(scan + 780)); - Assert.Equal(0, *(scan + 793)); - Assert.Equal(128, *(scan + 806)); - Assert.Equal(0, *(scan + 819)); - Assert.Equal(0, *(scan + 832)); - Assert.Equal(128, *(scan + 845)); - Assert.Equal(0, *(scan + 858)); - Assert.Equal(0, *(scan + 871)); - Assert.Equal(0, *(scan + 884)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - // 48x48_one_entry_1bit.ico only has a 48x48 size available - [Fact] - public void Bitmap48Features() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_one_entry_1bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.True(bmp.RawFormat.Equals(ImageFormat.Icon)); - Assert.Equal(PixelFormat.Format32bppArgb, bmp.PixelFormat); - Assert.Equal(73746, bmp.Flags); - - Assert.Equal(1, bmp.FrameDimensionsList.Length); - Assert.Equal(0, bmp.PropertyIdList.Length); - Assert.Equal(0, bmp.PropertyItems.Length); - Assert.Null(bmp.Tag); - Assert.Equal(96.0f, bmp.HorizontalResolution); - Assert.Equal(96.0f, bmp.VerticalResolution); - Assert.Equal(48, bmp.Width); - Assert.Equal(48, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(48, rect.Width); - Assert.Equal(48, rect.Height); - - Assert.Equal(48, bmp.Size.Width); - Assert.Equal(48, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap48Features_Palette_Entries() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_one_entry_1bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - Assert.Equal(0, bmp.Palette.Entries.Length); - } - } - - [Fact] - public void Bitmap48Pixels() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_one_entry_1bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-16777216, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 4).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 8).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 12).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 16).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 20).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 24).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 28).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 36).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 40).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 44).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(4, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 4).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 32).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 36).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 40).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(4, 44).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(8, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 4).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(8, 8).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(8, 12).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(8, 16).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(8, 20).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(8, 24).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(8, 28).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(8, 32).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(8, 36).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(8, 40).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(8, 44).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(12, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 4).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(12, 8).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(12, 12).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(12, 16).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(12, 20).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(12, 24).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(12, 28).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(12, 32).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 36).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(12, 40).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(12, 44).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(16, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 4).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(16, 8).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(16, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 28).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(16, 32).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 36).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(16, 40).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(16, 44).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(20, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 4).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(20, 8).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(20, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 16).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(20, 20).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(20, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 28).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(20, 32).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 36).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(20, 40).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(20, 44).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(24, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 4).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(24, 8).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(24, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 16).ToArgb()); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void Bitmap48Data() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_one_entry_1bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(48, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(0, *(scan + 0)); - Assert.Equal(0, *(scan + 13)); - Assert.Equal(0, *(scan + 26)); - Assert.Equal(0, *(scan + 39)); - Assert.Equal(0, *(scan + 52)); - Assert.Equal(0, *(scan + 65)); - Assert.Equal(0, *(scan + 78)); - Assert.Equal(0, *(scan + 91)); - Assert.Equal(0, *(scan + 104)); - Assert.Equal(0, *(scan + 117)); - Assert.Equal(0, *(scan + 130)); - Assert.Equal(0, *(scan + 143)); - Assert.Equal(0, *(scan + 156)); - Assert.Equal(0, *(scan + 169)); - Assert.Equal(0, *(scan + 182)); - Assert.Equal(0, *(scan + 195)); - Assert.Equal(0, *(scan + 208)); - Assert.Equal(0, *(scan + 221)); - Assert.Equal(0, *(scan + 234)); - Assert.Equal(0, *(scan + 247)); - Assert.Equal(0, *(scan + 260)); - Assert.Equal(0, *(scan + 273)); - Assert.Equal(0, *(scan + 286)); - Assert.Equal(255, *(scan + 299)); - Assert.Equal(255, *(scan + 312)); - Assert.Equal(255, *(scan + 325)); - Assert.Equal(255, *(scan + 338)); - Assert.Equal(255, *(scan + 351)); - Assert.Equal(255, *(scan + 364)); - Assert.Equal(255, *(scan + 377)); - Assert.Equal(255, *(scan + 390)); - Assert.Equal(255, *(scan + 403)); - Assert.Equal(255, *(scan + 416)); - Assert.Equal(0, *(scan + 429)); - Assert.Equal(255, *(scan + 442)); - Assert.Equal(255, *(scan + 455)); - Assert.Equal(255, *(scan + 468)); - Assert.Equal(255, *(scan + 481)); - Assert.Equal(255, *(scan + 494)); - Assert.Equal(255, *(scan + 507)); - Assert.Equal(255, *(scan + 520)); - Assert.Equal(255, *(scan + 533)); - Assert.Equal(255, *(scan + 546)); - Assert.Equal(255, *(scan + 559)); - Assert.Equal(0, *(scan + 572)); - Assert.Equal(255, *(scan + 585)); - Assert.Equal(0, *(scan + 598)); - Assert.Equal(0, *(scan + 611)); - Assert.Equal(0, *(scan + 624)); - Assert.Equal(0, *(scan + 637)); - Assert.Equal(0, *(scan + 650)); - Assert.Equal(0, *(scan + 663)); - Assert.Equal(0, *(scan + 676)); - Assert.Equal(0, *(scan + 689)); - Assert.Equal(0, *(scan + 702)); - Assert.Equal(0, *(scan + 715)); - Assert.Equal(255, *(scan + 728)); - Assert.Equal(0, *(scan + 741)); - Assert.Equal(0, *(scan + 754)); - Assert.Equal(0, *(scan + 767)); - Assert.Equal(0, *(scan + 780)); - Assert.Equal(0, *(scan + 793)); - Assert.Equal(0, *(scan + 806)); - Assert.Equal(0, *(scan + 819)); - Assert.Equal(0, *(scan + 832)); - Assert.Equal(0, *(scan + 845)); - Assert.Equal(0, *(scan + 858)); - Assert.Equal(255, *(scan + 871)); - Assert.Equal(0, *(scan + 884)); - Assert.Equal(0, *(scan + 897)); - Assert.Equal(0, *(scan + 910)); - Assert.Equal(0, *(scan + 923)); - Assert.Equal(0, *(scan + 936)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - // 64x64x256 only has a 64x64 size available - [Fact] - public void Bitmap64Features() - { - string sInFile = Helpers.GetTestBitmapPath("64x64_one_entry_8bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.True(bmp.RawFormat.Equals(ImageFormat.Icon)); - Assert.Equal(PixelFormat.Format32bppArgb, bmp.PixelFormat); - Assert.Equal(73746, bmp.Flags); - - Assert.Equal(1, bmp.FrameDimensionsList.Length); - Assert.Equal(0, bmp.PropertyIdList.Length); - Assert.Equal(0, bmp.PropertyItems.Length); - Assert.Null(bmp.Tag); - Assert.Equal(96.0f, bmp.HorizontalResolution); - Assert.Equal(96.0f, bmp.VerticalResolution); - Assert.Equal(64, bmp.Width); - Assert.Equal(64, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(64, rect.Width); - Assert.Equal(64, rect.Height); - - Assert.Equal(64, bmp.Size.Width); - Assert.Equal(64, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap64Features_Palette_Entries() - { - string sInFile = Helpers.GetTestBitmapPath("64x64_one_entry_8bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - Assert.Equal(0, bmp.Palette.Entries.Length); - } - } - - [Fact] - public void Bitmap64Pixels() - { - string sInFile = Helpers.GetTestBitmapPath("64x64_one_entry_8bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-65383, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 4).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 8).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 12).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 16).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 20).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 24).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 28).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 36).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 40).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 44).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 48).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 52).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 56).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(0, 60).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(4, 0).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 4).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 8).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 12).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 16).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 20).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 24).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 28).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 32).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 36).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 40).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 44).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 48).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 52).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(4, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 60).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(8, 0).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(8, 4).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 8).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 12).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 16).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 20).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 24).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 28).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 32).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 36).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 40).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 44).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 48).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(8, 52).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 60).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(12, 0).ToArgb()); - Assert.Equal(-10079335, bmp.GetPixel(12, 4).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(12, 8).ToArgb()); - Assert.Equal(-33664, bmp.GetPixel(12, 12).ToArgb()); - Assert.Equal(-33664, bmp.GetPixel(12, 16).ToArgb()); - Assert.Equal(-33664, bmp.GetPixel(12, 20).ToArgb()); - Assert.Equal(-33664, bmp.GetPixel(12, 24).ToArgb()); - Assert.Equal(-33664, bmp.GetPixel(12, 28).ToArgb()); - Assert.Equal(-33664, bmp.GetPixel(12, 32).ToArgb()); - Assert.Equal(-33664, bmp.GetPixel(12, 36).ToArgb()); - Assert.Equal(-33664, bmp.GetPixel(12, 40).ToArgb()); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void Bitmap64Data() - { - string sInFile = Helpers.GetTestBitmapPath("64x64_one_entry_8bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(64, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(153, *(scan + 0)); - Assert.Equal(0, *(scan + 97)); - Assert.Equal(255, *(scan + 194)); - Assert.Equal(0, *(scan + 291)); - Assert.Equal(0, *(scan + 388)); - Assert.Equal(204, *(scan + 485)); - Assert.Equal(204, *(scan + 582)); - Assert.Equal(0, *(scan + 679)); - Assert.Equal(204, *(scan + 776)); - Assert.Equal(153, *(scan + 873)); - Assert.Equal(0, *(scan + 970)); - Assert.Equal(0, *(scan + 1067)); - Assert.Equal(153, *(scan + 1164)); - Assert.Equal(153, *(scan + 1261)); - Assert.Equal(102, *(scan + 1358)); - Assert.Equal(0, *(scan + 1455)); - Assert.Equal(0, *(scan + 1552)); - Assert.Equal(204, *(scan + 1649)); - Assert.Equal(153, *(scan + 1746)); - Assert.Equal(0, *(scan + 1843)); - Assert.Equal(0, *(scan + 1940)); - Assert.Equal(51, *(scan + 2037)); - Assert.Equal(0, *(scan + 2134)); - Assert.Equal(0, *(scan + 2231)); - Assert.Equal(102, *(scan + 2328)); - Assert.Equal(124, *(scan + 2425)); - Assert.Equal(204, *(scan + 2522)); - Assert.Equal(0, *(scan + 2619)); - Assert.Equal(0, *(scan + 2716)); - Assert.Equal(204, *(scan + 2813)); - Assert.Equal(51, *(scan + 2910)); - Assert.Equal(0, *(scan + 3007)); - Assert.Equal(255, *(scan + 3104)); - Assert.Equal(0, *(scan + 3201)); - Assert.Equal(0, *(scan + 3298)); - Assert.Equal(0, *(scan + 3395)); - Assert.Equal(128, *(scan + 3492)); - Assert.Equal(0, *(scan + 3589)); - Assert.Equal(255, *(scan + 3686)); - Assert.Equal(128, *(scan + 3783)); - Assert.Equal(0, *(scan + 3880)); - Assert.Equal(128, *(scan + 3977)); - Assert.Equal(0, *(scan + 4074)); - Assert.Equal(0, *(scan + 4171)); - Assert.Equal(204, *(scan + 4268)); - Assert.Equal(0, *(scan + 4365)); - Assert.Equal(0, *(scan + 4462)); - Assert.Equal(102, *(scan + 4559)); - Assert.Equal(0, *(scan + 4656)); - Assert.Equal(0, *(scan + 4753)); - Assert.Equal(102, *(scan + 4850)); - Assert.Equal(0, *(scan + 4947)); - Assert.Equal(0, *(scan + 5044)); - Assert.Equal(204, *(scan + 5141)); - Assert.Equal(128, *(scan + 5238)); - Assert.Equal(0, *(scan + 5335)); - Assert.Equal(128, *(scan + 5432)); - Assert.Equal(128, *(scan + 5529)); - Assert.Equal(0, *(scan + 5626)); - Assert.Equal(255, *(scan + 5723)); - Assert.Equal(153, *(scan + 5820)); - Assert.Equal(0, *(scan + 5917)); - Assert.Equal(0, *(scan + 6014)); - Assert.Equal(51, *(scan + 6111)); - Assert.Equal(0, *(scan + 6208)); - Assert.Equal(255, *(scan + 6305)); - Assert.Equal(153, *(scan + 6402)); - Assert.Equal(0, *(scan + 6499)); - Assert.Equal(153, *(scan + 6596)); - Assert.Equal(102, *(scan + 6693)); - Assert.Equal(0, *(scan + 6790)); - Assert.Equal(204, *(scan + 6887)); - Assert.Equal(153, *(scan + 6984)); - Assert.Equal(0, *(scan + 7081)); - Assert.Equal(204, *(scan + 7178)); - Assert.Equal(153, *(scan + 7275)); - Assert.Equal(0, *(scan + 7372)); - Assert.Equal(0, *(scan + 7469)); - Assert.Equal(153, *(scan + 7566)); - Assert.Equal(0, *(scan + 7663)); - Assert.Equal(0, *(scan + 7760)); - Assert.Equal(153, *(scan + 7857)); - Assert.Equal(102, *(scan + 7954)); - Assert.Equal(102, *(scan + 8051)); - Assert.Equal(0, *(scan + 8148)); - Assert.Equal(0, *(scan + 8245)); - Assert.Equal(0, *(scan + 8342)); - Assert.Equal(204, *(scan + 8439)); - Assert.Equal(0, *(scan + 8536)); - Assert.Equal(204, *(scan + 8633)); - Assert.Equal(128, *(scan + 8730)); - Assert.Equal(0, *(scan + 8827)); - Assert.Equal(0, *(scan + 8924)); - Assert.Equal(153, *(scan + 9021)); - Assert.Equal(153, *(scan + 9118)); - Assert.Equal(255, *(scan + 9215)); - Assert.Equal(0, *(scan + 9312)); - Assert.Equal(0, *(scan + 9409)); - Assert.Equal(204, *(scan + 9506)); - Assert.Equal(0, *(scan + 9603)); - Assert.Equal(0, *(scan + 9700)); - Assert.Equal(0, *(scan + 9797)); - Assert.Equal(128, *(scan + 9894)); - Assert.Equal(0, *(scan + 9991)); - Assert.Equal(0, *(scan + 10088)); - Assert.Equal(0, *(scan + 10185)); - Assert.Equal(102, *(scan + 10282)); - Assert.Equal(0, *(scan + 10379)); - Assert.Equal(0, *(scan + 10476)); - Assert.Equal(51, *(scan + 10573)); - Assert.Equal(204, *(scan + 10670)); - Assert.Equal(0, *(scan + 10767)); - Assert.Equal(0, *(scan + 10864)); - Assert.Equal(0, *(scan + 10961)); - Assert.Equal(153, *(scan + 11058)); - Assert.Equal(0, *(scan + 11155)); - Assert.Equal(0, *(scan + 11252)); - Assert.Equal(153, *(scan + 11349)); - Assert.Equal(51, *(scan + 11446)); - Assert.Equal(0, *(scan + 11543)); - Assert.Equal(0, *(scan + 11640)); - Assert.Equal(0, *(scan + 11737)); - Assert.Equal(204, *(scan + 11834)); - Assert.Equal(0, *(scan + 11931)); - Assert.Equal(0, *(scan + 12028)); - Assert.Equal(255, *(scan + 12125)); - Assert.Equal(153, *(scan + 12222)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - // 96x96x256.ico only has a 96x96 size available - [Fact] - public void Bitmap96Features() - { - string sInFile = Helpers.GetTestBitmapPath("96x96_one_entry_8bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.True(bmp.RawFormat.Equals(ImageFormat.Icon)); - Assert.Equal(PixelFormat.Format32bppArgb, bmp.PixelFormat); - Assert.Equal(73746, bmp.Flags); - - Assert.Equal(1, bmp.FrameDimensionsList.Length); - Assert.Equal(0, bmp.PropertyIdList.Length); - Assert.Equal(0, bmp.PropertyItems.Length); - Assert.Null(bmp.Tag); - Assert.Equal(96.0f, bmp.HorizontalResolution); - Assert.Equal(96.0f, bmp.VerticalResolution); - Assert.Equal(96, bmp.Width); - Assert.Equal(96, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(96, rect.Width); - Assert.Equal(96, rect.Height); - - Assert.Equal(96, bmp.Size.Width); - Assert.Equal(96, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap96Features_Palette_Entries() - { - string sInFile = Helpers.GetTestBitmapPath("96x96_one_entry_8bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - Assert.Equal(0, bmp.Palette.Entries.Length); - } - } - - [Fact] - public void Bitmap96Pixels() - { - string sInFile = Helpers.GetTestBitmapPath("96x96_one_entry_8bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(0, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 4).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 36).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 40).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 44).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 48).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 52).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 60).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(0, 68).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 76).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 80).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 84).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 88).ToArgb()); - Assert.Equal(0, bmp.GetPixel(0, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 4).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(4, 8).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(4, 12).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(4, 16).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(4, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 32).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 36).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(4, 40).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(4, 44).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(4, 48).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(4, 52).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 60).ToArgb()); - Assert.Equal(-3342541, bmp.GetPixel(4, 64).ToArgb()); - Assert.Equal(-3342541, bmp.GetPixel(4, 68).ToArgb()); - Assert.Equal(-3342541, bmp.GetPixel(4, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 76).ToArgb()); - Assert.Equal(0, bmp.GetPixel(4, 80).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(4, 84).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(4, 88).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(4, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 0).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(8, 4).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(8, 8).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(8, 12).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(8, 16).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(8, 20).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(8, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 32).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(8, 36).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(8, 40).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(8, 44).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(8, 48).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(8, 52).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(8, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 60).ToArgb()); - Assert.Equal(-3342541, bmp.GetPixel(8, 64).ToArgb()); - Assert.Equal(-3342541, bmp.GetPixel(8, 68).ToArgb()); - Assert.Equal(-3342541, bmp.GetPixel(8, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 76).ToArgb()); - Assert.Equal(0, bmp.GetPixel(8, 80).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(8, 84).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(8, 88).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(8, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 0).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(12, 4).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(12, 8).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(12, 12).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(12, 16).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(12, 20).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(12, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 28).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(12, 32).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(12, 36).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(12, 40).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(12, 44).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(12, 48).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(12, 52).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(12, 56).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(12, 60).ToArgb()); - Assert.Equal(-3342541, bmp.GetPixel(12, 64).ToArgb()); - Assert.Equal(-3342541, bmp.GetPixel(12, 68).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(12, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 76).ToArgb()); - Assert.Equal(0, bmp.GetPixel(12, 80).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(12, 84).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(12, 88).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(12, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 0).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(16, 4).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(16, 8).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(16, 12).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(16, 16).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(16, 20).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(16, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 28).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(16, 32).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(16, 36).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(16, 40).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(16, 44).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(16, 48).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(16, 52).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(16, 56).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(16, 60).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 64).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 68).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 76).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(16, 80).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 84).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(16, 88).ToArgb()); - Assert.Equal(0, bmp.GetPixel(16, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 0).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(20, 4).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(20, 8).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(20, 12).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(20, 16).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(20, 20).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(20, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 28).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(20, 32).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(20, 36).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(20, 40).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(20, 44).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(20, 48).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(20, 52).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(20, 56).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(20, 60).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 64).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 68).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(20, 72).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(20, 76).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(20, 80).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(20, 84).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(20, 88).ToArgb()); - Assert.Equal(0, bmp.GetPixel(20, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 4).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(24, 8).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(24, 12).ToArgb()); - Assert.Equal(-3407872, bmp.GetPixel(24, 16).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(24, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 28).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(24, 32).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(24, 36).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(24, 40).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(24, 44).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(24, 48).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(24, 52).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(24, 56).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(24, 60).ToArgb()); - Assert.Equal(0, bmp.GetPixel(24, 64).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(24, 68).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(24, 72).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(24, 76).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(24, 80).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(24, 84).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(24, 88).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(24, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 4).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(28, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 16).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(28, 20).ToArgb()); - Assert.Equal(-16777012, bmp.GetPixel(28, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 28).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(28, 32).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(28, 36).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(28, 40).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(28, 44).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(28, 48).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(28, 52).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(28, 56).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(28, 60).ToArgb()); - Assert.Equal(0, bmp.GetPixel(28, 64).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(28, 68).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(28, 72).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(28, 76).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(28, 80).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(28, 84).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(28, 88).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(28, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-10027264, bmp.GetPixel(32, 4).ToArgb()); - Assert.Equal(-10027264, bmp.GetPixel(32, 8).ToArgb()); - Assert.Equal(-10027264, bmp.GetPixel(32, 12).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(32, 16).ToArgb()); - Assert.Equal(-16777012, bmp.GetPixel(32, 20).ToArgb()); - Assert.Equal(-16777012, bmp.GetPixel(32, 24).ToArgb()); - Assert.Equal(-16777012, bmp.GetPixel(32, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(32, 36).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(32, 40).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(32, 44).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(32, 48).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(32, 52).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(32, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(32, 60).ToArgb()); - Assert.Equal(0, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(32, 68).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(32, 72).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(32, 76).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(32, 80).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(32, 84).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(32, 88).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(32, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(36, 0).ToArgb()); - Assert.Equal(-10027264, bmp.GetPixel(36, 4).ToArgb()); - Assert.Equal(-10027264, bmp.GetPixel(36, 8).ToArgb()); - Assert.Equal(-10027264, bmp.GetPixel(36, 12).ToArgb()); - Assert.Equal(-10027264, bmp.GetPixel(36, 16).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(36, 20).ToArgb()); - Assert.Equal(-16777012, bmp.GetPixel(36, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(36, 28).ToArgb()); - Assert.Equal(0, bmp.GetPixel(36, 32).ToArgb()); - Assert.Equal(0, bmp.GetPixel(36, 36).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(36, 40).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(36, 44).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(36, 48).ToArgb()); - Assert.Equal(-3368602, bmp.GetPixel(36, 52).ToArgb()); - Assert.Equal(0, bmp.GetPixel(36, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(36, 60).ToArgb()); - Assert.Equal(0, bmp.GetPixel(36, 64).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(36, 68).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(36, 72).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(36, 76).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(36, 80).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(36, 84).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(36, 88).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(36, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(40, 0).ToArgb()); - Assert.Equal(-10027264, bmp.GetPixel(40, 4).ToArgb()); - Assert.Equal(-10027264, bmp.GetPixel(40, 8).ToArgb()); - Assert.Equal(-10027264, bmp.GetPixel(40, 12).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(40, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(40, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(40, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(40, 28).ToArgb()); - Assert.Equal(-13408717, bmp.GetPixel(40, 32).ToArgb()); - Assert.Equal(-13408717, bmp.GetPixel(40, 36).ToArgb()); - Assert.Equal(0, bmp.GetPixel(40, 40).ToArgb()); - Assert.Equal(0, bmp.GetPixel(40, 44).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(40, 48).ToArgb()); - Assert.Equal(0, bmp.GetPixel(40, 52).ToArgb()); - Assert.Equal(0, bmp.GetPixel(40, 56).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(40, 60).ToArgb()); - Assert.Equal(-26317, bmp.GetPixel(40, 64).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(40, 68).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(40, 72).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(40, 76).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(40, 80).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(40, 84).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(40, 88).ToArgb()); - Assert.Equal(0, bmp.GetPixel(40, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(44, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(44, 4).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(44, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(44, 12).ToArgb()); - Assert.Equal(0, bmp.GetPixel(44, 16).ToArgb()); - Assert.Equal(0, bmp.GetPixel(44, 20).ToArgb()); - Assert.Equal(0, bmp.GetPixel(44, 24).ToArgb()); - Assert.Equal(0, bmp.GetPixel(44, 28).ToArgb()); - Assert.Equal(-13408717, bmp.GetPixel(44, 32).ToArgb()); - Assert.Equal(-13408717, bmp.GetPixel(44, 36).ToArgb()); - Assert.Equal(0, bmp.GetPixel(44, 40).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(44, 44).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(44, 48).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(44, 52).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(44, 56).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(44, 60).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(44, 64).ToArgb()); - Assert.Equal(0, bmp.GetPixel(44, 68).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(44, 72).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(44, 76).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(44, 80).ToArgb()); - Assert.Equal(-13434829, bmp.GetPixel(44, 84).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(44, 88).ToArgb()); - Assert.Equal(0, bmp.GetPixel(44, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 4).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(48, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(48, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(48, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(48, 28).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(48, 32).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 36).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(48, 40).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(48, 44).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(48, 48).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(48, 52).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(48, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 60).ToArgb()); - // Assert.Equal(1842204, bmp.GetPixel(48, 64).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(48, 68).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(48, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 76).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 80).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 84).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 88).ToArgb()); - Assert.Equal(0, bmp.GetPixel(48, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(52, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(52, 4).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(52, 8).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(52, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(52, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(52, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(52, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(52, 28).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(52, 32).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(52, 36).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(52, 40).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(52, 44).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(52, 48).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(52, 52).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(52, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(52, 60).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(52, 64).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(52, 68).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(52, 72).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(52, 76).ToArgb()); - Assert.Equal(0, bmp.GetPixel(52, 80).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(52, 84).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(52, 88).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(52, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(56, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(56, 4).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(56, 8).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(56, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(56, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(56, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(56, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(56, 28).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(56, 32).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(56, 36).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(56, 40).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(56, 44).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(56, 48).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(56, 52).ToArgb()); - Assert.Equal(-13312, bmp.GetPixel(56, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(56, 60).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(56, 64).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(56, 68).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(56, 72).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(56, 76).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(56, 80).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(56, 84).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(56, 88).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(56, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(60, 0).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(60, 4).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(60, 8).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(60, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(60, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(60, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(60, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(60, 28).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(60, 32).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(60, 36).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(60, 40).ToArgb()); - Assert.Equal(0, bmp.GetPixel(60, 44).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(60, 48).ToArgb()); - Assert.Equal(0, bmp.GetPixel(60, 52).ToArgb()); - Assert.Equal(0, bmp.GetPixel(60, 56).ToArgb()); - Assert.Equal(0, bmp.GetPixel(60, 60).ToArgb()); - Assert.Equal(0, bmp.GetPixel(60, 64).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(60, 68).ToArgb()); - Assert.Equal(-3355546, bmp.GetPixel(60, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(60, 76).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(60, 80).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(60, 84).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(60, 88).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(60, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(64, 4).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(64, 8).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(64, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(64, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(64, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(64, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(64, 28).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(64, 36).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(64, 40).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(64, 44).ToArgb()); - Assert.Equal(0, bmp.GetPixel(64, 48).ToArgb()); - Assert.Equal(0, bmp.GetPixel(64, 52).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(64, 56).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(64, 60).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(64, 68).ToArgb()); - Assert.Equal(0, bmp.GetPixel(64, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(64, 76).ToArgb()); - Assert.Equal(0, bmp.GetPixel(64, 80).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(64, 84).ToArgb()); - Assert.Equal(-6737101, bmp.GetPixel(64, 88).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(64, 92).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(68, 0).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 4).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 8).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 28).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 32).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 36).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 40).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(68, 44).ToArgb()); - Assert.Equal(0, bmp.GetPixel(68, 48).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(68, 52).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(68, 56).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(68, 60).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(68, 64).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(68, 68).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(68, 72).ToArgb()); - Assert.Equal(-16751002, bmp.GetPixel(68, 76).ToArgb()); - Assert.Equal(-16751002, bmp.GetPixel(68, 80).ToArgb()); - Assert.Equal(0, bmp.GetPixel(68, 84).ToArgb()); - Assert.Equal(0, bmp.GetPixel(68, 88).ToArgb()); - Assert.Equal(-39373, bmp.GetPixel(68, 92).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(72, 0).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 4).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 8).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 28).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 32).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 36).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 40).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(72, 44).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(72, 48).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(72, 52).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(72, 56).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(72, 60).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(72, 64).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(72, 68).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(72, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(72, 76).ToArgb()); - Assert.Equal(0, bmp.GetPixel(72, 80).ToArgb()); - Assert.Equal(0, bmp.GetPixel(72, 84).ToArgb()); - Assert.Equal(0, bmp.GetPixel(72, 88).ToArgb()); - Assert.Equal(-39373, bmp.GetPixel(72, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(76, 0).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(76, 4).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(76, 8).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(76, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(76, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(76, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(76, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(76, 28).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(76, 32).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(76, 36).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(76, 40).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(76, 44).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(76, 48).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(76, 52).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(76, 56).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(76, 60).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(76, 64).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(76, 68).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(76, 72).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(76, 76).ToArgb()); - Assert.Equal(0, bmp.GetPixel(76, 80).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(76, 84).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(76, 88).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(76, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(80, 0).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(80, 4).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(80, 8).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(80, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(80, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(80, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(80, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(80, 28).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(80, 32).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(80, 36).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(80, 40).ToArgb()); - Assert.Equal(0, bmp.GetPixel(80, 44).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(80, 48).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(80, 52).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(80, 56).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(80, 60).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(80, 64).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(80, 68).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(80, 72).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(80, 76).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(80, 80).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(80, 84).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(80, 88).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(80, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(84, 0).ToArgb()); - Assert.Equal(0, bmp.GetPixel(84, 4).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(84, 8).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(84, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(84, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(84, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(84, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(84, 28).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(84, 32).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(84, 36).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(84, 40).ToArgb()); - Assert.Equal(0, bmp.GetPixel(84, 44).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(84, 48).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(84, 52).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(84, 56).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(84, 60).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(84, 64).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(84, 68).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(84, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(84, 76).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(84, 80).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(84, 84).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(84, 88).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(84, 92).ToArgb()); - Assert.Equal(0, bmp.GetPixel(88, 0).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(88, 4).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(88, 8).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(88, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(88, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(88, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(88, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(88, 28).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(88, 32).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(88, 36).ToArgb()); - Assert.Equal(0, bmp.GetPixel(88, 40).ToArgb()); - Assert.Equal(-16777063, bmp.GetPixel(88, 44).ToArgb()); - Assert.Equal(0, bmp.GetPixel(88, 48).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(88, 52).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(88, 56).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(88, 60).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(88, 64).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(88, 68).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(88, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(88, 76).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(88, 80).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(88, 84).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(88, 88).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(88, 92).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(92, 0).ToArgb()); - Assert.Equal(-3342490, bmp.GetPixel(92, 4).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(92, 8).ToArgb()); - Assert.Equal(0, bmp.GetPixel(92, 12).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(92, 16).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(92, 20).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(92, 24).ToArgb()); - Assert.Equal(-52429, bmp.GetPixel(92, 28).ToArgb()); - Assert.Equal(-14935012, bmp.GetPixel(92, 32).ToArgb()); - Assert.Equal(0, bmp.GetPixel(92, 36).ToArgb()); - Assert.Equal(0, bmp.GetPixel(92, 40).ToArgb()); - Assert.Equal(0, bmp.GetPixel(92, 44).ToArgb()); - Assert.Equal(0, bmp.GetPixel(92, 48).ToArgb()); - Assert.Equal(0, bmp.GetPixel(92, 52).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(92, 56).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(92, 60).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(92, 64).ToArgb()); - Assert.Equal(-6750157, bmp.GetPixel(92, 68).ToArgb()); - Assert.Equal(0, bmp.GetPixel(92, 72).ToArgb()); - Assert.Equal(0, bmp.GetPixel(92, 76).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(92, 80).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(92, 84).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(92, 88).ToArgb()); - Assert.Equal(-65383, bmp.GetPixel(92, 92).ToArgb()); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void Bitmap96Data() - { - string sInFile = Helpers.GetTestBitmapPath("96x96_one_entry_8bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(96, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(0, *(scan + 0)); - Assert.Equal(0, *(scan + 97)); - Assert.Equal(0, *(scan + 194)); - Assert.Equal(0, *(scan + 291)); - Assert.Equal(0, *(scan + 388)); - Assert.Equal(28, *(scan + 485)); - Assert.Equal(0, *(scan + 582)); - Assert.Equal(28, *(scan + 679)); - Assert.Equal(255, *(scan + 776)); - Assert.Equal(0, *(scan + 873)); - Assert.Equal(255, *(scan + 970)); - Assert.Equal(255, *(scan + 1067)); - Assert.Equal(0, *(scan + 1164)); - Assert.Equal(255, *(scan + 1261)); - Assert.Equal(255, *(scan + 1358)); - Assert.Equal(0, *(scan + 1455)); - Assert.Equal(255, *(scan + 1552)); - Assert.Equal(255, *(scan + 1649)); - Assert.Equal(0, *(scan + 1746)); - Assert.Equal(255, *(scan + 1843)); - Assert.Equal(255, *(scan + 1940)); - Assert.Equal(0, *(scan + 2037)); - Assert.Equal(255, *(scan + 2134)); - Assert.Equal(255, *(scan + 2231)); - Assert.Equal(0, *(scan + 2328)); - Assert.Equal(255, *(scan + 2425)); - Assert.Equal(255, *(scan + 2522)); - Assert.Equal(0, *(scan + 2619)); - Assert.Equal(255, *(scan + 2716)); - Assert.Equal(255, *(scan + 2813)); - Assert.Equal(0, *(scan + 2910)); - Assert.Equal(255, *(scan + 3007)); - Assert.Equal(255, *(scan + 3104)); - Assert.Equal(0, *(scan + 3201)); - Assert.Equal(255, *(scan + 3298)); - Assert.Equal(255, *(scan + 3395)); - Assert.Equal(0, *(scan + 3492)); - Assert.Equal(0, *(scan + 3589)); - Assert.Equal(255, *(scan + 3686)); - Assert.Equal(0, *(scan + 3783)); - Assert.Equal(0, *(scan + 3880)); - Assert.Equal(255, *(scan + 3977)); - Assert.Equal(0, *(scan + 4074)); - Assert.Equal(0, *(scan + 4171)); - Assert.Equal(255, *(scan + 4268)); - Assert.Equal(0, *(scan + 4365)); - Assert.Equal(28, *(scan + 4462)); - Assert.Equal(255, *(scan + 4559)); - Assert.Equal(0, *(scan + 4656)); - Assert.Equal(51, *(scan + 4753)); - Assert.Equal(255, *(scan + 4850)); - Assert.Equal(0, *(scan + 4947)); - Assert.Equal(51, *(scan + 5044)); - Assert.Equal(255, *(scan + 5141)); - Assert.Equal(0, *(scan + 5238)); - Assert.Equal(51, *(scan + 5335)); - Assert.Equal(255, *(scan + 5432)); - Assert.Equal(0, *(scan + 5529)); - Assert.Equal(51, *(scan + 5626)); - Assert.Equal(255, *(scan + 5723)); - Assert.Equal(0, *(scan + 5820)); - Assert.Equal(51, *(scan + 5917)); - Assert.Equal(255, *(scan + 6014)); - Assert.Equal(0, *(scan + 6111)); - Assert.Equal(51, *(scan + 6208)); - Assert.Equal(255, *(scan + 6305)); - Assert.Equal(0, *(scan + 6402)); - Assert.Equal(51, *(scan + 6499)); - Assert.Equal(255, *(scan + 6596)); - Assert.Equal(0, *(scan + 6693)); - Assert.Equal(51, *(scan + 6790)); - Assert.Equal(255, *(scan + 6887)); - Assert.Equal(0, *(scan + 6984)); - Assert.Equal(51, *(scan + 7081)); - Assert.Equal(255, *(scan + 7178)); - Assert.Equal(0, *(scan + 7275)); - Assert.Equal(51, *(scan + 7372)); - Assert.Equal(255, *(scan + 7469)); - Assert.Equal(0, *(scan + 7566)); - Assert.Equal(51, *(scan + 7663)); - Assert.Equal(255, *(scan + 7760)); - Assert.Equal(0, *(scan + 7857)); - Assert.Equal(51, *(scan + 7954)); - Assert.Equal(255, *(scan + 8051)); - Assert.Equal(0, *(scan + 8148)); - Assert.Equal(51, *(scan + 8245)); - Assert.Equal(255, *(scan + 8342)); - Assert.Equal(0, *(scan + 8439)); - Assert.Equal(51, *(scan + 8536)); - Assert.Equal(28, *(scan + 8633)); - Assert.Equal(0, *(scan + 8730)); - Assert.Equal(51, *(scan + 8827)); - Assert.Equal(0, *(scan + 8924)); - Assert.Equal(0, *(scan + 9021)); - Assert.Equal(51, *(scan + 9118)); - Assert.Equal(0, *(scan + 9215)); - Assert.Equal(0, *(scan + 9312)); - Assert.Equal(51, *(scan + 9409)); - Assert.Equal(0, *(scan + 9506)); - Assert.Equal(0, *(scan + 9603)); - Assert.Equal(51, *(scan + 9700)); - Assert.Equal(0, *(scan + 9797)); - Assert.Equal(28, *(scan + 9894)); - Assert.Equal(51, *(scan + 9991)); - Assert.Equal(0, *(scan + 10088)); - Assert.Equal(0, *(scan + 10185)); - Assert.Equal(51, *(scan + 10282)); - Assert.Equal(0, *(scan + 10379)); - Assert.Equal(0, *(scan + 10476)); - Assert.Equal(51, *(scan + 10573)); - Assert.Equal(0, *(scan + 10670)); - Assert.Equal(0, *(scan + 10767)); - Assert.Equal(51, *(scan + 10864)); - Assert.Equal(204, *(scan + 10961)); - Assert.Equal(0, *(scan + 11058)); - Assert.Equal(51, *(scan + 11155)); - Assert.Equal(204, *(scan + 11252)); - Assert.Equal(0, *(scan + 11349)); - Assert.Equal(51, *(scan + 11446)); - Assert.Equal(204, *(scan + 11543)); - Assert.Equal(0, *(scan + 11640)); - Assert.Equal(51, *(scan + 11737)); - Assert.Equal(204, *(scan + 11834)); - Assert.Equal(0, *(scan + 11931)); - Assert.Equal(51, *(scan + 12028)); - Assert.Equal(204, *(scan + 12125)); - Assert.Equal(0, *(scan + 12222)); - Assert.Equal(51, *(scan + 12319)); - Assert.Equal(204, *(scan + 12416)); - Assert.Equal(28, *(scan + 12513)); - Assert.Equal(51, *(scan + 12610)); - Assert.Equal(204, *(scan + 12707)); - Assert.Equal(0, *(scan + 12804)); - Assert.Equal(28, *(scan + 12901)); - Assert.Equal(204, *(scan + 12998)); - Assert.Equal(0, *(scan + 13095)); - Assert.Equal(0, *(scan + 13192)); - Assert.Equal(204, *(scan + 13289)); - Assert.Equal(0, *(scan + 13386)); - Assert.Equal(0, *(scan + 13483)); - Assert.Equal(204, *(scan + 13580)); - Assert.Equal(0, *(scan + 13677)); - Assert.Equal(28, *(scan + 13774)); - Assert.Equal(204, *(scan + 13871)); - Assert.Equal(0, *(scan + 13968)); - Assert.Equal(0, *(scan + 14065)); - Assert.Equal(204, *(scan + 14162)); - Assert.Equal(0, *(scan + 14259)); - Assert.Equal(0, *(scan + 14356)); - Assert.Equal(204, *(scan + 14453)); - Assert.Equal(0, *(scan + 14550)); - Assert.Equal(0, *(scan + 14647)); - Assert.Equal(204, *(scan + 14744)); - Assert.Equal(0, *(scan + 14841)); - Assert.Equal(0, *(scan + 14938)); - Assert.Equal(204, *(scan + 15035)); - Assert.Equal(0, *(scan + 15132)); - Assert.Equal(0, *(scan + 15229)); - Assert.Equal(204, *(scan + 15326)); - Assert.Equal(0, *(scan + 15423)); - Assert.Equal(0, *(scan + 15520)); - Assert.Equal(204, *(scan + 15617)); - Assert.Equal(0, *(scan + 15714)); - Assert.Equal(0, *(scan + 15811)); - Assert.Equal(204, *(scan + 15908)); - Assert.Equal(0, *(scan + 16005)); - Assert.Equal(0, *(scan + 16102)); - Assert.Equal(204, *(scan + 16199)); - Assert.Equal(0, *(scan + 16296)); - Assert.Equal(0, *(scan + 16393)); - Assert.Equal(204, *(scan + 16490)); - Assert.Equal(0, *(scan + 16587)); - Assert.Equal(0, *(scan + 16684)); - Assert.Equal(204, *(scan + 16781)); - Assert.Equal(0, *(scan + 16878)); - Assert.Equal(0, *(scan + 16975)); - Assert.Equal(204, *(scan + 17072)); - Assert.Equal(0, *(scan + 17169)); - Assert.Equal(0, *(scan + 17266)); - Assert.Equal(204, *(scan + 17363)); - Assert.Equal(0, *(scan + 17460)); - Assert.Equal(0, *(scan + 17557)); - Assert.Equal(28, *(scan + 17654)); - Assert.Equal(0, *(scan + 17751)); - Assert.Equal(0, *(scan + 17848)); - Assert.Equal(0, *(scan + 17945)); - Assert.Equal(28, *(scan + 18042)); - Assert.Equal(0, *(scan + 18139)); - Assert.Equal(0, *(scan + 18236)); - Assert.Equal(51, *(scan + 18333)); - Assert.Equal(28, *(scan + 18430)); - Assert.Equal(0, *(scan + 18527)); - Assert.Equal(51, *(scan + 18624)); - Assert.Equal(0, *(scan + 18721)); - Assert.Equal(28, *(scan + 18818)); - Assert.Equal(51, *(scan + 18915)); - Assert.Equal(255, *(scan + 19012)); - Assert.Equal(51, *(scan + 19109)); - Assert.Equal(51, *(scan + 19206)); - Assert.Equal(255, *(scan + 19303)); - Assert.Equal(51, *(scan + 19400)); - Assert.Equal(51, *(scan + 19497)); - Assert.Equal(255, *(scan + 19594)); - Assert.Equal(51, *(scan + 19691)); - Assert.Equal(51, *(scan + 19788)); - Assert.Equal(255, *(scan + 19885)); - Assert.Equal(51, *(scan + 19982)); - Assert.Equal(51, *(scan + 20079)); - Assert.Equal(255, *(scan + 20176)); - Assert.Equal(51, *(scan + 20273)); - Assert.Equal(51, *(scan + 20370)); - Assert.Equal(255, *(scan + 20467)); - Assert.Equal(51, *(scan + 20564)); - Assert.Equal(51, *(scan + 20661)); - Assert.Equal(255, *(scan + 20758)); - Assert.Equal(51, *(scan + 20855)); - Assert.Equal(51, *(scan + 20952)); - Assert.Equal(255, *(scan + 21049)); - Assert.Equal(51, *(scan + 21146)); - Assert.Equal(51, *(scan + 21243)); - Assert.Equal(28, *(scan + 21340)); - Assert.Equal(51, *(scan + 21437)); - Assert.Equal(51, *(scan + 21534)); - Assert.Equal(0, *(scan + 21631)); - Assert.Equal(51, *(scan + 21728)); - Assert.Equal(28, *(scan + 21825)); - Assert.Equal(0, *(scan + 21922)); - Assert.Equal(51, *(scan + 22019)); - Assert.Equal(28, *(scan + 22116)); - Assert.Equal(0, *(scan + 22213)); - Assert.Equal(51, *(scan + 22310)); - Assert.Equal(0, *(scan + 22407)); - Assert.Equal(0, *(scan + 22504)); - Assert.Equal(51, *(scan + 22601)); - Assert.Equal(0, *(scan + 22698)); - Assert.Equal(0, *(scan + 22795)); - Assert.Equal(51, *(scan + 22892)); - Assert.Equal(28, *(scan + 22989)); - Assert.Equal(0, *(scan + 23086)); - Assert.Equal(28, *(scan + 23183)); - Assert.Equal(153, *(scan + 23280)); - Assert.Equal(28, *(scan + 23377)); - Assert.Equal(0, *(scan + 23474)); - Assert.Equal(153, *(scan + 23571)); - Assert.Equal(28, *(scan + 23668)); - Assert.Equal(0, *(scan + 23765)); - Assert.Equal(153, *(scan + 23862)); - Assert.Equal(0, *(scan + 23959)); - Assert.Equal(28, *(scan + 24056)); - Assert.Equal(153, *(scan + 24153)); - Assert.Equal(0, *(scan + 24250)); - Assert.Equal(153, *(scan + 24347)); - Assert.Equal(153, *(scan + 24444)); - Assert.Equal(0, *(scan + 24541)); - Assert.Equal(153, *(scan + 24638)); - Assert.Equal(153, *(scan + 24735)); - Assert.Equal(0, *(scan + 24832)); - Assert.Equal(153, *(scan + 24929)); - Assert.Equal(153, *(scan + 25026)); - Assert.Equal(0, *(scan + 25123)); - Assert.Equal(153, *(scan + 25220)); - Assert.Equal(153, *(scan + 25317)); - Assert.Equal(0, *(scan + 25414)); - Assert.Equal(153, *(scan + 25511)); - Assert.Equal(153, *(scan + 25608)); - Assert.Equal(0, *(scan + 25705)); - Assert.Equal(153, *(scan + 25802)); - Assert.Equal(153, *(scan + 25899)); - Assert.Equal(0, *(scan + 25996)); - Assert.Equal(153, *(scan + 26093)); - Assert.Equal(153, *(scan + 26190)); - Assert.Equal(0, *(scan + 26287)); - Assert.Equal(153, *(scan + 26384)); - Assert.Equal(153, *(scan + 26481)); - Assert.Equal(0, *(scan + 26578)); - Assert.Equal(153, *(scan + 26675)); - Assert.Equal(153, *(scan + 26772)); - Assert.Equal(28, *(scan + 26869)); - Assert.Equal(153, *(scan + 26966)); - Assert.Equal(28, *(scan + 27063)); - Assert.Equal(28, *(scan + 27160)); - Assert.Equal(28, *(scan + 27257)); - Assert.Equal(0, *(scan + 27354)); - Assert.Equal(0, *(scan + 27451)); - Assert.Equal(0, *(scan + 27548)); - Assert.Equal(0, *(scan + 27645)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - [Fact] - public void Xp32bppIconFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_multiple_entries_32bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.True(bmp.RawFormat.Equals(ImageFormat.Icon)); - // note that image is "promoted" to 32bits - Assert.Equal(PixelFormat.Format32bppArgb, bmp.PixelFormat); - Assert.Equal(73746, bmp.Flags); - Assert.Equal(0, bmp.Palette.Entries.Length); - Assert.Equal(1, bmp.FrameDimensionsList.Length); - Assert.Equal(0, bmp.PropertyIdList.Length); - Assert.Equal(0, bmp.PropertyItems.Length); - Assert.Null(bmp.Tag); - Assert.Equal(96.0f, bmp.HorizontalResolution); - Assert.Equal(96.0f, bmp.VerticalResolution); - Assert.Equal(16, bmp.Width); - Assert.Equal(16, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(16, rect.Width); - Assert.Equal(16, rect.Height); - - Assert.Equal(16, bmp.Size.Width); - Assert.Equal(16, bmp.Size.Height); - } - } - - private void Save(PixelFormat original, PixelFormat expected, bool colorCheck) - { - string sOutFile = $"linerect-{expected}.ico"; - - // Save - Bitmap bmp = new Bitmap(100, 100, original); - Graphics gr = Graphics.FromImage(bmp); - - using (Pen p = new Pen(Color.Red, 2)) - { - gr.DrawLine(p, 10.0F, 10.0F, 90.0F, 90.0F); - gr.DrawRectangle(p, 10.0F, 10.0F, 80.0F, 80.0F); - } - - try - { - // there's no encoder, so we're not saving a ICO but the alpha - // bit get sets so it's not like saving a bitmap either - bmp.Save(sOutFile, ImageFormat.Icon); - - // Load - using (Bitmap bmpLoad = new Bitmap(sOutFile)) - { - Assert.Equal(ImageFormat.Png, bmpLoad.RawFormat); - Assert.Equal(expected, bmpLoad.PixelFormat); - if (colorCheck) - { - Color color = bmpLoad.GetPixel(10, 10); - Assert.Equal(Color.FromArgb(255, 255, 0, 0), color); - } - } - } - finally - { - gr.Dispose(); - bmp.Dispose(); - try - { - File.Delete(sOutFile); - } - catch - { - } - } - } - - [Fact] - public void Save_24bppRgb() - { - Save(PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb, true); - } - - [Fact] - public void Save_32bppRgb() - { - Save(PixelFormat.Format32bppRgb, PixelFormat.Format32bppArgb, true); - } - - [Fact] - public void Save_32bppArgb() - { - Save(PixelFormat.Format32bppArgb, PixelFormat.Format32bppArgb, true); - } - - [Fact] - public void Save_32bppPArgb() - { - Save(PixelFormat.Format32bppPArgb, PixelFormat.Format32bppArgb, true); - } -} diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/JpegCodecTests.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/JpegCodecTests.cs deleted file mode 100644 index a6cc63d5613..00000000000 --- a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/JpegCodecTests.cs +++ /dev/null @@ -1,422 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// JpegCodec class testing unit -// -// Authors: -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sebastien Pouliot -// -// (C) 2004 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Drawing.Imaging; - -namespace MonoTests.System.Drawing.Imaging; - -public class JpegCodecTest -{ - [Fact] - public void Bitmap8bbpIndexedGreyscaleFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("nature-greyscale.jpg"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.Equal(PixelFormat.Format8bppIndexed, bmp.PixelFormat); - Assert.Equal(110, bmp.Width); - Assert.Equal(100, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(110, rect.Width); - Assert.Equal(100, rect.Height); - - Assert.Equal(110, bmp.Size.Width); - Assert.Equal(100, bmp.Size.Height); - - Assert.Equal(110, bmp.PhysicalDimension.Width); - Assert.Equal(100, bmp.PhysicalDimension.Height); - - Assert.Equal(72, bmp.HorizontalResolution); - Assert.Equal(72, bmp.VerticalResolution); - - // This value is not consistent across Windows & Unix - // Assert.Equal(77896, bmp.Flags); - - ColorPalette cp = bmp.Palette; - Assert.Equal(256, cp.Entries.Length); - - // This value is not consistent across Windows & Unix - // Assert.Equal(0, cp.Flags); - for (int i = 0; i < 256; i++) - { - Color c = cp.Entries[i]; - Assert.Equal(0xFF, c.A); - Assert.Equal(i, c.R); - Assert.Equal(i, c.G); - Assert.Equal(i, c.B); - } - } - } - - [Fact] - public void Bitmap8bbpIndexedGreyscalePixels() - { - string sInFile = Helpers.GetTestBitmapPath("nature-greyscale.jpg"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-7697782, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-12171706, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-14013910, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-15132391, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-328966, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-9934744, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-10263709, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-7368817, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-4276546, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-9079435, bmp.GetPixel(64, 64).ToArgb()); - // Assert.Equal(-7697782, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-8224126, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-11053225, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-9211021, bmp.GetPixel(96, 96).ToArgb()); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void Bitmap8bbpIndexedGreyscaleData() - { - string sInFile = Helpers.GetTestBitmapPath("nature-greyscale.jpg"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(100, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(138, *(scan + 0)); - Assert.Equal(203, *(scan + 1009)); - Assert.Equal(156, *(scan + 2018)); - Assert.Equal(248, *(scan + 3027)); - Assert.Equal(221, *(scan + 4036)); - Assert.Equal(185, *(scan + 5045)); - Assert.Equal(128, *(scan + 6054)); - Assert.Equal(205, *(scan + 7063)); - Assert.Equal(153, *(scan + 8072)); - Assert.Equal(110, *(scan + 9081)); - Assert.Equal(163, *(scan + 10090)); - Assert.Equal(87, *(scan + 11099)); - Assert.Equal(90, *(scan + 12108)); - Assert.Equal(81, *(scan + 13117)); - // Assert.Equal(124, *(scan + 14126)); - Assert.Equal(99, *(scan + 15135)); - Assert.Equal(153, *(scan + 16144)); - Assert.Equal(57, *(scan + 17153)); - Assert.Equal(89, *(scan + 18162)); - Assert.Equal(71, *(scan + 19171)); - Assert.Equal(106, *(scan + 20180)); - Assert.Equal(55, *(scan + 21189)); - Assert.Equal(75, *(scan + 22198)); - Assert.Equal(77, *(scan + 23207)); - Assert.Equal(58, *(scan + 24216)); - Assert.Equal(69, *(scan + 25225)); - Assert.Equal(43, *(scan + 26234)); - Assert.Equal(55, *(scan + 27243)); - Assert.Equal(74, *(scan + 28252)); - Assert.Equal(145, *(scan + 29261)); - Assert.Equal(87, *(scan + 30270)); - Assert.Equal(85, *(scan + 31279)); - Assert.Equal(106, *(scan + 32288)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - /* Checks bitmap features on a known 24-bits bitmap */ - [Fact] - public void Bitmap24bitFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("nature24bits.jpg"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.Equal(PixelFormat.Format24bppRgb, bmp.PixelFormat); - Assert.Equal(110, bmp.Width); - Assert.Equal(100, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(110, rect.Width); - Assert.Equal(100, rect.Height); - - Assert.Equal(110, bmp.Size.Width); - Assert.Equal(100, bmp.Size.Height); - - Assert.Equal(110, bmp.PhysicalDimension.Width); - Assert.Equal(100, bmp.PhysicalDimension.Height); - - Assert.Equal(72, bmp.HorizontalResolution); - Assert.Equal(72, bmp.VerticalResolution); - - /* note: under MS flags aren't constant between executions in this case (no palette) */ - // Assert.Equal(77960, bmp.Flags); - - Assert.Equal(0, bmp.Palette.Entries.Length); - } - } - - [Fact] - public void Bitmap24bitPixels() - { - string sInFile = Helpers.GetTestBitmapPath("nature24bits.jpg"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-10447423, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-12171958, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-15192259, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-15131110, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-395272, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-10131359, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-10984322, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-11034683, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-3163242, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-7311538, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-12149780, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-8224378, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-11053718, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-12944166, bmp.GetPixel(96, 96).ToArgb()); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void Bitmap24bitData() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(520, data.Stride); - Assert.Equal(183, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(217, *(scan + 0)); - Assert.Equal(192, *(scan + 1009)); - Assert.Equal(210, *(scan + 2018)); - Assert.Equal(196, *(scan + 3027)); - Assert.Equal(216, *(scan + 4036)); - Assert.Equal(215, *(scan + 5045)); - Assert.Equal(218, *(scan + 6054)); - Assert.Equal(218, *(scan + 7063)); - Assert.Equal(95, *(scan + 8072)); - Assert.Equal(9, *(scan + 9081)); - Assert.Equal(247, *(scan + 10090)); - Assert.Equal(161, *(scan + 11099)); - Assert.Equal(130, *(scan + 12108)); - Assert.Equal(131, *(scan + 13117)); - Assert.Equal(175, *(scan + 14126)); - Assert.Equal(217, *(scan + 15135)); - Assert.Equal(201, *(scan + 16144)); - Assert.Equal(183, *(scan + 17153)); - Assert.Equal(236, *(scan + 18162)); - Assert.Equal(242, *(scan + 19171)); - Assert.Equal(125, *(scan + 20180)); - Assert.Equal(193, *(scan + 21189)); - Assert.Equal(227, *(scan + 22198)); - Assert.Equal(44, *(scan + 23207)); - Assert.Equal(230, *(scan + 24216)); - Assert.Equal(224, *(scan + 25225)); - Assert.Equal(164, *(scan + 26234)); - Assert.Equal(43, *(scan + 27243)); - Assert.Equal(200, *(scan + 28252)); - Assert.Equal(255, *(scan + 29261)); - Assert.Equal(226, *(scan + 30270)); - Assert.Equal(230, *(scan + 31279)); - Assert.Equal(178, *(scan + 32288)); - Assert.Equal(224, *(scan + 33297)); - Assert.Equal(233, *(scan + 34306)); - Assert.Equal(212, *(scan + 35315)); - Assert.Equal(153, *(scan + 36324)); - Assert.Equal(143, *(scan + 37333)); - Assert.Equal(215, *(scan + 38342)); - Assert.Equal(116, *(scan + 39351)); - Assert.Equal(26, *(scan + 40360)); - Assert.Equal(28, *(scan + 41369)); - Assert.Equal(75, *(scan + 42378)); - Assert.Equal(50, *(scan + 43387)); - Assert.Equal(244, *(scan + 44396)); - Assert.Equal(191, *(scan + 45405)); - Assert.Equal(200, *(scan + 46414)); - Assert.Equal(197, *(scan + 47423)); - Assert.Equal(232, *(scan + 48432)); - Assert.Equal(186, *(scan + 49441)); - Assert.Equal(210, *(scan + 50450)); - Assert.Equal(215, *(scan + 51459)); - Assert.Equal(155, *(scan + 52468)); - Assert.Equal(56, *(scan + 53477)); - Assert.Equal(149, *(scan + 54486)); - Assert.Equal(137, *(scan + 55495)); - Assert.Equal(141, *(scan + 56504)); - Assert.Equal(36, *(scan + 57513)); - Assert.Equal(39, *(scan + 58522)); - Assert.Equal(25, *(scan + 59531)); - Assert.Equal(44, *(scan + 60540)); - Assert.Equal(12, *(scan + 61549)); - Assert.Equal(161, *(scan + 62558)); - Assert.Equal(179, *(scan + 63567)); - Assert.Equal(181, *(scan + 64576)); - Assert.Equal(165, *(scan + 65585)); - Assert.Equal(182, *(scan + 66594)); - Assert.Equal(186, *(scan + 67603)); - Assert.Equal(201, *(scan + 68612)); - Assert.Equal(49, *(scan + 69621)); - Assert.Equal(161, *(scan + 70630)); - Assert.Equal(140, *(scan + 71639)); - Assert.Equal(2, *(scan + 72648)); - Assert.Equal(15, *(scan + 73657)); - Assert.Equal(33, *(scan + 74666)); - Assert.Equal(17, *(scan + 75675)); - Assert.Equal(0, *(scan + 76684)); - Assert.Equal(47, *(scan + 77693)); - Assert.Equal(4, *(scan + 78702)); - Assert.Equal(142, *(scan + 79711)); - Assert.Equal(151, *(scan + 80720)); - Assert.Equal(124, *(scan + 81729)); - Assert.Equal(81, *(scan + 82738)); - Assert.Equal(214, *(scan + 83747)); - Assert.Equal(217, *(scan + 84756)); - Assert.Equal(30, *(scan + 85765)); - Assert.Equal(185, *(scan + 86774)); - Assert.Equal(200, *(scan + 87783)); - Assert.Equal(37, *(scan + 88792)); - Assert.Equal(2, *(scan + 89801)); - Assert.Equal(41, *(scan + 90810)); - Assert.Equal(16, *(scan + 91819)); - Assert.Equal(0, *(scan + 92828)); - Assert.Equal(146, *(scan + 93837)); - Assert.Equal(163, *(scan + 94846)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - private void Save(PixelFormat original, PixelFormat expected) - { - string sOutFile = $"linerect-{expected}.jpeg"; - - // Save - Bitmap bmp = new Bitmap(100, 100, original); - Graphics gr = Graphics.FromImage(bmp); - - using (Pen p = new Pen(Color.Red, 2)) - { - gr.DrawLine(p, 10.0F, 10.0F, 90.0F, 90.0F); - gr.DrawRectangle(p, 10.0F, 10.0F, 80.0F, 80.0F); - } - - try - { - bmp.Save(sOutFile, ImageFormat.Jpeg); - - // Load - using (Bitmap bmpLoad = new Bitmap(sOutFile)) - { - Assert.Equal(expected, bmpLoad.PixelFormat); - Color color = bmpLoad.GetPixel(10, 10); - // by default JPEG isn't lossless - so value is "near" read - Assert.True(color.R >= 195); - Assert.True(color.G < 60); - Assert.True(color.B < 60); - Assert.Equal(0xFF, color.A); - } - } - finally - { - gr.Dispose(); - bmp.Dispose(); - try - { - File.Delete(sOutFile); - } - catch - { - } - } - } - - [Fact] - public void Save_24bppRgb() - { - Save(PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb); - } - - [Fact] - public void Save_32bppRgb() - { - Save(PixelFormat.Format32bppRgb, PixelFormat.Format24bppRgb); - } - - [Fact] - public void Save_32bppArgb() - { - Save(PixelFormat.Format32bppArgb, PixelFormat.Format24bppRgb); - } - - [Fact] - public void Save_32bppPArgb() - { - Save(PixelFormat.Format32bppPArgb, PixelFormat.Format24bppRgb); - } -} diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/PngCodecTests.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/PngCodecTests.cs deleted file mode 100644 index 9357f568e8b..00000000000 --- a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/PngCodecTests.cs +++ /dev/null @@ -1,649 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// PNG Codec class testing unit -// -// Authors: -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sebastien Pouliot -// -// Copyright (C) 2006, 2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Drawing.Imaging; - -namespace MonoTests.System.Drawing.Imaging; - -[ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported))] -public class PngCodecTest -{ - /* Checks bitmap features on a known 1bbp bitmap */ - [Fact] - public void Bitmap1bitFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("1bit.png"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.Equal(PixelFormat.Format1bppIndexed, bmp.PixelFormat); - - Assert.Equal(0, bmp.Palette.Flags); - Assert.Equal(2, bmp.Palette.Entries.Length); - Assert.Equal(-16777216, bmp.Palette.Entries[0].ToArgb()); - Assert.Equal(-1, bmp.Palette.Entries[1].ToArgb()); - - Assert.Equal(288, bmp.Width); - Assert.Equal(384, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(288, rect.Width); - Assert.Equal(384, rect.Height); - - Assert.Equal(288, bmp.Size.Width); - Assert.Equal(384, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap1bitPixels() - { - string sInFile = Helpers.GetTestBitmapPath("1bit.png"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-1, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(0, 128).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 160).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 192).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 224).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(0, 256).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 288).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(0, 320).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(0, 352).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(32, 128).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(32, 160).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(32, 192).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(32, 224).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(32, 256).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(32, 288).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(32, 320).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(32, 352).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 128).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 160).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 192).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 224).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 256).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 288).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 320).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 352).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(96, 96).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(96, 128).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(96, 160).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(96, 192).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(96, 224).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(96, 256).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(96, 288).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(96, 320).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(96, 352).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 0).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 32).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 64).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 96).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 128).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 160).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 192).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 224).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(128, 256).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 288).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 320).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(128, 352).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(160, 0).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(160, 32).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(160, 64).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(160, 96).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(160, 128).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(160, 160).ToArgb()); - } - } - - [Fact] - public void Bitmap1bitData() - { - string sInFile = Helpers.GetTestBitmapPath("1bit.png"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(864, data.Stride); - Assert.Equal(384, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(255, *(scan + 0)); - Assert.Equal(255, *(scan + 1009)); - Assert.Equal(255, *(scan + 2018)); - Assert.Equal(255, *(scan + 3027)); - Assert.Equal(255, *(scan + 4036)); - Assert.Equal(255, *(scan + 5045)); - Assert.Equal(255, *(scan + 6054)); - Assert.Equal(255, *(scan + 7063)); - Assert.Equal(255, *(scan + 8072)); - Assert.Equal(255, *(scan + 9081)); - Assert.Equal(255, *(scan + 10090)); - Assert.Equal(0, *(scan + 11099)); - Assert.Equal(255, *(scan + 12108)); - Assert.Equal(255, *(scan + 13117)); - Assert.Equal(0, *(scan + 14126)); - Assert.Equal(255, *(scan + 15135)); - Assert.Equal(255, *(scan + 16144)); - Assert.Equal(0, *(scan + 17153)); - Assert.Equal(0, *(scan + 18162)); - Assert.Equal(255, *(scan + 19171)); - Assert.Equal(0, *(scan + 20180)); - Assert.Equal(255, *(scan + 21189)); - Assert.Equal(255, *(scan + 22198)); - Assert.Equal(0, *(scan + 23207)); - Assert.Equal(0, *(scan + 24216)); - Assert.Equal(0, *(scan + 25225)); - Assert.Equal(0, *(scan + 26234)); - Assert.Equal(255, *(scan + 27243)); - Assert.Equal(255, *(scan + 28252)); - Assert.Equal(0, *(scan + 29261)); - Assert.Equal(255, *(scan + 30270)); - Assert.Equal(0, *(scan + 31279)); - Assert.Equal(0, *(scan + 32288)); - Assert.Equal(255, *(scan + 33297)); - Assert.Equal(255, *(scan + 34306)); - Assert.Equal(255, *(scan + 35315)); - Assert.Equal(255, *(scan + 36324)); - Assert.Equal(0, *(scan + 37333)); - Assert.Equal(255, *(scan + 38342)); - Assert.Equal(255, *(scan + 39351)); - Assert.Equal(255, *(scan + 40360)); - Assert.Equal(255, *(scan + 41369)); - Assert.Equal(255, *(scan + 42378)); - Assert.Equal(0, *(scan + 43387)); - Assert.Equal(0, *(scan + 44396)); - Assert.Equal(255, *(scan + 45405)); - Assert.Equal(255, *(scan + 46414)); - Assert.Equal(255, *(scan + 47423)); - Assert.Equal(255, *(scan + 48432)); - Assert.Equal(255, *(scan + 49441)); - Assert.Equal(0, *(scan + 50450)); - Assert.Equal(0, *(scan + 51459)); - Assert.Equal(255, *(scan + 52468)); - Assert.Equal(255, *(scan + 53477)); - Assert.Equal(255, *(scan + 54486)); - Assert.Equal(0, *(scan + 55495)); - Assert.Equal(0, *(scan + 56504)); - Assert.Equal(0, *(scan + 57513)); - Assert.Equal(255, *(scan + 58522)); - Assert.Equal(255, *(scan + 59531)); - Assert.Equal(0, *(scan + 60540)); - Assert.Equal(0, *(scan + 61549)); - Assert.Equal(0, *(scan + 62558)); - Assert.Equal(0, *(scan + 63567)); - Assert.Equal(255, *(scan + 64576)); - Assert.Equal(0, *(scan + 65585)); - Assert.Equal(255, *(scan + 66594)); - Assert.Equal(255, *(scan + 67603)); - Assert.Equal(0, *(scan + 68612)); - Assert.Equal(0, *(scan + 69621)); - Assert.Equal(0, *(scan + 70630)); - Assert.Equal(0, *(scan + 71639)); - Assert.Equal(0, *(scan + 72648)); - Assert.Equal(255, *(scan + 73657)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - /* Checks bitmap features on a known 2bbp bitmap */ - [Fact] - public void Bitmap2bitFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("81674-2bpp.png"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - // quite a promotion! (2 -> 32) - Assert.Equal(PixelFormat.Format32bppArgb, bmp.PixelFormat); - - // MS returns a random Flags value (not a good sign) - //Assert.Equal (0, bmp.Palette.Flags); - Assert.Equal(0, bmp.Palette.Entries.Length); - - Assert.Equal(100, bmp.Width); - Assert.Equal(100, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(100, rect.Width); - Assert.Equal(100, rect.Height); - - Assert.Equal(100, bmp.Size.Width); - Assert.Equal(100, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap2bitPixels() - { - string sInFile = Helpers.GetTestBitmapPath("81674-2bpp.png"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-11249559, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-16777216, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-11249559, bmp.GetPixel(96, 96).ToArgb()); - } - } - - [Fact] - public void Bitmap2bitData() - { - string sInFile = Helpers.GetTestBitmapPath("81674-2bpp.png"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(300, data.Stride); - Assert.Equal(100, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(105, *(scan + 0)); - Assert.Equal(88, *(scan + 1009)); - Assert.Equal(255, *(scan + 2018)); - Assert.Equal(105, *(scan + 3027)); - Assert.Equal(88, *(scan + 4036)); - Assert.Equal(84, *(scan + 5045)); - Assert.Equal(255, *(scan + 6054)); - Assert.Equal(88, *(scan + 7063)); - Assert.Equal(84, *(scan + 8072)); - Assert.Equal(0, *(scan + 9081)); - Assert.Equal(0, *(scan + 10090)); - Assert.Equal(84, *(scan + 11099)); - Assert.Equal(0, *(scan + 12108)); - Assert.Equal(88, *(scan + 13117)); - Assert.Equal(84, *(scan + 14126)); - Assert.Equal(105, *(scan + 15135)); - Assert.Equal(88, *(scan + 16144)); - Assert.Equal(84, *(scan + 17153)); - Assert.Equal(0, *(scan + 18162)); - Assert.Equal(88, *(scan + 19171)); - Assert.Equal(84, *(scan + 20180)); - Assert.Equal(0, *(scan + 21189)); - Assert.Equal(88, *(scan + 22198)); - Assert.Equal(84, *(scan + 23207)); - Assert.Equal(105, *(scan + 24216)); - Assert.Equal(88, *(scan + 25225)); - Assert.Equal(0, *(scan + 26234)); - Assert.Equal(105, *(scan + 27243)); - Assert.Equal(88, *(scan + 28252)); - Assert.Equal(84, *(scan + 29261)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - /* Checks bitmap features on a known 4bbp bitmap */ - [Fact] - public void Bitmap4bitFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("4bit.png"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - - Assert.Equal(PixelFormat.Format4bppIndexed, bmp.PixelFormat); - - Assert.Equal(0, bmp.Palette.Flags); - Assert.Equal(16, bmp.Palette.Entries.Length); - Assert.Equal(-12106173, bmp.Palette.Entries[0].ToArgb()); - Assert.Equal(-10979957, bmp.Palette.Entries[1].ToArgb()); - Assert.Equal(-8879241, bmp.Palette.Entries[2].ToArgb()); - Assert.Equal(-10381134, bmp.Palette.Entries[3].ToArgb()); - Assert.Equal(-7441574, bmp.Palette.Entries[4].ToArgb()); - Assert.Equal(-6391673, bmp.Palette.Entries[5].ToArgb()); - Assert.Equal(-5861009, bmp.Palette.Entries[6].ToArgb()); - Assert.Equal(-3824008, bmp.Palette.Entries[7].ToArgb()); - Assert.Equal(-5790569, bmp.Palette.Entries[8].ToArgb()); - Assert.Equal(-6178617, bmp.Palette.Entries[9].ToArgb()); - Assert.Equal(-4668490, bmp.Palette.Entries[10].ToArgb()); - Assert.Equal(-5060143, bmp.Palette.Entries[11].ToArgb()); - Assert.Equal(-3492461, bmp.Palette.Entries[12].ToArgb()); - Assert.Equal(-2967099, bmp.Palette.Entries[13].ToArgb()); - Assert.Equal(-2175574, bmp.Palette.Entries[14].ToArgb()); - Assert.Equal(-1314578, bmp.Palette.Entries[15].ToArgb()); - - Assert.Equal(288, bmp.Width); - Assert.Equal(384, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(288, rect.Width); - Assert.Equal(384, rect.Height); - - Assert.Equal(288, bmp.Size.Width); - Assert.Equal(384, bmp.Size.Height); - } - } - - [Fact] - public void Bitmap4bitPixels() - { - string sInFile = Helpers.GetTestBitmapPath("4bit.png"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-10381134, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-3824008, bmp.GetPixel(0, 128).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(0, 160).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(0, 192).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(0, 224).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(0, 256).ToArgb()); - Assert.Equal(-7441574, bmp.GetPixel(0, 288).ToArgb()); - Assert.Equal(-3492461, bmp.GetPixel(0, 320).ToArgb()); - Assert.Equal(-5861009, bmp.GetPixel(0, 352).ToArgb()); - Assert.Equal(-10381134, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-7441574, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(32, 128).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(32, 160).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(32, 192).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(32, 224).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(32, 256).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(32, 288).ToArgb()); - Assert.Equal(-3492461, bmp.GetPixel(32, 320).ToArgb()); - Assert.Equal(-2175574, bmp.GetPixel(32, 352).ToArgb()); - Assert.Equal(-6178617, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(64, 128).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(64, 160).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(64, 192).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(64, 224).ToArgb()); - Assert.Equal(-5790569, bmp.GetPixel(64, 256).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(64, 288).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(64, 320).ToArgb()); - Assert.Equal(-5790569, bmp.GetPixel(64, 352).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-10381134, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(96, 96).ToArgb()); - Assert.Equal(-7441574, bmp.GetPixel(96, 128).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(96, 160).ToArgb()); - Assert.Equal(-5790569, bmp.GetPixel(96, 192).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(96, 224).ToArgb()); - Assert.Equal(-4668490, bmp.GetPixel(96, 256).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(96, 288).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(96, 320).ToArgb()); - Assert.Equal(-3492461, bmp.GetPixel(96, 352).ToArgb()); - Assert.Equal(-5861009, bmp.GetPixel(128, 0).ToArgb()); - Assert.Equal(-7441574, bmp.GetPixel(128, 32).ToArgb()); - Assert.Equal(-7441574, bmp.GetPixel(128, 64).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(128, 96).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(128, 128).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(128, 160).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(128, 192).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(128, 224).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(128, 256).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(128, 288).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(128, 320).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(128, 352).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(160, 0).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(160, 32).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(160, 64).ToArgb()); - Assert.Equal(-1314578, bmp.GetPixel(160, 96).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(160, 128).ToArgb()); - Assert.Equal(-5790569, bmp.GetPixel(160, 160).ToArgb()); - Assert.Equal(-12106173, bmp.GetPixel(160, 192).ToArgb()); - } - } - - [Fact] - public void Bitmap4bitData() - { - string sInFile = Helpers.GetTestBitmapPath("4bit.png"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(864, data.Stride); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(178, *(scan + 0)); - Assert.Equal(184, *(scan + 1009)); - Assert.Equal(235, *(scan + 2018)); - Assert.Equal(209, *(scan + 3027)); - Assert.Equal(240, *(scan + 4036)); - Assert.Equal(142, *(scan + 5045)); - Assert.Equal(139, *(scan + 6054)); - Assert.Equal(152, *(scan + 7063)); - Assert.Equal(235, *(scan + 8072)); - Assert.Equal(209, *(scan + 9081)); - Assert.Equal(240, *(scan + 10090)); - Assert.Equal(142, *(scan + 11099)); - Assert.Equal(199, *(scan + 12108)); - Assert.Equal(201, *(scan + 13117)); - Assert.Equal(97, *(scan + 14126)); - Assert.Equal(238, *(scan + 15135)); - Assert.Equal(240, *(scan + 16144)); - Assert.Equal(158, *(scan + 17153)); - Assert.Equal(119, *(scan + 18162)); - Assert.Equal(201, *(scan + 19171)); - Assert.Equal(88, *(scan + 20180)); - Assert.Equal(238, *(scan + 21189)); - Assert.Equal(240, *(scan + 22198)); - Assert.Equal(120, *(scan + 23207)); - Assert.Equal(182, *(scan + 24216)); - Assert.Equal(70, *(scan + 25225)); - Assert.Equal(71, *(scan + 26234)); - Assert.Equal(238, *(scan + 27243)); - Assert.Equal(240, *(scan + 28252)); - Assert.Equal(120, *(scan + 29261)); - Assert.Equal(238, *(scan + 30270)); - Assert.Equal(70, *(scan + 31279)); - Assert.Equal(71, *(scan + 32288)); - Assert.Equal(238, *(scan + 33297)); - Assert.Equal(240, *(scan + 34306)); - Assert.Equal(210, *(scan + 35315)); - Assert.Equal(238, *(scan + 36324)); - Assert.Equal(70, *(scan + 37333)); - Assert.Equal(97, *(scan + 38342)); - Assert.Equal(238, *(scan + 39351)); - Assert.Equal(240, *(scan + 40360)); - Assert.Equal(235, *(scan + 41369)); - Assert.Equal(238, *(scan + 42378)); - Assert.Equal(117, *(scan + 43387)); - Assert.Equal(158, *(scan + 44396)); - Assert.Equal(170, *(scan + 45405)); - Assert.Equal(240, *(scan + 46414)); - Assert.Equal(235, *(scan + 47423)); - Assert.Equal(209, *(scan + 48432)); - Assert.Equal(120, *(scan + 49441)); - Assert.Equal(71, *(scan + 50450)); - Assert.Equal(119, *(scan + 51459)); - Assert.Equal(240, *(scan + 52468)); - Assert.Equal(235, *(scan + 53477)); - Assert.Equal(209, *(scan + 54486)); - Assert.Equal(70, *(scan + 55495)); - Assert.Equal(71, *(scan + 56504)); - Assert.Equal(67, *(scan + 57513)); - Assert.Equal(240, *(scan + 58522)); - Assert.Equal(167, *(scan + 59531)); - Assert.Equal(67, *(scan + 60540)); - Assert.Equal(70, *(scan + 61549)); - Assert.Equal(71, *(scan + 62558)); - Assert.Equal(67, *(scan + 63567)); - Assert.Equal(240, *(scan + 64576)); - Assert.Equal(120, *(scan + 65585)); - Assert.Equal(182, *(scan + 66594)); - Assert.Equal(70, *(scan + 67603)); - Assert.Equal(120, *(scan + 68612)); - Assert.Equal(67, *(scan + 69621)); - Assert.Equal(70, *(scan + 70630)); - Assert.Equal(71, *(scan + 71639)); - Assert.Equal(90, *(scan + 72648)); - Assert.Equal(240, *(scan + 73657)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - private void Save(PixelFormat original, PixelFormat expected, bool colorCheck) - { - string sOutFile = $"linerect-{expected}.png"; - - // Save - Bitmap bmp = new Bitmap(100, 100, original); - Graphics gr = Graphics.FromImage(bmp); - - using (Pen p = new Pen(Color.BlueViolet, 2)) - { - gr.DrawLine(p, 10.0F, 10.0F, 90.0F, 90.0F); - gr.DrawRectangle(p, 10.0F, 10.0F, 80.0F, 80.0F); - } - - try - { - bmp.Save(sOutFile, ImageFormat.Png); - - // Load - using (Bitmap bmpLoad = new Bitmap(sOutFile)) - { - Assert.Equal(expected, bmpLoad.PixelFormat); - if (colorCheck) - { - Color color = bmpLoad.GetPixel(10, 10); - Assert.Equal(Color.FromArgb(255, 138, 43, 226), color); - } - } - } - finally - { - gr.Dispose(); - bmp.Dispose(); - try - { - File.Delete(sOutFile); - } - catch - { - } - } - } - - [Fact] - public void Save_24bppRgb() - { - Save(PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb, true); - } - - [Fact] - public void Save_32bppRgb() - { - Save(PixelFormat.Format32bppRgb, PixelFormat.Format32bppArgb, true); - } - - [Fact] - public void Save_32bppArgb() - { - Save(PixelFormat.Format32bppArgb, PixelFormat.Format32bppArgb, true); - } - - [Fact] - public void Save_32bppPArgb() - { - Save(PixelFormat.Format32bppPArgb, PixelFormat.Format32bppArgb, true); - } -} diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TiffCodecTests.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TiffCodecTests.cs deleted file mode 100644 index e0a06e8dcc5..00000000000 --- a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TiffCodecTests.cs +++ /dev/null @@ -1,309 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// TIFF Codec class testing unit -// -// Authors: -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sebastien Pouliot -// -// Copyright (C) 2006, 2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Drawing.Imaging; - -namespace MonoTests.System.Drawing.Imaging; - -public class TiffCodecTest -{ - /* Checks bitmap features on a known 32bbp bitmap */ - [Fact] - public void Bitmap32bitsFeatures() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver32bits.tif"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - GraphicsUnit unit = GraphicsUnit.World; - RectangleF rect = bmp.GetBounds(ref unit); - // MS reports 24 bpp while we report 32 bpp - // Assert.Equal (PixelFormat.Format24bppRgb, bmp.PixelFormat); - Assert.Equal(173, bmp.Width); - Assert.Equal(183, bmp.Height); - - Assert.Equal(0, rect.X); - Assert.Equal(0, rect.Y); - Assert.Equal(173, rect.Width); - Assert.Equal(183, rect.Height); - - Assert.Equal(173, bmp.Size.Width); - Assert.Equal(183, bmp.Size.Height); - } - } - - /* Checks bitmap features on a known 32bbp bitmap */ - [Fact] - public void Bitmap32bitsPixelFormat() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver32bits.tif"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // GDI+ reports 24 bpp while libgdiplus reports 32 bpp - Assert.Equal (PixelFormat.Format24bppRgb, bmp.PixelFormat); - } - } - - [Fact] - public void Bitmap32bitsPixels() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver32bits.tif"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // sampling values from a well known bitmap - Assert.Equal(-1579559, bmp.GetPixel(0, 0).ToArgb()); - Assert.Equal(-1645353, bmp.GetPixel(0, 32).ToArgb()); - Assert.Equal(-461332, bmp.GetPixel(0, 64).ToArgb()); - Assert.Equal(-330005, bmp.GetPixel(0, 96).ToArgb()); - Assert.Equal(-2237489, bmp.GetPixel(0, 128).ToArgb()); - Assert.Equal(-1251105, bmp.GetPixel(0, 160).ToArgb()); - Assert.Equal(-3024947, bmp.GetPixel(32, 0).ToArgb()); - Assert.Equal(-2699070, bmp.GetPixel(32, 32).ToArgb()); - Assert.Equal(-2366734, bmp.GetPixel(32, 64).ToArgb()); - Assert.Equal(-4538413, bmp.GetPixel(32, 96).ToArgb()); - Assert.Equal(-6116681, bmp.GetPixel(32, 128).ToArgb()); - Assert.Equal(-7369076, bmp.GetPixel(32, 160).ToArgb()); - Assert.Equal(-13024729, bmp.GetPixel(64, 0).ToArgb()); - Assert.Equal(-7174020, bmp.GetPixel(64, 32).ToArgb()); - Assert.Equal(-51, bmp.GetPixel(64, 64).ToArgb()); - Assert.Equal(-16053503, bmp.GetPixel(64, 96).ToArgb()); - Assert.Equal(-8224431, bmp.GetPixel(64, 128).ToArgb()); - Assert.Equal(-16579326, bmp.GetPixel(64, 160).ToArgb()); - Assert.Equal(-2502457, bmp.GetPixel(96, 0).ToArgb()); - Assert.Equal(-9078395, bmp.GetPixel(96, 32).ToArgb()); - Assert.Equal(-12696508, bmp.GetPixel(96, 64).ToArgb()); - Assert.Equal(-70772, bmp.GetPixel(96, 96).ToArgb()); - Assert.Equal(-4346279, bmp.GetPixel(96, 128).ToArgb()); - Assert.Equal(-11583193, bmp.GetPixel(96, 160).ToArgb()); - Assert.Equal(-724763, bmp.GetPixel(128, 0).ToArgb()); - Assert.Equal(-7238268, bmp.GetPixel(128, 32).ToArgb()); - Assert.Equal(-2169612, bmp.GetPixel(128, 64).ToArgb()); - Assert.Equal(-3683883, bmp.GetPixel(128, 96).ToArgb()); - Assert.Equal(-12892867, bmp.GetPixel(128, 128).ToArgb()); - Assert.Equal(-3750464, bmp.GetPixel(128, 160).ToArgb()); - Assert.Equal(-3222844, bmp.GetPixel(160, 0).ToArgb()); - Assert.Equal(-65806, bmp.GetPixel(160, 32).ToArgb()); - Assert.Equal(-2961726, bmp.GetPixel(160, 64).ToArgb()); - Assert.Equal(-2435382, bmp.GetPixel(160, 96).ToArgb()); - Assert.Equal(-2501944, bmp.GetPixel(160, 128).ToArgb()); - Assert.Equal(-9211799, bmp.GetPixel(160, 160).ToArgb()); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void Bitmap32bitsData() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver32bits.tif"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(bmp.Height, data.Height); - Assert.Equal(bmp.Width, data.Width); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.Equal(520, data.Stride); - Assert.Equal(183, data.Height); - - unsafe - { - byte* scan = (byte*)data.Scan0; - // sampling values from a well known bitmap - Assert.Equal(217, *(scan + 0)); - Assert.Equal(192, *(scan + 1009)); - Assert.Equal(210, *(scan + 2018)); - Assert.Equal(196, *(scan + 3027)); - Assert.Equal(216, *(scan + 4036)); - Assert.Equal(215, *(scan + 5045)); - Assert.Equal(218, *(scan + 6054)); - Assert.Equal(218, *(scan + 7063)); - Assert.Equal(95, *(scan + 8072)); - Assert.Equal(9, *(scan + 9081)); - Assert.Equal(247, *(scan + 10090)); - Assert.Equal(161, *(scan + 11099)); - Assert.Equal(130, *(scan + 12108)); - Assert.Equal(131, *(scan + 13117)); - Assert.Equal(175, *(scan + 14126)); - Assert.Equal(217, *(scan + 15135)); - Assert.Equal(201, *(scan + 16144)); - Assert.Equal(183, *(scan + 17153)); - Assert.Equal(236, *(scan + 18162)); - Assert.Equal(242, *(scan + 19171)); - Assert.Equal(125, *(scan + 20180)); - Assert.Equal(193, *(scan + 21189)); - Assert.Equal(227, *(scan + 22198)); - Assert.Equal(44, *(scan + 23207)); - Assert.Equal(230, *(scan + 24216)); - Assert.Equal(224, *(scan + 25225)); - Assert.Equal(164, *(scan + 26234)); - Assert.Equal(43, *(scan + 27243)); - Assert.Equal(200, *(scan + 28252)); - Assert.Equal(255, *(scan + 29261)); - Assert.Equal(226, *(scan + 30270)); - Assert.Equal(230, *(scan + 31279)); - Assert.Equal(178, *(scan + 32288)); - Assert.Equal(224, *(scan + 33297)); - Assert.Equal(233, *(scan + 34306)); - Assert.Equal(212, *(scan + 35315)); - Assert.Equal(153, *(scan + 36324)); - Assert.Equal(143, *(scan + 37333)); - Assert.Equal(215, *(scan + 38342)); - Assert.Equal(116, *(scan + 39351)); - Assert.Equal(26, *(scan + 40360)); - Assert.Equal(28, *(scan + 41369)); - Assert.Equal(75, *(scan + 42378)); - Assert.Equal(50, *(scan + 43387)); - Assert.Equal(244, *(scan + 44396)); - Assert.Equal(191, *(scan + 45405)); - Assert.Equal(200, *(scan + 46414)); - Assert.Equal(197, *(scan + 47423)); - Assert.Equal(232, *(scan + 48432)); - Assert.Equal(186, *(scan + 49441)); - Assert.Equal(210, *(scan + 50450)); - Assert.Equal(215, *(scan + 51459)); - Assert.Equal(155, *(scan + 52468)); - Assert.Equal(56, *(scan + 53477)); - Assert.Equal(149, *(scan + 54486)); - Assert.Equal(137, *(scan + 55495)); - Assert.Equal(141, *(scan + 56504)); - Assert.Equal(36, *(scan + 57513)); - Assert.Equal(39, *(scan + 58522)); - Assert.Equal(25, *(scan + 59531)); - Assert.Equal(44, *(scan + 60540)); - Assert.Equal(12, *(scan + 61549)); - Assert.Equal(161, *(scan + 62558)); - Assert.Equal(179, *(scan + 63567)); - Assert.Equal(181, *(scan + 64576)); - Assert.Equal(165, *(scan + 65585)); - Assert.Equal(182, *(scan + 66594)); - Assert.Equal(186, *(scan + 67603)); - Assert.Equal(201, *(scan + 68612)); - Assert.Equal(49, *(scan + 69621)); - Assert.Equal(161, *(scan + 70630)); - Assert.Equal(140, *(scan + 71639)); - Assert.Equal(2, *(scan + 72648)); - Assert.Equal(15, *(scan + 73657)); - Assert.Equal(33, *(scan + 74666)); - Assert.Equal(17, *(scan + 75675)); - Assert.Equal(0, *(scan + 76684)); - Assert.Equal(47, *(scan + 77693)); - Assert.Equal(4, *(scan + 78702)); - Assert.Equal(142, *(scan + 79711)); - Assert.Equal(151, *(scan + 80720)); - Assert.Equal(124, *(scan + 81729)); - Assert.Equal(81, *(scan + 82738)); - Assert.Equal(214, *(scan + 83747)); - Assert.Equal(217, *(scan + 84756)); - Assert.Equal(30, *(scan + 85765)); - Assert.Equal(185, *(scan + 86774)); - Assert.Equal(200, *(scan + 87783)); - Assert.Equal(37, *(scan + 88792)); - Assert.Equal(2, *(scan + 89801)); - Assert.Equal(41, *(scan + 90810)); - Assert.Equal(16, *(scan + 91819)); - Assert.Equal(0, *(scan + 92828)); - Assert.Equal(146, *(scan + 93837)); - Assert.Equal(163, *(scan + 94846)); - } - } - finally - { - bmp.UnlockBits(data); - } - } - } - - private void Save(PixelFormat original, PixelFormat expected, bool colorCheck) - { - string sOutFile = $"linerect-{expected}.tif"; - - // Save - Bitmap bmp = new Bitmap(100, 100, original); - Graphics gr = Graphics.FromImage(bmp); - - using (Pen p = new Pen(Color.BlueViolet, 2)) - { - gr.DrawLine(p, 10.0F, 10.0F, 90.0F, 90.0F); - gr.DrawRectangle(p, 10.0F, 10.0F, 80.0F, 80.0F); - } - - try - { - bmp.Save(sOutFile, ImageFormat.Tiff); - - // Load - using (Bitmap bmpLoad = new Bitmap(sOutFile)) - { - Assert.Equal(expected, bmpLoad.PixelFormat); - if (colorCheck) - { - Color color = bmpLoad.GetPixel(10, 10); - Assert.Equal(Color.FromArgb(255, 138, 43, 226), color); - } - } - } - finally - { - gr.Dispose(); - bmp.Dispose(); - try - { - File.Delete(sOutFile); - } - catch - { - } - } - } - - [Fact] - public void Save_24bppRgb() - { - Save(PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb, true); - } - - [Fact] - public void Save_32bppRgb() - { - Save(PixelFormat.Format32bppRgb, PixelFormat.Format32bppArgb, true); - } - - [Fact] - public void Save_32bppArgb() - { - Save(PixelFormat.Format32bppArgb, PixelFormat.Format32bppArgb, true); - } - - [Fact] - public void Save_32bppPArgb() - { - Save(PixelFormat.Format32bppPArgb, PixelFormat.Format32bppArgb, true); - } -} diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs deleted file mode 100644 index 0680a98ce8e..00000000000 --- a/src/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs +++ /dev/null @@ -1,1407 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Bitmap class testing unit -// -// Authors: -// Jordi Mas i Hernandez (jordi@ximian.com) -// Jonathan Gilbert -// Sebastien Pouliot -// -// (C) 2004 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004,2006-2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Drawing.Imaging; -using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Text; -using System.Xml.Serialization; - -namespace MonoTests.System.Drawing; - -public class TestBitmap -{ - [Fact] - public void TestPixels() - { - // Tests GetSetPixel/SetPixel - Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb); - bmp.SetPixel(0, 0, Color.FromArgb(255, 128, 128, 128)); - Color color = bmp.GetPixel(0, 0); - - Assert.Equal(Color.FromArgb(255, 128, 128, 128), color); - - bmp.SetPixel(99, 99, Color.FromArgb(255, 255, 0, 155)); - Color color2 = bmp.GetPixel(99, 99); - Assert.Equal(Color.FromArgb(255, 255, 0, 155), color2); - } - - [Fact] - public void LockBits_IndexedWrite_NonIndexed() - { - using Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format8bppIndexed); - Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); - BitmapData bd = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - bmp.UnlockBits(bd); - } - - [Fact] - public void LockBits_NonIndexedWrite_ToIndexed() - { - using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb)) - { - BitmapData bd = new BitmapData(); - Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); - bd = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, bd); - - try - { - Assert.NotEqual(IntPtr.Zero, bd.Scan0); - } - finally - { - bmp.UnlockBits(bd); - } - } - } - - [Fact] - public void LockBits_ImageLockMode_Invalid() - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format24bppRgb)) - { - Rectangle r = new Rectangle(4, 4, 4, 4); - BitmapData data = bmp.LockBits(r, (ImageLockMode)0, PixelFormat.Format24bppRgb); - try - { - Assert.Equal(4, data.Height); - Assert.Equal(4, data.Width); - Assert.True(data.Stride >= 12); - Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat); - Assert.False(IntPtr.Zero.Equals(data.Scan0)); - } - finally - { - bmp.UnlockBits(data); - } - } - } - - [Fact] - public void LockBits_Double() - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format24bppRgb)) - { - Rectangle r = new Rectangle(4, 4, 4, 4); - BitmapData data = bmp.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - Assert.Throws(() => bmp.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb)); - } - finally - { - bmp.UnlockBits(data); - } - } - } - - [Fact] - public void Format1bppIndexed() - { - using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format1bppIndexed)) - { - Color c = bmp.GetPixel(0, 0); - Assert.Equal(-16777216, c.ToArgb()); - Assert.Throws(() => bmp.SetPixel(0, 0, c)); - } - } - - [Fact] - public void Format4bppIndexed() - { - using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format4bppIndexed)) - { - Color c = bmp.GetPixel(0, 0); - Assert.Equal(-16777216, c.ToArgb()); - Assert.Throws(() => bmp.SetPixel(0, 0, c)); - } - } - - [Fact] - public void Format8bppIndexed() - { - using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed)) - { - Color c = bmp.GetPixel(0, 0); - Assert.Equal(-16777216, c.ToArgb()); - Assert.Throws(() => bmp.SetPixel(0, 0, c)); - } - } - - private void FormatTest(PixelFormat format) - { - bool alpha = Image.IsAlphaPixelFormat(format); - int size = Image.GetPixelFormatSize(format) / 8 * 2; - using (Bitmap bmp = new Bitmap(2, 1, format)) - { - Color a = Color.FromArgb(128, 64, 32, 16); - Color b = Color.FromArgb(192, 96, 48, 24); - bmp.SetPixel(0, 0, a); - bmp.SetPixel(1, 0, b); - Color c = bmp.GetPixel(0, 0); - Color d = bmp.GetPixel(1, 0); - if (size == 4) - { - Assert.Equal(255, c.A); - Assert.Equal(66, c.R); - if (format == PixelFormat.Format16bppRgb565) - { - Assert.Equal(32, c.G); - } - else - { - Assert.Equal(33, c.G); - } - Assert.Equal(16, c.B); - - Assert.Equal(255, d.A); - Assert.Equal(99, d.R); - if (format == PixelFormat.Format16bppRgb565) - { - Assert.Equal(48, d.G); - } - else - { - Assert.Equal(49, d.G); - } - Assert.Equal(24, d.B); - } - else if (alpha) - { - if (format == PixelFormat.Format32bppPArgb) - { - Assert.Equal(a.A, c.A); - // note sure why the -1 - Assert.Equal(a.R - 1, c.R); - Assert.Equal(a.G - 1, c.G); - Assert.Equal(a.B - 1, c.B); - - Assert.Equal(b.A, d.A); - // note sure why the -1 - Assert.Equal(b.R - 1, d.R); - Assert.Equal(b.G - 1, d.G); - Assert.Equal(b.B - 1, d.B); - } - else - { - Assert.Equal(a, c); - Assert.Equal(b, d); - } - } - else - { - Assert.Equal(Color.FromArgb(255, 64, 32, 16), c); - Assert.Equal(Color.FromArgb(255, 96, 48, 24), d); - } - BitmapData bd = bmp.LockBits(new Rectangle(0, 0, 2, 1), ImageLockMode.ReadOnly, format); - try - { - byte[] data = new byte[size]; - Marshal.Copy(bd.Scan0, data, 0, size); - if (format == PixelFormat.Format32bppPArgb) - { - Assert.Equal(Math.Ceiling((float)c.B * c.A / 255), data[0]); - Assert.Equal(Math.Ceiling((float)c.G * c.A / 255), data[1]); - Assert.Equal(Math.Ceiling((float)c.R * c.A / 255), data[2]); - Assert.Equal(c.A, data[3]); - Assert.Equal(Math.Ceiling((float)d.B * d.A / 255), data[4]); - Assert.Equal(Math.Ceiling((float)d.G * d.A / 255), data[5]); - Assert.Equal(Math.Ceiling((float)d.R * d.A / 255), data[6]); - Assert.Equal(d.A, data[7]); - } - else if (size == 4) - { - int n = 0; - switch (format) - { - case PixelFormat.Format16bppRgb565: - Assert.Equal(2, data[n++]); - Assert.Equal(65, data[n++]); - Assert.Equal(131, data[n++]); - Assert.Equal(97, data[n++]); - break; - case PixelFormat.Format16bppArgb1555: - Assert.Equal(130, data[n++]); - Assert.Equal(160, data[n++]); - Assert.Equal(195, data[n++]); - Assert.Equal(176, data[n++]); - break; - case PixelFormat.Format16bppRgb555: - Assert.Equal(130, data[n++]); - Assert.Equal(32, data[n++]); - Assert.Equal(195, data[n++]); - Assert.Equal(48, data[n++]); - break; - } - } - else - { - int n = 0; - Assert.Equal(c.B, data[n++]); - Assert.Equal(c.G, data[n++]); - Assert.Equal(c.R, data[n++]); - if (format != PixelFormat.Format32bppRgb) - { - if (size % 4 == 0) - Assert.Equal(c.A, data[n++]); - Assert.Equal(d.B, data[n++]); - Assert.Equal(d.G, data[n++]); - Assert.Equal(d.R, data[n++]); - if (size % 4 == 0) - Assert.Equal(d.A, data[n++]); - } - } - } - finally - { - bmp.UnlockBits(bd); - } - } - } - - [Fact] - public void Format32bppArgb() - { - FormatTest(PixelFormat.Format32bppArgb); - } - - [Fact] - public void Format32bppRgb() - { - FormatTest(PixelFormat.Format32bppRgb); - } - - [Fact] - public void Format24bppRgb() - { - FormatTest(PixelFormat.Format24bppRgb); - } - - /* Get the output directory depending on the runtime and location*/ - public static string getOutSubDir() - { - string sSub, sRslt; - - if (Environment.GetEnvironmentVariable("MSNet") == null) - sSub = "mono/"; - else - sSub = "MSNet/"; - - sRslt = Path.GetFullPath(sSub); - - if (!Directory.Exists(sRslt)) - { - sRslt = "Test/System.Drawing/" + sSub; - } - - if (sRslt.Length > 0) - { - if (sRslt[sRslt.Length - 1] != '\\' && sRslt[sRslt.Length - 1] != '/') - { - sRslt += "/"; - } - } - - return sRslt; - } - - [Fact] - public void Clone() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp"); - Rectangle rect = new Rectangle(0, 0, 50, 50); - using (Bitmap bmp = new Bitmap(sInFile)) - using (Bitmap bmpNew = bmp.Clone(rect, PixelFormat.Format32bppArgb)) - { - Color colororg0 = bmp.GetPixel(0, 0); - Color colororg50 = bmp.GetPixel(49, 49); - Color colornew0 = bmpNew.GetPixel(0, 0); - Color colornew50 = bmpNew.GetPixel(49, 49); - - Assert.Equal(colororg0, colornew0); - Assert.Equal(colororg50, colornew50); - } - } - - [Fact] - public void CloneImage() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - using (Bitmap bmpNew = (Bitmap)bmp.Clone()) - { - Assert.Equal(bmp.Width, bmpNew.Width); - Assert.Equal(bmp.Height, bmpNew.Height); - Assert.Equal(bmp.PixelFormat, bmpNew.PixelFormat); - } - } - - [Fact] - public void Frames() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - int cnt = bmp.GetFrameCount(FrameDimension.Page); - int active = bmp.SelectActiveFrame(FrameDimension.Page, 0); - - Assert.Equal(1, cnt); - Assert.Equal(0, active); - } - } - - [Fact] - public void FileDoesNotExists() - { - Assert.Throws(() => new Bitmap("FileDoesNotExists.jpg")); - } - - static string ByteArrayToString(byte[] arrInput) - { - StringBuilder sOutput = new StringBuilder(arrInput.Length); - for (int i = 0; i < arrInput.Length; i++) - { - sOutput.Append(arrInput[i].ToString("X2")); - } - return sOutput.ToString(); - } - - - public string RotateBmp(Bitmap src, RotateFlipType rotate) - { - int width = 150, height = 150, index = 0; - byte[] pixels = new byte[width * height * 3]; - byte[] hash; - Color clr; - - using (Bitmap bmp_rotate = src.Clone(new RectangleF(0, 0, width, height), PixelFormat.Format32bppArgb)) - { - bmp_rotate.RotateFlip(rotate); - - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - clr = bmp_rotate.GetPixel(x, y); - pixels[index++] = clr.R; - pixels[index++] = clr.G; - pixels[index++] = clr.B; - } - } - - hash = MD5.Create().ComputeHash(pixels); - return ByteArrayToString(hash); - } - } - public string RotateIndexedBmp(Bitmap src, RotateFlipType type) - { - int pixels_per_byte; - - switch (src.PixelFormat) - { - case PixelFormat.Format1bppIndexed: - pixels_per_byte = 8; - break; - case PixelFormat.Format4bppIndexed: - pixels_per_byte = 2; - break; - case PixelFormat.Format8bppIndexed: - pixels_per_byte = 1; - break; - - default: - throw new Exception($"Cannot pass a bitmap of format {src.PixelFormat} to RotateIndexedBmp"); - } - - using (Bitmap test = src.Clone() as Bitmap) - { - test.RotateFlip(type); - - BitmapData data = null; - byte[] pixel_data; - - try - { - data = test.LockBits(new Rectangle(0, 0, test.Width, test.Height), ImageLockMode.ReadOnly, test.PixelFormat); - - int scan_size = (data.Width + pixels_per_byte - 1) / pixels_per_byte; - pixel_data = new byte[data.Height * scan_size]; - - for (int y = 0; y < data.Height; y++) - { - IntPtr src_ptr = (IntPtr)(y * data.Stride + data.Scan0.ToInt64()); - int dest_offset = y * scan_size; - for (int x = 0; x < scan_size; x++) - pixel_data[dest_offset + x] = Marshal.ReadByte(src_ptr, x); - } - } - finally - { - if (test != null && data != null) - { - try - { test.UnlockBits(data); } - catch { } - } - } - - if (pixel_data == null) - return "--ERROR--"; - - byte[] hash = MD5.Create().ComputeHash(pixel_data); - return ByteArrayToString(hash); - } - } - - - // Rotate bitmap in diffent ways, and check the result - // pixels using MD5 - [Fact] - public void Rotate() - { - string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - Assert.Equal("312958A3C67402E1299413794988A3C7", RotateBmp(bmp, RotateFlipType.Rotate90FlipNone)); - Assert.Equal("BF70D8DA4F1545AEDD77D0296B47AE58", RotateBmp(bmp, RotateFlipType.Rotate180FlipNone)); - Assert.Equal("15AD2ADBDC7090C0EC744D0F7ACE2FD4", RotateBmp(bmp, RotateFlipType.Rotate270FlipNone)); - Assert.Equal("2E10FEC1F4FD64ECC51D7CE68AEB183F", RotateBmp(bmp, RotateFlipType.RotateNoneFlipX)); - Assert.Equal("E63204779B566ED01162B90B49BD9EE9", RotateBmp(bmp, RotateFlipType.Rotate90FlipX)); - Assert.Equal("B1ECB17B5093E13D04FF55CFCF7763C9", RotateBmp(bmp, RotateFlipType.Rotate180FlipX)); - Assert.Equal("71A173882C16755D86F4BC2653237425", RotateBmp(bmp, RotateFlipType.Rotate270FlipX)); - } - } - - private Bitmap CreateBitmap(int width, int height, PixelFormat fmt) - { - Bitmap bmp = new Bitmap(width, height, fmt); - using (Graphics gr = Graphics.FromImage(bmp)) - { - Color c = Color.FromArgb(255, 100, 200, 250); - for (int x = 1; x < 80; x++) - { - bmp.SetPixel(x, 1, c); - bmp.SetPixel(x, 2, c); - bmp.SetPixel(x, 78, c); - bmp.SetPixel(x, 79, c); - } - for (int y = 3; y < 78; y++) - { - bmp.SetPixel(1, y, c); - bmp.SetPixel(2, y, c); - bmp.SetPixel(78, y, c); - bmp.SetPixel(79, y, c); - } - } - return bmp; - } - - private byte[] HashPixels(Bitmap bmp) - { - int len = bmp.Width * bmp.Height * 4; - int index = 0; - byte[] pixels = new byte[len]; - - for (int y = 0; y < bmp.Height; y++) - { - for (int x = 0; x < bmp.Width; x++) - { - Color clr = bmp.GetPixel(x, y); - pixels[index++] = clr.R; - pixels[index++] = clr.G; - pixels[index++] = clr.B; - } - } - return MD5.Create().ComputeHash(pixels); - } - - private byte[] HashLock(Bitmap bmp, int width, int height, PixelFormat fmt, ImageLockMode mode) - { - int len = bmp.Width * bmp.Height * 4; - byte[] pixels = new byte[len]; - BitmapData bd = bmp.LockBits(new Rectangle(0, 0, width, height), mode, fmt); - try - { - int index = 0; - int bbps = Image.GetPixelFormatSize(fmt); - long pos = bd.Scan0.ToInt64(); - byte[] btv = new byte[1]; - for (int y = 0; y < bd.Height; y++) - { - for (int x = 0; x < bd.Width; x++) - { - /* Read the pixels*/ - for (int bt = 0; bt < bbps / 8; bt++, index++) - { - long cur = pos; - cur += y * bd.Stride; - cur += x * bbps / 8; - cur += bt; - Marshal.Copy((IntPtr)cur, btv, 0, 1); - pixels[index] = btv[0]; - - /* Make change of all the colours = 250 to 10*/ - if (btv[0] == 250) - { - btv[0] = 10; - Marshal.Copy(btv, 0, (IntPtr)cur, 1); - } - } - } - } - - for (int i = index; i < len; i++) - pixels[index] = 0; - } - finally - { - bmp.UnlockBits(bd); - } - return MD5.Create().ComputeHash(pixels); - } - - // Tests the LockBitmap functions. Makes a hash of the block of pixels that it returns - // firsts, changes them, and then using GetPixel does another check of the changes. - // The results match the .NET Framework - private static byte[] DefaultBitmapHash = new byte[] { 0xD8, 0xD3, 0x68, 0x9C, 0x86, 0x7F, 0xB6, 0xA0, 0x76, 0xD6, 0x00, 0xEF, 0xFF, 0xE5, 0x8E, 0x1B }; - private static byte[] FinalWholeBitmapHash = new byte[] { 0x5F, 0x52, 0x98, 0x37, 0xE3, 0x94, 0xE1, 0xA6, 0x06, 0x6C, 0x5B, 0xF1, 0xA9, 0xC2, 0xA9, 0x43 }; - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Whole() - { - using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb)) - { - Assert.Equal(DefaultBitmapHash, HashPixels(bmp)); - byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C }; - byte[] actual = HashLock(bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite); - Assert.Equal(expected, actual); - Assert.Equal(FinalWholeBitmapHash, HashPixels(bmp)); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Whole() - { - using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb)) - { - Assert.Equal(DefaultBitmapHash, HashPixels(bmp)); - byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C }; - byte[] actual = HashLock(bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite); - Assert.Equal(expected, actual); - Assert.Equal(FinalWholeBitmapHash, HashPixels(bmp)); - } - } - - [Fact] - public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Whole() - { - using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb)) - { - Assert.Equal(DefaultBitmapHash, HashPixels(bmp)); - byte[] expected = { 0x89, 0x6a, 0x6b, 0x35, 0x5c, 0x89, 0xd9, 0xe9, 0xf4, 0x51, 0xd5, 0x89, 0xed, 0x28, 0x68, 0x5c }; - byte[] actual = HashLock(bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite); - Assert.Equal(expected, actual); - Assert.Equal(FinalWholeBitmapHash, HashPixels(bmp)); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Whole() - { - using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb)) - { - Assert.Equal(DefaultBitmapHash, HashPixels(bmp)); - byte[] expected = { 0xA7, 0xB2, 0x50, 0x04, 0x11, 0x12, 0x64, 0x68, 0x6B, 0x7D, 0x2F, 0x6E, 0x69, 0x24, 0xCB, 0x14 }; - byte[] actual = HashLock(bmp, bmp.Width, bmp.Height, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite); - Assert.Equal(expected, actual); - Assert.Equal(FinalWholeBitmapHash, HashPixels(bmp)); - } - } - - private static byte[] FinalPartialBitmapHash = new byte[] { 0xED, 0xD8, 0xDC, 0x9B, 0x44, 0x00, 0x22, 0x9B, 0x07, 0x06, 0x4A, 0x21, 0x70, 0xA7, 0x31, 0x1D }; - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Partial() - { - using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb)) - { - Assert.Equal(DefaultBitmapHash, HashPixels(bmp)); - byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC }; - byte[] actual = HashLock(bmp, 50, 50, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite); - Assert.Equal(expected, actual); - Assert.Equal(FinalPartialBitmapHash, HashPixels(bmp)); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Partial() - { - using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb)) - { - Assert.Equal(DefaultBitmapHash, HashPixels(bmp)); - byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC }; - byte[] actual = HashLock(bmp, 50, 50, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite); - Assert.Equal(expected, actual); - Assert.Equal(FinalPartialBitmapHash, HashPixels(bmp)); - } - } - - [Fact] - public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Partial() - { - using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb)) - { - Assert.Equal(DefaultBitmapHash, HashPixels(bmp)); - byte[] expected = { 0x5d, 0xFF, 0x02, 0x34, 0xeb, 0x7c, 0xf7, 0x42, 0xd4, 0xb7, 0x70, 0x49, 0xb4, 0x06, 0x79, 0xbc }; - byte[] actual = HashLock(bmp, 50, 50, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite); - Assert.Equal(expected, actual); - Assert.Equal(FinalPartialBitmapHash, HashPixels(bmp)); - } - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Partial() - { - using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb)) - { - Assert.Equal(DefaultBitmapHash, HashPixels(bmp)); - byte[] expected = { 0x4D, 0x39, 0x21, 0x88, 0xC2, 0x17, 0x14, 0x5F, 0x89, 0x9E, 0x02, 0x75, 0xF3, 0x64, 0xD8, 0xF0 }; - byte[] actual = HashLock(bmp, 50, 50, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite); - Assert.Equal(expected, actual); - Assert.Equal(FinalPartialBitmapHash, HashPixels(bmp)); - } - } - - // Tests the LockBitmap and UnlockBitmap functions, specifically the copying - // of bitmap data in the directions indicated by the ImageLockMode. - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - public void LockUnlockBitmap() - { - BitmapData data; - int pixel_value; - Color pixel_colour; - - Color red = Color.FromArgb(Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B); - Color blue = Color.FromArgb(Color.Blue.A, Color.Blue.R, Color.Blue.G, Color.Blue.B); - - using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format32bppRgb)) - { - bmp.SetPixel(0, 0, red); - pixel_colour = bmp.GetPixel(0, 0); - Assert.Equal(red, pixel_colour); - - data = bmp.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); - try - { - pixel_value = Marshal.ReadByte(data.Scan0, 0); - pixel_value |= Marshal.ReadByte(data.Scan0, 1) << 8; - pixel_value |= Marshal.ReadByte(data.Scan0, 2) << 16; - pixel_value |= Marshal.ReadByte(data.Scan0, 3) << 24; - - pixel_colour = Color.FromArgb(pixel_value); - // Disregard alpha information in the test - pixel_colour = Color.FromArgb(red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); - Assert.Equal(red, pixel_colour); - - // write blue but we're locked in read-only... - Marshal.WriteByte(data.Scan0, 0, blue.B); - Marshal.WriteByte(data.Scan0, 1, blue.G); - Marshal.WriteByte(data.Scan0, 2, blue.R); - Marshal.WriteByte(data.Scan0, 3, blue.A); - } - finally - { - bmp.UnlockBits(data); - pixel_colour = bmp.GetPixel(0, 0); - // Disregard alpha information in the test - pixel_colour = Color.FromArgb(red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); - // ...so we still read red after unlocking - Assert.Equal(red, pixel_colour); - } - - data = bmp.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); - try - { - // write blue - Marshal.WriteByte(data.Scan0, 0, blue.B); - Marshal.WriteByte(data.Scan0, 1, blue.G); - Marshal.WriteByte(data.Scan0, 2, blue.R); - Marshal.WriteByte(data.Scan0, 3, blue.A); - } - finally - { - bmp.UnlockBits(data); - pixel_colour = bmp.GetPixel(0, 0); - // Disregard alpha information in the test - pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); - // read blue - Assert.Equal(blue, pixel_colour); - } - } - - using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format32bppArgb)) - { - bmp.SetPixel(0, 0, red); - - data = bmp.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - try - { - byte b = Marshal.ReadByte(data.Scan0, 0); - byte g = Marshal.ReadByte(data.Scan0, 1); - byte r = Marshal.ReadByte(data.Scan0, 2); - pixel_colour = Color.FromArgb(red.A, r, g, b); - Assert.Equal(red, pixel_colour); - // write blue but we're locked in read-only... - Marshal.WriteByte(data.Scan0, 0, blue.B); - Marshal.WriteByte(data.Scan0, 1, blue.G); - Marshal.WriteByte(data.Scan0, 2, blue.R); - } - finally - { - bmp.UnlockBits(data); - // ...so we still read red after unlocking - Assert.Equal(red, bmp.GetPixel(0, 0)); - } - - data = bmp.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - try - { - // write blue - Marshal.WriteByte(data.Scan0, 0, blue.B); - Marshal.WriteByte(data.Scan0, 1, blue.G); - Marshal.WriteByte(data.Scan0, 2, blue.R); - } - finally - { - bmp.UnlockBits(data); - // read blue - Assert.Equal(blue, bmp.GetPixel(0, 0)); - } - } - } - [Fact] - public void DefaultFormat1() - { - using (Bitmap bmp = new Bitmap(20, 20)) - { - Assert.Equal(ImageFormat.MemoryBmp, bmp.RawFormat); - } - } - - [Fact] - public void DefaultFormat2() - { - string filename = Path.GetTempFileName(); - using (Bitmap bmp = new Bitmap(20, 20)) - { - bmp.Save(filename); - } - - using (Bitmap other = new Bitmap(filename)) - { - Assert.Equal(ImageFormat.Png, other.RawFormat); - } - File.Delete(filename); - } - - [Fact] - public void BmpDataStride1() - { - Bitmap bmp = new Bitmap(184, 184, PixelFormat.Format1bppIndexed); - BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed); - try - { - Assert.Equal(24, data.Stride); - } - finally - { - bmp.UnlockBits(data); - bmp.Dispose(); - } - } - - static int[] palette1 = { - -16777216, - -1, - }; - - [Fact] - public void Format1bppIndexed_Palette() - { - using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format1bppIndexed)) - { - ColorPalette pal = bmp.Palette; - Assert.Equal(2, pal.Entries.Length); - for (int i = 0; i < pal.Entries.Length; i++) - { - Assert.Equal(palette1[i], pal.Entries[i].ToArgb()); - } - Assert.Equal(2, pal.Flags); - } - } - - static int[] palette16 = { - -16777216, - -8388608, - -16744448, - -8355840, - -16777088, - -8388480, - -16744320, - -8355712, - -4144960, - -65536, - -16711936, - -256, - -16776961, - -65281, - -16711681, - -1, - }; - - [Fact] - public void Format4bppIndexed_Palette() - { - using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format4bppIndexed)) - { - ColorPalette pal = bmp.Palette; - Assert.Equal(16, pal.Entries.Length); - for (int i = 0; i < pal.Entries.Length; i++) - { - Assert.Equal(palette16[i], pal.Entries[i].ToArgb()); - } - Assert.Equal(0, pal.Flags); - } - } - - static int[] palette256 = { - -16777216, - -8388608, - -16744448, - -8355840, - -16777088, - -8388480, - -16744320, - -8355712, - -4144960, - -65536, - -16711936, - -256, - -16776961, - -65281, - -16711681, - -1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - -16777216, - -16777165, - -16777114, - -16777063, - -16777012, - -16776961, - -16764160, - -16764109, - -16764058, - -16764007, - -16763956, - -16763905, - -16751104, - -16751053, - -16751002, - -16750951, - -16750900, - -16750849, - -16738048, - -16737997, - -16737946, - -16737895, - -16737844, - -16737793, - -16724992, - -16724941, - -16724890, - -16724839, - -16724788, - -16724737, - -16711936, - -16711885, - -16711834, - -16711783, - -16711732, - -16711681, - -13434880, - -13434829, - -13434778, - -13434727, - -13434676, - -13434625, - -13421824, - -13421773, - -13421722, - -13421671, - -13421620, - -13421569, - -13408768, - -13408717, - -13408666, - -13408615, - -13408564, - -13408513, - -13395712, - -13395661, - -13395610, - -13395559, - -13395508, - -13395457, - -13382656, - -13382605, - -13382554, - -13382503, - -13382452, - -13382401, - -13369600, - -13369549, - -13369498, - -13369447, - -13369396, - -13369345, - -10092544, - -10092493, - -10092442, - -10092391, - -10092340, - -10092289, - -10079488, - -10079437, - -10079386, - -10079335, - -10079284, - -10079233, - -10066432, - -10066381, - -10066330, - -10066279, - -10066228, - -10066177, - -10053376, - -10053325, - -10053274, - -10053223, - -10053172, - -10053121, - -10040320, - -10040269, - -10040218, - -10040167, - -10040116, - -10040065, - -10027264, - -10027213, - -10027162, - -10027111, - -10027060, - -10027009, - -6750208, - -6750157, - -6750106, - -6750055, - -6750004, - -6749953, - -6737152, - -6737101, - -6737050, - -6736999, - -6736948, - -6736897, - -6724096, - -6724045, - -6723994, - -6723943, - -6723892, - -6723841, - -6711040, - -6710989, - -6710938, - -6710887, - -6710836, - -6710785, - -6697984, - -6697933, - -6697882, - -6697831, - -6697780, - -6697729, - -6684928, - -6684877, - -6684826, - -6684775, - -6684724, - -6684673, - -3407872, - -3407821, - -3407770, - -3407719, - -3407668, - -3407617, - -3394816, - -3394765, - -3394714, - -3394663, - -3394612, - -3394561, - -3381760, - -3381709, - -3381658, - -3381607, - -3381556, - -3381505, - -3368704, - -3368653, - -3368602, - -3368551, - -3368500, - -3368449, - -3355648, - -3355597, - -3355546, - -3355495, - -3355444, - -3355393, - -3342592, - -3342541, - -3342490, - -3342439, - -3342388, - -3342337, - -65536, - -65485, - -65434, - -65383, - -65332, - -65281, - -52480, - -52429, - -52378, - -52327, - -52276, - -52225, - -39424, - -39373, - -39322, - -39271, - -39220, - -39169, - -26368, - -26317, - -26266, - -26215, - -26164, - -26113, - -13312, - -13261, - -13210, - -13159, - -13108, - -13057, - -256, - -205, - -154, - -103, - -52, - -1, - }; - - [Fact] - public void Format8bppIndexed_Palette() - { - using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed)) - { - ColorPalette pal = bmp.Palette; - Assert.Equal(256, pal.Entries.Length); - for (int i = 0; i < pal.Entries.Length; i++) - { - Assert.Equal(palette256[i], pal.Entries[i].ToArgb()); - } - Assert.Equal(4, pal.Flags); - } - } - - [Fact] - public void XmlSerialization() - { - new XmlSerializer(typeof(Bitmap)); - } - - private void SetResolution(float x, float y) - { - using (Bitmap bmp = new Bitmap(1, 1)) - { - bmp.SetResolution(x, y); - } - } - - [Fact] - public void SetResolution_Zero() - { - Assert.Throws(() => SetResolution(0.0f, 0.0f)); - } - - [Fact] - public void SetResolution_Negative_X() - { - Assert.Throws(() => SetResolution(-1.0f, 1.0f)); - } - - [Fact] - public void SetResolution_Negative_Y() - { - Assert.Throws(() => SetResolution(1.0f, -1.0f)); - } - - [Fact] - public void SetResolution_MaxValue() - { - SetResolution(float.MaxValue, float.MaxValue); - } - - [Fact] - public void SetResolution_PositiveInfinity() - { - SetResolution(float.PositiveInfinity, float.PositiveInfinity); - } - - [Fact] - public void SetResolution_NaN() - { - Assert.Throws(() => SetResolution(float.NaN, float.NaN)); - } - - [Fact] - public void SetResolution_NegativeInfinity() - { - Assert.Throws(() => SetResolution(float.NegativeInfinity, float.NegativeInfinity)); - } -} - -public class BitmapFullTrustTest -{ - [Fact] - public void BitmapIntIntIntPixelFormatIntPtrCtor() - { - new Bitmap(1, 1, 1, PixelFormat.Format1bppIndexed, IntPtr.Zero); - } - - // BitmapFromHicon## is *almost* the same as IconTest.Icon##ToBitmap except - // for the Flags property - - private void HiconTest(string msg, Bitmap b, int size) - { - Assert.Equal(PixelFormat.Format32bppArgb, b.PixelFormat); - // unlike the GDI+ icon decoder the palette isn't kept - Assert.Equal(0, b.Palette.Entries.Length); - Assert.Equal(size, b.Height); - Assert.Equal(size, b.Width); - Assert.Equal(b.RawFormat, ImageFormat.MemoryBmp); - Assert.Equal(335888, b.Flags); - } - - [Fact] - public void Hicon16() - { - IntPtr hicon; - int size; - using (Icon icon = new Icon(Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"))) - { - size = icon.Width; - using (Bitmap bitmap = Bitmap.FromHicon(icon.Handle)) - { - HiconTest("Icon.Handle/FromHicon", bitmap, size); - hicon = bitmap.GetHicon(); - } - } - using (Bitmap bitmap2 = Bitmap.FromHicon(hicon)) - { - // hicon survives bitmap and icon disposal - HiconTest("GetHicon/FromHicon", bitmap2, size); - } - } - - [Fact] - public void Hicon32() - { - IntPtr hicon; - int size; - using (Icon icon = new Icon(Helpers.GetTestBitmapPath("32x32_one_entry_4bit.ico"))) - { - size = icon.Width; - using (Bitmap bitmap = Bitmap.FromHicon(icon.Handle)) - { - HiconTest("Icon.Handle/FromHicon", bitmap, size); - hicon = bitmap.GetHicon(); - } - } - using (Bitmap bitmap2 = Bitmap.FromHicon(hicon)) - { - // hicon survives bitmap and icon disposal - HiconTest("GetHicon/FromHicon", bitmap2, size); - } - } - - [Fact] - public void Hicon64() - { - IntPtr hicon; - int size; - using (Icon icon = new Icon(Helpers.GetTestBitmapPath("64x64_one_entry_8bit.ico"))) - { - size = icon.Width; - using (Bitmap bitmap = Bitmap.FromHicon(icon.Handle)) - { - HiconTest("Icon.Handle/FromHicon", bitmap, size); - hicon = bitmap.GetHicon(); - } - } - using (Bitmap bitmap2 = Bitmap.FromHicon(hicon)) - { - // hicon survives bitmap and icon disposal - HiconTest("GetHicon/FromHicon", bitmap2, size); - } - } - - [Fact] - public void Hicon96() - { - IntPtr hicon; - int size; - using (Icon icon = new Icon(Helpers.GetTestBitmapPath("96x96_one_entry_8bit.ico"))) - { - size = icon.Width; - using (Bitmap bitmap = Bitmap.FromHicon(icon.Handle)) - { - HiconTest("Icon.Handle/FromHicon", bitmap, size); - hicon = bitmap.GetHicon(); - } - } - using (Bitmap bitmap2 = Bitmap.FromHicon(hicon)) - { - // hicon survives bitmap and icon disposal - HiconTest("GetHicon/FromHicon", bitmap2, size); - } - } - - [Fact] - public void HBitmap() - { - IntPtr hbitmap; - string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp"); - using (Bitmap bitmap = new Bitmap(sInFile)) - { - Assert.Equal(PixelFormat.Format24bppRgb, bitmap.PixelFormat); - Assert.Equal(0, bitmap.Palette.Entries.Length); - Assert.Equal(183, bitmap.Height); - Assert.Equal(173, bitmap.Width); - Assert.Equal(73744, bitmap.Flags); - Assert.Equal(bitmap.RawFormat, ImageFormat.Bmp); - hbitmap = bitmap.GetHbitmap(); - } - - // hbitmap survives original bitmap disposal - using (Image image = Image.FromHbitmap(hbitmap)) - { - //Assert.Equal (PixelFormat.Format32bppRgb, image.PixelFormat); - Assert.Equal(0, image.Palette.Entries.Length); - Assert.Equal(183, image.Height); - Assert.Equal(173, image.Width); - Assert.Equal(335888, image.Flags); - Assert.Equal(image.RawFormat, ImageFormat.MemoryBmp); - } - } - - [Fact] - public void CreateMultipleBitmapFromSameHBITMAP() - { - IntPtr hbitmap; - string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp"); - using (Bitmap bitmap = new Bitmap(sInFile)) - { - Assert.Equal(PixelFormat.Format24bppRgb, bitmap.PixelFormat); - Assert.Equal(0, bitmap.Palette.Entries.Length); - Assert.Equal(183, bitmap.Height); - Assert.Equal(173, bitmap.Width); - Assert.Equal(73744, bitmap.Flags); - Assert.Equal(bitmap.RawFormat, ImageFormat.Bmp); - hbitmap = bitmap.GetHbitmap(); - } - // hbitmap survives original bitmap disposal - using (Image image = Image.FromHbitmap(hbitmap)) - { - //Assert.Equal (PixelFormat.Format32bppRgb, image.PixelFormat); - Assert.Equal(0, image.Palette.Entries.Length); - Assert.Equal(183, image.Height); - Assert.Equal(173, image.Width); - Assert.Equal(335888, image.Flags); - Assert.Equal(image.RawFormat, ImageFormat.MemoryBmp); - } - using (Image image2 = Image.FromHbitmap(hbitmap)) - { - //Assert.Equal (PixelFormat.Format32bppRgb, image2.PixelFormat); - Assert.Equal(0, image2.Palette.Entries.Length); - Assert.Equal(183, image2.Height); - Assert.Equal(173, image2.Width); - Assert.Equal(335888, image2.Flags); - Assert.Equal(image2.RawFormat, ImageFormat.MemoryBmp); - } - } -} diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs deleted file mode 100644 index 286fa8d2259..00000000000 --- a/src/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs +++ /dev/null @@ -1,3319 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Graphics class testing unit -// -// Authors: -// Jordi Mas, jordi@ximian.com -// Sebastien Pouliot -// -// Copyright (C) 2005-2008 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.Drawing.Text; -using Microsoft.DotNet.XUnitExtensions; - -namespace MonoTests.System.Drawing; - -[ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported))] -public class GraphicsTest : IDisposable -{ - private RectangleF[] rects; - private Font font; - - public GraphicsTest() - { - try - { - font = new Font("Arial", 12); - } - catch - { - } - } - - public void Dispose() - { - if (font != null) - font.Dispose(); - } - - private bool IsEmptyBitmap(Bitmap bitmap, out int x, out int y) - { - bool result = true; - int empty = Color.Empty.ToArgb(); - for (y = 0; y < bitmap.Height; y++) - { - for (x = 0; x < bitmap.Width; x++) - { - if (bitmap.GetPixel(x, y).ToArgb() != empty) - return false; - } - } - - x = -1; - y = -1; - return result; - } - - private void CheckForEmptyBitmap(Bitmap bitmap) - { - int x, y; - if (!IsEmptyBitmap(bitmap, out x, out y)) - Assert.True(false, $"Position {x},{y}"); - } - - private void CheckForNonEmptyBitmap(Bitmap bitmap) - { - int x, y; - if (IsEmptyBitmap(bitmap, out x, out y)) - Assert.True(false); - } - - private void AssertEquals(string msg, object expected, object actual) - { - Assert.Equal(expected, actual); - } - - private void AssertEquals(string msg, double expected, double actual, int precision) - { - Assert.Equal(expected, actual, precision); - } - - [Fact] - public void DefaultProperties() - { - using (Bitmap bmp = new Bitmap(200, 200)) - using (Graphics g = Graphics.FromImage(bmp)) - using (Region r = new Region()) - { - Assert.Equal(r.GetBounds(g), g.ClipBounds); - Assert.Equal(CompositingMode.SourceOver, g.CompositingMode); - Assert.Equal(CompositingQuality.Default, g.CompositingQuality); - Assert.Equal(InterpolationMode.Bilinear, g.InterpolationMode); - Assert.Equal(1, g.PageScale); - Assert.Equal(GraphicsUnit.Display, g.PageUnit); - Assert.Equal(PixelOffsetMode.Default, g.PixelOffsetMode); - Assert.Equal(new Point(0, 0), g.RenderingOrigin); - Assert.Equal(SmoothingMode.None, g.SmoothingMode); - Assert.Equal(TextRenderingHint.SystemDefault, g.TextRenderingHint); - } - } - - [Fact] - public void SetGetProperties() - { - using (Bitmap bmp = new Bitmap(200, 200)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.CompositingMode = CompositingMode.SourceCopy; - g.CompositingQuality = CompositingQuality.GammaCorrected; - g.InterpolationMode = InterpolationMode.HighQualityBilinear; - g.PageScale = 2; - g.PageUnit = GraphicsUnit.Inch; - g.PixelOffsetMode = PixelOffsetMode.Half; - g.RenderingOrigin = new Point(10, 20); - g.SmoothingMode = SmoothingMode.AntiAlias; - g.TextRenderingHint = TextRenderingHint.SystemDefault; - - //Clipping set/get tested in clipping functions - Assert.Equal(CompositingMode.SourceCopy, g.CompositingMode); - Assert.Equal(CompositingQuality.GammaCorrected, g.CompositingQuality); - Assert.Equal(InterpolationMode.HighQualityBilinear, g.InterpolationMode); - Assert.Equal(2, g.PageScale); - Assert.Equal(GraphicsUnit.Inch, g.PageUnit); - Assert.Equal(PixelOffsetMode.Half, g.PixelOffsetMode); - Assert.Equal(new Point(10, 20), g.RenderingOrigin); - Assert.Equal(SmoothingMode.AntiAlias, g.SmoothingMode); - Assert.Equal(TextRenderingHint.SystemDefault, g.TextRenderingHint); - } - } - - // Properties - [Fact] - public void Clip() - { - RectangleF[] rects; - using (Bitmap bmp = new Bitmap(200, 200)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.Clip = new Region(new Rectangle(50, 40, 210, 220)); - rects = g.Clip.GetRegionScans(new Matrix()); - - Assert.Equal(1, rects.Length); - Assert.Equal(50, rects[0].X); - Assert.Equal(40, rects[0].Y); - Assert.Equal(210, rects[0].Width); - Assert.Equal(220, rects[0].Height); - } - } - - [Fact] - public void Clip_NotAReference() - { - using (Bitmap bmp = new Bitmap(200, 200)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.True(g.Clip.IsInfinite(g)); - g.Clip.IsEmpty(g); - Assert.False(g.Clip.IsEmpty(g)); - Assert.True(g.Clip.IsInfinite(g)); - } - } - - [Fact] - public void ExcludeClip() - { - using (Bitmap bmp = new Bitmap(200, 200)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.Clip = new Region(new RectangleF(10, 10, 100, 100)); - g.ExcludeClip(new Rectangle(40, 60, 100, 20)); - rects = g.Clip.GetRegionScans(new Matrix()); - - Assert.Equal(3, rects.Length); - - Assert.Equal(10, rects[0].X); - Assert.Equal(10, rects[0].Y); - Assert.Equal(100, rects[0].Width); - Assert.Equal(50, rects[0].Height); - - Assert.Equal(10, rects[1].X); - Assert.Equal(60, rects[1].Y); - Assert.Equal(30, rects[1].Width); - Assert.Equal(20, rects[1].Height); - - Assert.Equal(10, rects[2].X); - Assert.Equal(80, rects[2].Y); - Assert.Equal(100, rects[2].Width); - Assert.Equal(30, rects[2].Height); - } - } - - [Fact] - public void IntersectClip() - { - using (Bitmap bmp = new Bitmap(200, 200)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.Clip = new Region(new RectangleF(260, 30, 60, 80)); - g.IntersectClip(new Rectangle(290, 40, 60, 80)); - rects = g.Clip.GetRegionScans(new Matrix()); - - Assert.Equal(1, rects.Length); - - Assert.Equal(290, rects[0].X); - Assert.Equal(40, rects[0].Y); - Assert.Equal(30, rects[0].Width); - Assert.Equal(70, rects[0].Height); - } - } - - [Fact] - public void ResetClip() - { - using (Bitmap bmp = new Bitmap(200, 200)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.Clip = new Region(new RectangleF(260, 30, 60, 80)); - g.IntersectClip(new Rectangle(290, 40, 60, 80)); - g.ResetClip(); - rects = g.Clip.GetRegionScans(new Matrix()); - - Assert.Equal(1, rects.Length); - - Assert.Equal(-4194304, rects[0].X); - Assert.Equal(-4194304, rects[0].Y); - Assert.Equal(8388608, rects[0].Width); - Assert.Equal(8388608, rects[0].Height); - } - } - - [Fact] - public void SetClip() - { - RectangleF[] rects; - using (Bitmap bmp = new Bitmap(200, 200)) - { - using (Graphics g = Graphics.FromImage(bmp)) - { - // Region - g.SetClip(new Region(new Rectangle(50, 40, 210, 220)), CombineMode.Replace); - rects = g.Clip.GetRegionScans(new Matrix()); - Assert.Equal(1, rects.Length); - Assert.Equal(50, rects[0].X); - Assert.Equal(40, rects[0].Y); - Assert.Equal(210, rects[0].Width); - Assert.Equal(220, rects[0].Height); - } - - // RectangleF - using (Graphics g = Graphics.FromImage(bmp)) - { - g.SetClip(new RectangleF(50, 40, 210, 220)); - rects = g.Clip.GetRegionScans(new Matrix()); - Assert.Equal(1, rects.Length); - Assert.Equal(50, rects[0].X); - Assert.Equal(40, rects[0].Y); - Assert.Equal(210, rects[0].Width); - Assert.Equal(220, rects[0].Height); - } - - // Rectangle - using (Graphics g = Graphics.FromImage(bmp)) - { - g.SetClip(new Rectangle(50, 40, 210, 220)); - rects = g.Clip.GetRegionScans(new Matrix()); - Assert.Equal(1, rects.Length); - Assert.Equal(50, rects[0].X); - Assert.Equal(40, rects[0].Y); - Assert.Equal(210, rects[0].Width); - Assert.Equal(220, rects[0].Height); - } - } - } - - [Fact] - public void SetSaveReset() - { - using (Bitmap bmp = new Bitmap(200, 200)) - using (Graphics g = Graphics.FromImage(bmp)) - { - GraphicsState state_default, state_modified; - - state_default = g.Save(); // Default - - g.CompositingMode = CompositingMode.SourceCopy; - g.CompositingQuality = CompositingQuality.GammaCorrected; - g.InterpolationMode = InterpolationMode.HighQualityBilinear; - g.PageScale = 2; - g.PageUnit = GraphicsUnit.Inch; - g.PixelOffsetMode = PixelOffsetMode.Half; - g.Clip = new Region(new Rectangle(0, 0, 100, 100)); - g.RenderingOrigin = new Point(10, 20); - g.SmoothingMode = SmoothingMode.AntiAlias; - g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; - - - state_modified = g.Save(); // Modified - - g.CompositingMode = CompositingMode.SourceOver; - g.CompositingQuality = CompositingQuality.Default; - g.InterpolationMode = InterpolationMode.Bilinear; - g.PageScale = 5; - g.PageUnit = GraphicsUnit.Display; - g.PixelOffsetMode = PixelOffsetMode.Default; - g.Clip = new Region(new Rectangle(1, 2, 20, 25)); - g.RenderingOrigin = new Point(5, 6); - g.SmoothingMode = SmoothingMode.None; - g.TextRenderingHint = TextRenderingHint.SystemDefault; - - g.Restore(state_modified); - - Assert.Equal(CompositingMode.SourceCopy, g.CompositingMode); - Assert.Equal(CompositingQuality.GammaCorrected, g.CompositingQuality); - Assert.Equal(InterpolationMode.HighQualityBilinear, g.InterpolationMode); - Assert.Equal(2, g.PageScale); - Assert.Equal(GraphicsUnit.Inch, g.PageUnit); - Assert.Equal(PixelOffsetMode.Half, g.PixelOffsetMode); - Assert.Equal(new Point(10, 20), g.RenderingOrigin); - Assert.Equal(SmoothingMode.AntiAlias, g.SmoothingMode); - Assert.Equal(TextRenderingHint.ClearTypeGridFit, g.TextRenderingHint); - Assert.Equal(0, (int)g.ClipBounds.X); - Assert.Equal(0, (int)g.ClipBounds.Y); - - g.Restore(state_default); - - Assert.Equal(CompositingMode.SourceOver, g.CompositingMode); - Assert.Equal(CompositingQuality.Default, g.CompositingQuality); - Assert.Equal(InterpolationMode.Bilinear, g.InterpolationMode); - Assert.Equal(1, g.PageScale); - Assert.Equal(GraphicsUnit.Display, g.PageUnit); - Assert.Equal(PixelOffsetMode.Default, g.PixelOffsetMode); - Assert.Equal(new Point(0, 0), g.RenderingOrigin); - Assert.Equal(SmoothingMode.None, g.SmoothingMode); - Assert.Equal(TextRenderingHint.SystemDefault, g.TextRenderingHint); - - Region r = new Region(); - Assert.Equal(r.GetBounds(g), g.ClipBounds); - } - } - - [Fact] - public void LoadIndexed_BmpFile() - { - // Tests that we can load an indexed file, but... - string sInFile = Helpers.GetTestBitmapPath("almogaver1bit.bmp"); - // note: file is misnamed (it's a 4bpp bitmap) - using (Image img = Image.FromFile(sInFile)) - { - Assert.Equal(PixelFormat.Format4bppIndexed, img.PixelFormat); - Exception exception = AssertExtensions.Throws(() => Graphics.FromImage(img)); - if (exception is ArgumentException argumentException) - Assert.Equal("image", argumentException.ParamName); - } - } - - class BitmapAndGraphics : IDisposable - { - private readonly Bitmap _bitmap; - public Graphics Graphics { get; } - public BitmapAndGraphics(int width, int height) - { - _bitmap = new Bitmap(width, height); - Graphics = Graphics.FromImage(_bitmap); - Graphics.Clip = new Region(new Rectangle(0, 0, width, height)); - } - public void Dispose() { Graphics.Dispose(); _bitmap.Dispose(); } - } - - private void Compare(string msg, RectangleF b1, RectangleF b2) - { - AssertEquals(msg + ".compare.X", b1.X, b2.X); - AssertEquals(msg + ".compare.Y", b1.Y, b2.Y); - AssertEquals(msg + ".compare.Width", b1.Width, b2.Width); - AssertEquals(msg + ".compare.Height", b1.Height, b2.Height); - } - - [Fact] - public void Clip_GetBounds() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - RectangleF bounds = g.Clip.GetBounds(g); - Assert.Equal(0, bounds.X); - Assert.Equal(0, bounds.Y); - Assert.Equal(16, bounds.Width); - Assert.Equal(16, bounds.Height); - Assert.True(g.Transform.IsIdentity); - } - } - - [Fact] - public void Clip_TranslateTransform() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - g.TranslateTransform(12.22f, 10.10f); - RectangleF bounds = g.Clip.GetBounds(g); - Compare("translate", bounds, g.ClipBounds); - Assert.Equal(-12.2200003f, bounds.X); - Assert.Equal(-10.1000004f, bounds.Y); - Assert.Equal(16, bounds.Width); - Assert.Equal(16, bounds.Height); - float[] elements = g.Transform.Elements; - Assert.Equal(1, elements[0]); - Assert.Equal(0, elements[1]); - Assert.Equal(0, elements[2]); - Assert.Equal(1, elements[3]); - Assert.Equal(12.2200003f, elements[4]); - Assert.Equal(10.1000004f, elements[5]); - - g.ResetTransform(); - bounds = g.Clip.GetBounds(g); - Compare("reset", bounds, g.ClipBounds); - Assert.Equal(0, bounds.X); - Assert.Equal(0, bounds.Y); - Assert.Equal(16, bounds.Width); - Assert.Equal(16, bounds.Height); - Assert.True(g.Transform.IsIdentity); - } - } - - [Fact] - public void Transform_NonInvertibleMatrix() - { - using (Matrix matrix = new Matrix(123, 24, 82, 16, 47, 30)) - using (var b = new BitmapAndGraphics(16, 16)) - { - Assert.False(matrix.IsInvertible); - - var g = b.Graphics; - Assert.Throws(() => g.Transform = matrix); - } - } - - - [Fact] - public void Multiply_NonInvertibleMatrix() - { - using (Matrix matrix = new Matrix(123, 24, 82, 16, 47, 30)) - using (var b = new BitmapAndGraphics(16, 16)) - { - Assert.False(matrix.IsInvertible); - - var g = b.Graphics; - Assert.Throws(() => g.MultiplyTransform(matrix)); - } - } - - private void CheckBounds(string msg, RectangleF bounds, float x, float y, float w, float h) - { - AssertEquals(msg + ".X", x, bounds.X, 1); - AssertEquals(msg + ".Y", y, bounds.Y, 1); - AssertEquals(msg + ".Width", w, bounds.Width, 1); - AssertEquals(msg + ".Height", h, bounds.Height, 1); - } - - [Fact] - public void ClipBounds() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - CheckBounds("graphics.ClipBounds", g.ClipBounds, 0, 0, 16, 16); - CheckBounds("graphics.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 16, 16); - - g.Clip = new Region(new Rectangle(0, 0, 8, 8)); - CheckBounds("clip.ClipBounds", g.ClipBounds, 0, 0, 8, 8); - CheckBounds("clip.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - } - } - - [Fact] - public void ClipBounds_Rotate() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - g.Clip = new Region(new Rectangle(0, 0, 8, 8)); - g.RotateTransform(90); - CheckBounds("rotate.ClipBounds", g.ClipBounds, 0, -8, 8, 8); - CheckBounds("rotate.Clip.GetBounds", g.Clip.GetBounds(g), 0, -8, 8, 8); - - g.Transform = new Matrix(); - CheckBounds("identity.ClipBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - CheckBounds("identity.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - } - } - - [Fact] - public void ClipBounds_Scale() - { - RectangleF clip = new Rectangle(0, 0, 8, 8); - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - g.Clip = new Region(clip); - g.ScaleTransform(0.25f, 0.5f); - CheckBounds("scale.ClipBounds", g.ClipBounds, 0, 0, 32, 16); - CheckBounds("scale.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 32, 16); - - g.SetClip(clip); - CheckBounds("setclip.ClipBounds", g.ClipBounds, 0, 0, 8, 8); - CheckBounds("setclip.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - } - } - - [Fact] - public void ClipBounds_Translate() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - g.Clip = new Region(new Rectangle(0, 0, 8, 8)); - using (Region clone = g.Clip.Clone()) - { - g.TranslateTransform(8, 8); - CheckBounds("translate.ClipBounds", g.ClipBounds, -8, -8, 8, 8); - CheckBounds("translate.Clip.GetBounds", g.Clip.GetBounds(g), -8, -8, 8, 8); - - g.SetClip(clone, CombineMode.Replace); - CheckBounds("setclip.ClipBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - CheckBounds("setclip.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - } - } - } - - [Fact] - public void ClipBounds_Transform_Translation() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - g.Clip = new Region(new Rectangle(0, 0, 8, 8)); - g.Transform = new Matrix(1, 0, 0, 1, 8, 8); - CheckBounds("transform.ClipBounds", g.ClipBounds, -8, -8, 8, 8); - CheckBounds("transform.Clip.GetBounds", g.Clip.GetBounds(g), -8, -8, 8, 8); - - g.ResetTransform(); - CheckBounds("reset.ClipBounds", g.ClipBounds, 0, 0, 8, 8); - CheckBounds("reset.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - } - } - - [Fact] - public void ClipBounds_Transform_Scale() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - g.Clip = new Region(new Rectangle(0, 0, 8, 8)); - g.Transform = new Matrix(0.5f, 0, 0, 0.25f, 0, 0); - CheckBounds("scale.ClipBounds", g.ClipBounds, 0, 0, 16, 32); - CheckBounds("scale.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 16, 32); - - g.ResetClip(); - // see next test for ClipBounds - CheckBounds("resetclip.Clip.GetBounds", g.Clip.GetBounds(g), -4194304, -4194304, 8388608, 8388608); - Assert.True(g.Clip.IsInfinite(g)); - } - } - - [Fact] - public void ClipBounds_Multiply() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - g.Clip = new Region(new Rectangle(0, 0, 8, 8)); - g.Transform = new Matrix(1, 0, 0, 1, 8, 8); - g.MultiplyTransform(g.Transform); - CheckBounds("multiply.ClipBounds", g.ClipBounds, -16, -16, 8, 8); - CheckBounds("multiply.Clip.GetBounds", g.Clip.GetBounds(g), -16, -16, 8, 8); - - g.ResetTransform(); - CheckBounds("reset.ClipBounds", g.ClipBounds, 0, 0, 8, 8); - CheckBounds("reset.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - } - } - - [Fact] - public void ClipBounds_Cumulative_Effects() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - CheckBounds("graphics.ClipBounds", g.ClipBounds, 0, 0, 16, 16); - CheckBounds("graphics.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 16, 16); - - g.Clip = new Region(new Rectangle(0, 0, 8, 8)); - CheckBounds("clip.ClipBounds", g.ClipBounds, 0, 0, 8, 8); - CheckBounds("clip.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - - g.RotateTransform(90); - CheckBounds("rotate.ClipBounds", g.ClipBounds, 0, -8, 8, 8); - CheckBounds("rotate.Clip.GetBounds", g.Clip.GetBounds(g), 0, -8, 8, 8); - - g.ScaleTransform(0.25f, 0.5f); - CheckBounds("scale.ClipBounds", g.ClipBounds, 0, -16, 32, 16); - CheckBounds("scale.Clip.GetBounds", g.Clip.GetBounds(g), 0, -16, 32, 16); - - g.TranslateTransform(8, 8); - CheckBounds("translate.ClipBounds", g.ClipBounds, -8, -24, 32, 16); - CheckBounds("translate.Clip.GetBounds", g.Clip.GetBounds(g), -8, -24, 32, 16); - - g.MultiplyTransform(g.Transform); - CheckBounds("multiply.ClipBounds", g.ClipBounds, -104, -56, 64, 64); - CheckBounds("multiply.Clip.GetBounds", g.Clip.GetBounds(g), -104, -56, 64, 64); - - g.ResetTransform(); - CheckBounds("reset.ClipBounds", g.ClipBounds, 0, 0, 8, 8); - CheckBounds("reset.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - } - } - - [Fact] - public void Clip_TranslateTransform_BoundsChange() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - CheckBounds("graphics.ClipBounds", g.ClipBounds, 0, 0, 16, 16); - CheckBounds("graphics.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 16, 16); - g.TranslateTransform(-16, -16); - CheckBounds("translated.ClipBounds", g.ClipBounds, 16, 16, 16, 16); - CheckBounds("translated.Clip.GetBounds", g.Clip.GetBounds(g), 16, 16, 16, 16); - - g.Clip = new Region(new Rectangle(0, 0, 8, 8)); - // ClipBounds isn't affected by a previous translation - CheckBounds("rectangle.ClipBounds", g.ClipBounds, 0, 0, 8, 8); - // Clip.GetBounds isn't affected by a previous translation - CheckBounds("rectangle.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - - g.ResetTransform(); - CheckBounds("reseted.ClipBounds", g.ClipBounds, -16, -16, 8, 8); - CheckBounds("reseted.Clip.GetBounds", g.Clip.GetBounds(g), -16, -16, 8, 8); - } - } - - [Fact] - public void Clip_RotateTransform_BoundsChange() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - CheckBounds("graphics.ClipBounds", g.ClipBounds, 0, 0, 16, 16); - CheckBounds("graphics.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 16, 16); - // we select a "simple" angle because the region will be converted into - // a bitmap (well for libgdiplus) and we would lose precision after that - g.RotateTransform(90); - CheckBounds("rotated.ClipBounds", g.ClipBounds, 0, -16, 16, 16); - CheckBounds("rotated.Clip.GetBounds", g.Clip.GetBounds(g), 0, -16, 16, 16); - g.Clip = new Region(new Rectangle(0, 0, 8, 8)); - // ClipBounds isn't affected by a previous rotation (90) - CheckBounds("rectangle.ClipBounds", g.ClipBounds, 0, 0, 8, 8); - // Clip.GetBounds isn't affected by a previous rotation - CheckBounds("rectangle.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - - g.ResetTransform(); - CheckBounds("reseted.ClipBounds", g.ClipBounds, -8, 0, 8, 8); - CheckBounds("reseted.Clip.GetBounds", g.Clip.GetBounds(g), -8, 0, 8, 8); - } - } - - [Fact] - public void Clip_ScaleTransform_NoBoundsChange() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - CheckBounds("graphics.ClipBounds", g.ClipBounds, 0, 0, 16, 16); - CheckBounds("graphics.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 16, 16); - g.ScaleTransform(2, 0.5f); - CheckBounds("scaled.ClipBounds", g.ClipBounds, 0, 0, 8, 32); - CheckBounds("scaled.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 32); - g.Clip = new Region(new Rectangle(0, 0, 8, 8)); - // ClipBounds isn't affected by a previous scaling - CheckBounds("rectangle.ClipBounds", g.ClipBounds, 0, 0, 8, 8); - // Clip.GetBounds isn't affected by a previous scaling - CheckBounds("rectangle.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 8, 8); - - g.ResetTransform(); - CheckBounds("reseted.ClipBounds", g.ClipBounds, 0, 0, 16, 4); - CheckBounds("reseted.Clip.GetBounds", g.Clip.GetBounds(g), 0, 0, 16, 4); - } - } - - [Fact] - public void ScaleTransform_X0() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - Assert.Throws(() => g.ScaleTransform(0, 1)); - } - } - - [Fact] - public void ScaleTransform_Y0() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - Assert.Throws(() => g.ScaleTransform(1, 0)); - } - } - - [Fact] - public void TranslateTransform_Order() - { - using (var b = new BitmapAndGraphics(16, 16)) - { - var g = b.Graphics; - g.Transform = new Matrix(1, 2, 3, 4, 5, 6); - g.TranslateTransform(3, -3); - float[] elements = g.Transform.Elements; - Assert.Equal(1, elements[0]); - Assert.Equal(2, elements[1]); - Assert.Equal(3, elements[2]); - Assert.Equal(4, elements[3]); - Assert.Equal(-1, elements[4]); - Assert.Equal(0, elements[5]); - - g.Transform = new Matrix(1, 2, 3, 4, 5, 6); - g.TranslateTransform(3, -3, MatrixOrder.Prepend); - elements = g.Transform.Elements; - Assert.Equal(1, elements[0]); - Assert.Equal(2, elements[1]); - Assert.Equal(3, elements[2]); - Assert.Equal(4, elements[3]); - Assert.Equal(-1, elements[4]); - Assert.Equal(0, elements[5]); - - g.Transform = new Matrix(1, 2, 3, 4, 5, 6); - g.TranslateTransform(3, -3, MatrixOrder.Append); - elements = g.Transform.Elements; - Assert.Equal(1, elements[0]); - Assert.Equal(2, elements[1]); - Assert.Equal(3, elements[2]); - Assert.Equal(4, elements[3]); - Assert.Equal(8, elements[4]); - Assert.Equal(3, elements[5]); - } - } - - static PointF[] SmallCurveF = new PointF[3] { new PointF(0, 0), new PointF(15, 5), new PointF(5, 15) }; - - static Point[] TooSmallCurve = new Point[2] { new Point(0, 0), new Point(15, 5) }; - static PointF[] LargeCurveF = new PointF[4] { new PointF(0, 0), new PointF(15, 5), new PointF(5, 15), new PointF(0, 20) }; - - [Fact] - public void DrawCurve_NotEnoughPoints() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - CheckForEmptyBitmap(bitmap); - g.DrawCurve(Pens.Black, TooSmallCurve, 0.5f); - CheckForNonEmptyBitmap(bitmap); - // so a "curve" can be drawn with less than 3 points! - // actually I used to call that a line... (and it's not related to tension) - g.Dispose(); - bitmap.Dispose(); - } - } - - [Fact] - public void DrawCurve_SinglePoint() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.DrawCurve(Pens.Black, new Point[1] { new Point(10, 10) }, 0.5f)); - // a single point isn't enough - } - } - - [Fact] - public void DrawCurve3_NotEnoughPoints() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.DrawCurve(Pens.Black, TooSmallCurve, 0, 2, 0.5f)); - // aha, this is API dependent - } - } - - [Fact] - public void DrawCurve_NegativeTension() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - // documented as bigger (or equals) to 0 - g.DrawCurve(Pens.Black, SmallCurveF, -0.9f); - CheckForNonEmptyBitmap(bitmap); - g.Dispose(); - bitmap.Dispose(); - } - } - - [Fact] - public void DrawCurve_PositiveTension() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - g.DrawCurve(Pens.Black, SmallCurveF, 0.9f); - // this is not the same as -1 - CheckForNonEmptyBitmap(bitmap); - g.Dispose(); - bitmap.Dispose(); - } - } - - [Fact] - public void DrawCurve_ZeroSegments() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.DrawCurve(Pens.Black, SmallCurveF, 0, 0)); - } - } - - [Fact] - public void DrawCurve_NegativeSegments() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.DrawCurve(Pens.Black, SmallCurveF, 0, -1)); - } - } - - [Fact] - public void DrawCurve_OffsetTooLarge() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - // starting offset 1 doesn't give 3 points to make a curve - Assert.Throws(() => g.DrawCurve(Pens.Black, SmallCurveF, 1, 2)); - // and in this case 2 points aren't enough to draw something - } - } - - [Fact] - public void DrawCurve_Offset_0() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - g.DrawCurve(Pens.Black, LargeCurveF, 0, 2, 0.5f); - CheckForNonEmptyBitmap(bitmap); - g.Dispose(); - bitmap.Dispose(); - } - } - - [Fact] - public void DrawCurve_Offset_1() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - g.DrawCurve(Pens.Black, LargeCurveF, 1, 2, 0.5f); - CheckForNonEmptyBitmap(bitmap); - g.Dispose(); - bitmap.Dispose(); - } - } - - [Fact] - public void DrawCurve_Offset_2() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - // it works even with two points because we know the previous ones - g.DrawCurve(Pens.Black, LargeCurveF, 2, 1, 0.5f); - CheckForNonEmptyBitmap(bitmap); - g.Dispose(); - bitmap.Dispose(); - } - } - - [Fact] - public void DrawRectangle_Negative() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - using (Pen pen = new Pen(Color.Red)) - { - g.DrawRectangle(pen, 5, 5, -10, -10); - g.DrawRectangle(pen, 0.0f, 0.0f, 5.0f, -10.0f); - g.DrawRectangle(pen, new Rectangle(15, 0, -10, 5)); - CheckForEmptyBitmap(bitmap); - pen.Dispose(); - g.Dispose(); - bitmap.Dispose(); - } - } - - [Fact] - public void DrawRectangles_Negative() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - using (Pen pen = new Pen(Color.Red)) - { - Rectangle[] rects = new Rectangle[2] - { - new Rectangle (5, 5, -10, -10), - new Rectangle (0, 0, 5, -10) - }; - RectangleF[] rectf = new RectangleF[2] - { - new RectangleF (0.0f, 5.0f, -10.0f, -10.0f), - new RectangleF (15.0f, 0.0f, -10.0f, 5.0f) - }; - g.DrawRectangles(pen, rects); - g.DrawRectangles(pen, rectf); - CheckForEmptyBitmap(bitmap); - pen.Dispose(); - g.Dispose(); - bitmap.Dispose(); - } - } - - [Fact] - public void FillRectangle_Negative() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - using (SolidBrush brush = new SolidBrush(Color.Red)) - { - g.FillRectangle(brush, 5, 5, -10, -10); - g.FillRectangle(brush, 0.0f, 0.0f, 5.0f, -10.0f); - g.FillRectangle(brush, new Rectangle(15, 0, -10, 5)); - CheckForEmptyBitmap(bitmap); - brush.Dispose(); - g.Dispose(); - bitmap.Dispose(); - } - } - - [Fact] - public void FillRectangles_Negative() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - using (SolidBrush brush = new SolidBrush(Color.Red)) - { - Rectangle[] rects = new Rectangle[2] - { - new Rectangle (5, 5, -10, -10), - new Rectangle (0, 0, 5, -10) - }; - - RectangleF[] rectf = new RectangleF[2] - { - new RectangleF (0.0f, 5.0f, -10.0f, -10.0f), - new RectangleF (15.0f, 0.0f, -10.0f, 5.0f) - }; - - g.FillRectangles(brush, rects); - g.FillRectangles(brush, rectf); - CheckForEmptyBitmap(bitmap); - brush.Dispose(); - g.Dispose(); - bitmap.Dispose(); - } - } - - private void CheckDefaultProperties(string message, Graphics g) - { - Assert.True(g.Clip.IsInfinite(g), message + ".Clip.IsInfinite"); - AssertEquals(message + ".CompositingMode", CompositingMode.SourceOver, g.CompositingMode); - AssertEquals(message + ".CompositingQuality", CompositingQuality.Default, g.CompositingQuality); - AssertEquals(message + ".InterpolationMode", InterpolationMode.Bilinear, g.InterpolationMode); - AssertEquals(message + ".PageScale", 1.0f, g.PageScale); - AssertEquals(message + ".PageUnit", GraphicsUnit.Display, g.PageUnit); - AssertEquals(message + ".PixelOffsetMode", PixelOffsetMode.Default, g.PixelOffsetMode); - AssertEquals(message + ".SmoothingMode", SmoothingMode.None, g.SmoothingMode); - AssertEquals(message + ".TextContrast", 4, g.TextContrast); - AssertEquals(message + ".TextRenderingHint", TextRenderingHint.SystemDefault, g.TextRenderingHint); - Assert.True(g.Transform.IsIdentity, message + ".Transform.IsIdentity"); - } - - private void CheckCustomProperties(string message, Graphics g) - { - Assert.False(g.Clip.IsInfinite(g), message + ".Clip.IsInfinite"); - AssertEquals(message + ".CompositingMode", CompositingMode.SourceCopy, g.CompositingMode); - AssertEquals(message + ".CompositingQuality", CompositingQuality.HighQuality, g.CompositingQuality); - AssertEquals(message + ".InterpolationMode", InterpolationMode.HighQualityBicubic, g.InterpolationMode); - AssertEquals(message + ".PageScale", 0.5f, g.PageScale); - AssertEquals(message + ".PageUnit", GraphicsUnit.Inch, g.PageUnit); - AssertEquals(message + ".PixelOffsetMode", PixelOffsetMode.Half, g.PixelOffsetMode); - AssertEquals(message + ".RenderingOrigin", new Point(-1, -1), g.RenderingOrigin); - AssertEquals(message + ".SmoothingMode", SmoothingMode.AntiAlias, g.SmoothingMode); - AssertEquals(message + ".TextContrast", 0, g.TextContrast); - AssertEquals(message + ".TextRenderingHint", TextRenderingHint.AntiAlias, g.TextRenderingHint); - Assert.False(g.Transform.IsIdentity, message + ".Transform.IsIdentity"); - } - - private void CheckMatrix(string message, Matrix m, float xx, float yx, float xy, float yy, float x0, float y0) - { - float[] elements = m.Elements; - AssertEquals(message + ".Matrix.xx", xx, elements[0], 2); - AssertEquals(message + ".Matrix.yx", yx, elements[1], 2); - AssertEquals(message + ".Matrix.xy", xy, elements[2], 2); - AssertEquals(message + ".Matrix.yy", yy, elements[3], 2); - AssertEquals(message + ".Matrix.x0", x0, elements[4], 2); - AssertEquals(message + ".Matrix.y0", y0, elements[5], 2); - } - - [Fact] - public void BeginContainer() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - CheckDefaultProperties("default", g); - Assert.Equal(new Point(0, 0), g.RenderingOrigin); - - g.Clip = new Region(new Rectangle(10, 10, 10, 10)); - g.CompositingMode = CompositingMode.SourceCopy; - g.CompositingQuality = CompositingQuality.HighQuality; - g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.PageScale = 0.5f; - g.PageUnit = GraphicsUnit.Inch; - g.PixelOffsetMode = PixelOffsetMode.Half; - g.RenderingOrigin = new Point(-1, -1); - g.RotateTransform(45); - g.SmoothingMode = SmoothingMode.AntiAlias; - g.TextContrast = 0; - g.TextRenderingHint = TextRenderingHint.AntiAlias; - CheckCustomProperties("modified", g); - CheckMatrix("modified.Transform", g.Transform, 0.707f, 0.707f, -0.707f, 0.707f, 0, 0); - - GraphicsContainer gc = g.BeginContainer(); - // things gets reseted after calling BeginContainer - CheckDefaultProperties("BeginContainer", g); - // but not everything - Assert.Equal(new Point(-1, -1), g.RenderingOrigin); - - g.EndContainer(gc); - CheckCustomProperties("EndContainer", g); - } - } - - [Fact] - public void BeginContainer_Rect() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - CheckDefaultProperties("default", g); - Assert.Equal(new Point(0, 0), g.RenderingOrigin); - - g.Clip = new Region(new Rectangle(10, 10, 10, 10)); - g.CompositingMode = CompositingMode.SourceCopy; - g.CompositingQuality = CompositingQuality.HighQuality; - g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.PageScale = 0.5f; - g.PageUnit = GraphicsUnit.Inch; - g.PixelOffsetMode = PixelOffsetMode.Half; - g.RenderingOrigin = new Point(-1, -1); - g.RotateTransform(45); - g.SmoothingMode = SmoothingMode.AntiAlias; - g.TextContrast = 0; - g.TextRenderingHint = TextRenderingHint.AntiAlias; - CheckCustomProperties("modified", g); - CheckMatrix("modified.Transform", g.Transform, 0.707f, 0.707f, -0.707f, 0.707f, 0, 0); - - GraphicsContainer gc = g.BeginContainer(new Rectangle(10, 20, 30, 40), new Rectangle(10, 20, 300, 400), GraphicsUnit.Millimeter); - // things gets reseted after calling BeginContainer - CheckDefaultProperties("BeginContainer", g); - // but not everything - Assert.Equal(new Point(-1, -1), g.RenderingOrigin); - - g.EndContainer(gc); - CheckCustomProperties("EndContainer", g); - CheckMatrix("EndContainer.Transform", g.Transform, 0.707f, 0.707f, -0.707f, 0.707f, 0, 0); - } - } - - [Fact] - public void BeginContainer_RectF() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - CheckDefaultProperties("default", g); - Assert.Equal(new Point(0, 0), g.RenderingOrigin); - - g.Clip = new Region(new Rectangle(10, 10, 10, 10)); - g.CompositingMode = CompositingMode.SourceCopy; - g.CompositingQuality = CompositingQuality.HighQuality; - g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.PageScale = 0.5f; - g.PageUnit = GraphicsUnit.Inch; - g.PixelOffsetMode = PixelOffsetMode.Half; - g.RenderingOrigin = new Point(-1, -1); - g.RotateTransform(45); - g.SmoothingMode = SmoothingMode.AntiAlias; - g.TextContrast = 0; - g.TextRenderingHint = TextRenderingHint.AntiAlias; - CheckCustomProperties("modified", g); - CheckMatrix("modified.Transform", g.Transform, 0.707f, 0.707f, -0.707f, 0.707f, 0, 0); - - GraphicsContainer gc = g.BeginContainer(new RectangleF(40, 30, 20, 10), new RectangleF(10, 20, 30, 40), GraphicsUnit.Inch); - // things gets reseted after calling BeginContainer - CheckDefaultProperties("BeginContainer", g); - // but not everything - Assert.Equal(new Point(-1, -1), g.RenderingOrigin); - - g.EndContainer(gc); - CheckCustomProperties("EndContainer", g); - } - } - - private void BeginContainer_GraphicsUnit(GraphicsUnit unit) - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - g.BeginContainer(new RectangleF(40, 30, 20, 10), new RectangleF(10, 20, 30, 40), unit); - } - } - - [Fact] - public void BeginContainer_GraphicsUnit_Display() - { - Assert.Throws(() => BeginContainer_GraphicsUnit(GraphicsUnit.Display)); - } - - [Fact] - public void BeginContainer_GraphicsUnit_Valid() - { - BeginContainer_GraphicsUnit(GraphicsUnit.Document); - BeginContainer_GraphicsUnit(GraphicsUnit.Inch); - BeginContainer_GraphicsUnit(GraphicsUnit.Millimeter); - BeginContainer_GraphicsUnit(GraphicsUnit.Pixel); - BeginContainer_GraphicsUnit(GraphicsUnit.Point); - } - - [Fact] - public void BeginContainer_GraphicsUnit_World() - { - Assert.Throws(() => BeginContainer_GraphicsUnit(GraphicsUnit.World)); - } - - [Fact] - public void BeginContainer_GraphicsUnit_Bad() - { - Assert.Throws(() => BeginContainer_GraphicsUnit((GraphicsUnit)int.MinValue)); - } - - [Fact] - public void EndContainer_Null() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.EndContainer(null)); - } - } - - [Fact] - public void Save() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - CheckDefaultProperties("default", g); - Assert.Equal(new Point(0, 0), g.RenderingOrigin); - - GraphicsState gs1 = g.Save(); - // nothing is changed after a save - CheckDefaultProperties("save1", g); - Assert.Equal(new Point(0, 0), g.RenderingOrigin); - - g.Clip = new Region(new Rectangle(10, 10, 10, 10)); - g.CompositingMode = CompositingMode.SourceCopy; - g.CompositingQuality = CompositingQuality.HighQuality; - g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.PageScale = 0.5f; - g.PageUnit = GraphicsUnit.Inch; - g.PixelOffsetMode = PixelOffsetMode.Half; - g.RenderingOrigin = new Point(-1, -1); - g.RotateTransform(45); - g.SmoothingMode = SmoothingMode.AntiAlias; - g.TextContrast = 0; - g.TextRenderingHint = TextRenderingHint.AntiAlias; - CheckCustomProperties("modified", g); - CheckMatrix("modified.Transform", g.Transform, 0.707f, 0.707f, -0.707f, 0.707f, 0, 0); - - GraphicsState gs2 = g.Save(); - CheckCustomProperties("save2", g); - - g.Restore(gs2); - CheckCustomProperties("restored1", g); - CheckMatrix("restored1.Transform", g.Transform, 0.707f, 0.707f, -0.707f, 0.707f, 0, 0); - - g.Restore(gs1); - CheckDefaultProperties("restored2", g); - Assert.Equal(new Point(0, 0), g.RenderingOrigin); - } - } - - [Fact] - public void Restore_Null() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.Restore(null)); - } - } - - [Fact] - public void FillRectangles_BrushNull_Rectangle() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.FillRectangles(null, new Rectangle[1])); - } - } - - [Fact] - public void FillRectangles_Rectangle_Null() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.FillRectangles(Brushes.Red, (Rectangle[])null)); - } - } - - [Fact] - public void FillRectanglesZeroRectangle() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.FillRectangles(Brushes.Red, new Rectangle[0])); - } - } - - [Fact] - public void FillRectangles_BrushNull_RectangleF() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.FillRectangles(null, new RectangleF[1])); - } - } - - [Fact] - public void FillRectangles_RectangleF_Null() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.FillRectangles(Brushes.Red, (RectangleF[])null)); - } - } - - [Fact] - public void FillRectanglesZeroRectangleF() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.FillRectangles(Brushes.Red, new RectangleF[0])); - } - } - - [Fact] - public void FillRectangles_NormalBehavior() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - { - using (Graphics g = Graphics.FromImage(bitmap)) - { - g.Clear(Color.Fuchsia); - Rectangle rect = new Rectangle(5, 5, 10, 10); - g.Clip = new Region(rect); - g.FillRectangle(Brushes.Red, rect); - } - Assert.Equal(Color.Red.ToArgb(), bitmap.GetPixel(5, 5).ToArgb()); - Assert.Equal(Color.Red.ToArgb(), bitmap.GetPixel(14, 5).ToArgb()); - Assert.Equal(Color.Red.ToArgb(), bitmap.GetPixel(5, 14).ToArgb()); - Assert.Equal(Color.Red.ToArgb(), bitmap.GetPixel(14, 14).ToArgb()); - - Assert.Equal(Color.Fuchsia.ToArgb(), bitmap.GetPixel(15, 5).ToArgb()); - Assert.Equal(Color.Fuchsia.ToArgb(), bitmap.GetPixel(5, 15).ToArgb()); - Assert.Equal(Color.Fuchsia.ToArgb(), bitmap.GetPixel(15, 15).ToArgb()); - } - } - - private Bitmap FillDrawRectangle(float width) - { - Bitmap bitmap = new Bitmap(20, 20); - using (Graphics g = Graphics.FromImage(bitmap)) - { - g.Clear(Color.Red); - Rectangle rect = new Rectangle(5, 5, 10, 10); - g.FillRectangle(Brushes.Green, rect); - if (width >= 0) - { - using (Pen pen = new Pen(Color.Blue, width)) - { - g.DrawRectangle(pen, rect); - } - } - else - { - g.DrawRectangle(Pens.Blue, rect); - } - } - return bitmap; - } - - [Fact] - public void FillDrawRectangle_Width_Default() - { - // default pen size - using (Bitmap bitmap = FillDrawRectangle(float.MinValue)) - { - // NW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(4, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 5).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(6, 6).ToArgb()); - // N - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 5).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 6).ToArgb()); - // NE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 5).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 6).ToArgb()); - // E - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 9).ToArgb()); - // SE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 14).ToArgb()); - // S - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 14).ToArgb()); - // SW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(4, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(6, 14).ToArgb()); - // W - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(4, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(6, 9).ToArgb()); - } - } - - [Fact] - public void FillDrawRectangle_Width_2() - { - // even pen size - using (Bitmap bitmap = FillDrawRectangle(2.0f)) - { - // NW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 5).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(6, 6).ToArgb()); - // N - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 5).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 6).ToArgb()); - // NE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(14, 5).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(13, 6).ToArgb()); - // E - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(14, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(13, 9).ToArgb()); - // SE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 15).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(14, 14).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(13, 13).ToArgb()); - // S - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 15).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 14).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 13).ToArgb()); - // SW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 15).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 14).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(6, 13).ToArgb()); - // W - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(6, 9).ToArgb()); - } - } - - [Fact] - public void FillDrawRectangle_Width_3() - { - // odd pen size - using (Bitmap bitmap = FillDrawRectangle(3.0f)) - { - // NW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 5).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(6, 6).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(7, 7).ToArgb()); - // N - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 5).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 6).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 7).ToArgb()); - // NE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(17, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(16, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 5).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(14, 6).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(13, 7).ToArgb()); - // E - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(17, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(16, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(14, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(13, 9).ToArgb()); - // SE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(17, 17).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(16, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 15).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(14, 14).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(13, 13).ToArgb()); - // S - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 17).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 15).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 14).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 13).ToArgb()); - // SW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 17).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 15).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(6, 14).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(7, 13).ToArgb()); - // W - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(6, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(7, 9).ToArgb()); - } - } - - // reverse, draw the fill over - private Bitmap DrawFillRectangle(float width) - { - Bitmap bitmap = new Bitmap(20, 20); - using (Graphics g = Graphics.FromImage(bitmap)) - { - g.Clear(Color.Red); - Rectangle rect = new Rectangle(5, 5, 10, 10); - if (width >= 0) - { - using (Pen pen = new Pen(Color.Blue, width)) - { - g.DrawRectangle(pen, rect); - } - } - else - { - g.DrawRectangle(Pens.Blue, rect); - } - g.FillRectangle(Brushes.Green, rect); - } - return bitmap; - } - - [Fact] - public void DrawFillRectangle_Width_Default() - { - // default pen size - using (Bitmap bitmap = DrawFillRectangle(float.MinValue)) - { - // NW - no blue border - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(4, 4).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(5, 5).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(6, 6).ToArgb()); - // N - no blue border - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 4).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 5).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 6).ToArgb()); - // NE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 5).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 6).ToArgb()); - // E - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 9).ToArgb()); - // SE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 14).ToArgb()); - // S - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 14).ToArgb()); - // SW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(4, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(6, 14).ToArgb()); - // W - no blue border - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(4, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(5, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(6, 9).ToArgb()); - } - } - - [Fact] - public void DrawFillRectangle_Width_2() - { - // even pen size - using (Bitmap bitmap = DrawFillRectangle(2.0f)) - { - // looks like a one pixel border - but enlarged - // NW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 4).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(5, 5).ToArgb()); - // N - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 4).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 5).ToArgb()); - // NE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 4).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 5).ToArgb()); - // E - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 9).ToArgb()); - // SE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 14).ToArgb()); - // S - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 14).ToArgb()); - // SW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(5, 14).ToArgb()); - // W - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(5, 9).ToArgb()); - } - } - - [Fact] - public void DrawFillRectangle_Width_3() - { - // odd pen size - using (Bitmap bitmap = DrawFillRectangle(3.0f)) - { - // NW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 4).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(5, 5).ToArgb()); - // N - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 4).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 5).ToArgb()); - // NE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(17, 3).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(16, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 4).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 5).ToArgb()); - // E - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(17, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(16, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 9).ToArgb()); - // SE - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(17, 17).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(16, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(14, 14).ToArgb()); - // S - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(9, 17).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(9, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(9, 14).ToArgb()); - // SW - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 17).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 16).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 15).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(6, 14).ToArgb()); - // W - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(3, 9).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(4, 9).ToArgb()); - Assert.Equal(0xFF008000, (uint)bitmap.GetPixel(5, 9).ToArgb()); - } - } - - private Bitmap DrawLines(float width) - { - Bitmap bitmap = new Bitmap(20, 20); - using (Graphics g = Graphics.FromImage(bitmap)) - { - g.Clear(Color.Red); - Point[] pts = new Point[3] { new Point(5, 5), new Point(15, 5), new Point(15, 15) }; - if (width >= 0) - { - using (Pen pen = new Pen(Color.Blue, width)) - { - g.DrawLines(pen, pts); - } - } - else - { - g.DrawLines(Pens.Blue, pts); - } - } - return bitmap; - } - - [Fact] - public void DrawLines_Width_Default() - { - // default pen size - using (Bitmap bitmap = DrawLines(float.MinValue)) - { - // start - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(4, 4).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(4, 5).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(4, 6).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(5, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(5, 5).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(5, 6).ToArgb()); - // middle - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(14, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(14, 5).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(14, 6).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(15, 4).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 5).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 6).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 4).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 5).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 6).ToArgb()); - //end - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(14, 15).ToArgb()); - Assert.Equal(0xFF0000FF, (uint)bitmap.GetPixel(15, 15).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 15).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(14, 16).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(15, 16).ToArgb()); - Assert.Equal(0xFFFF0000, (uint)bitmap.GetPixel(16, 16).ToArgb()); - } - } - - [Fact] - public void MeasureString_StringFont() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - { - using (Graphics g = Graphics.FromImage(bitmap)) - { - SizeF size = g.MeasureString(null, font); - Assert.True(size.IsEmpty); - size = g.MeasureString(string.Empty, font); - Assert.True(size.IsEmpty); - g.MeasureString(string.Empty.AsSpan(), font); - Assert.True(size.IsEmpty); - - // null font - size = g.MeasureString(null, null); - Assert.True(size.IsEmpty); - size = g.MeasureString(string.Empty, null); - Assert.True(size.IsEmpty); - g.MeasureString(string.Empty.AsSpan(), null); - Assert.True(size.IsEmpty); - } - } - } - - [Fact] - public void MeasureString_StringFont_Null() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.MeasureString("a", null)); - Assert.Throws(() => g.MeasureString("a".AsSpan(), null)); - } - } - - [Fact] - public void MeasureString_StringFontSizeF() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - SizeF size = g.MeasureString("a", font, SizeF.Empty); - Assert.False(size.IsEmpty); - - size = g.MeasureString("a".AsSpan(), font, SizeF.Empty); - Assert.False(size.IsEmpty); - - size = g.MeasureString(string.Empty, font, SizeF.Empty); - Assert.True(size.IsEmpty); - - size = g.MeasureString(string.Empty.AsSpan(), font, SizeF.Empty); - Assert.True(size.IsEmpty); - } - } - - private void MeasureString_StringFontInt(string s, bool useSpan) - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - SizeF size0 = useSpan ? g.MeasureString(s.AsSpan(), font, 0) : g.MeasureString(s, font, 0); - SizeF sizeN = useSpan ? g.MeasureString(s.AsSpan(), font, int.MinValue) : g.MeasureString(s, font, int.MinValue); - SizeF sizeP = useSpan ? g.MeasureString(s.AsSpan(), font, int.MaxValue) : g.MeasureString(s, font, int.MaxValue); - Assert.Equal(size0, sizeN); - Assert.Equal(size0, sizeP); - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureString_StringFontInt_ShortString(bool useSpan) - { - MeasureString_StringFontInt("a", useSpan); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureString_StringFontInt_LongString(bool useSpan) - { - MeasureString_StringFontInt("A very long string...", useSpan); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureString_StringFormat_Alignment(bool useSpan) - { - string text = "Hello Mono::"; - - using (StringFormat string_format = new StringFormat()) - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - string_format.Alignment = StringAlignment.Near; - SizeF near = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - string_format.Alignment = StringAlignment.Center; - SizeF center = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - string_format.Alignment = StringAlignment.Far; - SizeF far = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - Assert.Equal((double)near.Width, center.Width, 1); - Assert.Equal((double)near.Height, center.Height, 1); - - Assert.Equal((double)center.Width, far.Width, 1); - Assert.Equal((double)center.Height, far.Height, 1); - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureString_StringFormat_Alignment_DirectionVertical(bool useSpan) - { - string text = "Hello Mono::"; - using (StringFormat string_format = new StringFormat()) - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - string_format.FormatFlags = StringFormatFlags.DirectionVertical; - - string_format.Alignment = StringAlignment.Near; - SizeF near = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - string_format.Alignment = StringAlignment.Center; - SizeF center = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - string_format.Alignment = StringAlignment.Far; - SizeF far = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - Assert.Equal((double)near.Width, center.Width, 0); - Assert.Equal((double)near.Height, center.Height, 0); - - Assert.Equal((double)center.Width, far.Width, 0); - Assert.Equal((double)center.Height, far.Height, 0); - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureString_StringFormat_LineAlignment(bool useSpan) - { - string text = "Hello Mono::"; - using (StringFormat string_format = new StringFormat()) - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - string_format.LineAlignment = StringAlignment.Near; - SizeF near = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - string_format.LineAlignment = StringAlignment.Center; - SizeF center = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - string_format.LineAlignment = StringAlignment.Far; - SizeF far = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - Assert.Equal((double)near.Width, center.Width, 1); - Assert.Equal((double)near.Height, center.Height, 1); - - Assert.Equal((double)center.Width, far.Width, 1); - Assert.Equal((double)center.Height, far.Height, 1); - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureString_StringFormat_LineAlignment_DirectionVertical(bool useSpan) - { - string text = "Hello Mono::"; - using (StringFormat string_format = new StringFormat()) - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - string_format.FormatFlags = StringFormatFlags.DirectionVertical; - - string_format.LineAlignment = StringAlignment.Near; - SizeF near = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - string_format.LineAlignment = StringAlignment.Center; - SizeF center = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - string_format.LineAlignment = StringAlignment.Far; - SizeF far = useSpan - ? g.MeasureString(text.AsSpan(), font, int.MaxValue, string_format) - : g.MeasureString(text, font, int.MaxValue, string_format); - - Assert.Equal((double)near.Width, center.Width, 1); - Assert.Equal((double)near.Height, center.Height, 1); - - Assert.Equal((double)center.Width, far.Width, 1); - Assert.Equal((double)center.Height, far.Height, 1); - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureString_CharactersFitted(bool useSpan) - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - string s = "aaa aa aaaa a aaa"; - SizeF size = useSpan ? g.MeasureString(s.AsSpan(), font) : g.MeasureString(s, font); - - int chars, lines; - SizeF size2 = useSpan - ? g.MeasureString(s.AsSpan(), font, new SizeF(80, size.Height), null, out chars, out lines) - : g.MeasureString(s, font, new SizeF(80, size.Height), null, out chars, out lines); - - // in pixels - Assert.True(size2.Width < size.Width); - Assert.Equal((double)size2.Height, size.Height); - - Assert.Equal(1, lines); - // documentation seems to suggest chars is total length - Assert.True(chars < s.Length); - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureString_Whitespace(bool useSpan) - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - string s = string.Empty; - SizeF size = useSpan ? g.MeasureString(s.AsSpan(), font) : g.MeasureString(s, font); - Assert.Equal(0, size.Height); - Assert.Equal(0, size.Width); - - s += " "; - SizeF expected = useSpan ? g.MeasureString(s.AsSpan(), font) : g.MeasureString(s, font); - for (int i = 1; i < 10; i++) - { - s += " "; - size = useSpan ? g.MeasureString(s.AsSpan(), font) : g.MeasureString(s, font); - Assert.Equal((double)expected.Height, size.Height, 1); - Assert.Equal((double)expected.Width, size.Width, 1); - } - - s = "a"; - expected = useSpan ? g.MeasureString(s.AsSpan(), font) : g.MeasureString(s, font); - s = " " + s; - size = useSpan ? g.MeasureString(s.AsSpan(), font) : g.MeasureString(s, font); - float space_width = size.Width - expected.Width; - for (int i = 1; i < 10; i++) - { - size = useSpan ? g.MeasureString(s.AsSpan(), font) : g.MeasureString(s, font); - Assert.Equal((double)expected.Height, size.Height, 1); - Assert.Equal((double)expected.Width + i * space_width, size.Width, 1); - s = " " + s; - } - - s = "a"; - expected = useSpan ? g.MeasureString(s.AsSpan(), font) : g.MeasureString(s, font); - for (int i = 1; i < 10; i++) - { - s = s + " "; - size = useSpan ? g.MeasureString(s.AsSpan(), font) : g.MeasureString(s, font); - Assert.Equal((double)expected.Height, size.Height, 1); - Assert.Equal((double)expected.Width, size.Width, 1); - } - } - } - - [Fact] - public void MeasureCharacterRanges_NullOrEmptyText() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Region[] regions = g.MeasureCharacterRanges(null, font, new RectangleF(), null); - Assert.Equal(0, regions.Length); - - regions = g.MeasureCharacterRanges(string.Empty, font, new RectangleF(), null); - Assert.Equal(0, regions.Length); - regions = g.MeasureCharacterRanges(string.Empty.AsSpan(), font, new RectangleF(), null); - Assert.Equal(0, regions.Length); - - // null font is ok with null or empty string - regions = g.MeasureCharacterRanges(null, null, new RectangleF(), null); - Assert.Equal(0, regions.Length); - - regions = g.MeasureCharacterRanges(string.Empty, null, new RectangleF(), null); - Assert.Equal(0, regions.Length); - regions = g.MeasureCharacterRanges(string.Empty.AsSpan(), null, new RectangleF(), null); - Assert.Equal(0, regions.Length); - } - } - - [Fact] - public void MeasureCharacterRanges_EmptyStringFormat() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - // string format without character ranges - Region[] regions = g.MeasureCharacterRanges("Mono", font, new RectangleF(), new StringFormat()); - Assert.Equal(0, regions.Length); - - g.MeasureCharacterRanges("Mono".AsSpan(), font, new RectangleF(), new StringFormat()); - Assert.Equal(0, regions.Length); - } - } - - [Fact] - public void MeasureCharacterRanges_FontNull() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.MeasureCharacterRanges("a", null, new RectangleF(), null)); - Assert.Throws(() => g.MeasureCharacterRanges("a".AsSpan(), null, new RectangleF(), null)); - } - } - - [Fact] - public void MeasureCharacterRanges_TwoLines() - { - string text = "this\nis a test"; - CharacterRange[] ranges = new CharacterRange[2]; - ranges[0] = new CharacterRange(0, 5); - ranges[1] = new CharacterRange(5, 9); - - using (StringFormat string_format = new StringFormat()) - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - string_format.FormatFlags = StringFormatFlags.NoClip; - string_format.SetMeasurableCharacterRanges(ranges); - - SizeF size = g.MeasureString(text, font, new Point(0, 0), string_format); - RectangleF layout_rect = new RectangleF(0.0f, 0.0f, size.Width, size.Height); - Region[] regions = g.MeasureCharacterRanges(text, font, layout_rect, string_format); - - Assert.Equal(2, regions.Length); - Assert.Equal(regions[0].GetBounds(g).Height, regions[1].GetBounds(g).Height); - - regions = g.MeasureCharacterRanges(text.AsSpan(), font, layout_rect, string_format); - - Assert.Equal(2, regions.Length); - Assert.Equal(regions[0].GetBounds(g).Height, regions[1].GetBounds(g).Height); - } - } - - private void MeasureCharacterRanges(string text, int first, int length, bool useSpan) - { - CharacterRange[] ranges = new CharacterRange[1]; - ranges[0] = new CharacterRange(first, length); - - using (StringFormat string_format = new StringFormat()) - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - string_format.FormatFlags = StringFormatFlags.NoClip; - string_format.SetMeasurableCharacterRanges(ranges); - - SizeF size = useSpan - ? g.MeasureString(text.AsSpan(), font, new Point(0, 0), string_format) - : g.MeasureString(text, font, new Point(0, 0), string_format); - RectangleF layout_rect = new RectangleF(0.0f, 0.0f, size.Width, size.Height); - if (useSpan) - { - g.MeasureCharacterRanges(text.AsSpan(), font, layout_rect, string_format); - } - else - { - g.MeasureCharacterRanges(text, font, layout_rect, string_format); - } - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureCharacterRanges_FirstTooFar(bool useSpan) - { - string text = "this\nis a test"; - Assert.Throws(() => MeasureCharacterRanges(text, text.Length, 1, useSpan)); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureCharacterRanges_LengthTooLong(bool useSpan) - { - string text = "this\nis a test"; - Assert.Throws(() => MeasureCharacterRanges(text, 0, text.Length + 1, useSpan)); - } - - [Fact] - public void MeasureCharacterRanges_Prefix() - { - string text = "Hello &Mono::"; - CharacterRange[] ranges = new CharacterRange[1]; - ranges[0] = new CharacterRange(5, 4); - - using (StringFormat string_format = new StringFormat()) - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - string_format.SetMeasurableCharacterRanges(ranges); - - SizeF size = g.MeasureString(text, font, new Point(0, 0), string_format); - RectangleF layout_rect = new RectangleF(0.0f, 0.0f, size.Width, size.Height); - - // here & is part of the measure and visible - string_format.HotkeyPrefix = HotkeyPrefix.None; - Region[] regions = g.MeasureCharacterRanges(text, font, layout_rect, string_format); - RectangleF bounds_none = regions[0].GetBounds(g); - - // here & is part of the measure (range) but visible as an underline - string_format.HotkeyPrefix = HotkeyPrefix.Show; - regions = g.MeasureCharacterRanges(text, font, layout_rect, string_format); - RectangleF bounds_show = regions[0].GetBounds(g); - Assert.True(bounds_show.Width < bounds_none.Width); - - regions = g.MeasureCharacterRanges(text.AsSpan(), font, layout_rect, string_format); - bounds_show = regions[0].GetBounds(g); - Assert.True(bounds_show.Width < bounds_none.Width); - - // here & is part of the measure (range) but invisible - string_format.HotkeyPrefix = HotkeyPrefix.Hide; - regions = g.MeasureCharacterRanges(text, font, layout_rect, string_format); - RectangleF bounds_hide = regions[0].GetBounds(g); - Assert.Equal((double)bounds_hide.Width, bounds_show.Width); - - g.MeasureCharacterRanges(text.AsSpan(), font, layout_rect, string_format); - bounds_hide = regions[0].GetBounds(g); - Assert.Equal((double)bounds_hide.Width, bounds_show.Width); - } - } - - [Fact] - public void MeasureCharacterRanges_NullStringFormat() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - { - Assert.Throws(() => g.MeasureCharacterRanges("Mono", font, new RectangleF(), null)); - Assert.Throws(() => g.MeasureCharacterRanges("Mono".AsSpan(), font, new RectangleF(), null)); - } - } - - static CharacterRange[] ranges = new CharacterRange[] { - new CharacterRange (0, 1), - new CharacterRange (1, 1), - new CharacterRange (2, 1) - }; - - Region[] Measure_Helper(Graphics gfx, RectangleF rect, bool useSpan) - { - using (StringFormat format = StringFormat.GenericTypographic) - { - format.SetMeasurableCharacterRanges(ranges); - - using (Font font = new Font(FontFamily.GenericSerif, 11.0f)) - { - return useSpan - ? gfx.MeasureCharacterRanges("abc".AsSpan(), font, rect, format) - : gfx.MeasureCharacterRanges("abc", font, rect, format); - } - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void Measure(bool useSpan) - { - using (Graphics gfx = Graphics.FromImage(new Bitmap(1, 1))) - { - Region[] zero = Measure_Helper(gfx, new RectangleF(0, 0, 0, 0), useSpan); - Assert.Equal(3, zero.Length); - - Region[] small = Measure_Helper(gfx, new RectangleF(0, 0, 100, 100), useSpan); - Assert.Equal(3, small.Length); - for (int i = 0; i < 3; i++) - { - RectangleF zb = zero[i].GetBounds(gfx); - RectangleF sb = small[i].GetBounds(gfx); - Assert.Equal(sb.X, zb.X); - Assert.Equal(sb.Y, zb.Y); - Assert.Equal((double)sb.Width, zb.Width); - Assert.Equal((double)sb.Height, zb.Height); - } - - Region[] max = Measure_Helper(gfx, new RectangleF(0, 0, float.MaxValue, float.MaxValue), useSpan); - Assert.Equal(3, max.Length); - for (int i = 0; i < 3; i++) - { - RectangleF zb = zero[i].GetBounds(gfx); - RectangleF mb = max[i].GetBounds(gfx); - Assert.Equal(mb.X, zb.X); - Assert.Equal(mb.Y, zb.Y); - Assert.Equal((double)mb.Width, zb.Width); - Assert.Equal((double)mb.Height, zb.Height); - } - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void MeasureLimits(bool useSpan) - { - using (Graphics gfx = Graphics.FromImage(new Bitmap(1, 1))) - { - Region[] min = Measure_Helper(gfx, new RectangleF(0, 0, float.MinValue, float.MinValue), useSpan); - Assert.Equal(3, min.Length); - for (int i = 0; i < 3; i++) - { - RectangleF mb = min[i].GetBounds(gfx); - Assert.Equal(-4194304.0f, mb.X); - Assert.Equal(-4194304.0f, mb.Y); - Assert.Equal(8388608.0f, mb.Width); - Assert.Equal(8388608.0f, mb.Height); - } - - Region[] neg = Measure_Helper(gfx, new RectangleF(0, 0, -20, -20), useSpan); - Assert.Equal(3, neg.Length); - for (int i = 0; i < 3; i++) - { - RectangleF mb = neg[i].GetBounds(gfx); - Assert.Equal(-4194304.0f, mb.X); - Assert.Equal(-4194304.0f, mb.Y); - Assert.Equal(8388608.0f, mb.Width); - Assert.Equal(8388608.0f, mb.Height); - } - } - } - - [Fact] - public void DrawString_EndlessLoop() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - using (StringFormat fmt = new StringFormat()) - { - Rectangle rect = Rectangle.Empty; - rect.Location = new Point(10, 10); - rect.Size = new Size(1, 20); - fmt.Alignment = StringAlignment.Center; - fmt.LineAlignment = StringAlignment.Center; - fmt.FormatFlags = StringFormatFlags.NoWrap; - fmt.Trimming = StringTrimming.EllipsisWord; - g.DrawString("Test String", font, Brushes.Black, rect, fmt); - g.DrawString("Test String".AsSpan(), font, Brushes.Black, rect, fmt); - } - } - - [Fact] - public void DrawString_EndlessLoop_Wrapping() - { - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - using (StringFormat fmt = new StringFormat()) - { - Rectangle rect = Rectangle.Empty; - rect.Location = new Point(10, 10); - rect.Size = new Size(1, 20); - fmt.Alignment = StringAlignment.Center; - fmt.LineAlignment = StringAlignment.Center; - fmt.Trimming = StringTrimming.EllipsisWord; - g.DrawString("Test String", font, Brushes.Black, rect, fmt); - g.DrawString("Test String".AsSpan(), font, Brushes.Black, rect, fmt); - } - } - - [Fact] - public void MeasureString_Wrapping_Dots() - { - string text = "this is really long text........................................... with a lot o periods."; - using (Bitmap bitmap = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bitmap)) - using (StringFormat format = new StringFormat()) - { - format.Alignment = StringAlignment.Center; - SizeF sz = g.MeasureString(text, font, 80, format); - Assert.True(sz.Width <= 80); - Assert.True(sz.Height > font.Height * 2); - - sz = g.MeasureString(text.AsSpan(), font, 80, format); - Assert.True(sz.Width <= 80); - Assert.True(sz.Height > font.Height * 2); - } - } - - [Fact] - public void GetReleaseHdcInternal() - { - using (Bitmap b = new Bitmap(10, 10)) - using (Graphics g = Graphics.FromImage(b)) - { - IntPtr hdc1 = g.GetHdc(); - g.ReleaseHdcInternal(hdc1); - IntPtr hdc2 = g.GetHdc(); - g.ReleaseHdcInternal(hdc2); - Assert.Equal(hdc1, hdc2); - } - } - - [Fact] - public void ReleaseHdcInternal_IntPtrZero() - { - using (Bitmap b = new Bitmap(10, 10)) - using (Graphics g = Graphics.FromImage(b)) - { - Assert.Throws(() => g.ReleaseHdcInternal(IntPtr.Zero)); - } - } - - [Fact] - public void ReleaseHdcInternal_TwoTimes() - { - using (Bitmap b = new Bitmap(10, 10)) - using (Graphics g = Graphics.FromImage(b)) - { - IntPtr hdc = g.GetHdc(); - g.ReleaseHdcInternal(hdc); - Assert.Throws(() => g.ReleaseHdcInternal(hdc)); - } - } - [Fact] - public void TestReleaseHdc() - { - using (Bitmap b = new Bitmap(10, 10)) - using (Graphics g = Graphics.FromImage(b)) - { - IntPtr hdc1 = g.GetHdc(); - g.ReleaseHdc(); - IntPtr hdc2 = g.GetHdc(); - g.ReleaseHdc(); - Assert.Equal(hdc1, hdc2); - } - } - - [Fact] - public void TestReleaseHdcException() - { - using (Bitmap b = new Bitmap(10, 10)) - using (Graphics g = Graphics.FromImage(b)) - { - Assert.Throws(() => g.ReleaseHdc()); - } - } - - [Fact] - public void TestReleaseHdcException2() - { - using (Bitmap b = new Bitmap(10, 10)) - using (Graphics g = Graphics.FromImage(b)) - { - g.GetHdc(); - g.ReleaseHdc(); - Assert.Throws(() => g.ReleaseHdc()); - } - } - [ConditionalFact] - public void VisibleClipBound() - { - if (PlatformDetection.IsArmOrArm64Process) - { - // [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")] - throw new SkipTestException("Precision on float numbers"); - } - - // see #78958 - using (Bitmap bmp = new Bitmap(100, 100)) - using (Graphics g = Graphics.FromImage(bmp)) - { - RectangleF noclip = g.VisibleClipBounds; - Assert.Equal(0, noclip.X); - Assert.Equal(0, noclip.Y); - Assert.Equal(100, noclip.Width); - Assert.Equal(100, noclip.Height); - - // note: libgdiplus regions are precise to multiple of multiple of 8 - g.Clip = new Region(new RectangleF(0, 0, 32, 32)); - RectangleF clip = g.VisibleClipBounds; - Assert.Equal(0, clip.X); - Assert.Equal(0, clip.Y); - Assert.Equal(32.0, clip.Width, 4); - Assert.Equal(32.0, clip.Height, 4); - - g.RotateTransform(90); - RectangleF rotclip = g.VisibleClipBounds; - Assert.Equal(0, rotclip.X); - Assert.Equal(-32.0, rotclip.Y, 4); - Assert.Equal(32.0, rotclip.Width, 4); - Assert.Equal(32.0, rotclip.Height, 4); - } - } - - [ConditionalFact] - public void VisibleClipBound_BigClip() - { - if (PlatformDetection.IsArmOrArm64Process) - { - //ActiveIssue: 35744 - throw new SkipTestException("Precision on float numbers"); - } - - using (Bitmap bmp = new Bitmap(100, 100)) - using (Graphics g = Graphics.FromImage(bmp)) - { - RectangleF noclip = g.VisibleClipBounds; - Assert.Equal(0, noclip.X); - Assert.Equal(0, noclip.Y); - Assert.Equal(100, noclip.Width); - Assert.Equal(100, noclip.Height); - - // clip is larger than bitmap - g.Clip = new Region(new RectangleF(0, 0, 200, 200)); - RectangleF clipbound = g.ClipBounds; - Assert.Equal(0, clipbound.X); - Assert.Equal(0, clipbound.Y); - Assert.Equal(200, clipbound.Width); - Assert.Equal(200, clipbound.Height); - - RectangleF clip = g.VisibleClipBounds; - Assert.Equal(0, clip.X); - Assert.Equal(0, clip.Y); - Assert.Equal(100, clip.Width); - Assert.Equal(100, clip.Height); - - g.RotateTransform(90); - RectangleF rotclipbound = g.ClipBounds; - Assert.Equal(0, rotclipbound.X); - Assert.Equal(-200.0, rotclipbound.Y, 4); - Assert.Equal(200.0, rotclipbound.Width, 4); - Assert.Equal(200.0, rotclipbound.Height, 4); - - RectangleF rotclip = g.VisibleClipBounds; - Assert.Equal(0, rotclip.X); - Assert.Equal(-100.0, rotclip.Y, 4); - Assert.Equal(100.0, rotclip.Width, 4); - Assert.Equal(100.0, rotclip.Height, 4); - } - } - - [ConditionalFact] - public void Rotate() - { - if (PlatformDetection.IsArmOrArm64Process) - { - //ActiveIssue: 35744 - throw new SkipTestException("Precision on float numbers"); - } - - using (Bitmap bmp = new Bitmap(100, 50)) - using (Graphics g = Graphics.FromImage(bmp)) - { - RectangleF vcb = g.VisibleClipBounds; - Assert.Equal(0, vcb.X); - Assert.Equal(0, vcb.Y); - Assert.Equal(100.0, vcb.Width, 4); - Assert.Equal(50.0, vcb.Height, 4); - - g.RotateTransform(90); - RectangleF rvcb = g.VisibleClipBounds; - Assert.Equal(0, rvcb.X); - Assert.Equal(-100.0, rvcb.Y, 4); - Assert.Equal(50.0, rvcb.Width, 4); - Assert.Equal(100.0, rvcb.Height, 4); - } - } - - [Fact] - public void Scale() - { - using (Bitmap bmp = new Bitmap(100, 50)) - using (Graphics g = Graphics.FromImage(bmp)) - { - RectangleF vcb = g.VisibleClipBounds; - Assert.Equal(0, vcb.X); - Assert.Equal(0, vcb.Y); - Assert.Equal(100, vcb.Width); - Assert.Equal(50, vcb.Height); - - g.ScaleTransform(2, 0.5f); - RectangleF svcb = g.VisibleClipBounds; - Assert.Equal(0, svcb.X); - Assert.Equal(0, svcb.Y); - Assert.Equal(50, svcb.Width); - Assert.Equal(100, svcb.Height); - } - } - - [Fact] - public void Translate() - { - using (Bitmap bmp = new Bitmap(100, 50)) - using (Graphics g = Graphics.FromImage(bmp)) - { - RectangleF vcb = g.VisibleClipBounds; - Assert.Equal(0, vcb.X); - Assert.Equal(0, vcb.Y); - Assert.Equal(100, vcb.Width); - Assert.Equal(50, vcb.Height); - - g.TranslateTransform(-25, 25); - RectangleF tvcb = g.VisibleClipBounds; - Assert.Equal(25, tvcb.X); - Assert.Equal(-25, tvcb.Y); - Assert.Equal(100, tvcb.Width); - Assert.Equal(50, tvcb.Height); - } - } - - [Fact] - public void DrawIcon_NullRectangle() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawIcon(null, new Rectangle(0, 0, 32, 32))); - } - } - - [Fact] - public void DrawIcon_IconRectangle() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawIcon(SystemIcons.Application, new Rectangle(0, 0, 40, 20)); - // Rectangle is empty when X, Y, Width and Height == 0 - // (yep X and Y too, RectangleF only checks for Width and Height) - g.DrawIcon(SystemIcons.Asterisk, new Rectangle(0, 0, 0, 0)); - // so this one is half-empty ;-) - g.DrawIcon(SystemIcons.Error, new Rectangle(20, 40, 0, 0)); - // negative width or height isn't empty (for Rectangle) - g.DrawIconUnstretched(SystemIcons.WinLogo, new Rectangle(10, 20, -1, 0)); - g.DrawIconUnstretched(SystemIcons.WinLogo, new Rectangle(20, 10, 0, -1)); - } - } - - [Fact] - public void DrawIcon_NullIntInt() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawIcon(null, 4, 2)); - } - } - - [Fact] - public void DrawIcon_IconIntInt() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawIcon(SystemIcons.Exclamation, 4, 2); - g.DrawIcon(SystemIcons.Hand, 0, 0); - } - } - - [Fact] - public void DrawIconUnstretched_NullRectangle() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawIconUnstretched(null, new Rectangle(0, 0, 40, 20))); - } - } - - [Fact] - public void DrawIconUnstretched_IconRectangle() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawIconUnstretched(SystemIcons.Information, new Rectangle(0, 0, 40, 20)); - // Rectangle is empty when X, Y, Width and Height == 0 - // (yep X and Y too, RectangleF only checks for Width and Height) - g.DrawIconUnstretched(SystemIcons.Question, new Rectangle(0, 0, 0, 0)); - // so this one is half-empty ;-) - g.DrawIconUnstretched(SystemIcons.Warning, new Rectangle(20, 40, 0, 0)); - // negative width or height isn't empty (for Rectangle) - g.DrawIconUnstretched(SystemIcons.WinLogo, new Rectangle(10, 20, -1, 0)); - g.DrawIconUnstretched(SystemIcons.WinLogo, new Rectangle(20, 10, 0, -1)); - } - } - - [Fact] - public void DrawImage_NullRectangleF() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, new RectangleF(0, 0, 0, 0))); - } - } - - [Fact] - public void DrawImage_ImageRectangleF() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImage(bmp, new RectangleF(0, 0, 0, 0)); - g.DrawImage(bmp, new RectangleF(20, 40, 0, 0)); - g.DrawImage(bmp, new RectangleF(10, 20, -1, 0)); - g.DrawImage(bmp, new RectangleF(20, 10, 0, -1)); - } - } - - [Fact] - public void DrawImage_NullPointF() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, new PointF(0, 0))); - } - } - - [Fact] - public void DrawImage_ImagePointF() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImage(bmp, new PointF(0, 0)); - } - } - - [Fact] - public void DrawImage_NullPointFArray() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, new PointF[0])); - } - } - - [Fact] - public void DrawImage_ImagePointFArrayNull() - { - using (Bitmap bmp = new Bitmap(40, 40)) - { - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(bmp, (PointF[])null)); - } - } - } - - [Fact] - public void DrawImage_ImagePointFArrayEmpty() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(bmp, new PointF[0])); - } - } - - [Fact] - public void DrawImage_ImagePointFArray() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImage(bmp, new PointF[] { - new PointF (0, 0), new PointF (1, 1), new PointF (2, 2) }); - } - } - - [Fact] - public void DrawImage_NullRectangle() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, new Rectangle(0, 0, 0, 0))); - } - } - - [Fact] - public void DrawImage_ImageRectangle() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - // Rectangle is empty when X, Y, Width and Height == 0 - // (yep X and Y too, RectangleF only checks for Width and Height) - g.DrawImage(bmp, new Rectangle(0, 0, 0, 0)); - // so this one is half-empty ;-) - g.DrawImage(bmp, new Rectangle(20, 40, 0, 0)); - // negative width or height isn't empty (for Rectangle) - g.DrawImage(bmp, new Rectangle(10, 20, -1, 0)); - g.DrawImage(bmp, new Rectangle(20, 10, 0, -1)); - } - } - - [Fact] - public void DrawImage_NullPoint() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, new Point(0, 0))); - } - } - - [Fact] - public void DrawImage_ImagePoint() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImage(bmp, new Point(0, 0)); - } - } - - [Fact] - public void DrawImage_NullPointArray() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, new Point[0])); - } - } - - [Fact] - public void DrawImage_ImagePointArrayNull() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(bmp, (Point[])null)); - } - } - - [Fact] - public void DrawImage_ImagePointArrayEmpty() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(bmp, new Point[0])); - } - } - - [Fact] - public void DrawImage_ImagePointArray() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImage(bmp, new Point[] { - new Point (0, 0), new Point (1, 1), new Point (2, 2) }); - } - } - - [Fact] - public void DrawImage_NullIntInt() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, int.MaxValue, int.MinValue)); - } - } - - [Fact] - public void DrawImage_ImageIntInt_Overflow() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(bmp, int.MaxValue, int.MinValue)); - } - } - - [Fact] - public void DrawImage_ImageIntInt() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImage(bmp, -40, -40); - } - } - - [Fact] - public void DrawImage_NullFloat() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, float.MaxValue, float.MinValue)); - } - } - - [Fact] - public void DrawImage_ImageFloatFloat_Overflow() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(bmp, float.MaxValue, float.MinValue)); - } - } - - [Fact] - public void DrawImage_ImageFloatFloat() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImage(bmp, -40.0f, -40.0f); - } - } - - [Fact] - public void DrawImage_NullRectangleRectangleGraphicsUnit() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, new Rectangle(), new Rectangle(), GraphicsUnit.Display)); - } - } - - private void DrawImage_ImageRectangleRectangleGraphicsUnit(GraphicsUnit unit) - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Rectangle r = new Rectangle(0, 0, 40, 40); - g.DrawImage(bmp, r, r, unit); - } - } - - [Fact] - public void DrawImage_ImageRectangleRectangleGraphicsUnit_Display() - { - Assert.Throws(() => DrawImage_ImageRectangleRectangleGraphicsUnit(GraphicsUnit.Display)); - } - - [Fact] - public void DrawImage_ImageRectangleRectangleGraphicsUnit_Pixel() - { - // this unit works - DrawImage_ImageRectangleRectangleGraphicsUnit(GraphicsUnit.Pixel); - } - - [Fact] - public void DrawImage_ImageRectangleRectangleGraphicsUnit_World() - { - Assert.Throws(() => DrawImage_ImageRectangleRectangleGraphicsUnit(GraphicsUnit.World)); - } - - [Fact] - public void DrawImage_NullPointRectangleGraphicsUnit() - { - Rectangle r = new Rectangle(1, 2, 3, 4); - Point[] pts = new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }; - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, pts, r, GraphicsUnit.Pixel)); - } - } - - private void DrawImage_ImagePointRectangleGraphicsUnit(Point[] pts) - { - Rectangle r = new Rectangle(1, 2, 3, 4); - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImage(bmp, pts, r, GraphicsUnit.Pixel); - } - } - - [Fact] - public void DrawImage_ImageNullRectangleGraphicsUnit() - { - Assert.Throws(() => DrawImage_ImagePointRectangleGraphicsUnit(null)); - } - - [Fact] - public void DrawImage_ImagePoint0RectangleGraphicsUnit() - { - Assert.Throws(() => DrawImage_ImagePointRectangleGraphicsUnit(new Point[0])); - } - - [Fact] - public void DrawImage_ImagePoint1RectangleGraphicsUnit() - { - Point p = new Point(1, 1); - Assert.Throws(() => DrawImage_ImagePointRectangleGraphicsUnit(new Point[1] { p })); - } - - [Fact] - public void DrawImage_ImagePoint2RectangleGraphicsUnit() - { - Point p = new Point(1, 1); - Assert.Throws(() => DrawImage_ImagePointRectangleGraphicsUnit(new Point[2] { p, p })); - } - - [Fact] - public void DrawImage_ImagePoint3RectangleGraphicsUnit() - { - Point p = new Point(1, 1); - DrawImage_ImagePointRectangleGraphicsUnit(new Point[3] { p, p, p }); - } - - [Fact] - public void DrawImage_ImagePoint4RectangleGraphicsUnit() - { - Point p = new Point(1, 1); - Assert.Throws(() => DrawImage_ImagePointRectangleGraphicsUnit(new Point[4] { p, p, p, p })); - } - - [Fact] - public void DrawImage_NullPointFRectangleGraphicsUnit() - { - Rectangle r = new Rectangle(1, 2, 3, 4); - PointF[] pts = new PointF[3] { new PointF(1, 1), new PointF(2, 2), new PointF(3, 3) }; - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImage(null, pts, r, GraphicsUnit.Pixel)); - } - } - - private void DrawImage_ImagePointFRectangleGraphicsUnit(PointF[] pts) - { - Rectangle r = new Rectangle(1, 2, 3, 4); - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImage(bmp, pts, r, GraphicsUnit.Pixel); - } - } - - [Fact] - public void DrawImage_ImageNullFRectangleGraphicsUnit() - { - Assert.Throws(() => DrawImage_ImagePointFRectangleGraphicsUnit(null)); - } - - [Fact] - public void DrawImage_ImagePointF0RectangleGraphicsUnit() - { - Assert.Throws(() => DrawImage_ImagePointFRectangleGraphicsUnit(new PointF[0])); - } - - [Fact] - public void DrawImage_ImagePointF1RectangleGraphicsUnit() - { - PointF p = new PointF(1, 1); - Assert.Throws(() => DrawImage_ImagePointFRectangleGraphicsUnit(new PointF[1] { p })); - } - - [Fact] - public void DrawImage_ImagePointF2RectangleGraphicsUnit() - { - PointF p = new PointF(1, 1); - Assert.Throws(() => DrawImage_ImagePointFRectangleGraphicsUnit(new PointF[2] { p, p })); - } - - [Fact] - public void DrawImage_ImagePointF3RectangleGraphicsUnit() - { - PointF p = new PointF(1, 1); - DrawImage_ImagePointFRectangleGraphicsUnit(new PointF[3] { p, p, p }); - } - - [Fact] - public void DrawImage_ImagePointF4RectangleGraphicsUnit() - { - PointF p = new PointF(1, 1); - Assert.Throws(() => DrawImage_ImagePointFRectangleGraphicsUnit(new PointF[4] { p, p, p, p })); - } - - [Fact] - public void DrawImage_ImagePointRectangleGraphicsUnitNull() - { - Point p = new Point(1, 1); - Point[] pts = new Point[3] { p, p, p }; - Rectangle r = new Rectangle(1, 2, 3, 4); - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImage(bmp, pts, r, GraphicsUnit.Pixel, null); - } - } - - [Fact] - public void DrawImage_ImagePointRectangleGraphicsUnitAttributes() - { - Point p = new Point(1, 1); - Point[] pts = new Point[3] { p, p, p }; - Rectangle r = new Rectangle(1, 2, 3, 4); - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - using (ImageAttributes ia = new ImageAttributes()) - { - g.DrawImage(bmp, pts, r, GraphicsUnit.Pixel, ia); - } - } - - [Fact] - public void DrawImageUnscaled_NullPoint() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImageUnscaled(null, new Point(0, 0))); - } - } - - [Fact] - public void DrawImageUnscaled_ImagePoint() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImageUnscaled(bmp, new Point(0, 0)); - } - } - - [Fact] - public void DrawImageUnscaled_NullRectangle() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImageUnscaled(null, new Rectangle(0, 0, -1, -1))); - } - } - - [Fact] - public void DrawImageUnscaled_ImageRectangle() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImageUnscaled(bmp, new Rectangle(0, 0, -1, -1)); - } - } - - [Fact] - public void DrawImageUnscaled_NullIntInt() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImageUnscaled(null, 0, 0)); - } - } - - [Fact] - public void DrawImageUnscaled_ImageIntInt() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImageUnscaled(bmp, 0, 0); - } - } - - [Fact] - public void DrawImageUnscaled_NullIntIntIntInt() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImageUnscaled(null, 0, 0, -1, -1)); - } - } - - [Fact] - public void DrawImageUnscaled_ImageIntIntIntInt() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - g.DrawImageUnscaled(bmp, 0, 0, -1, -1); - } - } - - [Fact] - public void DrawImageUnscaledAndClipped_Null() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawImageUnscaledAndClipped(null, new Rectangle(0, 0, 0, 0))); - } - } - - [Fact] - public void DrawImageUnscaledAndClipped() - { - using (Bitmap bmp = new Bitmap(40, 40)) - using (Graphics g = Graphics.FromImage(bmp)) - { - // Rectangle is empty when X, Y, Width and Height == 0 - // (yep X and Y too, RectangleF only checks for Width and Height) - g.DrawImageUnscaledAndClipped(bmp, new Rectangle(0, 0, 0, 0)); - // so this one is half-empty ;-) - g.DrawImageUnscaledAndClipped(bmp, new Rectangle(20, 40, 0, 0)); - // negative width or height isn't empty (for Rectangle) - g.DrawImageUnscaledAndClipped(bmp, new Rectangle(10, 20, -1, 0)); - g.DrawImageUnscaledAndClipped(bmp, new Rectangle(20, 10, 0, -1)); - // smaller - g.DrawImageUnscaledAndClipped(bmp, new Rectangle(0, 0, 10, 20)); - g.DrawImageUnscaledAndClipped(bmp, new Rectangle(0, 0, 40, 10)); - g.DrawImageUnscaledAndClipped(bmp, new Rectangle(0, 0, 80, 20)); - } - } - - [Fact] - public void DrawPath_Pen_Null() - { - using (Bitmap bmp = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bmp)) - using (GraphicsPath path = new GraphicsPath()) - { - Assert.Throws(() => g.DrawPath(null, path)); - } - } - - [Fact] - public void DrawPath_Path_Null() - { - using (Bitmap bmp = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.DrawPath(Pens.Black, null)); - } - } - - [Fact] - public void DrawPath_Arcs() - { - using (Bitmap bmp = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bmp)) - using (GraphicsPath path = new GraphicsPath()) - { - int d = 5; - Rectangle baserect = new Rectangle(0, 0, 19, 19); - Rectangle arcrect = new Rectangle(baserect.Location, new Size(d, d)); - - path.AddArc(arcrect, 180, 90); - arcrect.X = baserect.Right - d; - path.AddArc(arcrect, 270, 90); - arcrect.Y = baserect.Bottom - d; - path.AddArc(arcrect, 0, 90); - arcrect.X = baserect.Left; - path.AddArc(arcrect, 90, 90); - path.CloseFigure(); - g.Clear(Color.White); - g.DrawPath(Pens.SteelBlue, path); - - Assert.Equal(-12156236, bmp.GetPixel(0, 9).ToArgb()); - Assert.Equal(-1, bmp.GetPixel(1, 9).ToArgb()); - } - } - - [Fact] - public void FillPath_Brush_Null() - { - using (Bitmap bmp = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bmp)) - using (GraphicsPath path = new GraphicsPath()) - { - Assert.Throws(() => g.FillPath(null, path)); - } - } - - [Fact] - public void FillPath_Path_Null() - { - using (Bitmap bmp = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Throws(() => g.FillPath(Brushes.Black, null)); - } - } - - [Fact] - public void FillPath_Arcs() - { - using (Bitmap bmp = new Bitmap(20, 20)) - using (Graphics g = Graphics.FromImage(bmp)) - using (GraphicsPath path = new GraphicsPath()) - { - int d = 5; - Rectangle baserect = new Rectangle(0, 0, 19, 19); - Rectangle arcrect = new Rectangle(baserect.Location, new Size(d, d)); - - path.AddArc(arcrect, 180, 90); - arcrect.X = baserect.Right - d; - path.AddArc(arcrect, 270, 90); - arcrect.Y = baserect.Bottom - d; - path.AddArc(arcrect, 0, 90); - arcrect.X = baserect.Left; - path.AddArc(arcrect, 90, 90); - path.CloseFigure(); - g.Clear(Color.White); - g.FillPath(Brushes.SteelBlue, path); - - Assert.Equal(-12156236, bmp.GetPixel(0, 9).ToArgb()); - Assert.Equal(-12156236, bmp.GetPixel(1, 9).ToArgb()); - } - } - - [Fact] - public void TransformPoints() - { - using (Bitmap bmp = new Bitmap(10, 10)) - using (Graphics g = Graphics.FromImage(bmp)) - { - Point[] pts = new Point[5]; - PointF[] ptf = new PointF[5]; - for (int i = 0; i < 5; i++) - { - pts[i] = new Point(i, i); - ptf[i] = new PointF(i, i); - } - - g.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Device, pts); - g.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Device, ptf); - - for (int i = 0; i < 5; i++) - { - Assert.Equal(i, pts[i].X); - Assert.Equal(i, pts[i].Y); - Assert.Equal(i, ptf[i].X); - Assert.Equal(i, ptf[i].Y); - } - } - } - - [Fact] - public void Dpi() - { - float x, y; - using (Bitmap bmp = new Bitmap(10, 10)) - { - using (Graphics g = Graphics.FromImage(bmp)) - { - x = g.DpiX - 10; - y = g.DpiY + 10; - } - bmp.SetResolution(x, y); - using (Graphics g = Graphics.FromImage(bmp)) - { - Assert.Equal(x, g.DpiX); - Assert.Equal(y, g.DpiY); - } - } - } - - [Fact] - public void GetReleaseHdc() - { - using (Bitmap b = new Bitmap(100, 100)) - { - using (Graphics g = Graphics.FromImage(b)) - { - IntPtr hdc1 = g.GetHdc(); - g.ReleaseHdc(hdc1); - IntPtr hdc2 = g.GetHdc(); - g.ReleaseHdc(hdc2); - Assert.Equal(hdc1, hdc2); - } - } - } -} diff --git a/src/System.Drawing.Common/tests/mono/System.Imaging/MetafileTest.cs b/src/System.Drawing.Common/tests/mono/System.Imaging/MetafileTest.cs deleted file mode 100644 index fd34ddd01dc..00000000000 --- a/src/System.Drawing.Common/tests/mono/System.Imaging/MetafileTest.cs +++ /dev/null @@ -1,461 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Metafile class unit tests -// -// Authors: -// Sebastien Pouliot -// -// Copyright (C) 2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; - -namespace MonoTests.System.Drawing.Imaging; - -public class MetafileTest -{ - public const string Bitmap = "non-inverted.bmp"; - public const string WmfPlaceable = "telescope_01.wmf"; - public const string Emf = "milkmateya01.emf"; - - [Fact] - public void Metafile_String() - { - string filename = Helpers.GetTestBitmapPath(WmfPlaceable); - using (Metafile mf = new Metafile(filename)) - using (Metafile clone = (Metafile)mf.Clone()) - { - } - } - - private static void Check_MetaHeader_WmfPlaceable(MetaHeader mh) - { - Assert.Equal(9, mh.HeaderSize); - Assert.Equal(98, mh.MaxRecord); - Assert.Equal(3, mh.NoObjects); - Assert.Equal(0, mh.NoParameters); - Assert.Equal(1737, mh.Size); - Assert.Equal(1, mh.Type); - Assert.Equal(0x300, mh.Version); - } - - private static void Check_MetafileHeader_WmfPlaceable(MetafileHeader header) - { - Assert.Equal(MetafileType.WmfPlaceable, header.Type); - Assert.Equal(0x300, header.Version); - // filesize - 22, which happens to be the size (22) of a PLACEABLEMETAHEADER struct - Assert.Equal(3474, header.MetafileSize); - - Assert.Equal(-30, header.Bounds.X); - Assert.Equal(-40, header.Bounds.Y); - Assert.Equal(3096, header.Bounds.Width); - Assert.Equal(4127, header.Bounds.Height); - Assert.Equal(606, header.DpiX); - Assert.Equal(606, header.DpiY); - Assert.Equal(0, header.EmfPlusHeaderSize); - Assert.Equal(0, header.LogicalDpiX); - Assert.Equal(0, header.LogicalDpiY); - - Assert.NotNull(header.WmfHeader); - Check_MetaHeader_WmfPlaceable(header.WmfHeader); - - Assert.False(header.IsDisplay()); - Assert.False(header.IsEmf()); - Assert.False(header.IsEmfOrEmfPlus()); - Assert.False(header.IsEmfPlus()); - Assert.False(header.IsEmfPlusDual()); - Assert.False(header.IsEmfPlusOnly()); - Assert.True(header.IsWmf()); - Assert.True(header.IsWmfPlaceable()); - } - - [Fact] - public void GetMetafileHeader_FromFile_WmfPlaceable() - { - using (Metafile mf = new Metafile(Helpers.GetTestBitmapPath(WmfPlaceable))) - { - MetafileHeader header1 = mf.GetMetafileHeader(); - Check_MetafileHeader_WmfPlaceable(header1); - - MetaHeader mh1 = header1.WmfHeader; - Check_MetaHeader_WmfPlaceable(mh1); - - MetaHeader mh2 = mf.GetMetafileHeader().WmfHeader; - Assert.NotSame(mh1, mh2); - } - } - - [Fact] - public void GetMetafileHeader_FromFileStream_WmfPlaceable() - { - using (FileStream fs = File.OpenRead(Helpers.GetTestBitmapPath(WmfPlaceable))) - using (Metafile mf = new Metafile(fs)) - { - MetafileHeader header1 = mf.GetMetafileHeader(); - Check_MetafileHeader_WmfPlaceable(header1); - - MetaHeader mh1 = header1.WmfHeader; - Check_MetaHeader_WmfPlaceable(mh1); - - MetaHeader mh2 = mf.GetMetafileHeader().WmfHeader; - Assert.NotSame(mh1, mh2); - } - } - - [Fact] - public void GetMetafileHeader_FromMemoryStream_WmfPlaceable() - { - string filename = Helpers.GetTestBitmapPath(WmfPlaceable); - using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(filename))) - using (Metafile mf = new Metafile(ms)) - { - MetafileHeader header1 = mf.GetMetafileHeader(); - Check_MetafileHeader_WmfPlaceable(header1); - - MetaHeader mh1 = header1.WmfHeader; - Check_MetaHeader_WmfPlaceable(mh1); - - MetaHeader mh2 = mf.GetMetafileHeader().WmfHeader; - Assert.NotSame(mh1, mh2); - } - } - - private static void Check_MetafileHeader_Emf(MetafileHeader header) - { - Assert.Equal(MetafileType.Emf, header.Type); - Assert.Equal(65536, header.Version); - // exactly the filesize - Assert.Equal(20456, header.MetafileSize); - - Assert.Equal(0, header.Bounds.X); - Assert.Equal(0, header.Bounds.Y); - - Assert.Throws(() => header.WmfHeader); - - Assert.False(header.IsDisplay()); - Assert.True(header.IsEmf()); - Assert.True(header.IsEmfOrEmfPlus()); - Assert.False(header.IsEmfPlus()); - Assert.False(header.IsEmfPlusDual()); - Assert.False(header.IsEmfPlusOnly()); - Assert.False(header.IsWmf()); - Assert.False(header.IsWmfPlaceable()); - } - - [Fact] - public void GetMetafileHeader_FromFile_Emf() - { - using (Metafile mf = new Metafile(Helpers.GetTestBitmapPath(Emf))) - { - MetafileHeader header1 = mf.GetMetafileHeader(); - Check_MetafileHeader_Emf(header1); - } - } - - [Fact] - public void GetMetafileHeader_FromFileStream_Emf() - { - using (FileStream fs = File.OpenRead(Helpers.GetTestBitmapPath(Emf))) - using (Metafile mf = new Metafile(fs)) - { - MetafileHeader header1 = mf.GetMetafileHeader(); - Check_MetafileHeader_Emf(header1); - } - } - - [Fact] - public void GetMetafileHeader_FromMemoryStream_Emf() - { - string filename = Helpers.GetTestBitmapPath(Emf); - using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(filename))) - using (Metafile mf = new Metafile(ms)) - { - MetafileHeader header1 = mf.GetMetafileHeader(); - Check_MetafileHeader_Emf(header1); - } - } -} - -public class MetafileFulltrustTest -{ - private void CheckEmptyHeader(Metafile mf, EmfType type) - { - MetafileHeader mh = mf.GetMetafileHeader(); - Assert.Equal(0, mh.Bounds.X); - Assert.Equal(0, mh.Bounds.Y); - Assert.Equal(0, mh.Bounds.Width); - Assert.Equal(0, mh.Bounds.Height); - Assert.Equal(0, mh.MetafileSize); - switch (type) - { - case EmfType.EmfOnly: - Assert.Equal(MetafileType.Emf, mh.Type); - break; - case EmfType.EmfPlusDual: - Assert.Equal(MetafileType.EmfPlusDual, mh.Type); - break; - case EmfType.EmfPlusOnly: - Assert.Equal(MetafileType.EmfPlusOnly, mh.Type); - break; - default: - Assert.True(false, $"Unknown EmfType '{type}'"); - break; - } - } - - private void Metafile_IntPtrEmfType(EmfType type) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - { - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr hdc = g.GetHdc(); - try - { - Metafile mf = new Metafile(hdc, type); - CheckEmptyHeader(mf, type); - } - finally - { - g.ReleaseHdc(hdc); - } - } - } - } - - [Fact] - public void Metafile_IntPtrRectangle_Empty() - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr hdc = g.GetHdc(); - try - { - Metafile mf = new Metafile(hdc, new Rectangle()); - CheckEmptyHeader(mf, EmfType.EmfPlusDual); - } - finally - { - g.ReleaseHdc(hdc); - } - } - } - - [Fact] - public void Metafile_IntPtrRectangleF_Empty() - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr hdc = g.GetHdc(); - try - { - Metafile mf = new Metafile(hdc, new RectangleF()); - CheckEmptyHeader(mf, EmfType.EmfPlusDual); - } - finally - { - g.ReleaseHdc(hdc); - } - } - } - - private void Metafile_StreamEmfType(Stream stream, EmfType type) - { - using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr hdc = g.GetHdc(); - try - { - Metafile mf = new Metafile(stream, hdc, type); - CheckEmptyHeader(mf, type); - } - finally - { - g.ReleaseHdc(hdc); - } - } - } - - [Fact] - public void Metafile_StreamIntPtrEmfType_Null() - { - Assert.Throws(() => Metafile_StreamEmfType(null, EmfType.EmfOnly)); - } - - [Fact] - public void Metafile_StreamIntPtrEmfType_EmfOnly() - { - using (MemoryStream ms = new MemoryStream()) - { - Metafile_StreamEmfType(ms, EmfType.EmfOnly); - } - } - - [Fact] - public void Metafile_StreamIntPtrEmfType_Invalid() - { - using (MemoryStream ms = new MemoryStream()) - { - Assert.Throws(() => Metafile_StreamEmfType(ms, (EmfType)int.MinValue)); - } - } - - private void CreateFilename(EmfType type, bool single) - { - string name = $"{type}-{(single ? "Single" : "Multiple")}.emf"; - string filename = Path.Combine(Path.GetTempPath(), name); - Metafile mf; - using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppArgb)) - { - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr hdc = g.GetHdc(); - try - { - mf = new Metafile(filename, hdc, type); - Assert.Equal(0, new FileInfo(filename).Length); - } - finally - { - g.ReleaseHdc(hdc); - } - } - long size = 0; - using (Graphics g = Graphics.FromImage(mf)) - { - g.FillRectangle(Brushes.BlueViolet, 10, 10, 80, 80); - size = new FileInfo(filename).Length; - Assert.Equal(0, size); - } - - if (!single) - { - using (Graphics g = Graphics.FromImage(mf)) - { - g.DrawRectangle(Pens.Azure, 10, 10, 80, 80); - } - } - mf.Dispose(); - Assert.Equal(size, new FileInfo(filename).Length); - } - } - - [Fact] - public void Measure() - { - Font test_font = new Font(FontFamily.GenericMonospace, 12); - - Metafile mf; - using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppArgb)) - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr hdc = g.GetHdc(); - try - { - mf = new Metafile(hdc, EmfType.EmfPlusOnly); - } - finally - { - g.ReleaseHdc(hdc); - } - } - using (Graphics g = Graphics.FromImage(mf)) - { - string text = "this\nis a test"; - CharacterRange[] ranges = new CharacterRange[2]; - ranges[0] = new CharacterRange(0, 5); - ranges[1] = new CharacterRange(5, 9); - - SizeF size = g.MeasureString(text, test_font); - Assert.False(size.IsEmpty); - - StringFormat sf = new StringFormat(); - sf.FormatFlags = StringFormatFlags.NoClip; - sf.SetMeasurableCharacterRanges(ranges); - - RectangleF rect = new RectangleF(0, 0, size.Width, size.Height); - Region[] region = g.MeasureCharacterRanges(text, test_font, rect, sf); - Assert.Equal(2, region.Length); - - region = g.MeasureCharacterRanges(text.AsSpan(), test_font, rect, sf); - Assert.Equal(2, region.Length); - mf.Dispose(); - } - } - - [Fact] - public void WorldTransforms() - { - Metafile mf; - using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppArgb)) - { - using (Graphics g = Graphics.FromImage(bmp)) - { - IntPtr hdc = g.GetHdc(); - try - { - mf = new Metafile(hdc, EmfType.EmfPlusOnly); - } - finally - { - g.ReleaseHdc(hdc); - } - } - using (Graphics g = Graphics.FromImage(mf)) - { - Assert.True(g.Transform.IsIdentity); - g.ScaleTransform(2f, 0.5f); - Assert.False(g.Transform.IsIdentity); - g.RotateTransform(90); - g.TranslateTransform(-2, 2); - Matrix m = g.Transform; - g.MultiplyTransform(m); - // check - float[] elements = g.Transform.Elements; - Assert.Equal(-1.0, elements[0], 5); - Assert.Equal(0.0, elements[1], 5); - Assert.Equal(0.0, elements[2], 5); - Assert.Equal(-1.0, elements[3], 5); - Assert.Equal(-2.0, elements[4], 5); - Assert.Equal(-3.0, elements[5], 5); - - g.Transform = m; - elements = g.Transform.Elements; - Assert.Equal(0.0, elements[0], 5); - Assert.Equal(0.5, elements[1], 5); - Assert.Equal(-2.0, elements[2], 5); - Assert.Equal(0.0, elements[3], 5); - Assert.Equal(-4.0, elements[4], 5); - Assert.Equal(-1.0, elements[5], 5); - - g.ResetTransform(); - Assert.True(g.Transform.IsIdentity); - } - mf.Dispose(); - } - } -} diff --git a/src/System.Drawing.Common/tests/runtimeconfig.template.json b/src/System.Drawing.Common/tests/runtimeconfig.template.json deleted file mode 100644 index e460762026c..00000000000 --- a/src/System.Drawing.Common/tests/runtimeconfig.template.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "configProperties": { - "TestSwitch.LocalAppContext.DisableCaching": "true", - "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": "false" - } -} \ No newline at end of file diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/CompilerAnalyzerConfigOptions.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/CompilerAnalyzerConfigOptions.cs deleted file mode 100644 index ebeecf43bc1..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/CompilerAnalyzerConfigOptions.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; -using Microsoft.CodeAnalysis.Diagnostics; - -namespace System.Windows.Forms.Analyzers.Tests; - -// Borrowed from https://github.com/dotnet/roslyn/blob/main/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerConfigOptions.cs - -[ExcludeFromCodeCoverage] -internal sealed class CompilerAnalyzerConfigOptions : AnalyzerConfigOptions -{ - public static CompilerAnalyzerConfigOptions Empty { get; } = new CompilerAnalyzerConfigOptions(ImmutableDictionary.Create()); - - private readonly ImmutableDictionary _backing; - - public CompilerAnalyzerConfigOptions(ImmutableDictionary properties) - { - _backing = properties; - } - - public override bool TryGetValue(string key, [NotNullWhen(true)] out string? value) => _backing.TryGetValue(key, out value); -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/CompilerAnalyzerConfigOptionsProvider.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/CompilerAnalyzerConfigOptionsProvider.cs deleted file mode 100644 index 691b01ba4d4..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/CompilerAnalyzerConfigOptionsProvider.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Diagnostics; - -namespace System.Windows.Forms.Analyzers.Tests; - -// Borrowed from https://github.com/dotnet/roslyn/blob/main/src/Compilers/Core/Portable/DiagnosticAnalyzer/CompilerAnalyzerConfigOptionsProvider.cs - -[ExcludeFromCodeCoverage] -internal sealed class CompilerAnalyzerConfigOptionsProvider : AnalyzerConfigOptionsProvider -{ - private readonly ImmutableDictionary _treeDict; - - public static CompilerAnalyzerConfigOptionsProvider Empty { get; } - = new CompilerAnalyzerConfigOptionsProvider( - ImmutableDictionary.Empty, - CompilerAnalyzerConfigOptions.Empty); - - internal CompilerAnalyzerConfigOptionsProvider( - ImmutableDictionary treeDict, - AnalyzerConfigOptions globalOptions) - { - _treeDict = treeDict; - GlobalOptions = globalOptions; - } - - public override AnalyzerConfigOptions GlobalOptions { get; } - - public override AnalyzerConfigOptions GetOptions(SyntaxTree tree) - => _treeDict.TryGetValue(tree, out var options) ? options : CompilerAnalyzerConfigOptions.Empty; - - public override AnalyzerConfigOptions GetOptions(AdditionalText textFile) - => _treeDict.TryGetValue(textFile, out var options) ? options : CompilerAnalyzerConfigOptions.Empty; - - internal CompilerAnalyzerConfigOptionsProvider WithAdditionalTreeOptions(ImmutableDictionary treeDict) - => new(_treeDict.AddRange(treeDict), GlobalOptions); - - internal CompilerAnalyzerConfigOptionsProvider WithGlobalOptions(AnalyzerConfigOptions globalOptions) - => new(_treeDict, globalOptions); -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System.Windows.Forms.Analyzers.CSharp.Tests.csproj b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System.Windows.Forms.Analyzers.CSharp.Tests.csproj deleted file mode 100644 index dacf2b356ce..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System.Windows.Forms.Analyzers.CSharp.Tests.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - enable - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - PreserveNewest - - - - diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationGeneratorTests.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationGeneratorTests.cs deleted file mode 100644 index 9f957a3e8d0..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationGeneratorTests.cs +++ /dev/null @@ -1,211 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text; -using System.Windows.Forms.Analyzers; -using System.Windows.Forms.Analyzers.Tests; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Text; -using Xunit; -using static System.Windows.Forms.Analyzers.ApplicationConfig; - -namespace System.Windows.Forms.Generators.Tests; - -public partial class ApplicationConfigurationGeneratorTests -{ - private const string SourceCompilable = @" -namespace MyProject -{ - class Program - { - static void Main() - { - ApplicationConfiguration.Initialize(); - } - } -}"; - private const string SourceCompilationFailed = @" -namespace MyProject -{ - class Program - { - static void Main() - { - {|CS0103:ApplicationConfiguration|}.Initialize(); - } - } -}"; - - public static IEnumerable UnsupportedProjectTypes_TestData() - { - foreach (OutputKind projectType in Enum.GetValues(typeof(OutputKind))) - { - if (projectType != OutputKind.ConsoleApplication && - projectType != OutputKind.WindowsApplication) - { - yield return new object[] { projectType }; - } - } - } - - [Theory] - [MemberData(nameof(UnsupportedProjectTypes_TestData))] - public async Task ApplicationConfigurationGenerator_GenerateInitialize_fails_if_project_type_unsupported(OutputKind projectType) - { - var test = new CSharpIncrementalSourceGeneratorVerifier.Test - { - TestState = - { - OutputKind = projectType, - Sources = { SourceCompilationFailed }, - ExpectedDiagnostics = - { - DiagnosticResult.CompilerError("WFAC001").WithArguments("WindowsApplication"), - } - }, - }; - - await test.RunAsync().ConfigureAwait(false); - } - - [Theory] - [InlineData(OutputKind.ConsoleApplication)] - [InlineData(OutputKind.WindowsApplication)] - public async Task ApplicationConfigurationGenerator_GenerateInitialize_pass_if_supported_project_type(OutputKind projectType) - { - SourceText generatedCode = LoadFileContent("GenerateInitialize_default_boilerplate"); - - var test = new CSharpIncrementalSourceGeneratorVerifier.Test - { - TestState = - { - OutputKind = projectType, - Sources = { SourceCompilable }, - GeneratedSources = - { - (typeof(ApplicationConfigurationGenerator), "ApplicationConfiguration.g.cs", generatedCode), - }, - }, - }; - - await test.RunAsync().ConfigureAwait(false); - } - - [Fact] - public async Task ApplicationConfigurationGenerator_GenerateInitialize_default_boilerplate() - { - SourceText generatedCode = LoadFileContent("GenerateInitialize_default_boilerplate"); - - var test = new CSharpIncrementalSourceGeneratorVerifier.Test - { - TestState = - { - OutputKind = OutputKind.WindowsApplication, - Sources = { SourceCompilable }, - GeneratedSources = - { - (typeof(ApplicationConfigurationGenerator), "ApplicationConfiguration.g.cs", generatedCode), - }, - }, - }; - - await test.RunAsync().ConfigureAwait(false); - } - - [Fact] - public async Task ApplicationConfigurationGenerator_GenerateInitialize_user_settings_boilerplate() - { - SourceText generatedCode = LoadFileContent("GenerateInitialize_user_settings_boilerplate"); - - var test = new CSharpIncrementalSourceGeneratorVerifier.Test - { - TestState = - { - OutputKind = OutputKind.WindowsApplication, - Sources = { SourceCompilable }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $@"is_global = true - -build_property.{PropertyNameCSharp.DefaultFont} = Microsoft Sans Serif, 8.25px -build_property.{PropertyNameCSharp.EnableVisualStyles} = -build_property.{PropertyNameCSharp.HighDpiMode} = {HighDpiMode.DpiUnawareGdiScaled} -build_property.{PropertyNameCSharp.UseCompatibleTextRendering} = true -"), - }, - GeneratedSources = - { - (typeof(ApplicationConfigurationGenerator), "ApplicationConfiguration.g.cs", generatedCode), - }, - }, - }; - - await test.RunAsync().ConfigureAwait(false); - } - - [Fact] - public async Task ApplicationConfigurationGenerator_GenerateInitialize_default_top_level() - { - const string source = @" -ApplicationConfiguration.Initialize(); -"; - - SourceText generatedCode = LoadFileContent("GenerateInitialize_default_top_level"); - - var test = new CSharpIncrementalSourceGeneratorVerifier.Test - { - TestState = - { - OutputKind = OutputKind.WindowsApplication, - Sources = { source }, - GeneratedSources = - { - (typeof(ApplicationConfigurationGenerator), "ApplicationConfiguration.g.cs", generatedCode), - }, - }, - }; - - await test.RunAsync().ConfigureAwait(false); - } - - [Fact] - public async Task ApplicationConfigurationGenerator_GenerateInitialize_user_settings_top_level() - { - const string source = @" -ApplicationConfiguration.Initialize(); -"; - - SourceText generatedCode = LoadFileContent("GenerateInitialize_user_top_level"); - - var test = new CSharpIncrementalSourceGeneratorVerifier.Test - { - TestState = - { - OutputKind = OutputKind.WindowsApplication, - Sources = { source }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $@"is_global = true - -build_property.{PropertyNameCSharp.DefaultFont} = Microsoft Sans Serif, 8.25px -build_property.{PropertyNameCSharp.EnableVisualStyles} = -build_property.{PropertyNameCSharp.HighDpiMode} = {HighDpiMode.DpiUnawareGdiScaled} -build_property.{PropertyNameCSharp.UseCompatibleTextRendering} = true -"), - }, - GeneratedSources = - { - (typeof(ApplicationConfigurationGenerator), "ApplicationConfiguration.g.cs", generatedCode), - }, - }, - }; - - await test.RunAsync().ConfigureAwait(false); - } - - private SourceText LoadFileContent(string testName) - => SourceText.From( - File.ReadAllText($@"System\Windows\Forms\Generators\MockData\{GetType().Name}.{testName}.cs"), - Encoding.UTF8); -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=SansSerif.verified.txt b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=SansSerif.verified.txt deleted file mode 100644 index f76e8661f6f..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=SansSerif.verified.txt +++ /dev/null @@ -1,30 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// global::System.Windows.Forms.Application.SetDefaultFont(new global::System.Drawing.Font(new global::System.Drawing.FontFamily("Microsoft Sans Serif"), 8.25f, (global::System.Drawing.FontStyle)0, (global::System.Drawing.GraphicsUnit)3)); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - global::System.Windows.Forms.Application.SetDefaultFont(new global::System.Drawing.Font(new global::System.Drawing.FontFamily("Microsoft Sans Serif"), 8.25f, (global::System.Drawing.FontStyle)0, (global::System.Drawing.GraphicsUnit)3)); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=Tahoma.verified.txt b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=Tahoma.verified.txt deleted file mode 100644 index 97184b57304..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=Tahoma.verified.txt +++ /dev/null @@ -1,30 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// global::System.Windows.Forms.Application.SetDefaultFont(new global::System.Drawing.Font(new global::System.Drawing.FontFamily("Tahoma"), 12f, (global::System.Drawing.FontStyle)0, (global::System.Drawing.GraphicsUnit)3)); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - global::System.Windows.Forms.Application.SetDefaultFont(new global::System.Drawing.Font(new global::System.Drawing.FontFamily("Tahoma"), 12f, (global::System.Drawing.FontStyle)0, (global::System.Drawing.GraphicsUnit)3)); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=default.verified.txt b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=default.verified.txt deleted file mode 100644 index f47084cb332..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=default.verified.txt +++ /dev/null @@ -1,30 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// global::System.Windows.Forms.Application.SetDefaultFont(new global::System.Drawing.Font(global::System.Windows.Forms.Control.DefaultFont.FontFamily, 12f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)6)); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - global::System.Windows.Forms.Application.SetDefaultFont(new global::System.Drawing.Font(global::System.Windows.Forms.Control.DefaultFont.FontFamily, 12f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)6)); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=null.verified.txt b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=null.verified.txt deleted file mode 100644 index 4a0fdfa03df..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_DefaultFont=null.verified.txt +++ /dev/null @@ -1,28 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_EnableVisualStyles=false.verified.txt b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_EnableVisualStyles=false.verified.txt deleted file mode 100644 index 1cb051c7d4b..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_EnableVisualStyles=false.verified.txt +++ /dev/null @@ -1,26 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_EnableVisualStyles=true.verified.txt b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_EnableVisualStyles=true.verified.txt deleted file mode 100644 index 4a0fdfa03df..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_EnableVisualStyles=true.verified.txt +++ /dev/null @@ -1,28 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_UseCompTextRendering=false.verified.txt b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_UseCompTextRendering=false.verified.txt deleted file mode 100644 index 4a0fdfa03df..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_UseCompTextRendering=false.verified.txt +++ /dev/null @@ -1,28 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_UseCompTextRendering=true.verified.txt b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_UseCompTextRendering=true.verified.txt deleted file mode 100644 index c163b70a99a..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.GenerateInitialize_UseCompTextRendering=true.verified.txt +++ /dev/null @@ -1,28 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.cs deleted file mode 100644 index 77fd3124ed9..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ApplicationConfigurationInitializeBuilderTests.cs +++ /dev/null @@ -1,165 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Globalization; -using System.Windows.Forms.Analyzers; -using VerifyXunit; -using Xunit; -using static System.Windows.Forms.Analyzers.ApplicationConfig; - -namespace System.Windows.Forms.Generators.Tests; - -[UsesVerify] -public partial class ApplicationConfigurationInitializeBuilderTests -{ - private static readonly string[] s_locales = new[] - { - "ar-SA", - "en-US", - "es-ES", - "fr-FR", - "hi-IN", - "ja-JP", - "ru-RU", - "tr-TR", - "zh-CN" - }; - - [Theory] - [InlineData(null, "default_top_level")] - [InlineData("", "default_top_level")] - [InlineData(" ", "default_top_level")] - [InlineData("\t", "default_top_level")] - [InlineData("MyProject", "default_boilerplate")] - public void ApplicationConfigurationInitializeBuilder_GenerateInitialize_can_handle_namespace(string ns, string expectedFileName) - { - string expected = File.ReadAllText($@"System\Windows\Forms\Generators\MockData\{GetType().Name}.{expectedFileName}.cs"); - - string output = ApplicationConfigurationInitializeBuilder.GenerateInitialize(ns, - new ApplicationConfig( - EnableVisualStyles: PropertyDefaultValue.EnableVisualStyles, - DefaultFont: null, - HighDpiMode: PropertyDefaultValue.DpiMode, - UseCompatibleTextRendering: PropertyDefaultValue.UseCompatibleTextRendering - )); - - Assert.Equal(expected, output); - } - - public static IEnumerable GenerateInitializeData() - { - foreach (string cultureName in s_locales) - { - CultureInfo culture = new CultureInfo(cultureName); - - // EnableVisualStyles: false, true - yield return new object[] - { - culture, - new ApplicationConfig( - EnableVisualStyles: false, - DefaultFont: null, - HighDpiMode: PropertyDefaultValue.DpiMode, - UseCompatibleTextRendering: PropertyDefaultValue.UseCompatibleTextRendering - ), - "EnableVisualStyles=false" - }; - yield return new object[] - { - culture, - new ApplicationConfig( - EnableVisualStyles: true, - DefaultFont: null, - HighDpiMode: PropertyDefaultValue.DpiMode, - UseCompatibleTextRendering: PropertyDefaultValue.UseCompatibleTextRendering - ), - "EnableVisualStyles=true" - }; - - // UseCompatibleTextRendering: false, true - yield return new object[] - { - culture, - new ApplicationConfig( - EnableVisualStyles: PropertyDefaultValue.EnableVisualStyles, - DefaultFont: null, - HighDpiMode: PropertyDefaultValue.DpiMode, - UseCompatibleTextRendering: false - ), - "UseCompTextRendering=false" - }; - yield return new object[] - { - culture, - new ApplicationConfig( - EnableVisualStyles: PropertyDefaultValue.EnableVisualStyles, - DefaultFont: null, - HighDpiMode: PropertyDefaultValue.DpiMode, - UseCompatibleTextRendering: true - ), - "UseCompTextRendering=true" - }; - - // DefaultFont: null, FontDescriptor - yield return new object[] - { - culture, - new ApplicationConfig( - EnableVisualStyles: PropertyDefaultValue.EnableVisualStyles, - DefaultFont: null, - HighDpiMode: PropertyDefaultValue.DpiMode, - UseCompatibleTextRendering: false - ), - "DefaultFont=null" - }; - yield return new object[] - { - culture, - new ApplicationConfig( - EnableVisualStyles: PropertyDefaultValue.EnableVisualStyles, - DefaultFont: new FontDescriptor(string.Empty, 12, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Millimeter).ToString(), - HighDpiMode: PropertyDefaultValue.DpiMode, - UseCompatibleTextRendering: true - ), - "DefaultFont=default" - }; - yield return new object[] - { - culture, - new ApplicationConfig( - EnableVisualStyles: PropertyDefaultValue.EnableVisualStyles, - DefaultFont: new FontDescriptor("Tahoma", 12, FontStyle.Regular, GraphicsUnit.Point).ToString(), - HighDpiMode: PropertyDefaultValue.DpiMode, - UseCompatibleTextRendering: true - ), - "DefaultFont=Tahoma" - }; - yield return new object[] - { - culture, - new ApplicationConfig( - EnableVisualStyles: PropertyDefaultValue.EnableVisualStyles, - DefaultFont: new FontDescriptor("Microsoft Sans Serif", 8.25f, FontStyle.Regular, GraphicsUnit.Point).ToString(), - HighDpiMode: PropertyDefaultValue.DpiMode, - UseCompatibleTextRendering: true - ), - "DefaultFont=SansSerif" - }; - } - } - - [Theory] - [MemberData(nameof(GenerateInitializeData))] - public Task ApplicationConfigurationInitializeBuilder_GenerateInitialize(CultureInfo culture, /* ApplicationConfig */object config, string testName) - { - Thread.CurrentThread.CurrentCulture = culture; - - string output = ApplicationConfigurationInitializeBuilder.GenerateInitialize(null, (ApplicationConfig)config); - - // Compare all locale tests against the same files - we expect the produced output to be the same - return Verifier.Verify(output) - .UseMethodName("GenerateInitialize") - .UseTextForParameters(testName) - .DisableRequireUniquePrefix(); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_default_boilerplate.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_default_boilerplate.cs deleted file mode 100644 index 5fb1050cdc8..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_default_boilerplate.cs +++ /dev/null @@ -1,30 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Windows.Forms; - -namespace MyProject -{ - /// - /// Bootstrap the application configuration. - /// - [CompilerGenerated] - internal static partial class ApplicationConfiguration - { - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - global::System.Windows.Forms.Application.{|CS0117:SetHighDpiMode|}({|CS0103:HighDpiMode|}.SystemAware); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_default_top_level.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_default_top_level.cs deleted file mode 100644 index 10c6ce18b1f..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_default_top_level.cs +++ /dev/null @@ -1,28 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - global::System.Windows.Forms.Application.{|CS0117:SetHighDpiMode|}({|CS0103:HighDpiMode|}.SystemAware); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_user_settings_boilerplate.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_user_settings_boilerplate.cs deleted file mode 100644 index 7e3e726507a..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_user_settings_boilerplate.cs +++ /dev/null @@ -1,32 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Windows.Forms; - -namespace MyProject -{ - /// - /// Bootstrap the application configuration. - /// - [CompilerGenerated] - internal static partial class ApplicationConfiguration - { - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.DpiUnawareGdiScaled); - /// global::System.Windows.Forms.Application.SetDefaultFont(new global::System.Drawing.Font(new global::System.Drawing.FontFamily("Microsoft Sans Serif"), 8.25f, (global::System.Drawing.FontStyle)0, (global::System.Drawing.GraphicsUnit)2)); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - global::System.Windows.Forms.Application.{|CS0117:SetHighDpiMode|}({|CS0103:HighDpiMode|}.DpiUnawareGdiScaled); - global::System.Windows.Forms.Application.{|CS0117:SetDefaultFont|}(new global::System.Drawing.Font(new global::System.Drawing.FontFamily("Microsoft Sans Serif"), 8.25f, (global::System.Drawing.FontStyle)0, (global::System.Drawing.GraphicsUnit)2)); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_user_top_level.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_user_top_level.cs deleted file mode 100644 index d030c8babd4..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationGeneratorTests.GenerateInitialize_user_top_level.cs +++ /dev/null @@ -1,30 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.DpiUnawareGdiScaled); - /// global::System.Windows.Forms.Application.SetDefaultFont(new global::System.Drawing.Font(new global::System.Drawing.FontFamily("Microsoft Sans Serif"), 8.25f, (global::System.Drawing.FontStyle)0, (global::System.Drawing.GraphicsUnit)2)); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(true); - global::System.Windows.Forms.Application.{|CS0117:SetHighDpiMode|}({|CS0103:HighDpiMode|}.DpiUnawareGdiScaled); - global::System.Windows.Forms.Application.{|CS0117:SetDefaultFont|}(new global::System.Drawing.Font(new global::System.Drawing.FontFamily("Microsoft Sans Serif"), 8.25f, (global::System.Drawing.FontStyle)0, (global::System.Drawing.GraphicsUnit)2)); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationInitializeBuilderTests.default_boilerplate.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationInitializeBuilderTests.default_boilerplate.cs deleted file mode 100644 index 1b57f5db88a..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationInitializeBuilderTests.default_boilerplate.cs +++ /dev/null @@ -1,30 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Windows.Forms; - -namespace MyProject -{ - /// - /// Bootstrap the application configuration. - /// - [CompilerGenerated] - internal static partial class ApplicationConfiguration - { - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationInitializeBuilderTests.default_top_level.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationInitializeBuilderTests.default_top_level.cs deleted file mode 100644 index 4a0fdfa03df..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/MockData/ApplicationConfigurationInitializeBuilderTests.default_top_level.cs +++ /dev/null @@ -1,28 +0,0 @@ -// - -using System.Drawing; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Windows.Forms; - -/// -/// Bootstrap the application configuration. -/// -[CompilerGenerated] -internal static partial class ApplicationConfiguration -{ - /// - /// Bootstrap the application as follows: - /// - /// global::System.Windows.Forms.Application.EnableVisualStyles(); - /// global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - /// global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - /// - /// - public static void Initialize() - { - global::System.Windows.Forms.Application.EnableVisualStyles(); - global::System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); - global::System.Windows.Forms.Application.SetHighDpiMode(HighDpiMode.SystemAware); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ProjectFileReaderTests.FontConverter.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ProjectFileReaderTests.FontConverter.cs deleted file mode 100644 index 316fbc4022d..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ProjectFileReaderTests.FontConverter.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Globalization; -using Xunit; -using static System.Windows.Forms.Analyzers.ApplicationConfig; -using static System.Windows.Forms.Generators.ProjectFileReader; - -namespace System.Windows.Forms.Generators.Tests; - -public partial class ProjectFileReaderTests -{ - public class FontConverterTest - { - private static readonly string[] s_locales = new[] - { - "ar-SA", - "en-US", - "es-ES", - "fr-FR", - "hi-IN", - "ja-JP", - "ru-RU", - "tr-TR", - "zh-CN" - }; - - public static IEnumerable TestConvertFormData() - { - foreach (string cultureName in s_locales) - { - CultureInfo culture = new CultureInfo(cultureName); - - yield return new object[] { culture, $"Courier New", "Courier New", PropertyDefaultValue.FontSize, (int)GraphicsUnit.Point, (int)FontStyle.Regular }; - yield return new object[] { culture, $"Courier New{s_separator} 11", "Courier New", 11f, (int)GraphicsUnit.Point, (int)FontStyle.Regular }; - yield return new object[] { culture, $"Arial{s_separator} 11px", "Arial", 11f, (int)GraphicsUnit.Pixel, (int)FontStyle.Regular }; - yield return new object[] { culture, $"Courier New{s_separator} 11 px", "Courier New", 11f, (int)GraphicsUnit.Pixel, (int)FontStyle.Regular }; - yield return new object[] { culture, $"Courier New{s_separator} 11 px{s_separator} style=Regular", "Courier New", 11f, (int)GraphicsUnit.Pixel, (int)FontStyle.Regular }; - yield return new object[] { culture, $"Courier New{s_separator} style=Bold", "Courier New", PropertyDefaultValue.FontSize, (int)GraphicsUnit.Point, (int)FontStyle.Bold }; - yield return new object[] { culture, $"Courier New{s_separator} 11 px{s_separator} style=Bold{s_separator} Italic", "Courier New", 11f, (int)GraphicsUnit.Pixel, (int)(FontStyle.Bold | FontStyle.Italic) }; - yield return new object[] { culture, $"Courier New{s_separator} 11 px{s_separator} style=Regular, Italic", "Courier New", 11f, (int)GraphicsUnit.Pixel, (int)(FontStyle.Regular | FontStyle.Italic) }; - yield return new object[] { culture, $"Courier New{s_separator} 11 px{s_separator} style=Bold{s_separator} Italic{s_separator} Strikeout", "Courier New", 11f, (int)GraphicsUnit.Pixel, (int)(FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout) }; - yield return new object[] { culture, $"Arial{s_separator} 11 px{s_separator} style=Bold, Italic, Strikeout", "Arial", 11f, (int)GraphicsUnit.Pixel, (int)(FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout) }; - yield return new object[] { culture, $"arIAL{s_separator} 10{s_separator} style=bold", "arIAL", 10f, (int)GraphicsUnit.Point, (int)FontStyle.Bold }; - yield return new object[] { culture, $"Arial{s_separator} 10{s_separator}", "Arial", 10f, (int)GraphicsUnit.Point, (int)FontStyle.Regular }; - yield return new object[] { culture, $"Arial{s_separator}", "Arial", PropertyDefaultValue.FontSize, (int)GraphicsUnit.Point, (int)FontStyle.Regular }; - yield return new object[] { culture, $"Arial{s_separator} 10{s_separator} style=12", "Arial", 10f, (int)GraphicsUnit.Point, (int)(FontStyle.Underline | FontStyle.Strikeout) }; - yield return new object[] { culture, $"Courier New{s_separator} Style=Bold", "Courier New", PropertyDefaultValue.FontSize, (int)GraphicsUnit.Point, (int)FontStyle.Bold }; // FullFramework style keyword is case sensitive. - yield return new object[] { culture, $"{s_separator} 10{s_separator} style=bold", "", 10f, (int)GraphicsUnit.Point, (int)FontStyle.Bold }; - - // NOTE: in .NET runtime these tests will result in FontName='', but the implementation relies on GDI+, which we don't have... - yield return new object[] { culture, $"11px{s_separator} Style=Bold", $"11px", PropertyDefaultValue.FontSize, (int)GraphicsUnit.Point, (int)FontStyle.Bold }; - yield return new object[] { culture, $"11px", "11px", PropertyDefaultValue.FontSize, (int)GraphicsUnit.Point, (int)FontStyle.Regular }; - yield return new object[] { culture, $"Style=Bold", "Style=Bold", PropertyDefaultValue.FontSize, (int)GraphicsUnit.Point, (int)FontStyle.Regular }; - } - } - - [Theory] - [MemberData(nameof(TestConvertFormData))] - internal void TestConvertFrom(CultureInfo culture, string input, string expectedName, float expectedSize, GraphicsUnit expectedUnits, FontStyle expectedFontStyle) - { - Thread.CurrentThread.CurrentCulture = culture; - - FontDescriptor font = FontConverter.ConvertFrom(input)!; - - Assert.Equal(expectedName, font.Name); - Assert.Equal(expectedSize, font.Size); - Assert.Equal(expectedUnits, font.Unit); - Assert.Equal(expectedFontStyle, font.Style); - } - - public static TheoryData ArgumentExceptionFontConverterData() - => new() - { - { $"Courier New{s_separator} 11 px{s_separator} type=Bold{s_separator} Italic" }, - { $"Courier New{s_separator} {s_separator} Style=Bold" }, - { $"Courier New{s_separator} 11{s_separator} Style=" }, - { $"Courier New{s_separator} 11{s_separator} Style=RandomEnum" }, - { $"Arial{s_separator} 10{s_separator} style=bold{s_separator}" }, - { $"Arial{s_separator} 10{s_separator} style=null" }, - { $"Arial{s_separator} 10{s_separator} style=abc#" }, - { $"Arial{s_separator} 10{s_separator} style=##" }, - { $"Arial{s_separator} 10display{s_separator} style=bold" }, - { $"Arial{s_separator} 10style{s_separator} style=bold" }, - }; - - [Theory] - [MemberData(nameof(ArgumentExceptionFontConverterData))] - public void InvalidInputThrowsArgumentException(string input) - { - Assert.Throws(() => FontConverter.ConvertFrom(input)); - } - - public static TheoryData InvalidEnumArgumentExceptionFontConverterData() - => new() - { - { $"Arial{s_separator} 10{s_separator} style=56", "style" }, - { $"Arial{s_separator} 10{s_separator} style=-1", "style" }, - }; - - [Theory] - [MemberData(nameof(InvalidEnumArgumentExceptionFontConverterData))] - public void InvalidInputThrowsInvalidEnumArgumentException(string input, string paramName) - { - Assert.Throws(paramName, () => FontConverter.ConvertFrom(input)); - } - - [Fact] - public void EmptyStringInput() - { - FontDescriptor? font = FontConverter.ConvertFrom(string.Empty); - Assert.Null(font); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ProjectFileReaderTests.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ProjectFileReaderTests.cs deleted file mode 100644 index 1ab65bba012..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System/Windows/Forms/Generators/ProjectFileReaderTests.cs +++ /dev/null @@ -1,220 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using System.Globalization; -using System.Windows.Forms.Analyzers; -using System.Windows.Forms.Analyzers.Tests; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Diagnostics; -using Xunit; -using Xunit.Abstractions; -using static System.Windows.Forms.Analyzers.ApplicationConfig; - -namespace System.Windows.Forms.Generators.Tests; - -public partial class ProjectFileReaderTests -{ - private static readonly char s_separator = CultureInfo.CurrentCulture.TextInfo.ListSeparator[0]; - private static readonly dynamic s_static = typeof(ProjectFileReader).TestAccessor().Dynamic; - private readonly ITestOutputHelper _output; - - private static bool TryReadBool(AnalyzerConfigOptionsProvider configOptions, string propertyName, bool defaultValue, out bool value, out Diagnostic? diagnostic) - => (bool)s_static.TryReadBool(configOptions, propertyName, defaultValue, out value, out diagnostic); - - private static bool TryReadFont(AnalyzerConfigOptionsProvider configOptions, out FontDescriptor? font, out Diagnostic? diagnostic) - => (bool)s_static.TryReadFont(configOptions, out font, out diagnostic); - - private static bool TryReadHighDpiMode(AnalyzerConfigOptionsProvider configOptions, out HighDpiMode highDpiMode, out Diagnostic? diagnostic) - => (bool)s_static.TryReadHighDpiMode(configOptions, out highDpiMode, out diagnostic); - - public ProjectFileReaderTests(ITestOutputHelper output) - { - _output = output; - } - - [Theory] - [InlineData("a")] - [InlineData("@")] - [InlineData("yes")] - [InlineData("no")] - [InlineData("0")] - [InlineData("1")] - [InlineData("-1")] - public void ProjectFileReader_TryReadBool_value_invalid(string value) - { - Dictionary properties = new() - { - { $"build_property.myvalue", value } - }; - CompilerAnalyzerConfigOptions configOptions = new(properties.ToImmutableDictionary()); - CompilerAnalyzerConfigOptionsProvider provider = new(ImmutableDictionary.Empty, configOptions); - - bool result = TryReadBool(provider, "myvalue", defaultValue: false, out bool returnedValue, out Diagnostic? diagnostic); - - Assert.False(result); - Assert.False(returnedValue); - Assert.NotNull(diagnostic); - Assert.Equal(DiagnosticDescriptors.s_propertyCantBeSetToValue, diagnostic!.Descriptor); - _output.WriteLine(diagnostic.ToString()); - } - - [Theory] - [InlineData("", true)] // default value - [InlineData("false", false)] - [InlineData("true", true)] - [InlineData("False", false)] - [InlineData("True", true)] - [InlineData("FALSE", false)] - [InlineData("TRUE", true)] - public void ProjectFileReader_TryReadBool_value_valid(string value, bool expected) - { - Dictionary properties = new() - { - { $"build_property.myvalue", value } - }; - CompilerAnalyzerConfigOptions configOptions = new(properties.ToImmutableDictionary()); - CompilerAnalyzerConfigOptionsProvider provider = new(ImmutableDictionary.Empty, configOptions); - - bool result = TryReadBool(provider, "myvalue", defaultValue: true, out bool returnedValue, out Diagnostic? diagnostic); - - Assert.True(result); - Assert.Equal(expected, returnedValue); - Assert.Null(diagnostic); - } - - public static TheoryData ExceptionFontConverterData() - => new() - { - // ArgumentException - { $"Courier New{s_separator} 11 px{s_separator} type=Bold{s_separator} Italic" }, - { $"Courier New{s_separator} {s_separator} Style=Bold" }, - { $"Courier New{s_separator} 11{s_separator} Style=" }, - { $"Courier New{s_separator} 11{s_separator} Style=RandomEnum" }, - { $"Arial{s_separator} 10{s_separator} style=bold{s_separator}" }, - { $"Arial{s_separator} 10{s_separator} style=null" }, - { $"Arial{s_separator} 10{s_separator} style=abc#" }, - { $"Arial{s_separator} 10{s_separator} style=##" }, - { $"Arial{s_separator} 10display{s_separator} style=bold" }, - { $"Arial{s_separator} 10style{s_separator} style=bold" }, - - // InvalidEnumArgumentException - { $"Arial{s_separator} 10{s_separator} style=56" }, - { $"Arial{s_separator} 10{s_separator} style=-1" }, - }; - - [Theory] - [MemberData(nameof(ExceptionFontConverterData))] - public void ProjectFileReader_TryReadFont_value_invalid(string font) - { - Dictionary properties = new() - { - { $"build_property.{PropertyNameCSharp.DefaultFont}", font } - }; - CompilerAnalyzerConfigOptions configOptions = new(properties.ToImmutableDictionary()); - CompilerAnalyzerConfigOptionsProvider provider = new(ImmutableDictionary.Empty, configOptions); - - bool result = TryReadFont(provider, out FontDescriptor? returnedValue, out Diagnostic? diagnostic); - - Assert.False(result); - Assert.Null(returnedValue); - Assert.NotNull(diagnostic); - Assert.Equal(DiagnosticDescriptors.s_propertyCantBeSetToValueWithReason, diagnostic!.Descriptor); - _output.WriteLine(diagnostic.ToString()); - } - - public static TheoryData TestConvertFormData() - => new() - { - { "Courier New" }, - { $"Arial{s_separator} 11px" }, - { $"Courier New{s_separator} style=Bold" }, - { $"Courier New{s_separator} 11 px{s_separator} style=Regular, Italic" }, - { $"arIAL{s_separator} 10{s_separator} style=bold" }, - { $"Arial{s_separator}" }, - { $"{s_separator} 10{s_separator} style=bold" }, - - // NOTE: in .NET runtime these tests will result in FontName='', but the implementation relies on GDI+, which we don't have... - { $"11px{s_separator} Style=Bold" }, - { $"11px" }, - { $"Style=Bold" }, - }; - - [Theory] - [MemberData(nameof(TestConvertFormData))] - public void ProjectFileReader_TryReadFont_value_valid(string font) - { - Dictionary properties = new() - { - { $"build_property.{PropertyNameCSharp.DefaultFont}", font } - }; - CompilerAnalyzerConfigOptions configOptions = new(properties.ToImmutableDictionary()); - CompilerAnalyzerConfigOptionsProvider provider = new(ImmutableDictionary.Empty, configOptions); - - bool result = TryReadFont(provider, out _, out Diagnostic? diagnostic); - - Assert.True(result); - Assert.Null(diagnostic); - } - - [Theory] - [InlineData("@")] - [InlineData("yes")] - [InlineData("no")] - [InlineData("System")] - [InlineData("10")] - [InlineData("-1")] - public void ProjectFileReader_TryReadHighDpiMode_value_invalid(string value) - { - Dictionary properties = new() - { - { $"build_property.{PropertyNameCSharp.HighDpiMode}", value } - }; - CompilerAnalyzerConfigOptions configOptions = new(properties.ToImmutableDictionary()); - CompilerAnalyzerConfigOptionsProvider provider = new(ImmutableDictionary.Empty, configOptions); - - bool result = TryReadHighDpiMode(provider, out HighDpiMode returnedValue, out Diagnostic? diagnostic); - - Assert.False(result); - Assert.Equal(PropertyDefaultValue.DpiMode, returnedValue); - Assert.NotNull(diagnostic); - Assert.Equal(DiagnosticDescriptors.s_propertyCantBeSetToValue, diagnostic!.Descriptor); - _output.WriteLine(diagnostic.ToString()); - } - - [Theory] - [EnumData] - public void ProjectFileReader_TryReadHighDpiMode_value_valid(HighDpiMode value) - { - Dictionary properties = new() - { - { $"build_property.{PropertyNameCSharp.HighDpiMode}", value.ToString() } - }; - CompilerAnalyzerConfigOptions configOptions = new(properties.ToImmutableDictionary()); - CompilerAnalyzerConfigOptionsProvider provider = new(ImmutableDictionary.Empty, configOptions); - - bool result = TryReadHighDpiMode(provider, out HighDpiMode returnedValue, out Diagnostic? diagnostic); - - Assert.True(result); - Assert.Equal(value, returnedValue); - Assert.Null(diagnostic); - } - - [Theory] - [EnumData] - public void ProjectFileReader_TryReadHighDpiMode_value_asint_valid(HighDpiMode value) - { - Dictionary properties = new() - { - { $"build_property.{PropertyNameCSharp.HighDpiMode}", ((int)value).ToString() } - }; - CompilerAnalyzerConfigOptions configOptions = new(properties.ToImmutableDictionary()); - CompilerAnalyzerConfigOptionsProvider provider = new(ImmutableDictionary.Empty, configOptions); - - bool result = TryReadHighDpiMode(provider, out HighDpiMode returnedValue, out Diagnostic? diagnostic); - - Assert.True(result); - Assert.Equal(value, returnedValue); - Assert.Null(diagnostic); - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/TestAdditionalText.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/TestAdditionalText.cs deleted file mode 100644 index d2c3d139283..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/TestAdditionalText.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Diagnostics.CodeAnalysis; -using System.Text; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Text; - -namespace System.Windows.Forms.Analyzers.Tests; - -// Borrowed from https://github.com/dotnet/roslyn/blob/main/src/Compilers/Test/Core/Mocks/TestAdditionalText.cs - -[ExcludeFromCodeCoverage] -public sealed class TestAdditionalText : AdditionalText -{ - private readonly SourceText _text; - - public TestAdditionalText(string path, SourceText text) - { - Path = path; - _text = text; - } - - public TestAdditionalText(string text = "", Encoding? encoding = null, string path = "dummy") - : this(path, SourceText.From(text, encoding)) - { - } - - public override string Path { get; } - - public override SourceText GetText(CancellationToken cancellationToken = default) => _text; -} - diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Verifiers/CSharpIncrementalSourceGeneratorVerifier.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Verifiers/CSharpIncrementalSourceGeneratorVerifier.cs deleted file mode 100644 index 530188736a5..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Verifiers/CSharpIncrementalSourceGeneratorVerifier.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Testing; - -namespace System.Windows.Forms.Analyzers.Tests; - -// Note: this is bleeding edge, eventually this can be removed once it is all baked in to Roslyn SDK. -public static partial class CSharpIncrementalSourceGeneratorVerifier - where TIncrementalGenerator : IIncrementalGenerator, new() -{ - public class Test : CSharpSourceGeneratorTest - { - public Test() - { - SolutionTransforms.Add((solution, projectId) => - { - var compilationOptions = solution.GetProject(projectId)!.CompilationOptions; - compilationOptions = compilationOptions!.WithSpecificDiagnosticOptions( - compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); - solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); - - return solution; - }); - } - - protected override IEnumerable GetSourceGenerators() - { - yield return typeof(TIncrementalGenerator); - } - - protected override ParseOptions CreateParseOptions() - { - var parseOptions = (CSharpParseOptions)base.CreateParseOptions(); - return parseOptions.WithLanguageVersion(LanguageVersion.Preview); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Verifiers/CSharpSourceGeneratorTest`1.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Verifiers/CSharpSourceGeneratorTest`1.cs deleted file mode 100644 index 7d1fbe564b6..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Verifiers/CSharpSourceGeneratorTest`1.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; -using static Microsoft.CodeAnalysis.Testing.ReferenceAssemblies; - -namespace System.Windows.Forms.Analyzers.Tests; - -public class CSharpSourceGeneratorTest : CSharpSourceGeneratorTest - where TSourceGenerator : ISourceGenerator, new() -{ - public CSharpSourceGeneratorTest() - { - ReferenceAssemblies = NetFramework.Net472.WindowsForms; - } -} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Verifiers/CSharpVerifierHelper.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Verifiers/CSharpVerifierHelper.cs deleted file mode 100644 index 9d5eb03101f..00000000000 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Verifiers/CSharpVerifierHelper.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; - -namespace System.Windows.Forms.Analyzers.Tests; - -internal static class CSharpVerifierHelper -{ - /// - /// By default, the compiler reports diagnostics for nullable reference types at - /// , and the analyzer test framework defaults to only validating - /// diagnostics at . This map contains all compiler diagnostic IDs - /// related to nullability mapped to , which is then used to enable all - /// of these warnings for default validation during analyzer and code fix tests. - /// - internal static ImmutableDictionary NullableWarnings { get; } = GetNullableWarningsFromCompiler(); - - static ImmutableDictionary GetNullableWarningsFromCompiler() - { - string[] args = { "/warnaserror:nullable" }; - var commandLineArguments = CSharpCommandLineParser.Default.Parse(args, baseDirectory: Environment.CurrentDirectory, sdkDirectory: Environment.CurrentDirectory); - return commandLineArguments.CompilationOptions.SpecificDiagnosticOptions; - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System.Windows.Forms.Analyzers.Tests.csproj b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System.Windows.Forms.Analyzers.Tests.csproj deleted file mode 100644 index 60cd05a24b5..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System.Windows.Forms.Analyzers.Tests.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - - enable - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - - Always - - - diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/AppManifestAnalyzerTests.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/AppManifestAnalyzerTests.cs deleted file mode 100644 index 800eaf6ee0c..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/AppManifestAnalyzerTests.cs +++ /dev/null @@ -1,141 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Text; -using Xunit; -using VerifyCS = System.Windows.Forms.Analyzers.Tests.CSharpAnalyzerVerifier< - System.Windows.Forms.Analyzers.AppManifestAnalyzer>; -using VerifyVB = System.Windows.Forms.Analyzers.Tests.VisualBasicAnalyzerVerifier< - System.Windows.Forms.Analyzers.AppManifestAnalyzer>; - -namespace System.Windows.Forms.Analyzers.Tests; - -public class AppManifestAnalyzerTests -{ - private const string CSharCode = @" - namespace ConsoleApplication1 - { - class {|#0:TypeName|} - { - } - }"; - private const string VbCode = @" -Namespace ConsoleApplication1 - Class {|#0:TypeName|} - End Class -End Namespace"; - - [Fact] - public async Task AppManifestAnalyzer_noop_if_no_manifest_file() - { - await new VerifyCS.Test - { - TestCode = CSharCode, - TestState = - { - AdditionalFiles = { } - } - }.RunAsync(); - } - - [Fact] - public async Task AppManifestAnalyzer_noop_if_manifest_file_has_no_dpi_info() - { - SourceText manifestFile = SourceText.From(File.ReadAllText(@"System\Windows\Forms\Analyzers\MockData\nodpi.manifest")); - await new VerifyCS.Test - { - TestCode = CSharCode, - TestState = - { - AdditionalFiles = { (@"C:\temp\app.manifest", manifestFile) } - } - }.RunAsync(); - } - - [Fact] - public async Task AppManifestAnalyzer_noop_if_manifest_file_corrupt() - { - SourceText manifestFile = SourceText.From(File.ReadAllText(@"System\Windows\Forms\Analyzers\MockData\invalid.manifest")); - await new VerifyCS.Test - { - TestCode = CSharCode, - TestState = - { - AdditionalFiles = { (@"C:\temp\app.manifest", manifestFile) } - } - }.RunAsync(); - } - - [Fact] - public async Task AppManifestAnalyzer_warn_if_manifest_file_has_dpi_info_CSharp() - { - const string manifestFilePath = @"C:\temp\app.manifest"; - SourceText manifestFile = SourceText.From(File.ReadAllText(@"System\Windows\Forms\Analyzers\MockData\dpi.manifest")); - await new VerifyCS.Test - { - TestCode = CSharCode, - TestState = - { - AdditionalFiles = { (manifestFilePath, manifestFile) } - }, - ExpectedDiagnostics = - { - new DiagnosticResult(DiagnosticDescriptors.s_migrateHighDpiSettings_CSharp) - .WithArguments(manifestFilePath, ApplicationConfig.PropertyNameCSharp.HighDpiMode) - } - }.RunAsync(); - } - - [Fact] - public async Task AppManifestAnalyzer_warn_if_manifest_file_has_dpi_info_VB() - { - const string manifestFilePath = @"C:\temp\app.manifest"; - SourceText manifestFile = SourceText.From(File.ReadAllText(@"System\Windows\Forms\Analyzers\MockData\dpi.manifest")); - await new VerifyVB.Test - { - TestCode = VbCode, - TestState = - { - AdditionalFiles = { (manifestFilePath, manifestFile) } - }, - ExpectedDiagnostics = - { - new DiagnosticResult(DiagnosticDescriptors.s_migrateHighDpiSettings_VB) - .WithArguments(manifestFilePath, ApplicationConfig.PropertyNameVisualBasic.HighDpiMode) - } - }.RunAsync(); - } - - [Fact] - public async Task AppManifestAnalyzer_can_suppressed_if_manifest_file_has_dpi_info_CSharp() - { - const string manifestFilePath = @"C:\temp\app.manifest"; - SourceText manifestFile = SourceText.From(File.ReadAllText(@"System\Windows\Forms\Analyzers\MockData\dpi.manifest")); - await new VerifyCS.Test - { - TestCode = CSharCode, - TestState = - { - AdditionalFiles = { (manifestFilePath, manifestFile) }, - AnalyzerConfigFiles = { ("/.globalconfig", $"is_global = true\r\ndotnet_diagnostic.WFAC010.severity = none") } - } - }.RunAsync(); - } - - [Fact] - public async Task AppManifestAnalyzer_can_suppressed_if_manifest_file_has_dpi_info_VB() - { - const string manifestFilePath = @"C:\temp\app.manifest"; - SourceText manifestFile = SourceText.From(File.ReadAllText(@"System\Windows\Forms\Analyzers\MockData\dpi.manifest")); - await new VerifyVB.Test - { - TestCode = VbCode, - TestState = - { - AdditionalFiles = { (manifestFilePath, manifestFile) }, - AnalyzerConfigFiles = { ("/.globalconfig", $"is_global = true\r\ndotnet_diagnostic.WFAC010.severity = none") } - } - }.RunAsync(); - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.FontDescriptor.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.FontDescriptor.cs deleted file mode 100644 index ffaa924630b..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.FontDescriptor.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Globalization; -using Xunit; -using Xunit.Abstractions; -using static System.Windows.Forms.Analyzers.ApplicationConfig; - -namespace System.Windows.Forms.Analyzers.Tests; - -public partial class ApplicationConfigTests -{ - public class FontDescriptorTests - { - private readonly ITestOutputHelper _output; - - public FontDescriptorTests(ITestOutputHelper output) - { - _output = output; - } - - [Fact] - public void FontDescriptor_ctor() - { - FontDescriptor descriptor = new("fontName", 10f, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point); - - Assert.Equal("fontName", descriptor.Name); - Assert.Equal(10f, descriptor.Size); - Assert.Equal(FontStyle.Bold | FontStyle.Italic, descriptor.Style); - Assert.Equal(GraphicsUnit.Point, descriptor.Unit); - } - - [Theory] - [InlineData("", "new global::System.Drawing.Font(global::System.Windows.Forms.Control.DefaultFont.FontFamily, 10f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)3)")] - [InlineData(" ", "new global::System.Drawing.Font(global::System.Windows.Forms.Control.DefaultFont.FontFamily, 10f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)3)")] - [InlineData("\t", "new global::System.Drawing.Font(global::System.Windows.Forms.Control.DefaultFont.FontFamily, 10f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)3)")] - [InlineData("fontName", "new global::System.Drawing.Font(new global::System.Drawing.FontFamily(\"fontName\"), 10f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)3)")] - [InlineData("\"fontName\"", "new global::System.Drawing.Font(new global::System.Drawing.FontFamily(\"fontName\"), 10f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)3)")] - [InlineData("Name with \tspaces", "new global::System.Drawing.Font(new global::System.Drawing.FontFamily(\"Name with spaces\"), 10f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)3)")] - [InlineData("Name with 'quotes'", "new global::System.Drawing.Font(new global::System.Drawing.FontFamily(\"Name with quotes\"), 10f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)3)")] - [InlineData("Name with \r\n lines", "new global::System.Drawing.Font(new global::System.Drawing.FontFamily(\"Name with lines\"), 10f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)3)")] - public void FontDescriptor_ToString(string fontName, string expected) - { - FontDescriptor descriptor = new(fontName, 10f, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point); - - _output.WriteLine(descriptor.ToString()); - Assert.Equal(expected, descriptor.ToString()); - } - - [Theory] - [InlineData("ar-SA")] - [InlineData("en-US")] - [InlineData("es-ES")] - [InlineData("fr-FR")] - [InlineData("hi-IN")] - [InlineData("ja-JP")] - [InlineData("ru-RU")] - [InlineData("tr-TR")] - [InlineData("zh-CN")] - public void FontDescriptor_ToString_culture_agnostic(string cultureName) - { - Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureName); - - FontDescriptor descriptor = new("Microsoft Sans Serif", 8.25f, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point); - - _output.WriteLine(descriptor.ToString()); - Assert.Equal("new global::System.Drawing.Font(new global::System.Drawing.FontFamily(\"Microsoft Sans Serif\"), 8.25f, (global::System.Drawing.FontStyle)3, (global::System.Drawing.GraphicsUnit)3)", descriptor.ToString()); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.FontStyle.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.FontStyle.cs deleted file mode 100644 index 6d7dd0c1cdf..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.FontStyle.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; -using static System.Windows.Forms.Analyzers.ApplicationConfig; - -namespace System.Windows.Forms.Analyzers.Tests; - -public partial class ApplicationConfigTests -{ - public class FontStyleTests - { - [Fact] - public void GetStandardValuesTest() - { - var values = Enum.GetValues(typeof(FontStyle)); - Assert.Equal(5, values.Length); // The values of Graphics unit: Regular, Bold, Italic, Underline, Strikeout. - } - - [Theory] - [InlineData("Bold", FontStyle.Bold)] - [InlineData("Italic", FontStyle.Italic)] - [InlineData("Regular", FontStyle.Regular)] - [InlineData("Strikeout", FontStyle.Strikeout)] - [InlineData("Underline", FontStyle.Underline)] - internal void CanConvertFrom(string input, FontStyle expected) - { - FontStyle value = Enum.Parse(input); - Assert.Equal(expected, value); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.GraphicsUnit.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.GraphicsUnit.cs deleted file mode 100644 index a0be6ece1db..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.GraphicsUnit.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; -using static System.Windows.Forms.Analyzers.ApplicationConfig; - -namespace System.Windows.Forms.Analyzers.Tests; - -public partial class ApplicationConfigTests -{ - // Copied from https://github.com/dotnet/runtime/blob/00ee1c18715723e62484c9bc8a14f517455fc3b3/src/libraries/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs#L203 - public class GraphicsUnitTests - { - [Fact] - public void GetStandardValuesTest() - { - var values = Enum.GetValues(typeof(GraphicsUnit)); - Assert.Equal(7, values.Length); // The values of Graphics unit: World, Display, Pixel, Point, Inch, Document, Millimeter. - } - - [Theory] - [InlineData("Display", GraphicsUnit.Display)] - [InlineData("Document", GraphicsUnit.Document)] - [InlineData("Inch", GraphicsUnit.Inch)] - [InlineData("Millimeter", GraphicsUnit.Millimeter)] - [InlineData("Pixel", GraphicsUnit.Pixel)] - [InlineData("Point", GraphicsUnit.Point)] - [InlineData("World", GraphicsUnit.World)] - internal void CanConvertFrom(string input, GraphicsUnit expected) - { - GraphicsUnit value = Enum.Parse(input); - Assert.Equal(expected, value); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.cs deleted file mode 100644 index a725b5a116a..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/ApplicationConfigTests.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Analyzers.Tests; - -public partial class ApplicationConfigTests -{ - // See nested files -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/MockData/dpi.manifest b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/MockData/dpi.manifest deleted file mode 100644 index ef80698dfef..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/MockData/dpi.manifest +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - - - diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/MockData/invalid.manifest b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/MockData/invalid.manifest deleted file mode 100644 index e09f1115699..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/MockData/invalid.manifest +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/MockData/nodpi.manifest b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/MockData/nodpi.manifest deleted file mode 100644 index d9bbc1e5f7b..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System/Windows/Forms/Analyzers/MockData/nodpi.manifest +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpAnalyzerVerifier`1+Test.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpAnalyzerVerifier`1+Test.cs deleted file mode 100644 index 6905e29ec43..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpAnalyzerVerifier`1+Test.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Testing; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class CSharpAnalyzerVerifier - where TAnalyzer : DiagnosticAnalyzer, new() -{ - public class Test : CSharpAnalyzerTest - { - public Test() - { - ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net472.WindowsForms; - - SolutionTransforms.Add((solution, projectId) => - { - CompilationOptions compilationOptions = solution.GetProject(projectId)!.CompilationOptions!; - compilationOptions = compilationOptions.WithSpecificDiagnosticOptions( - compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); - solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); - - return solution; - }); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpAnalyzerVerifier`1.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpAnalyzerVerifier`1.cs deleted file mode 100644 index e317183b963..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpAnalyzerVerifier`1.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Testing; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class CSharpAnalyzerVerifier - where TAnalyzer : DiagnosticAnalyzer, new() -{ - /// - public static DiagnosticResult Diagnostic() - => CSharpAnalyzerVerifier.Diagnostic(); - - /// - public static DiagnosticResult Diagnostic(string diagnosticId) - => CSharpAnalyzerVerifier.Diagnostic(diagnosticId); - - /// - public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) - => CSharpAnalyzerVerifier.Diagnostic(descriptor); - - /// - public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) - { - var test = new Test - { - TestCode = source, - }; - - test.ExpectedDiagnostics.AddRange(expected); - await test.RunAsync(CancellationToken.None); - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeFixVerifier`2+Test.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeFixVerifier`2+Test.cs deleted file mode 100644 index 99626f17ae5..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeFixVerifier`2+Test.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp.Testing; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class CSharpCodeFixVerifier - where TAnalyzer : DiagnosticAnalyzer, new() - where TCodeFix : CodeFixProvider, new() -{ - public class Test : CSharpCodeFixTest - { - public Test() - { - ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net472.WindowsForms; - - SolutionTransforms.Add((solution, projectId) => - { - CompilationOptions? compilationOptions = solution.GetProject(projectId)!.CompilationOptions!; - compilationOptions = compilationOptions.WithSpecificDiagnosticOptions( - compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); - solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); - - return solution; - }); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs deleted file mode 100644 index 3070478ab92..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp.Testing; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class CSharpCodeFixVerifier - where TAnalyzer : DiagnosticAnalyzer, new() - where TCodeFix : CodeFixProvider, new() -{ - /// - public static DiagnosticResult Diagnostic() - => CSharpCodeFixVerifier.Diagnostic(); - - /// - public static DiagnosticResult Diagnostic(string diagnosticId) - => CSharpCodeFixVerifier.Diagnostic(diagnosticId); - - /// - public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) - => CSharpCodeFixVerifier.Diagnostic(descriptor); - - /// - public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) - { - var test = new Test - { - TestCode = source, - }; - - test.ExpectedDiagnostics.AddRange(expected); - await test.RunAsync(CancellationToken.None); - } - - /// - public static async Task VerifyCodeFixAsync(string source, string fixedSource) - => await VerifyCodeFixAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); - - /// - public static async Task VerifyCodeFixAsync(string source, DiagnosticResult expected, string fixedSource) - => await VerifyCodeFixAsync(source, new[] { expected }, fixedSource); - - /// - public static async Task VerifyCodeFixAsync(string source, DiagnosticResult[] expected, string fixedSource) - { - var test = new Test - { - TestCode = source, - FixedCode = fixedSource, - }; - - test.ExpectedDiagnostics.AddRange(expected); - await test.RunAsync(CancellationToken.None); - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeRefactoringVerifier`1+Test.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeRefactoringVerifier`1+Test.cs deleted file mode 100644 index 0922d3fcc2c..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeRefactoringVerifier`1+Test.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeRefactorings; -using Microsoft.CodeAnalysis.CSharp.Testing; -using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class CSharpCodeRefactoringVerifier - where TCodeRefactoring : CodeRefactoringProvider, new() -{ - public class Test : CSharpCodeRefactoringTest - { - public Test() - { - ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net472.WindowsForms; - - SolutionTransforms.Add((solution, projectId) => - { - CompilationOptions compilationOptions = solution.GetProject(projectId)!.CompilationOptions!; - compilationOptions = compilationOptions.WithSpecificDiagnosticOptions( - compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); - solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); - - return solution; - }); - } - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeRefactoringVerifier`1.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeRefactoringVerifier`1.cs deleted file mode 100644 index 13d8999d867..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpCodeRefactoringVerifier`1.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis.CodeRefactorings; -using Microsoft.CodeAnalysis.Testing; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class CSharpCodeRefactoringVerifier - where TCodeRefactoring : CodeRefactoringProvider, new() -{ - /// - public static async Task VerifyRefactoringAsync(string source, string fixedSource) - { - await VerifyRefactoringAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); - } - - /// - public static async Task VerifyRefactoringAsync(string source, DiagnosticResult expected, string fixedSource) - { - await VerifyRefactoringAsync(source, new[] { expected }, fixedSource); - } - - /// - public static async Task VerifyRefactoringAsync(string source, DiagnosticResult[] expected, string fixedSource) - { - var test = new Test - { - TestCode = source, - FixedCode = fixedSource, - }; - - test.ExpectedDiagnostics.AddRange(expected); - await test.RunAsync(CancellationToken.None); - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpVerifierHelper.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpVerifierHelper.cs deleted file mode 100644 index ff766b66212..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/CSharpVerifierHelper.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using System.Collections.Immutable; - -namespace System.Windows.Forms.Analyzers.Tests; - -internal static class CSharpVerifierHelper -{ - /// - /// By default, the compiler reports diagnostics for nullable reference types at - /// , and the analyzer test framework defaults to only validating - /// diagnostics at . This map contains all compiler diagnostic IDs - /// related to nullability mapped to , which is then used to enable all - /// of these warnings for default validation during analyzer and code fix tests. - /// - internal static ImmutableDictionary NullableWarnings { get; } = GetNullableWarningsFromCompiler(); - - private static ImmutableDictionary GetNullableWarningsFromCompiler() - { - string[] args = { "/warnaserror:nullable" }; - var commandLineArguments = CSharpCommandLineParser.Default.Parse(args, baseDirectory: Environment.CurrentDirectory, sdkDirectory: Environment.CurrentDirectory); - var nullableWarnings = commandLineArguments.CompilationOptions.SpecificDiagnosticOptions; - - // Workaround for https://github.com/dotnet/roslyn/issues/41610 - nullableWarnings = nullableWarnings - .SetItem("CS8632", ReportDiagnostic.Error) - .SetItem("CS8669", ReportDiagnostic.Error); - - return nullableWarnings; - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicAnalyzerVerifier`1+Test.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicAnalyzerVerifier`1+Test.cs deleted file mode 100644 index d4afd5bc2b7..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicAnalyzerVerifier`1+Test.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; -using Microsoft.CodeAnalysis.VisualBasic.Testing; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class VisualBasicAnalyzerVerifier - where TAnalyzer : DiagnosticAnalyzer, new() -{ - public class Test : VisualBasicAnalyzerTest - { - public Test() - { - ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net472.WindowsForms; - } - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicAnalyzerVerifier`1.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicAnalyzerVerifier`1.cs deleted file mode 100644 index a2791ca44c1..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicAnalyzerVerifier`1.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; -using Microsoft.CodeAnalysis.VisualBasic.Testing; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class VisualBasicAnalyzerVerifier - where TAnalyzer : DiagnosticAnalyzer, new() -{ - /// - public static DiagnosticResult Diagnostic() - => VisualBasicAnalyzerVerifier.Diagnostic(); - - /// - public static DiagnosticResult Diagnostic(string diagnosticId) - => VisualBasicAnalyzerVerifier.Diagnostic(diagnosticId); - - /// - public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) - => VisualBasicAnalyzerVerifier.Diagnostic(descriptor); - - /// - public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) - { - var test = new Test - { - TestCode = source, - }; - - test.ExpectedDiagnostics.AddRange(expected); - await test.RunAsync(CancellationToken.None); - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeFixVerifier`2+Test.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeFixVerifier`2+Test.cs deleted file mode 100644 index 9e59d844bc6..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeFixVerifier`2+Test.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Testing.Verifiers; -using Microsoft.CodeAnalysis.VisualBasic.Testing; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class VisualBasicCodeFixVerifier - where TAnalyzer : DiagnosticAnalyzer, new() - where TCodeFix : CodeFixProvider, new() -{ - public class Test : VisualBasicCodeFixTest - { - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeFixVerifier`2.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeFixVerifier`2.cs deleted file mode 100644 index e05c8fa0b53..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeFixVerifier`2.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; -using Microsoft.CodeAnalysis.VisualBasic.Testing; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class VisualBasicCodeFixVerifier - where TAnalyzer : DiagnosticAnalyzer, new() - where TCodeFix : CodeFixProvider, new() -{ - /// - public static DiagnosticResult Diagnostic() - => VisualBasicCodeFixVerifier.Diagnostic(); - - /// - public static DiagnosticResult Diagnostic(string diagnosticId) - => VisualBasicCodeFixVerifier.Diagnostic(diagnosticId); - - /// - public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) - => VisualBasicCodeFixVerifier.Diagnostic(descriptor); - - /// - public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) - { - var test = new Test - { - TestCode = source, - }; - - test.ExpectedDiagnostics.AddRange(expected); - await test.RunAsync(CancellationToken.None); - } - - /// - public static async Task VerifyCodeFixAsync(string source, string fixedSource) - => await VerifyCodeFixAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); - - /// - public static async Task VerifyCodeFixAsync(string source, DiagnosticResult expected, string fixedSource) - => await VerifyCodeFixAsync(source, new[] { expected }, fixedSource); - - /// - public static async Task VerifyCodeFixAsync(string source, DiagnosticResult[] expected, string fixedSource) - { - var test = new Test - { - TestCode = source, - FixedCode = fixedSource, - }; - - test.ExpectedDiagnostics.AddRange(expected); - await test.RunAsync(CancellationToken.None); - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeRefactoringVerifier`1+Test.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeRefactoringVerifier`1+Test.cs deleted file mode 100644 index e4927138b71..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeRefactoringVerifier`1+Test.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis.CodeRefactorings; -using Microsoft.CodeAnalysis.Testing.Verifiers; -using Microsoft.CodeAnalysis.VisualBasic.Testing; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class VisualBasicCodeRefactoringVerifier - where TCodeRefactoring : CodeRefactoringProvider, new() -{ - public class Test : VisualBasicCodeRefactoringTest - { - } -} diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeRefactoringVerifier`1.cs b/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeRefactoringVerifier`1.cs deleted file mode 100644 index 113bf6e2baa..00000000000 --- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/Verifiers/VisualBasicCodeRefactoringVerifier`1.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis.CodeRefactorings; -using Microsoft.CodeAnalysis.Testing; - -namespace System.Windows.Forms.Analyzers.Tests; - -public static partial class VisualBasicCodeRefactoringVerifier - where TCodeRefactoring : CodeRefactoringProvider, new() -{ - /// - public static async Task VerifyRefactoringAsync(string source, string fixedSource) - { - await VerifyRefactoringAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); - } - - /// - public static async Task VerifyRefactoringAsync(string source, DiagnosticResult expected, string fixedSource) - { - await VerifyRefactoringAsync(source, new[] { expected }, fixedSource); - } - - /// - public static async Task VerifyRefactoringAsync(string source, DiagnosticResult[] expected, string fixedSource) - { - var test = new Test - { - TestCode = source, - FixedCode = fixedSource, - }; - - test.ExpectedDiagnostics.AddRange(expected); - await test.RunAsync(CancellationToken.None); - } -} diff --git a/src/System.Windows.Forms.Design.Editors/src/System.Windows.Forms.Design.Editors.Facade3x.csproj b/src/System.Windows.Forms.Design.Editors/src/System.Windows.Forms.Design.Editors.Facade3x.csproj index 2bef560b323..307ecaabce2 100644 --- a/src/System.Windows.Forms.Design.Editors/src/System.Windows.Forms.Design.Editors.Facade3x.csproj +++ b/src/System.Windows.Forms.Design.Editors/src/System.Windows.Forms.Design.Editors.Facade3x.csproj @@ -1,4 +1,4 @@ - + System.Windows.Forms.Design.Editors diff --git a/src/System.Windows.Forms.Design/src/AssemblyRef.cs b/src/System.Windows.Forms.Design/src/AssemblyRef.cs index 926015f15c1..5e1feb99215 100644 --- a/src/System.Windows.Forms.Design/src/AssemblyRef.cs +++ b/src/System.Windows.Forms.Design/src/AssemblyRef.cs @@ -5,7 +5,7 @@ internal static class FXAssembly { // NB: this must never-ever change to facilitate type-forwarding from // .NET Framework, if those are referenced in .NET project. - internal const string Version = "4.0.0.0"; + internal const string Version = "8.0.0.0"; } internal static class AssemblyRef diff --git a/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj b/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj index e9926e0f264..bb4f9b05193 100644 --- a/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj +++ b/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj @@ -1,7 +1,8 @@ - + System.Windows.Forms.Design + 8.0.0.0 true true true @@ -16,6 +17,7 @@ $(NoWarn);IDE0090 true true + @@ -63,6 +65,7 @@ + @@ -103,4 +106,8 @@ + + + + diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/BinaryEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/BinaryEditorTests.cs deleted file mode 100644 index f34461c5a53..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/BinaryEditorTests.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design; -using Moq; - -namespace System.Windows.Forms.Design.Editors.Tests; - -public class BinaryEditorTests -{ - [WinFormsFact] - public void BinaryEditor_EditValue() - { - // Ensure that we can instantiate the modal editor. - - BinaryEditor editor = new(); - var editorService = new Mock(); - editorService.Setup(e => e.ShowDialog(It.IsAny
())) - .Callback(f => { f.Show(); f.Close(); }) - .Returns(DialogResult.OK); - var serviceProvider = new Mock(); - serviceProvider.Setup(s => s.GetService(typeof(IWindowsFormsEditorService))).Returns(editorService.Object); - - var result = editor.EditValue(serviceProvider.Object, new byte[10]); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/CodeDomHelpers.cs b/src/System.Windows.Forms.Design/tests/UnitTests/CodeDomHelpers.cs deleted file mode 100644 index 93ed7c7938f..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/CodeDomHelpers.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.CodeDom; - -namespace System.Windows.Forms.TestUtilities; - -public static class CodeDomHelpers -{ - public static void AssertEqualCodeStatementCollection(CodeStatementCollection expected, CodeStatementCollection actual) - { - try - { - Assert.Equal(expected.Count, actual.Count); - for (int i = 0; i < expected.Count; i++) - { - Assert.Equal(GetConstructionString(expected[i]), GetConstructionString(actual[i])); - } - } - catch (Xunit.Sdk.AssertActualExpectedException) - { - Console.WriteLine($"Expected: {expected.Count} elements"); - for (int i = 0; i < expected.Count; i++) - { - Console.WriteLine($"- [{i}] {GetConstructionString(expected[i])}"); - } - - Console.WriteLine(""); - - Console.WriteLine($"Actual: {actual.Count} elements"); - for (int i = 0; i < actual.Count; i++) - { - Console.WriteLine($"- [{i}] {GetConstructionString(actual[i])}"); - } - - throw; - } - } - - public static string GetConstructionString(CodeObject o) - { - if (o is CodeStatement cs) - { - if (cs.StartDirectives.Count != 0 || cs.EndDirectives.Count != 0) - { - throw new NotImplementedException("Directives not supported."); - } - } - - switch (o) - { - case CodeVariableDeclarationStatement v: - if (v.InitExpression is null) - { - return $"new CodeVariableDeclarationStatement({GetType(v.Type)}, {GetString(v.Name)});"; - } - - return $"new CodeVariableDeclarationStatement({GetType(v.Type)}, {GetString(v.Name)}, {GetConstructionString(v.InitExpression)});"; - case CodeAssignStatement cas: - return $"new CodeAssignStatement({GetConstructionString(cas.Left)}, {GetConstructionString(cas.Right)})"; - case CodeVariableReferenceExpression cvre: - return $"new CodeVariableReferenceExpression({GetString(cvre.VariableName)})"; - case CodeObjectCreateExpression coce: - { - if (coce.Parameters.Count == 0) - { - return $"new CodeObjectCreateExpression({GetType(coce.CreateType)})"; - } - - string parameters = string.Join(", ", coce.Parameters.Cast().Select(o => GetConstructionString(o))); - return $"new CodeObjectCreateExpression({GetType(coce.CreateType)}, {parameters})"; - } - - case CodeCommentStatement ccs: - if (ccs.Comment.DocComment) - { - return $"new CodeCommentStatement({GetString(ccs.Comment.Text)}, true)"; - } - - return $"new CodeCommentStatement({GetString(ccs.Comment.Text)})"; - case CodePropertyReferenceExpression cpre: - return $"new CodePropertyReferenceExpression({GetConstructionString(cpre.TargetObject)}, {GetString(cpre.PropertyName)})"; - case CodePrimitiveExpression cpe: - { - if (cpe.Value is null) - { - return "new CodePrimitiveExpression(null)"; - } - else if (cpe.Value is string s) - { - return $"new CodePrimitiveExpression({GetString(s)})"; - } - - return $"new CodePrimitiveExpression({cpe.Value})"; - } - - default: - throw new NotImplementedException(o.ToString()); - } - - string GetString(string s) - { - if (s is null) - { - return "null"; - } - else if (s.Length == 0) - { - return "string.Empty"; - } - - return $"\"{s}\""; - } - - string GetType(CodeTypeReference reference) - { - Type result = Type.GetType(reference.BaseType); - if (result is not null) - { - return $"typeof({result.Name})"; - } - - return GetString(reference.BaseType); - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/ControlDesignerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/ControlDesignerTests.cs deleted file mode 100644 index 4b591e25770..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/ControlDesignerTests.cs +++ /dev/null @@ -1,243 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design; -using System.Windows.Forms.Design.Tests.Mocks; -using Moq; -using Windows.Win32; - -namespace System.Windows.Forms.Design.Tests; - -public class ControlDesignerTests -{ - [WinFormsFact] - public void ControlDesigner_Ctor_Default() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Assert.False(controlDesigner.AutoResizeHandles); - Assert.Null(controlDesigner.Control); - Assert.True(controlDesigner.ControlSupportsSnaplines); - Assert.Null(controlDesigner.Component); - Assert.True(controlDesigner.ForceVisible); - Assert.Null(controlDesigner.GetParentComponentProperty()); - Assert.False(controlDesigner.SerializePerformLayout); - } - - [WinFormsFact] - public void ControlDesigner_PropertiesTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - using Button button = new Button(); - controlDesigner.Initialize(button); - Assert.Empty(controlDesigner.AssociatedComponents); - Assert.False(controlDesigner.IsRootDesigner); - Assert.NotNull(controlDesigner.SnapLines); - Assert.Equal(8, controlDesigner.SnapLines.Count); - Assert.NotNull(controlDesigner.StandardBehavior); - Assert.Equal(Cursors.Default, controlDesigner.StandardBehavior.Cursor); - } - - [Fact] - public void AccessibleObjectField() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Assert.Null(controlDesigner.GetAccessibleObjectField()); - } - - [Fact] - public void BehaviorServiceProperty() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Assert.Null(controlDesigner.GetBehaviorServiceProperty()); - } - - [Fact] - public void AccessibilityObjectField() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Assert.NotNull(controlDesigner.AccessibilityObject); - } - - [Fact] - public void EnableDragRectProperty() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Assert.False(controlDesigner.GetEnableDragRectProperty()); - } - - [Fact] - public void ParticipatesWithSnapLinesProperty() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Assert.True(controlDesigner.ParticipatesWithSnapLines); - } - - [Fact] - public void AutoResizeHandlesProperty() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Assert.True(controlDesigner.AutoResizeHandles = true); - Assert.True(controlDesigner.AutoResizeHandles); - } - - [Fact] - public void SelectionRulesProperty() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Assert.Equal(SelectionRules.Visible, controlDesigner.SelectionRules); - } - - [Fact] - public void InheritanceAttributeProperty() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - using Button button = new Button(); - controlDesigner.Initialize(button); - Assert.NotNull(controlDesigner.GetInheritanceAttributeProperty()); - } - - [Fact] - public void NumberOfInternalControlDesignersTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Assert.Equal(0, controlDesigner.NumberOfInternalControlDesigners()); - } - - [Fact] - public void BaseWndProcTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Message m = default; - controlDesigner.BaseWndProcMethod(ref m); - } - - [Fact] - public void CanBeParentedToTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - using Button button = new Button(); - controlDesigner.Initialize(button); - Assert.True(controlDesigner.CanBeParentedTo(new ParentControlDesigner())); - } - - [Theory] - [BoolData] - public void EnableDragDropTest(bool val) - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - controlDesigner.EnableDragDropMethod(val); - } - - [Fact] - public void GetHitTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - Assert.False(controlDesigner.GetHitTestMethod(new Drawing.Point())); - } - - [Fact] - public void HookChildControlsTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - using Button button = new Button(); - controlDesigner.Initialize(button); - controlDesigner.HookChildControlsMethod(new Control()); - } - - [Fact] - public void InitializeTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - using Button button = new Button(); - controlDesigner.Initialize(button); - } - - [Fact] - public void InitializeNewComponentTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - using Button button = new Button(); - controlDesigner.Initialize(button); - } - - [Fact] - public void OnSetComponentDefaultsTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - using Button button = new Button(); - controlDesigner.Initialize(button); -#pragma warning disable CS0618 // Type or member is obsolete - controlDesigner.OnSetComponentDefaults(); -#pragma warning restore CS0618 - } - - [Fact] - public void OnContextMenuTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - controlDesigner.OnContextMenuMethod(0, 0); - } - - [Fact] - public void OnCreateHandleTest() - { - using TestControlDesigner controlDesigner = new TestControlDesigner(); - using Button button = new Button(); - controlDesigner.Initialize(button); - controlDesigner.OnCreateHandleMethod(); - } - - [WinFormsFact] - public void ControlDesigner_WndProc_InvokePaint_Success() - { - using ControlDesigner designer = new(); - Message m = new Message - { - Msg = (int)PInvoke.WM_PAINT - }; - designer.TestAccessor().Dynamic.WndProc(ref m); - } - - [Fact] - public void ControlDesigner_AssociatedComponents_NullSite_Test() - { - using ControlDesigner controlDesigner = new(); - using Control control = new(); - - using Control childControl = new(); - controlDesigner.Initialize(control); - - Assert.Empty(controlDesigner.AssociatedComponents); - - control.Controls.Add(childControl); - - Assert.Empty(controlDesigner.AssociatedComponents); - } - - [WinFormsFact] - public void ControlDesigner_AssociatedComponentsTest() - { - using Control control = new(); - using ControlDesigner controlDesigner = new(); - - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(control); - mockDesignerHost - .Setup(s => s.GetDesigner(It.IsAny())) - .Returns(() => null); - var mockSite = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object); - control.Site = mockSite.Object; - - controlDesigner.Initialize(control); - - Assert.Empty(controlDesigner.AssociatedComponents); - - using Control childControl = new(); - childControl.Site = mockSite.Object; - control.Controls.Add(childControl); - - Assert.Equal(1, controlDesigner.AssociatedComponents.Count); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/EnsureDesignerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/EnsureDesignerTests.cs deleted file mode 100644 index 2ee6b726208..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/EnsureDesignerTests.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design; - -namespace System.Windows.Forms.Design.Editors.Tests; - -public class EnsureDesignerTests -{ - [WinFormsFact] - public void Ensure_designer_type_forwarded() - { - SystemDesignMetadataReader metadataReader = new(); - IReadOnlyList forwardedTypes = metadataReader.GetExportedTypeNames(); - - IEnumerable designers = typeof(ComponentDesigner).Assembly - .GetTypes() - .Where(t => t.IsSubclassOf(typeof(ComponentDesigner)) - && !t.IsPublic); - foreach (Type designer in designers) - { - Assert.True(forwardedTypes.Contains(designer.FullName), $"{designer.FullName} must be type forwarded"); - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/EnsureEditorsTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/EnsureEditorsTests.cs deleted file mode 100644 index 4b8b4f50823..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/EnsureEditorsTests.cs +++ /dev/null @@ -1,176 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design; -using System.Drawing; -using System.Drawing.Design; -using System.Drawing.Imaging; -using System.Reflection; - -namespace System.Windows.Forms.Design.Editors.Tests; - -public class EnsureEditorsTests -{ - [WinFormsFact] - public void Ensure_editors_type_forwarded() - { - // The list of editors which either didn't exist in .NET Framework - Type[] nonTypeForwardedEditors = - { - typeof(InitialDirectoryEditor), // introduced in .NET 6.0, https://github.com/dotnet/winforms/pull/4645 - }; - - SystemDesignMetadataReader metadataReader = new(); - IReadOnlyList forwardedTypes = metadataReader.GetExportedTypeNames(); - - IEnumerable editors = typeof(ComponentDesigner).Assembly - .GetTypes() - .Where(t => t.IsSubclassOf(typeof(UITypeEditor)) - && !t.IsPublic - && !nonTypeForwardedEditors.Contains(t)); - foreach (Type editor in editors) - { - Assert.True(forwardedTypes.Contains(editor.FullName), $"{editor.FullName} must be type forwarded"); - } - } - - [WinFormsTheory] - // In Table - [InlineData(typeof(Array), typeof(ArrayEditor))] - [InlineData(typeof(IList), typeof(CollectionEditor))] - [InlineData(typeof(ICollection), typeof(CollectionEditor))] - [InlineData(typeof(byte[]), typeof(BinaryEditor))] - [InlineData(typeof(Stream), typeof(BinaryEditor))] - [InlineData(typeof(string[]), typeof(StringArrayEditor))] - [InlineData(typeof(Bitmap), typeof(BitmapEditor))] - [InlineData(typeof(Color), typeof(ColorEditor))] - [InlineData(typeof(ContentAlignment), typeof(ContentAlignmentEditor))] - [InlineData(typeof(Font), typeof(FontEditor))] - [InlineData(typeof(Icon), typeof(IconEditor))] - [InlineData(typeof(Image), typeof(ImageEditor))] - [InlineData(typeof(Metafile), typeof(MetafileEditor))] - [InlineData(typeof(AnchorStyles), typeof(AnchorEditor))] - [InlineData(typeof(DockStyle), typeof(DockEditor))] - [InlineData(typeof(ImageListImage), typeof(ImageListImageEditor))] - [InlineData(typeof(DateTime), typeof(DateTimeEditor))] - // With Editor Attribute - [InlineData(typeof(Cursor), typeof(CursorEditor))] - //[InlineData(typeof(GridColumnStylesCollection), typeof(DataGridColumnCollectionEditor))] - //[InlineData(typeof(DataGridView), typeof(DataGridViewComponentEditor))] - //[InlineData(typeof(DataGridViewCellStyle), typeof(DataGridViewCellStyleEditor))] - [InlineData(typeof(ImageList.ImageCollection), typeof(ImageCollectionEditor))] - [InlineData(typeof(Keys), typeof(ShortcutKeysEditor))] - //[InlineData(typeof(TableLayoutStyleCollection), typeof(StyleCollectionEditor))] - //[InlineData(typeof(ToolStripItemCollection), typeof(ToolStripCollectionEditor))] - [InlineData(typeof(ToolStripStatusLabelBorderSides), typeof(BorderSidesEditor))] - //[InlineData(typeof(TreeNodeCollection), typeof(TreeNodeCollectionEditor))] - public void EnsureUITypeEditorForType(Type type, Type expectedEditorType) - { - var editor = TypeDescriptor.GetEditor(type, typeof(UITypeEditor)); - - Assert.NotNull(editor); - Assert.Equal(expectedEditorType, editor.GetType()); - } - - [WinFormsTheory] - //[InlineData(typeof(BindingSource), "DataMember", typeof(DataMemberListEditor))] - [InlineData(typeof(ButtonBase), "ImageIndex", typeof(ImageIndexEditor))] - [InlineData(typeof(ButtonBase), "ImageKey", typeof(ImageIndexEditor))] - [InlineData(typeof(ButtonBase), "Text", typeof(MultilineStringEditor))] - [InlineData(typeof(CheckedListBox), "Items", typeof(ListControlStringCollectionEditor))] - [InlineData(typeof(ColumnHeader), "ImageIndex", typeof(ImageIndexEditor))] - [InlineData(typeof(ColumnHeader), "ImageKey", typeof(ImageIndexEditor))] - [InlineData(typeof(ComboBox), "AutoCompleteCustomSource", typeof(ListControlStringCollectionEditor))] - [InlineData(typeof(ComboBox), "Items", typeof(ListControlStringCollectionEditor))] - //[InlineData(typeof(DataGridView), "Columns", typeof(DataGridViewColumnCollectionEditor))] - //[InlineData(typeof(DataGridView), "DataMember", typeof(DataMemberListEditor))] - [InlineData(typeof(DataGridViewCellStyle), "Format", typeof(FormatStringEditor))] - //[InlineData(typeof(DataGridViewColumn), "DataPropertyName", typeof(DataGridViewColumnDataPropertyNameEditor))] - //[InlineData(typeof(DataGridViewComboBoxColumn), "DisplayMember", typeof(DataMemberFieldEditor))] - [InlineData(typeof(DataGridViewComboBoxColumn), "Items", typeof(StringCollectionEditor))] - //[InlineData(typeof(DataGridViewComboBoxColumn), "ValueMember", typeof(DataMemberFieldEditor))] - [InlineData(typeof(DateTimePicker), "MaxDate", typeof(DateTimeEditor))] - [InlineData(typeof(DateTimePicker), "MinDate", typeof(DateTimeEditor))] - [InlineData(typeof(DateTimePicker), "Value", typeof(DateTimeEditor))] - [InlineData(typeof(DomainUpDown), "Items", typeof(StringCollectionEditor))] - //[InlineData(typeof(ErrorProvider), "DataMember", typeof(DataMemberListEditor))] - [InlineData(typeof(FolderBrowserDialog), "SelectedPath", typeof(SelectedPathEditor))] - [InlineData(typeof(HelpProvider), "HelpNamespace", typeof(HelpNamespaceEditor))] - [InlineData(typeof(Label), "ImageIndex", typeof(ImageIndexEditor))] - [InlineData(typeof(Label), "ImageKey", typeof(ImageIndexEditor))] - [InlineData(typeof(Label), "Text", typeof(MultilineStringEditor))] - [InlineData(typeof(LinkLabel), "LinkArea", typeof(LinkAreaEditor))] - [InlineData(typeof(ListBox), "Items", typeof(ListControlStringCollectionEditor))] - //[InlineData(typeof(ListControl), "DisplayMember", typeof(DataMemberFieldEditor))] - [InlineData(typeof(ListControl), "FormatString", typeof(FormatStringEditor))] - //[InlineData(typeof(ListControl), "ValueMember", typeof(DataMemberFieldEditor))] - //[InlineData(typeof(ListView), "Columns", typeof(ColumnHeaderCollectionEditor))] - [InlineData(typeof(ListView), "Groups", typeof(ListViewGroupCollectionEditor))] - [InlineData(typeof(ListView), "Items", typeof(ListViewItemCollectionEditor))] - [InlineData(typeof(ListViewItem), "ImageIndex", typeof(ImageIndexEditor))] - [InlineData(typeof(ListViewItem), "ImageKey", typeof(ImageIndexEditor))] - [InlineData(typeof(ListViewItem), "StateImageIndex", typeof(ImageIndexEditor))] - [InlineData(typeof(ListViewItem), "SubItems", typeof(ListViewSubItemCollectionEditor))] - [InlineData(typeof(MaskedTextBox), "Mask", typeof(MaskPropertyEditor))] - [InlineData(typeof(MaskedTextBox), "Text", typeof(MaskedTextBoxTextEditor))] - [InlineData(typeof(MonthCalendar), "MaxDate", typeof(DateTimeEditor))] - [InlineData(typeof(MonthCalendar), "MinDate", typeof(DateTimeEditor))] - [InlineData(typeof(MonthCalendar), "SelectionEnd", typeof(DateTimeEditor))] - [InlineData(typeof(MonthCalendar), "SelectionStart", typeof(DateTimeEditor))] - [InlineData(typeof(MonthCalendar), "TodayDate", typeof(DateTimeEditor))] - [InlineData(typeof(NotifyIcon), "BalloonTipText", typeof(MultilineStringEditor))] - [InlineData(typeof(NotifyIcon), "Text", typeof(MultilineStringEditor))] - [InlineData(typeof(TabControl), "TabPages", typeof(TabPageCollectionEditor))] - [InlineData(typeof(TabPage), "ImageIndex", typeof(ImageIndexEditor))] - [InlineData(typeof(TabPage), "ImageKey", typeof(ImageIndexEditor))] - [InlineData(typeof(TextBox), "AutoCompleteCustomSource", typeof(ListControlStringCollectionEditor))] - [InlineData(typeof(TextBoxBase), "Lines", typeof(StringArrayEditor))] - [InlineData(typeof(TextBoxBase), "Text", typeof(MultilineStringEditor))] - [InlineData(typeof(ToolStripComboBox), "AutoCompleteCustomSource", typeof(ListControlStringCollectionEditor))] - [InlineData(typeof(ToolStripComboBox), "Items", typeof(ListControlStringCollectionEditor))] - //[InlineData(typeof(ToolStripItem), "ImageIndex", typeof(ToolStripImageIndexEditor))] - //[InlineData(typeof(ToolStripItem), "ImageKey", typeof(ToolStripImageIndexEditor))] - [InlineData(typeof(ToolStripItem), "ToolTipText", typeof(MultilineStringEditor))] - [InlineData(typeof(ToolStripTextBox), "AutoCompleteCustomSource", typeof(ListControlStringCollectionEditor))] - [InlineData(typeof(ToolStripTextBox), "Lines", typeof(StringArrayEditor))] - [InlineData(typeof(TreeNode), "ImageIndex", typeof(ImageIndexEditor))] - [InlineData(typeof(TreeNode), "ImageKey", typeof(ImageIndexEditor))] - [InlineData(typeof(TreeNode), "SelectedImageKey", typeof(ImageIndexEditor))] - [InlineData(typeof(TreeNode), "StateImageKey", typeof(ImageIndexEditor))] - [InlineData(typeof(TreeNode), "StateImageIndex", typeof(ImageIndexEditor))] - [InlineData(typeof(TreeView), "ImageIndex", typeof(ImageIndexEditor))] - [InlineData(typeof(TreeView), "ImageKey", typeof(ImageIndexEditor))] - [InlineData(typeof(TreeView), "SelectedImageIndex", typeof(ImageIndexEditor))] - [InlineData(typeof(TreeView), "SelectedImageKey", typeof(ImageIndexEditor))] - public void EnsureUITypeEditorForProperty(Type type, string propertyName, Type expectedEditorType) - { - PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(type); - Assert.NotNull(properties); - Assert.NotEmpty(properties); - - PropertyDescriptor propertyDescriptor = properties.Find(propertyName, true); - Assert.NotNull(propertyDescriptor); - - var editor = propertyDescriptor.GetEditor(typeof(UITypeEditor)); - Assert.NotNull(editor); - Assert.Equal(expectedEditorType, editor.GetType()); - } - - [WinFormsTheory] - [InlineData(typeof(ToolTip), "GetToolTip", typeof(MultilineStringEditor))] - public void EnsureUITypeEditorForMethod(Type type, string methodName, Type expectedEditorType) - { - Type reflectType = TypeDescriptor.GetReflectionType(type); - Assert.NotNull(reflectType); - - MethodInfo method = reflectType.GetMethod(methodName); - Assert.NotNull(method); - - IEnumerable attributes = method.GetCustomAttributes(typeof(EditorAttribute), false).Cast(); - Assert.NotNull(attributes); - Assert.NotEmpty(attributes); - Assert.Contains(attributes, editor => editor.EditorTypeName.StartsWith(expectedEditorType.FullName + ", ")); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/GlobalUsings.cs b/src/System.Windows.Forms.Design/tests/UnitTests/GlobalUsings.cs deleted file mode 100644 index 12febf7aa93..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/GlobalUsings.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -global using System.Windows.Forms; -global using Xunit; diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/ListViewDesignerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/ListViewDesignerTests.cs deleted file mode 100644 index 5a3aa0deef3..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/ListViewDesignerTests.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Design.Tests; - -public class ListViewDesignerTests -{ - [WinFormsFact] - public void ListViewDesigner_AssociatedComponentsTest() - { - using ListViewDesigner listViewDesigner = new(); - using ListView listView = new(); - listViewDesigner.Initialize(listView); - - Assert.Empty(listViewDesigner.AssociatedComponents); - - listView.Columns.Add("123"); - listView.Columns.Add("abc"); - - Assert.Equal(2, listViewDesigner.AssociatedComponents.Count); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Mocks/MockSite.cs b/src/System.Windows.Forms.Design/tests/UnitTests/Mocks/MockSite.cs deleted file mode 100644 index c995c284322..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/Mocks/MockSite.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.ComponentModel.Design; -using System.ComponentModel; -using Moq; - -namespace System.Windows.Forms.Design.Tests.Mocks -{ - public class MockSite - { - public static Mock CreateMockSiteWithDesignerHost(object designerHost) - { - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(designerHost); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(AmbientProperties))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(DesignerActionService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ToolStripKeyboardHandlingService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ISupportInSituService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(INestedContainer))) - .Returns(null); - - Mock mockSelectionService = new(MockBehavior.Strict); - - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object); - mockSite - .Setup(s => s.Container) - .Returns((IContainer)null); - mockSite - .Setup(s => s.Name) - .Returns("Site"); - mockSite - .Setup(s => s.DesignMode) - .Returns(true); - mockSite - .Setup(s => s.GetService(typeof(UndoEngine))) - .Returns(null); - - return mockSite; - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Properties/launchSettings.json b/src/System.Windows.Forms.Design/tests/UnitTests/Properties/launchSettings.json deleted file mode 100644 index 90729785053..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "System.Windows.Forms.Design.Tests": { - "commandName": "Project", - "nativeDebugging": true - } - } -} \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/16x16.bmp b/src/System.Windows.Forms.Design/tests/UnitTests/Resources/16x16.bmp deleted file mode 100644 index 8bf35136370..00000000000 Binary files a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/16x16.bmp and /dev/null differ diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/16x24.bmp b/src/System.Windows.Forms.Design/tests/UnitTests/Resources/16x24.bmp deleted file mode 100644 index 9fa2469f870..00000000000 Binary files a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/16x24.bmp and /dev/null differ diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/24x16.bmp b/src/System.Windows.Forms.Design/tests/UnitTests/Resources/24x16.bmp deleted file mode 100644 index d3fdc521f1f..00000000000 Binary files a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/24x16.bmp and /dev/null differ diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/Audio1.wav b/src/System.Windows.Forms.Design/tests/UnitTests/Resources/Audio1.wav deleted file mode 100644 index d9605cba788..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/Audio1.wav +++ /dev/null @@ -1 +0,0 @@ -HELLO \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/Icon1.ico b/src/System.Windows.Forms.Design/tests/UnitTests/Resources/Icon1.ico deleted file mode 100644 index 5d06b9f2857..00000000000 Binary files a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/Icon1.ico and /dev/null differ diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/Image1.png b/src/System.Windows.Forms.Design/tests/UnitTests/Resources/Image1.png deleted file mode 100644 index 8d4272efa7f..00000000000 Binary files a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/Image1.png and /dev/null differ diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/TextFile1.txt b/src/System.Windows.Forms.Design/tests/UnitTests/Resources/TextFile1.txt deleted file mode 100644 index 530c72a067f..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/TextFile1.txt +++ /dev/null @@ -1,2 +0,0 @@ -hello test -! \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/telescope_01.wmf b/src/System.Windows.Forms.Design/tests/UnitTests/Resources/telescope_01.wmf deleted file mode 100644 index 453986c39c1..00000000000 Binary files a/src/System.Windows.Forms.Design/tests/UnitTests/Resources/telescope_01.wmf and /dev/null differ diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/SerializableAttributeTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/SerializableAttributeTests.cs deleted file mode 100644 index c9bef24c0c8..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/SerializableAttributeTests.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Design.Tests.Serialization; - -public class SerializableAttributeTests -{ - [Fact] - public void EnsureSerializableAttribute() - { - BinarySerialization.EnsureSerializableAttribute( - typeof(Behavior.Behavior).Assembly, - new HashSet - { - typeof(OleDragDropHandler.CfCodeToolboxItem).FullName, - { "System.Windows.Forms.Design.Behavior.DesignerActionKeyboardBehavior+<>c" } - }); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/CodeDomSerializerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/CodeDomSerializerTests.cs deleted file mode 100644 index bc74b9c8b43..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/CodeDomSerializerTests.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design.Serialization; - -namespace System.Windows.Forms.Design.Serialization.Tests; - -public class CodeDomSerializerTests -{ - [Fact] - public void CodeDomSerializer_Constructor() - { - CodeDomSerializer underTest = new(); - Assert.NotNull(underTest); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/CollectionCodeDomSerializerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/CollectionCodeDomSerializerTests.cs deleted file mode 100644 index 462e562f7b6..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/CollectionCodeDomSerializerTests.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design.Serialization; - -namespace System.Windows.Forms.Design.Serialization.Tests; - -public class CollectionCodeDomSerializerTests -{ - [Fact] - public void CollectionCodeDomSerializer_Constructor() - { - CollectionCodeDomSerializer underTest = CollectionCodeDomSerializer.Default; - Assert.NotNull(underTest); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/PrimitiveCodeDomSerializerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/PrimitiveCodeDomSerializerTests.cs deleted file mode 100644 index 7638edaf1ed..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/PrimitiveCodeDomSerializerTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.CodeDom; -using System.ComponentModel.Design.Serialization; - -namespace System.Windows.Forms.Design.Serialization.Tests; - -public class PrimitiveCodeDomSerializerTests -{ - [Fact] - public void PrimitiveCodeDomSerializerTests_Constructor() - { - PrimitiveCodeDomSerializer underTest = new(); - Assert.NotNull(underTest); - } - - [Theory] - [InlineData(null)] - [InlineData(false)] - [InlineData("some string")] - [InlineData('c')] - [InlineData(42)] - [InlineData(42F)] - [InlineData(42.123)] - public void PrimitiveCodeDomSerializerTests_Serialize(object input) - { - DesignerSerializationManager manager = new(); - PrimitiveCodeDomSerializer underTest = PrimitiveCodeDomSerializer.Default; - Assert.NotNull(underTest); - - var result = underTest.Serialize(manager, input) as CodePrimitiveExpression; - Assert.NotNull(result); - Assert.Equal(input, result.Value); - Assert.Empty(result.UserData); - } - - [Fact] - public void PrimitiveCodeDomSerializerTests_Serialize_Cast() - { - DesignerSerializationManager manager = new(); - PrimitiveCodeDomSerializer underTest = PrimitiveCodeDomSerializer.Default; - Assert.NotNull(underTest); - - var cast = underTest.Serialize(manager, (byte)42) as CodeCastExpression; - - Assert.NotNull(cast); - Assert.Equal(typeof(byte).ToString(), cast.TargetType.BaseType); - Assert.IsType(cast.Expression); - var primitive = cast.Expression as CodePrimitiveExpression; - Assert.Equal((byte)42, primitive.Value); - Assert.Empty(cast.UserData); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/TypeCodeDomSerializerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/TypeCodeDomSerializerTests.cs deleted file mode 100644 index 6cd6b565d6d..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/Serialization/TypeCodeDomSerializerTests.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Moq; - -namespace System.ComponentModel.Design.Serialization.Tests; - -public class TypeCodeDomSerializerTests -{ - [Fact] - public void TypeCodeDomSerializer_Constructor() - { - TypeCodeDomSerializer underTest = new(); - Assert.NotNull(underTest); - } - - [Fact] - public void TypeCodeDomSerializer_Serialize_Manager_Null() - { - TypeCodeDomSerializer underTest = new(); - Assert.Throws(() => underTest.Serialize(null, null, null)); - } - - [Fact] - public void TypeCodeDomSerializer_Serialize_Root_Null() - { - Mock mockSerializationManager = new(MockBehavior.Strict); - TypeCodeDomSerializer underTest = new(); - Assert.Throws(() => underTest.Serialize(mockSerializationManager.Object, null, null)); - } - - [Fact] - public void TypeCodeDomSerializer_Deserialize_Manager_Null() - { - TypeCodeDomSerializer underTest = new(); - Assert.Throws(() => underTest.Deserialize(null, null)); - } - - [Fact] - public void TypeCodeDomSerializer_Deserialize_CodeTypeDec_Null() - { - Mock mockSerializationManager = new(MockBehavior.Strict); - TypeCodeDomSerializer underTest = new(); - Assert.Throws(() => underTest.Deserialize(mockSerializationManager.Object, null)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/SplitContainerDesignerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/SplitContainerDesignerTests.cs deleted file mode 100644 index c14736ffddd..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/SplitContainerDesignerTests.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design; -using Moq; -using System.Windows.Forms.Design.Tests.Mocks; - -namespace System.Windows.Forms.Design.Tests; - -public class SplitContainerDesignerTests -{ - [WinFormsFact] - public void SplitContainerDesigner_AssociatedComponentsTest() - { - using SplitContainer splitContainer = new(); - using SplitContainerDesigner splitContainerDesigner = new(); - - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(splitContainer); - mockDesignerHost - .Setup(s => s.GetDesigner(It.IsAny())) - .Returns(splitContainerDesigner); - Mock mockComponentChangeService = new(MockBehavior.Strict); - mockDesignerHost - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(mockComponentChangeService.Object); - - var mockSite = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object); - splitContainer.Site = mockSite.Object; - - splitContainerDesigner.Initialize(splitContainer); - - Assert.Empty(splitContainerDesigner.AssociatedComponents); - - using Control control = new(); - control.Parent = splitContainer.Panel1; - - Assert.Equal(1, splitContainerDesigner.AssociatedComponents.Count); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System.Windows.Forms.Design.Tests.csproj b/src/System.Windows.Forms.Design/tests/UnitTests/System.Windows.Forms.Design.Tests.csproj deleted file mode 100644 index d6f6e747ae9..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System.Windows.Forms.Design.Tests.csproj +++ /dev/null @@ -1,68 +0,0 @@ - - - $(TargetFramework) - $(TargetFramework)-windows7.0 - true - System.Windows.Forms.Design.Tests - true - $(NoWarn);SYSLIB0050;SYSLIB0051;SYSLIB0011 - $(NoWarn);IDE0090 - - - - - - - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - - System.Drawing.Design.Tests.16x16.bmp - - - System.Drawing.Design.Tests.24x16.bmp - - - System.Drawing.Design.Tests.16x24.bmp - - - - - - PreserveNewest - - - - - - $(ArtifactsBinDir)\AxHosts\$(Configuration)\net472\AxInterop.WMPLib.dll - - - $(ArtifactsBinDir)\AxHosts\$(Configuration)\net472\Interop.WMPLib.dll - - - - diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ArrayEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ArrayEditorTests.cs deleted file mode 100644 index a7028015085..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ArrayEditorTests.cs +++ /dev/null @@ -1,317 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Drawing.Design; -using System.Reflection; -using System.Windows.Forms.TestUtilities; - -namespace System.ComponentModel.Design.Tests; - -public class ArrayEditorTests -{ - [Theory] - [InlineData(typeof(object), null)] - [InlineData(typeof(string), null)] - [InlineData(typeof(int[]), typeof(int))] - [InlineData(typeof(IList), null)] - [InlineData(typeof(IList), null)] - [InlineData(typeof(ClassWithItem), null)] - [InlineData(typeof(ClassWithPrivateItem), null)] - [InlineData(typeof(ClassWithStaticItem), null)] - [InlineData(typeof(ClassWithItems), null)] - [InlineData(typeof(ClassWithPrivateItems), null)] - [InlineData(typeof(ClassWithStaticItems), null)] - public void ArrayEditor_Ctor_Type(Type type, Type expectedItemType) - { - SubArrayEditor editor = new(type); - Assert.Equal(expectedItemType, editor.CollectionItemType); - Assert.Same(editor.CollectionItemType, editor.CollectionItemType); - Assert.Equal(type, editor.CollectionType); - Assert.Null(editor.Context); - Assert.Equal("net.ComponentModel.CollectionEditor", editor.HelpTopic); - Assert.False(editor.IsDropDownResizable); - Assert.Equal(new Type[] { expectedItemType }, editor.NewItemTypes); - } - - [Fact] - public void ArrayEditor_Ctor_NullType() - { - SubArrayEditor editor = new(null); - Assert.Null(editor.CollectionItemType); - Assert.Null(editor.CollectionType); - Assert.Null(editor.Context); - Assert.Equal("net.ComponentModel.CollectionEditor", editor.HelpTopic); - Assert.False(editor.IsDropDownResizable); - Assert.Equal(new Type[] { null }, editor.NewItemTypes); - } - - public static IEnumerable CanRemoveInstance_TestData() - { - yield return new object[] { "some string" }; - yield return new object[] { 123 }; - yield return new object[] { null }; - yield return new object[] { new Component() }; - } - - [Theory] - [MemberData(nameof(CanRemoveInstance_TestData))] - public void ArrayEditor_CanRemoveInstance_Invoke_ReturnsExpected(object value) - { - SubArrayEditor editor = new(null); - Assert.True(editor.CanRemoveInstance(value)); - } - - public static IEnumerable CanRemoveInstance_InheritanceAttribute_TestData() - { - yield return new object[] { new InheritanceAttribute(InheritanceLevel.Inherited - 1), false }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.Inherited), false }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.InheritedReadOnly), false }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.NotInherited), true }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.NotInherited + 1), false }; - } - - [Theory] - [MemberData(nameof(CanRemoveInstance_InheritanceAttribute_TestData))] - public void ArrayEditor_CanRemoveInstance_InheritanceAttribute_ReturnsExpected(InheritanceAttribute attribute, bool expected) - { - using Component component = new(); - TypeDescriptor.AddAttributes(component, attribute); - SubArrayEditor editor = new(null); - Assert.Equal(expected, editor.CanRemoveInstance(component)); - } - - [Fact] - public void ArrayEditor_CanSelectMultipleInstances_Invoke_ReturnsFalse() - { - SubArrayEditor editor = new(null); - Assert.True(editor.CanSelectMultipleInstances()); - } - - public static IEnumerable GetDisplayText_TestData() - { - yield return new object[] { null, null, string.Empty }; - yield return new object[] { null, string.Empty, "String" }; - yield return new object[] { null, "string", "string" }; - - yield return new object[] { null, new ClassWithStringName { Name = "CustomName" }, "CustomName" }; - yield return new object[] { null, new ClassWithStringName { Name = string.Empty }, "ClassWithStringName" }; - yield return new object[] { null, new ClassWithStringName { Name = null }, "ClassWithStringName" }; - yield return new object[] { null, new ClassWithNonStringName { Name = 1 }, "ClassWithNonStringName" }; - yield return new object[] { null, new ClassWithNullToString(), "ClassWithNullToString" }; - - yield return new object[] { typeof(int), null, string.Empty }; - yield return new object[] { typeof(int), "", "String" }; - yield return new object[] { typeof(int), "value", "value" }; - yield return new object[] { typeof(int), 1, "1" }; - yield return new object[] { typeof(int), new ClassWithStringDefaultProperty { DefaultProperty = "CustomName" }, "ClassWithStringDefaultProperty" }; - - yield return new object[] { typeof(ClassWithStringDefaultProperty), null, string.Empty }; - yield return new object[] { typeof(ClassWithStringDefaultProperty), new ClassWithStringDefaultProperty { DefaultProperty = "CustomName" }, "CustomName" }; - yield return new object[] { typeof(ClassWithStringDefaultProperty), new ClassWithStringDefaultProperty { DefaultProperty = string.Empty }, "ClassWithStringDefaultProperty" }; - yield return new object[] { typeof(ClassWithStringDefaultProperty), new ClassWithStringDefaultProperty { DefaultProperty = null }, "ClassWithStringDefaultProperty" }; - yield return new object[] { typeof(ClassWithNonStringDefaultProperty), new ClassWithNonStringDefaultProperty { DefaultProperty = 1 }, "ClassWithNonStringDefaultProperty" }; - yield return new object[] { typeof(ClassWithNoSuchDefaultProperty), new ClassWithNoSuchDefaultProperty { DefaultProperty = "CustomName" }, "ClassWithNoSuchDefaultProperty" }; - yield return new object[] { typeof(List), new ClassWithStringDefaultProperty { DefaultProperty = "CustomName" }, "ClassWithStringDefaultProperty" }; - } - - [Theory] - [MemberData(nameof(GetDisplayText_TestData))] - public void ArrayEditor_GetDisplayText_Invoke_ReturnsExpected(Type type, object value, string expected) - { - SubArrayEditor editor = new(type); - Assert.Equal(expected, editor.GetDisplayText(value)); - } - - [Fact] - public void ArrayEditor_GetDisplayText_ValueDoesntMatchCollectionType_ThrowsTargetException() - { - SubArrayEditor editor = new(typeof(ClassWithStringDefaultProperty)); - TargetInvocationException ex = Assert.Throws(() => editor.GetDisplayText(new ClassWithNonStringDefaultProperty())); - Assert.IsType(ex.InnerException); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void ArrayEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - ArrayEditor editor = new(null); - Assert.Equal(UITypeEditorEditStyle.Modal, editor.GetEditStyle(context)); - } - - public static IEnumerable GetItems_TestData() - { - yield return new object[] { null, Array.Empty() }; - yield return new object[] { new object(), Array.Empty() }; - yield return new object[] { new int[] { 1, 2, 3 }, new object[] { 1, 2, 3, } }; - yield return new object[] { new ArrayList { 1, 2, 3 }, Array.Empty() }; - } - - [Theory] - [MemberData(nameof(GetItems_TestData))] - public void ArrayEditor_GetItems_Invoke_ReturnsExpected(object editValue, object[] expected) - { - SubArrayEditor editor = new(null); - object[] items = editor.GetItems(editValue); - Assert.Equal(expected, items); - Assert.IsType(expected.GetType(), items); - Assert.NotSame(editValue, items); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void ArrayEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - ArrayEditor editor = new(null); - Assert.False(editor.GetPaintValueSupported(context)); - } - - public static IEnumerable SetItems_Array_TestData() - { - yield return new object[] { null, Array.Empty(), Array.Empty() }; - yield return new object[] { null, new object[] { 1, 2, 3 }, new object[] { 1, 2, 3 } }; - yield return new object[] { new object[] { 4, 5 }, new object[] { 1, 2, 3 }, new object[] { 1, 2, 3 } }; - yield return new object[] { new object[] { 4, 5, 6 }, new object[] { 1, 2, 3 }, new object[] { 1, 2, 3 } }; - yield return new object[] { new object[] { 4, 5, 6, 7 }, new object[] { 1, 2, 3 }, new object[] { 1, 2, 3 } }; - } - - [Theory] - [MemberData(nameof(SetItems_Array_TestData))] - public void ArrayEditor_SetItems_InvokeArray_ReturnsCopy(object editValue, object[] value, int[] expected) - { - SubArrayEditor editor = new(typeof(int[])); - int[] result = Assert.IsType(editor.SetItems(editValue, value)); - Assert.NotSame(value, expected); - Assert.Equal(expected, result); - } - - public static IEnumerable SetItems_NonArray_TestData() - { - object editValue = new(); - yield return new object[] { editValue, null, editValue }; - yield return new object[] { editValue, Array.Empty(), editValue }; - yield return new object[] { Array.Empty(), null, null }; - yield return new object[] { null, null, null }; - } - - [Theory] - [MemberData(nameof(SetItems_NonArray_TestData))] - public void ArrayEditor_SetItems_InvokeNonArrayValue_ReturnsExpected(object editValue, object[] value, object expected) - { - SubArrayEditor editor = new(typeof(int[])); - Assert.Same(expected, editor.SetItems(editValue, value)); - } - - [Theory] - [InlineData(typeof(object))] - [InlineData(null)] - public void ArrayEditor_SetItems_NullCollectionItemType_ThrowsArgumentNullException(Type type) - { - SubArrayEditor editor = new(type); - Assert.Null(editor.CollectionItemType); - Assert.Throws("elementType", () => editor.SetItems(null, Array.Empty())); - Assert.Throws("elementType", () => editor.SetItems(Array.Empty(), Array.Empty())); - } - - private class SubArrayEditor : ArrayEditor - { - public SubArrayEditor(Type type) : base(type) - { - } - - public new Type CollectionItemType => base.CollectionItemType; - - public new Type CollectionType => base.CollectionType; - - public new ITypeDescriptorContext Context => base.Context; - - public new string HelpTopic => base.HelpTopic; - - public new Type[] NewItemTypes => base.NewItemTypes; - - public new bool CanRemoveInstance(object value) => base.CanRemoveInstance(value); - - public new bool CanSelectMultipleInstances() => base.CanSelectMultipleInstances(); - - public new string GetDisplayText(object value) => base.GetDisplayText(value); - - public new object[] GetItems(object editValue) => base.GetItems(editValue); - - public new object SetItems(object editValue, object[] value) => base.SetItems(editValue, value); - } - - private class ClassWithItem - { - public int Item { get; set; } - } - - private class ClassWithPrivateItem - { - private int Item { get; set; } - } - - private class ClassWithStaticItem - { - public static int Item { get; set; } - } - - private class ClassWithItems - { - public int Items { get; set; } - } - - private class ClassWithPrivateItems - { - private int Items { get; set; } - } - - private class ClassWithStaticItems - { - public static int Items { get; set; } - } - - private class ClassWithStringName - { - public string Name { get; set; } - - public override string ToString() => nameof(ClassWithStringName); - } - - private class ClassWithNonStringName - { - public int Name { get; set; } - - public override string ToString() => nameof(ClassWithNonStringName); - } - - private class ClassWithNullToString - { - public int Name { get; set; } - - public override string ToString() => null; - } - - [DefaultProperty(nameof(ClassWithStringDefaultProperty.DefaultProperty))] - private class ClassWithStringDefaultProperty - { - public string DefaultProperty { get; set; } - - public override string ToString() => nameof(ClassWithStringDefaultProperty); - } - - [DefaultProperty(nameof(ClassWithNonStringDefaultProperty.DefaultProperty))] - private class ClassWithNonStringDefaultProperty - { - public int DefaultProperty { get; set; } - - public override string ToString() => nameof(ClassWithNonStringDefaultProperty); - } - - [DefaultProperty("NoSuchProperty")] - private class ClassWithNoSuchDefaultProperty - { - public string DefaultProperty { get; set; } - - public override string ToString() => nameof(ClassWithNoSuchDefaultProperty); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ByteViewerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ByteViewerTests.cs deleted file mode 100644 index 34499ca652e..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ByteViewerTests.cs +++ /dev/null @@ -1,1117 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Windows.Forms.TestUtilities; -using Point = System.Drawing.Point; -using Size = System.Drawing.Size; - -namespace System.ComponentModel.Design.Tests; - -public class ByteViewerTests -{ - [WinFormsFact] - public void ByteViewer_Ctor_Default() - { - using SubByteViewer control = new(); - Assert.Null(control.AccessibleDefaultActionDescription); - Assert.Null(control.AccessibleDescription); - Assert.Null(control.AccessibleName); - Assert.Equal(AccessibleRole.Default, control.AccessibleRole); - Assert.False(control.AllowDrop); - Assert.Equal(AnchorStyles.Top | AnchorStyles.Left, control.Anchor); - Assert.False(control.AutoScroll); - Assert.Equal(Size.Empty, control.AutoScrollMargin); - Assert.Equal(Size.Empty, control.AutoScrollMinSize); - Assert.Equal(Point.Empty, control.AutoScrollPosition); - Assert.False(control.AutoSize); - Assert.Equal(AutoSizeMode.GrowOnly, control.AutoSizeMode); - Assert.Equal(Control.DefaultBackColor, control.BackColor); - Assert.Null(control.BackgroundImage); - Assert.Equal(ImageLayout.Tile, control.BackgroundImageLayout); - Assert.Null(control.BindingContext); - Assert.Equal(BorderStyle.None, control.BorderStyle); - Assert.True(control.Bottom > 0); - Assert.Equal(new Rectangle(0, 0, control.Width, control.Height), control.Bounds); - Assert.True(control.CanEnableIme); - Assert.False(control.CanFocus); - Assert.True(control.CanRaiseEvents); - Assert.False(control.CanSelect); - Assert.False(control.Capture); - Assert.True(control.CausesValidation); - Assert.Equal(TableLayoutPanelCellBorderStyle.Inset, control.CellBorderStyle); - Assert.Equal(new Rectangle(0, 0, control.Width, control.Height), control.ClientRectangle); - Assert.Equal(new Size(control.Width, control.Height), control.ClientSize); - Assert.Equal(1, control.ColumnCount); - ColumnStyle columnStyle = Assert.IsType(Assert.Single(control.ColumnStyles)); - Assert.Equal(SizeType.Percent, columnStyle.SizeType); - Assert.Equal(100F, columnStyle.Width); - Assert.Same(control.LayoutSettings.ColumnStyles, control.ColumnStyles); - Assert.Null(control.Container); - Assert.False(control.ContainsFocus); - Assert.Null(control.ContextMenuStrip); - Assert.NotEmpty(control.Controls); - Assert.Same(control.Controls, control.Controls); - Assert.False(control.Created); - Assert.Equal(Cursors.Default, control.Cursor); - Assert.Equal(Cursors.Default, control.DefaultCursor); - Assert.Equal(ImeMode.Inherit, control.DefaultImeMode); - Assert.Equal(new Padding(3), control.DefaultMargin); - Assert.Equal(Size.Empty, control.DefaultMaximumSize); - Assert.Equal(Size.Empty, control.DefaultMinimumSize); - Assert.Equal(Padding.Empty, control.DefaultPadding); - Assert.Equal(new Size(200, 100), control.DefaultSize); - Assert.False(control.DesignMode); - Assert.Equal(new Rectangle(0, 0, control.Width, control.Height), control.DisplayRectangle); - Assert.Equal(DockStyle.None, control.Dock); - Assert.NotNull(control.DockPadding); - Assert.Same(control.DockPadding, control.DockPadding); - Assert.Equal(0, control.DockPadding.Top); - Assert.Equal(0, control.DockPadding.Bottom); - Assert.Equal(0, control.DockPadding.Left); - Assert.Equal(0, control.DockPadding.Right); - Assert.True(control.DoubleBuffered); - Assert.True(control.Enabled); - Assert.NotNull(control.Events); - Assert.Same(control.Events, control.Events); - Assert.False(control.Focused); - Assert.Equal(Control.DefaultFont, control.Font); - Assert.Equal(control.Font.Height, control.FontHeight); - Assert.Equal(Control.DefaultForeColor, control.ForeColor); - Assert.Equal(TableLayoutPanelGrowStyle.AddRows, control.GrowStyle); - Assert.True(control.HasChildren); - Assert.True(control.Height > 0); - Assert.NotNull(control.HorizontalScroll); - Assert.Same(control.HorizontalScroll, control.HorizontalScroll); - Assert.False(control.HScroll); - Assert.Equal(ImeMode.NoControl, control.ImeMode); - Assert.Equal(ImeMode.NoControl, control.ImeModeBase); - Assert.False(control.IsAccessible); - Assert.False(control.IsMirrored); - Assert.NotNull(control.LayoutEngine); - Assert.Same(control.LayoutEngine, control.LayoutEngine); - Assert.NotNull(control.LayoutSettings); - Assert.Same(control.LayoutSettings, control.LayoutSettings); - Assert.Equal(0, control.Left); - Assert.Equal(Point.Empty, control.Location); - Assert.Equal(new Padding(3), control.Margin); - Assert.Equal(Size.Empty, control.MaximumSize); - Assert.Equal(Size.Empty, control.MinimumSize); - Assert.Equal(Padding.Empty, control.Padding); - Assert.Null(control.Parent); - Assert.Equal(new Size(4, 4), control.PreferredSize); - Assert.Equal("Microsoft\u00AE .NET", control.ProductName); - Assert.False(control.RecreatingHandle); - Assert.Null(control.Region); - Assert.True(control.ResizeRedraw); - Assert.True(control.Right > 0); - Assert.Equal(RightToLeft.No, control.RightToLeft); - Assert.Equal(1, control.RowCount); - RowStyle rowStyle = Assert.IsType(Assert.Single(control.RowStyles)); - Assert.Equal(SizeType.Percent, rowStyle.SizeType); - Assert.Equal(100F, rowStyle.Height); - Assert.Same(control.LayoutSettings.RowStyles, control.RowStyles); - Assert.True(control.ShowFocusCues); - Assert.True(control.ShowKeyboardCues); - Assert.Equal(new Size(control.Width, control.Height), control.Size); - Assert.Equal(0, control.TabIndex); - Assert.False(control.TabStop); - Assert.Empty(control.Text); - Assert.Equal(0, control.Top); - Assert.Null(control.TopLevelControl); - Assert.False(control.UseWaitCursor); - Assert.True(control.Visible); - Assert.NotNull(control.VerticalScroll); - Assert.Same(control.VerticalScroll, control.VerticalScroll); - Assert.False(control.VScroll); - Assert.True(control.Width > 0); - - Assert.False(control.IsHandleCreated); - } - - [WinFormsFact] - public void ByteViewer_CreateParams_GetDefault_ReturnsExpected() - { - using SubByteViewer control = new(); - CreateParams createParams = control.CreateParams; - Assert.Null(createParams.Caption); - Assert.Null(createParams.ClassName); - Assert.Equal(0x8, createParams.ClassStyle); - Assert.Equal(0x10000, createParams.ExStyle); - Assert.Equal(control.Height, createParams.Height); - Assert.Equal(IntPtr.Zero, createParams.Parent); - Assert.Null(createParams.Param); - Assert.Equal(0x56000000, createParams.Style); - Assert.Equal(control.Width, createParams.Width); - Assert.Equal(0, createParams.X); - Assert.Equal(0, createParams.Y); - Assert.Same(createParams, control.CreateParams); - Assert.False(control.IsHandleCreated); - } - - [WinFormsFact] - public void ByteViewer_GetAutoSizeMode_Invoke_ReturnsExpected() - { - using SubByteViewer control = new(); - Assert.Equal(AutoSizeMode.GrowOnly, control.GetAutoSizeMode()); - } - - [WinFormsFact] - public void ByteViewer_GetBytes_Invoke_ReturnsExpected() - { - using ByteViewer control = new(); - Assert.Null(control.GetBytes()); - Assert.False(control.IsHandleCreated); - } - - [WinFormsFact] - public void ByteViewer_GetDisplayMode_Invoke_ReturnsExpected() - { - using ByteViewer control = new(); - Assert.Equal(DisplayMode.Hexdump, control.GetDisplayMode()); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [InlineData(0, true)] - [InlineData(SubByteViewer.ScrollStateAutoScrolling, false)] - [InlineData(SubByteViewer.ScrollStateFullDrag, false)] - [InlineData(SubByteViewer.ScrollStateHScrollVisible, false)] - [InlineData(SubByteViewer.ScrollStateUserHasScrolled, false)] - [InlineData(SubByteViewer.ScrollStateVScrollVisible, false)] - [InlineData(int.MaxValue, false)] - [InlineData((-1), false)] - public void ByteViewer_GetScrollState_Invoke_ReturnsExpected(int bit, bool expected) - { - using SubByteViewer control = new(); - Assert.Equal(expected, control.GetScrollState(bit)); - } - - [WinFormsTheory] - [InlineData(ControlStyles.ContainerControl, true)] - [InlineData(ControlStyles.UserPaint, true)] - [InlineData(ControlStyles.Opaque, false)] - [InlineData(ControlStyles.ResizeRedraw, true)] - [InlineData(ControlStyles.FixedWidth, false)] - [InlineData(ControlStyles.FixedHeight, false)] - [InlineData(ControlStyles.StandardClick, true)] - [InlineData(ControlStyles.Selectable, false)] - [InlineData(ControlStyles.UserMouse, false)] - [InlineData(ControlStyles.SupportsTransparentBackColor, true)] - [InlineData(ControlStyles.StandardDoubleClick, true)] - [InlineData(ControlStyles.AllPaintingInWmPaint, true)] - [InlineData(ControlStyles.CacheText, false)] - [InlineData(ControlStyles.EnableNotifyMessage, false)] - [InlineData(ControlStyles.DoubleBuffer, false)] - [InlineData(ControlStyles.OptimizedDoubleBuffer, true)] - [InlineData(ControlStyles.UseTextForAccessibility, true)] - [InlineData((ControlStyles)0, true)] - [InlineData((ControlStyles)int.MaxValue, false)] - [InlineData((ControlStyles)(-1), false)] - public void ByteViewer_GetStyle_Invoke_ReturnsExpected(ControlStyles flag, bool expected) - { - using SubByteViewer control = new(); - Assert.Equal(expected, control.GetStyle(flag)); - - // Call again to test caching. - Assert.Equal(expected, control.GetStyle(flag)); - } - - [WinFormsFact] - public void ByteViewer_GetTopLevel_Invoke_ReturnsExpected() - { - using SubByteViewer control = new(); - Assert.False(control.GetTopLevel()); - } - - [WinFormsTheory] - [NewAndDefaultData] - public void ByteViewer_OnHandleCreated_InvokeWithHandle_CallsHandleCreated(EventArgs eventArgs) - { - using SubByteViewer control = new(); - Assert.NotEqual(IntPtr.Zero, control.Handle); - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(control, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - // Call with handler. - control.HandleCreated += handler; - control.OnHandleCreated(eventArgs); - Assert.Equal(1, callCount); - Assert.True(control.IsHandleCreated); - - // Remove handler. - control.HandleCreated -= handler; - control.OnHandleCreated(eventArgs); - Assert.Equal(1, callCount); - Assert.True(control.IsHandleCreated); - } - - [WinFormsTheory] - [NewAndDefaultData] - public void ByteViewer_OnHandleDestroyed_Invoke_CallsHandleDestroyed(EventArgs eventArgs) - { - using SubByteViewer control = new(); - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(control, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - // Call with handler. - control.HandleDestroyed += handler; - control.OnHandleDestroyed(eventArgs); - Assert.Equal(1, callCount); - Assert.False(control.IsHandleCreated); - - // Remove handler. - control.HandleDestroyed -= handler; - control.OnHandleDestroyed(eventArgs); - Assert.Equal(1, callCount); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [NewAndDefaultData] - public void ByteViewer_OnHandleDestroyed_InvokeWithHandle_CallsHandleDestroyed(EventArgs eventArgs) - { - using SubByteViewer control = new(); - Assert.NotEqual(IntPtr.Zero, control.Handle); - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(control, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - // Call with handler. - control.HandleDestroyed += handler; - control.OnHandleDestroyed(eventArgs); - Assert.Equal(1, callCount); - Assert.True(control.IsHandleCreated); - - // Remove handler. - control.HandleDestroyed -= handler; - control.OnHandleDestroyed(eventArgs); - Assert.Equal(1, callCount); - Assert.True(control.IsHandleCreated); - } - - public static IEnumerable OnLayout_TestData() - { - yield return new object[] { new LayoutEventArgs(null, null) }; - yield return new object[] { new LayoutEventArgs(new Control(), null) }; - yield return new object[] { new LayoutEventArgs(new Control(), string.Empty) }; - yield return new object[] { new LayoutEventArgs(new Control(), "ChildIndex") }; - yield return new object[] { new LayoutEventArgs(new Control(), "Visible") }; - yield return new object[] { new LayoutEventArgs(new Control(), "Items") }; - yield return new object[] { new LayoutEventArgs(new Control(), "Rows") }; - yield return new object[] { new LayoutEventArgs(new Control(), "Columns") }; - yield return new object[] { new LayoutEventArgs(new Control(), "RowStyles") }; - yield return new object[] { new LayoutEventArgs(new Control(), "ColumnStyles") }; - yield return new object[] { new LayoutEventArgs(new Control(), "TableIndex") }; - yield return new object[] { new LayoutEventArgs(new Control(), "GrowStyle") }; - yield return new object[] { new LayoutEventArgs(new Control(), "CellBorderStyle") }; - yield return new object[] { new LayoutEventArgs(new Control(), "LayoutSettings") }; - yield return new object[] { new LayoutEventArgs(new Control(), "NoSuchProperty") }; - } - - [WinFormsTheory] - [MemberData(nameof(OnLayout_TestData))] - public void ByteViewer_OnLayout_Invoke_CallsLayout(LayoutEventArgs eventArgs) - { - using SubByteViewer control = new(); - int callCount = 0; - LayoutEventHandler handler = (sender, e) => - { - Assert.Same(control, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - // Call with handler. - control.Layout += handler; - control.OnLayout(eventArgs); - Assert.Equal(1, callCount); - Assert.False(control.IsHandleCreated); - - // Remove handler. - control.Layout -= handler; - control.OnLayout(eventArgs); - Assert.Equal(1, callCount); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [MemberData(nameof(OnLayout_TestData))] - public void ByteViewer_OnLayout_InvokeWithHandle_CallsLayout(LayoutEventArgs eventArgs) - { - using SubByteViewer control = new(); - Assert.NotEqual(IntPtr.Zero, control.Handle); - int invalidatedCallCount = 0; - control.Invalidated += (sender, e) => invalidatedCallCount++; - int styleChangedCallCount = 0; - control.StyleChanged += (sender, e) => styleChangedCallCount++; - int createdCallCount = 0; - control.HandleCreated += (sender, e) => createdCallCount++; - int callCount = 0; - LayoutEventHandler handler = (sender, e) => - { - Assert.Same(control, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - // Call with handler. - control.Layout += handler; - control.OnLayout(eventArgs); - Assert.Equal(1, callCount); - Assert.True(control.IsHandleCreated); - Assert.Equal(1, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - - // Remove handler. - control.Layout -= handler; - control.OnLayout(eventArgs); - Assert.Equal(1, callCount); - Assert.True(control.IsHandleCreated); - Assert.Equal(2, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - } - - [WinFormsFact] - public void ByteViewer_OnLayout_InvokeNullE_ThrowsNullReferenceException() - { - using SubByteViewer control = new(); - Assert.Throws(() => control.OnLayout(null)); - } - - [WinFormsTheory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetKeyEventArgsTheoryData))] - public void ByteViewer_OnKeyDown_Invoke_CallsKeyDown(KeyEventArgs eventArgs) - { - using SubByteViewer control = new(); - int callCount = 0; - KeyEventHandler handler = (sender, e) => - { - Assert.Same(control, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - // Call with handler. - control.KeyDown += handler; - control.OnKeyDown(eventArgs); - Assert.Equal(0, callCount); - - // Remove handler. - control.KeyDown -= handler; - control.OnKeyDown(eventArgs); - Assert.Equal(0, callCount); - } - - [WinFormsFact] - public void ByteViewer_OnPaint_Invoke_CallsPaint() - { - using Bitmap image = new(10, 10); - using Graphics graphics = Graphics.FromImage(image); - using PaintEventArgs eventArgs = new(graphics, Rectangle.Empty); - - using SubByteViewer control = new(); - int callCount = 0; - PaintEventHandler handler = (sender, e) => - { - Assert.Same(control, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - // Call with handler. - control.Paint += handler; - control.OnPaint(eventArgs); - Assert.Equal(1, callCount); - Assert.False(control.IsHandleCreated); - - // Remove handler. - control.Paint -= handler; - control.OnPaint(eventArgs); - Assert.Equal(1, callCount); - Assert.False(control.IsHandleCreated); - } - - public static IEnumerable OnPaint_WithBytes_TestData() - { - foreach (DisplayMode displayMode in Enum.GetValues(typeof(DisplayMode))) - { - yield return new object[] { Array.Empty(), displayMode }; - yield return new object[] { new byte[] { 1, 2, 3 }, displayMode }; - yield return new object[] { new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, displayMode }; - yield return new object[] { new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, displayMode }; - } - } - - [WinFormsTheory] - [MemberData(nameof(OnPaint_WithBytes_TestData))] - public void ByteViewer_OnPaint_InvokeWithBytes_CallsPaint(byte[] bytes, DisplayMode displayMode) - { - using Bitmap image = new(10, 10); - using Graphics graphics = Graphics.FromImage(image); - using PaintEventArgs eventArgs = new(graphics, Rectangle.Empty); - - using SubByteViewer control = new(); - control.SetBytes(bytes); - control.SetDisplayMode(displayMode); - Assert.NotEqual(IntPtr.Zero, control.Handle); - int invalidatedCallCount = 0; - control.Invalidated += (sender, e) => invalidatedCallCount++; - int styleChangedCallCount = 0; - control.StyleChanged += (sender, e) => styleChangedCallCount++; - int createdCallCount = 0; - control.HandleCreated += (sender, e) => createdCallCount++; - - int callCount = 0; - PaintEventHandler handler = (sender, e) => - { - Assert.Same(control, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - // Call with handler. - control.Paint += handler; - control.OnPaint(eventArgs); - Assert.Equal(1, callCount); - Assert.True(control.IsHandleCreated); - Assert.Equal(0, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - - // Remove handler. - control.Paint -= handler; - control.OnPaint(eventArgs); - Assert.Equal(1, callCount); - Assert.True(control.IsHandleCreated); - Assert.Equal(0, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - } - - [WinFormsFact] - public void ByteViewer_OnPaint_InvokeWithHandle_CallsPaint() - { - using Bitmap image = new(10, 10); - using Graphics graphics = Graphics.FromImage(image); - using PaintEventArgs eventArgs = new(graphics, Rectangle.Empty); - - using SubByteViewer control = new(); - int callCount = 0; - PaintEventHandler handler = (sender, e) => - { - Assert.Same(control, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - // Call with handler. - control.Paint += handler; - control.OnPaint(eventArgs); - Assert.Equal(1, callCount); - Assert.False(control.IsHandleCreated); - - // Remove handler. - control.Paint -= handler; - control.OnPaint(eventArgs); - Assert.Equal(1, callCount); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [MemberData(nameof(OnPaint_WithBytes_TestData))] - public void ByteViewer_OnPaint_InvokeWithBytesWithHandle_CallsPaint(byte[] bytes, DisplayMode displayMode) - { - using Bitmap image = new(10, 10); - using Graphics graphics = Graphics.FromImage(image); - using PaintEventArgs eventArgs = new(graphics, Rectangle.Empty); - - using SubByteViewer control = new(); - control.SetBytes(bytes); - control.SetDisplayMode(displayMode); - Assert.NotEqual(IntPtr.Zero, control.Handle); - int invalidatedCallCount = 0; - control.Invalidated += (sender, e) => invalidatedCallCount++; - int styleChangedCallCount = 0; - control.StyleChanged += (sender, e) => styleChangedCallCount++; - int createdCallCount = 0; - control.HandleCreated += (sender, e) => createdCallCount++; - - int callCount = 0; - PaintEventHandler handler = (sender, e) => - { - Assert.Same(control, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - // Call with handler. - control.Paint += handler; - control.OnPaint(eventArgs); - Assert.Equal(1, callCount); - Assert.True(control.IsHandleCreated); - Assert.Equal(0, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - - // Remove handler. - control.Paint -= handler; - control.OnPaint(eventArgs); - Assert.Equal(1, callCount); - Assert.True(control.IsHandleCreated); - Assert.Equal(0, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - } - - [WinFormsFact] - public void ByteViewer_OnPaint_NullE_ThrowsNullReferenceException() - { - using SubByteViewer control = new(); - Assert.Throws(() => control.OnPaint(null)); - } - - [WinFormsTheory] - [InlineData(null)] - [InlineData("*")] // Invalid path - public void ByteViewer_SaveToFile_InvokeNoBytes_Nop(string path) - { - using ByteViewer control = new(); - control.SaveToFile(path); - } - - [WinFormsFact] - public void ByteViewer_SaveToFile_InvokeWithBytes_Success() - { - using ByteViewer control = new(); - control.SetBytes(new byte[] { 1, 2, 3 }); - string path = "ByteViewerContent"; - try - { - control.SaveToFile(path); - Assert.Equal(new byte[] { 1, 2, 3 }, File.ReadAllBytes(path)); - } - finally - { - File.Delete(path); - } - } - - [WinFormsFact] - public void ByteViewer_SaveToFile_InvokeNullPath_ThrowsArgumentNullException() - { - using ByteViewer control = new(); - control.SetBytes(Array.Empty()); - Assert.Throws("path", () => control.SaveToFile(null)); - } - - [WinFormsTheory] - [InlineData("")] - [InlineData("\0")] - public void ByteViewer_SaveToFile_InvokeInvalidPath_ThrowsArgumentException(string path) - { - using ByteViewer control = new(); - control.SetBytes(Array.Empty()); - Assert.Throws("path", () => control.SaveToFile(path)); - } - - public static IEnumerable ScrollChanged_TestData() - { - yield return new object[] { null, null }; - yield return new object[] { null, new EventArgs() }; - yield return new object[] { new object(), null }; - yield return new object[] { new object(), new EventArgs() }; - } - - [WinFormsTheory] - [MemberData(nameof(ScrollChanged_TestData))] - public void ByteViewer_ScrollChanged_Invoke_Success(object source, EventArgs e) - { - using SubByteViewer control = new(); - control.ScrollChanged(source, e); - Assert.False(control.IsHandleCreated); - - // Call again. - control.ScrollChanged(source, e); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [MemberData(nameof(ScrollChanged_TestData))] - public void ByteViewer_ScrollChanged_InvokeWithHandle_Success(object source, EventArgs e) - { - using SubByteViewer control = new(); - Assert.NotEqual(IntPtr.Zero, control.Handle); - int invalidatedCallCount = 0; - control.Invalidated += (sender, e) => invalidatedCallCount++; - int styleChangedCallCount = 0; - control.StyleChanged += (sender, e) => styleChangedCallCount++; - int createdCallCount = 0; - control.HandleCreated += (sender, e) => createdCallCount++; - - control.ScrollChanged(source, e); - Assert.True(control.IsHandleCreated); - Assert.Equal(1, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - - // Call again. - control.ScrollChanged(source, e); - Assert.True(control.IsHandleCreated); - Assert.Equal(2, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - } - - public static IEnumerable SetBytes_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new byte[] { 1, 2, 3 } }; - yield return new object[] { new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 } }; - yield return new object[] { new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } }; - } - - [WinFormsTheory] - [MemberData(nameof(SetBytes_TestData))] - public void ByteViewer_SetBytes_Invoke_GetReturnExpected(byte[] bytes) - { - using ByteViewer control = new(); - control.SetBytes(bytes); - Assert.Same(bytes, control.GetBytes()); - Assert.False(control.IsHandleCreated); - - // Set same. - control.SetBytes(bytes); - Assert.Same(bytes, control.GetBytes()); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [MemberData(nameof(SetBytes_TestData))] - public void ByteViewer_SetBytes_InvokeWithBytes_GetReturnExpected(byte[] bytes) - { - using ByteViewer control = new(); - control.SetBytes(new byte[] { 1 }); - - control.SetBytes(bytes); - Assert.Same(bytes, control.GetBytes()); - Assert.False(control.IsHandleCreated); - - // Set same. - control.SetBytes(bytes); - Assert.Same(bytes, control.GetBytes()); - Assert.False(control.IsHandleCreated); - } - - [WinFormsFact] - public void ByteViewer_SetBytes_NullBytes_ThrowsArgumentNullException() - { - using ByteViewer control = new(); - Assert.Throws("bytes", () => control.SetBytes(null)); - } - - [WinFormsTheory] - [InlineData(DisplayMode.Auto)] - [InlineData(DisplayMode.Hexdump)] - public void ByteViewer_SetDisplayMode_InvokeNoBytes_GetReturnsExpected(DisplayMode value) - { - using ByteViewer control = new(); - control.SetDisplayMode(value); - Assert.Equal(value, control.GetDisplayMode()); - Assert.False(control.IsHandleCreated); - - // Set same. - control.SetDisplayMode(value); - Assert.Equal(value, control.GetDisplayMode()); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [EnumData] - public void ByteViewer_SetDisplayMode_InvokeWithBytes_GetReturnsExpected(DisplayMode value) - { - using ByteViewer control = new(); - control.SetBytes(new byte[] { 1, 2, 3 }); - - control.SetDisplayMode(value); - Assert.Equal(value, control.GetDisplayMode()); - Assert.False(control.IsHandleCreated); - - // Set same. - control.SetDisplayMode(value); - Assert.Equal(value, control.GetDisplayMode()); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [InlineData(DisplayMode.Ansi, 2, 3)] - [InlineData(DisplayMode.Auto, 0, 0)] - [InlineData(DisplayMode.Hexdump, 0, 0)] - [InlineData(DisplayMode.Unicode, 2, 3)] - public void ByteViewer_SetDisplayMode_InvokeWithBytesWithHandle_GetReturnsExpected(DisplayMode value, int expectedInvalidatedCallCount1, int expectedInvalidatedCallCount2) - { - using ByteViewer control = new(); - control.SetBytes(new byte[] { 1, 2, 3 }); - Assert.NotEqual(IntPtr.Zero, control.Handle); - int invalidatedCallCount = 0; - control.Invalidated += (sender, e) => invalidatedCallCount++; - int styleChangedCallCount = 0; - control.StyleChanged += (sender, e) => styleChangedCallCount++; - int createdCallCount = 0; - control.HandleCreated += (sender, e) => createdCallCount++; - - control.SetDisplayMode(value); - Assert.Equal(value, control.GetDisplayMode()); - Assert.True(control.IsHandleCreated); - Assert.Equal(expectedInvalidatedCallCount1, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - - // Set same. - control.SetDisplayMode(value); - Assert.Equal(value, control.GetDisplayMode()); - Assert.True(control.IsHandleCreated); - Assert.Equal(expectedInvalidatedCallCount2, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - } - - public static IEnumerable SetDisplayMode_AnsiWithBytes_TestData() - { - yield return new object[] { new byte[] { 1, 2, 3 }, "\u0001\u0002\u0003" }; - yield return new object[] { new byte[] { (byte)'a', (byte)'b', (byte)'c' }, "abc" }; - yield return new object[] { new byte[] { (byte)'a', (byte)'b', (byte)'c', (byte)'\0', (byte)'d', (byte)'e', (byte)'f' }, $"abc\u000Bdef" }; - } - - [WinFormsTheory] - [MemberData(nameof(SetDisplayMode_AnsiWithBytes_TestData))] - public void ByteViewer_SetDisplayMode_AnsiWithBytes_EditReturnsExpected(byte[] bytes, string expected) - { - using ByteViewer control = new(); - control.SetBytes(bytes); - control.SetDisplayMode(DisplayMode.Ansi); - - TextBox textBox = control.Controls.OfType().Single(); - ScrollBar scrollBar = control.Controls.OfType().Single(); - Assert.Equal(expected, textBox.Text); - Assert.True(textBox.Visible); - Assert.False(scrollBar.Visible); - Assert.False(control.IsHandleCreated); - - // Set different. - control.SetBytes(new byte[] { (byte)'1', (byte)'2', (byte)'3' }); - Assert.Equal("123", textBox.Text); - Assert.True(textBox.Visible); - Assert.False(scrollBar.Visible); - Assert.False(control.IsHandleCreated); - } - - public static IEnumerable SetDisplayMode_UnicodeWithBytes_TestData() - { - yield return new object[] { new byte[] { 1, 0, 2, 0, 3, 0 }, "\u0001\u0002\u0003" }; - yield return new object[] { new byte[] { (byte)'a', 0, (byte)'b', 0, (byte)'c', 0 }, "abc" }; - yield return new object[] { new byte[] { (byte)'a', 0, (byte)'b', 0, (byte)'c', 0, (byte)'\0', 0, (byte)'d', 0, (byte)'e', 0, (byte)'f', 0 }, $"abc\u000Bdef" }; - } - - [WinFormsTheory] - [MemberData(nameof(SetDisplayMode_UnicodeWithBytes_TestData))] - public void ByteViewer_SetDisplayMode_UnicodeWithBytes_EditReturnsExpected(byte[] bytes, string expected) - { - using ByteViewer control = new(); - control.SetBytes(bytes); - control.SetDisplayMode(DisplayMode.Unicode); - - TextBox textBox = control.Controls.OfType().Single(); - ScrollBar scrollBar = control.Controls.OfType().Single(); - Assert.Equal(expected, textBox.Text); - Assert.True(textBox.Visible); - Assert.False(scrollBar.Visible); - Assert.False(control.IsHandleCreated); - - // Set different. - control.SetBytes(new byte[] { (byte)'1', 0, (byte)'2', 0, (byte)'3', 0 }); - Assert.Equal("123", textBox.Text); - Assert.True(textBox.Visible); - Assert.False(scrollBar.Visible); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [InlineData(DisplayMode.Ansi)] - [InlineData(DisplayMode.Unicode)] - public void ByteViewer_SetDisplayMode_InvokeNoBytes_ThrowsNullReferenceException(DisplayMode value) - { - using ByteViewer control = new(); - Assert.Throws(() => control.SetDisplayMode(value)); - Assert.Equal(value, control.GetDisplayMode()); - Assert.False(control.IsHandleCreated); - - // Set same. - Assert.Throws(() => control.SetDisplayMode(value)); - Assert.Equal(value, control.GetDisplayMode()); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [InvalidEnumData] - public void ByteViewer_SetDisplayMode_InvokeInvalidMode_ThrowsInvalidEnumArgumentException(DisplayMode value) - { - using ByteViewer control = new(); - Assert.Throws("mode", () => control.SetDisplayMode(value)); - } - - [WinFormsFact] - public void ByteViewer_SetFile_InvokeNoBytes_Success() - { - using ByteViewer control = new(); - using TempFile file = TempFile.Create(new byte[] { 1, 2, 3 }); - control.SetFile(file.Path); - Assert.Equal(new byte[] { 1, 2, 3, 0 }, control.GetBytes()); - } - - [WinFormsFact] - public void ByteViewer_SetFile_InvokeWithBytes_Success() - { - using ByteViewer control = new(); - control.SetBytes(new byte[] { 4, 5, 6 }); - - using TempFile file = TempFile.Create(new byte[] { 1, 2, 3 }); - control.SetFile(file.Path); - Assert.Equal(new byte[] { 1, 2, 3, 0 }, control.GetBytes()); - } - - [WinFormsFact] - public void ByteViewer_SetFile_InvokeNullPath_ThrowsArgumentNullException() - { - using ByteViewer control = new(); - control.SetBytes(Array.Empty()); - Assert.Throws("path", () => control.SetFile(null)); - } - - [WinFormsTheory] - [InlineData("")] - [InlineData("\0")] - public void ByteViewer_SetFile_InvokeInvalidPath_ThrowsArgumentException(string path) - { - using ByteViewer control = new(); - control.SetBytes(Array.Empty()); - Assert.Throws("path", () => control.SetFile(path)); - } - - [WinFormsTheory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(1)] - public void ByteViewer_SetStartLine_InvokeNoBytes_Success(int line) - { - using ByteViewer control = new(); - control.SetStartLine(line); - Assert.False(control.IsHandleCreated); - - // Call again. - control.SetStartLine(line); - Assert.False(control.IsHandleCreated); - } - - public static IEnumerable SetStartLine_WithBytes_TestData() - { - yield return new object[] { Array.Empty(), -1 }; - yield return new object[] { Array.Empty(), 0 }; - yield return new object[] { Array.Empty(), 1 }; - yield return new object[] { Array.Empty(), int.MaxValue }; - yield return new object[] { new byte[] { 1, 2, 3 }, -1 }; - yield return new object[] { new byte[] { 1, 2, 3 }, 0 }; - yield return new object[] { new byte[] { 1, 2, 3 }, 1 }; - yield return new object[] { new byte[] { 1, 2, 3 }, int.MaxValue }; - yield return new object[] { new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, -1 }; - yield return new object[] { new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 0 }; - yield return new object[] { new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 1 }; - yield return new object[] { new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, int.MaxValue }; - } - - [WinFormsTheory] - [MemberData(nameof(SetStartLine_WithBytes_TestData))] - public void ByteViewer_SetStartLine_InvokeWithBytes_Success(byte[] bytes, int line) - { - using ByteViewer control = new(); - control.SetBytes(bytes); - - control.SetStartLine(line); - Assert.False(control.IsHandleCreated); - - // Call again. - control.SetStartLine(line); - Assert.False(control.IsHandleCreated); - } - - [WinFormsTheory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(1)] - [InlineData(int.MaxValue)] - public void ByteViewer_SetStartLine_InvokeNoBytesWithHandle_Success(int line) - { - using ByteViewer control = new(); - Assert.NotEqual(IntPtr.Zero, control.Handle); - int invalidatedCallCount = 0; - control.Invalidated += (sender, e) => invalidatedCallCount++; - int styleChangedCallCount = 0; - control.StyleChanged += (sender, e) => styleChangedCallCount++; - int createdCallCount = 0; - control.HandleCreated += (sender, e) => createdCallCount++; - - control.SetStartLine(line); - Assert.True(control.IsHandleCreated); - Assert.Equal(0, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - - // Call again. - control.SetStartLine(line); - Assert.True(control.IsHandleCreated); - Assert.Equal(0, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - } - - [WinFormsTheory] - [MemberData(nameof(SetStartLine_WithBytes_TestData))] - public void ByteViewer_SetStartLine_InvokeWithBytesWithHandle_Success(byte[] bytes, int line) - { - using ByteViewer control = new(); - control.SetBytes(bytes); - Assert.NotEqual(IntPtr.Zero, control.Handle); - int invalidatedCallCount = 0; - control.Invalidated += (sender, e) => invalidatedCallCount++; - int styleChangedCallCount = 0; - control.StyleChanged += (sender, e) => styleChangedCallCount++; - int createdCallCount = 0; - control.HandleCreated += (sender, e) => createdCallCount++; - - control.SetStartLine(line); - Assert.True(control.IsHandleCreated); - Assert.Equal(0, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - - // Call again. - control.SetStartLine(line); - Assert.True(control.IsHandleCreated); - Assert.Equal(0, invalidatedCallCount); - Assert.Equal(0, styleChangedCallCount); - Assert.Equal(0, createdCallCount); - } - - private class SubByteViewer : ByteViewer - { - public new const int ScrollStateAutoScrolling = ByteViewer.ScrollStateAutoScrolling; - - public new const int ScrollStateHScrollVisible = ByteViewer.ScrollStateHScrollVisible; - - public new const int ScrollStateVScrollVisible = ByteViewer.ScrollStateVScrollVisible; - - public new const int ScrollStateUserHasScrolled = ByteViewer.ScrollStateUserHasScrolled; - - public new const int ScrollStateFullDrag = ByteViewer.ScrollStateFullDrag; - - public new bool CanEnableIme => base.CanEnableIme; - - public new bool CanRaiseEvents => base.CanRaiseEvents; - - public new CreateParams CreateParams => base.CreateParams; - - public new Cursor DefaultCursor => base.DefaultCursor; - - public new ImeMode DefaultImeMode => base.DefaultImeMode; - - public new Padding DefaultMargin => base.DefaultMargin; - - public new Size DefaultMaximumSize => base.DefaultMaximumSize; - - public new Size DefaultMinimumSize => base.DefaultMinimumSize; - - public new Padding DefaultPadding => base.DefaultPadding; - - public new Size DefaultSize => base.DefaultSize; - - public new bool DesignMode => base.DesignMode; - - public new bool DoubleBuffered - { - get => base.DoubleBuffered; - set => base.DoubleBuffered = value; - } - - public new EventHandlerList Events => base.Events; - - public new int FontHeight - { - get => base.FontHeight; - set => base.FontHeight = value; - } - - public new ImeMode ImeModeBase - { - get => base.ImeModeBase; - set => base.ImeModeBase = value; - } - - public new bool HScroll - { - get => base.HScroll; - set => base.HScroll = value; - } - - public new bool ResizeRedraw - { - get => base.ResizeRedraw; - set => base.ResizeRedraw = value; - } - - public new bool ShowFocusCues => base.ShowFocusCues; - - public new bool ShowKeyboardCues => base.ShowKeyboardCues; - - public new bool VScroll - { - get => base.VScroll; - set => base.VScroll = value; - } - - public new AutoSizeMode GetAutoSizeMode() => base.GetAutoSizeMode(); - - public new bool GetScrollState(int bit) => base.GetScrollState(bit); - - public new bool GetStyle(ControlStyles flag) => base.GetStyle(flag); - - public new bool GetTopLevel() => base.GetTopLevel(); - - public new void OnHandleCreated(EventArgs e) => base.OnHandleCreated(e); - - public new void OnHandleDestroyed(EventArgs e) => base.OnHandleDestroyed(e); - - public new void OnLayout(LayoutEventArgs levent) => base.OnLayout(levent); - - public new void OnKeyDown(KeyEventArgs e) => base.OnKeyDown(e); - - public new void OnPaint(PaintEventArgs e) => base.OnPaint(e); - - public new void ScrollChanged(object source, EventArgs e) => base.ScrollChanged(source, e); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/CollectionEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/CollectionEditorTests.cs deleted file mode 100644 index 6cadb7e8fd8..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/CollectionEditorTests.cs +++ /dev/null @@ -1,1143 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Drawing.Design; -using System.Reflection; -using System.Windows.Forms.Design; -using Moq; -using Moq.Protected; -using System.Windows.Forms.TestUtilities; - -namespace System.ComponentModel.Design.Tests; - -public class CollectionEditorTests -{ - [Theory] - [InlineData(typeof(object), typeof(object))] - [InlineData(typeof(string), typeof(object))] - [InlineData(typeof(int[]), typeof(object))] - [InlineData(typeof(IList), typeof(int))] - [InlineData(typeof(IList), typeof(object))] - [InlineData(typeof(ClassWithItem), typeof(int))] - [InlineData(typeof(ClassWithPrivateItem), typeof(object))] - [InlineData(typeof(ClassWithStaticItem), typeof(object))] - [InlineData(typeof(ClassWithItems), typeof(int))] - [InlineData(typeof(ClassWithPrivateItems), typeof(object))] - [InlineData(typeof(ClassWithStaticItems), typeof(object))] - public void CollectionEditor_Ctor_Type(Type type, Type expectedItemType) - { - SubCollectionEditor editor = new(type); - Assert.Equal(expectedItemType, editor.CollectionItemType); - Assert.Same(editor.CollectionItemType, editor.CollectionItemType); - Assert.Equal(type, editor.CollectionType); - Assert.Null(editor.Context); - Assert.Equal("net.ComponentModel.CollectionEditor", editor.HelpTopic); - Assert.False(editor.IsDropDownResizable); - Assert.Equal(new Type[] { expectedItemType }, editor.NewItemTypes); - } - - [Fact] - public void CollectionEditor_Ctor_NullType() - { - SubCollectionEditor editor = new(null); - Assert.Throws("type", () => editor.CollectionItemType); - Assert.Null(editor.CollectionType); - Assert.Null(editor.Context); - Assert.Equal("net.ComponentModel.CollectionEditor", editor.HelpTopic); - Assert.False(editor.IsDropDownResizable); - Assert.Throws("type", () => editor.NewItemTypes); - } - - [Fact] - public void CollectionEditor_CollectionEditor_CancelChanges_Invoke_Nop() - { - SubCollectionEditor editor = new(null); - editor.CancelChanges(); - } - - public static IEnumerable CanRemoveInstance_TestData() - { - yield return new object[] { "some string" }; - yield return new object[] { 123 }; - yield return new object[] { null }; - yield return new object[] { new Component() }; - } - - [Theory] - [MemberData(nameof(CanRemoveInstance_TestData))] - public void CollectionEditor_CanRemoveInstance_Invoke_ReturnsExpected(object value) - { - SubCollectionEditor editor = new(null); - Assert.True(editor.CanRemoveInstance(value)); - } - - public static IEnumerable CanRemoveInstance_InheritanceAttribute_TestData() - { - yield return new object[] { new InheritanceAttribute(InheritanceLevel.Inherited - 1), false }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.Inherited), false }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.InheritedReadOnly), false }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.NotInherited), true }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.NotInherited + 1), false }; - } - - [Theory] - [MemberData(nameof(CanRemoveInstance_InheritanceAttribute_TestData))] - public void CollectionEditor_CanRemoveInstance_InheritanceAttribute_ReturnsExpected(InheritanceAttribute attribute, bool expected) - { - using Component component = new(); - TypeDescriptor.AddAttributes(component, attribute); - SubCollectionEditor editor = new(null); - Assert.Equal(expected, editor.CanRemoveInstance(component)); - } - - [Fact] - public void CollectionEditor_CanSelectMultipleInstances_Invoke_ReturnsFalse() - { - SubCollectionEditor editor = new(null); - Assert.True(editor.CanSelectMultipleInstances()); - } - - [Fact] - public void CollectionEditor_CreateCollectionForm_Invoke_Success() - { - SubCollectionEditor editor = new(typeof(List)); - Form form = editor.CreateCollectionForm(); - Assert.NotSame(form, editor.CreateCollectionForm()); - } - - [Fact] - public void CollectionEditor_CreateCollectionForm_NullCollectionType_ThrowsArgumentNullException() - { - SubCollectionEditor editor = new(null); - Assert.Throws("type", () => editor.CreateCollectionForm()); - } - - [Theory] - [InlineData(typeof(object), typeof(object))] - [InlineData(typeof(int[]), typeof(object))] - [InlineData(typeof(IList), typeof(int))] - [InlineData(typeof(ClassWithItem), typeof(int))] - [InlineData(typeof(ClassWithPrivateItem), typeof(object))] - [InlineData(typeof(ClassWithStaticItem), typeof(object))] - [InlineData(typeof(ClassWithItems), typeof(int))] - [InlineData(typeof(ClassWithPrivateItems), typeof(object))] - [InlineData(typeof(ClassWithStaticItems), typeof(object))] - public void CollectionEditor_CreateCollectionItemType_Invoke_ReturnsExpected(Type type, Type expected) - { - SubCollectionEditor editor = new(type); - Type itemType = editor.CreateCollectionItemType(); - Assert.Equal(expected, itemType); - Assert.Same(itemType, editor.CreateCollectionItemType()); - } - - [Fact] - public void CollectionEditor_CreateCollectionItemType_NullType_ThrowsArgumentNullException() - { - SubCollectionEditor editor = new(null); - Assert.Throws("type", () => editor.CreateCollectionItemType()); - } - - public static IEnumerable InvalidDesignerHost_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(InvalidDesignerHost_TestData))] - public void CollectionEditor_CreateInstance_WithContextWithInvalidDesignerHost_ReturnsExpected(object host) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(host); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - Assert.IsType(editor.CreateInstance(typeof(Component))); - } - - public static IEnumerable CreateInstance_HostDesigner_TestData() - { - yield return new object[] { null }; - - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner - .Setup(d => d.Dispose()); - yield return new object[] { mockDesigner.Object }; - } - - [Theory] - [MemberData(nameof(CreateInstance_HostDesigner_TestData))] - public void CollectionEditor_CreateInstance_WithContextWithHostReturningComponent_CallsCreateComponent(IDesigner designer) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - using Component result = new(); - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns((DesignerTransaction)null); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockHost - .Setup(h => h.CreateComponent(typeof(Component), null)) - .Returns(result); - mockHost - .Setup(h => h.GetDesigner(result)) - .Returns(designer); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - Assert.Same(result, editor.CreateInstance(typeof(Component))); - } - - [Theory] - [MemberData(nameof(CreateInstance_HostDesigner_TestData))] - public void CollectionEditor_CreateInstance_WithContextWithHostReturningNullComponent_CallsCreateComponent(IDesigner designer) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns((DesignerTransaction)null); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockHost - .Setup(h => h.CreateComponent(typeof(Component), null)) - .Returns((IComponent)null); - mockHost - .Setup(h => h.GetDesigner(null)) - .Returns(designer); - mockHost - .Setup(c => c.GetService(typeof(TypeDescriptionProvider))) - .Returns(null); - - object result = new(); - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - Assert.IsType(editor.CreateInstance(typeof(Component))); - } - - [Fact] - public void CollectionEditor_CreateInstance_WithContextWithHostReturningComponentWithIComponentInitializerDesigner_CallsInitializeNewComponent() - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - using Component result = new(); - Mock mockDesigner = new(MockBehavior.Strict); - Mock mockComponentInitializer = mockDesigner.As(); - mockComponentInitializer - .Setup(d => d.InitializeNewComponent(null)) - .Verifiable(); - - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns((DesignerTransaction)null); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockHost - .Setup(h => h.CreateComponent(typeof(Component), null)) - .Returns(result); - mockHost - .Setup(h => h.GetDesigner(result)) - .Returns(mockDesigner.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - Assert.Same(result, editor.CreateInstance(typeof(Component))); - mockComponentInitializer.Verify(d => d.InitializeNewComponent(null), Times.Once()); - } - - public static IEnumerable CreateInstance_InvokeWithoutContext_TestData() - { - yield return new object[] { typeof(int), 0 }; - yield return new object[] { typeof(string), string.Empty }; - } - - [Theory] - [MemberData(nameof(CreateInstance_InvokeWithoutContext_TestData))] - public void CollectionEditor_CreateInstance_InvokeWithoutContext_ReturnsExpected(Type type, object expected) - { - SubCollectionEditor editor = new(null); - Assert.Equal(expected, editor.CreateInstance(type)); - } - - [Fact] - public void CollectionEditor_CreateInstance_NullItemType_ThrowsArgumentNullException() - { - SubCollectionEditor editor = new(null); - Assert.Throws("objectType", () => editor.CreateInstance(null)); - } - - [Theory] - [InlineData(typeof(object), new Type[] { typeof(object) })] - [InlineData(typeof(int[]), new Type[] { typeof(object) })] - [InlineData(typeof(IList), new Type[] { typeof(int) })] - [InlineData(typeof(ClassWithItem), new Type[] { typeof(int) })] - [InlineData(typeof(ClassWithPrivateItem), new Type[] { typeof(object) })] - [InlineData(typeof(ClassWithStaticItem), new Type[] { typeof(object) })] - [InlineData(typeof(ClassWithItems), new Type[] { typeof(int) })] - [InlineData(typeof(ClassWithPrivateItems), new Type[] { typeof(object) })] - [InlineData(typeof(ClassWithStaticItems), new Type[] { typeof(object) })] - public void CollectionEditor_CreateNewItemTypes_Invoke_ReturnsExpected(Type type, Type[] expected) - { - SubCollectionEditor editor = new(type); - Type[] itemTypes = editor.CreateNewItemTypes(); - Assert.Equal(expected, itemTypes); - Assert.NotSame(itemTypes, editor.CreateNewItemTypes()); - } - - [Fact] - public void CollectionEditor_CreateNewItemTypes_NullType_ThrowsArgumentNullException() - { - SubCollectionEditor editor = new(null); - Assert.Throws("type", () => editor.CreateNewItemTypes()); - } - - public static IEnumerable DestroyInstance_NormalObject_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(DestroyInstance_NormalObject_TestData))] - public void CollectionEditor_DestroyInstance_NormalObject_Nop(object instance) - { - SubCollectionEditor editor = new(null); - editor.DestroyInstance(instance); - } - - [Theory] - [MemberData(nameof(InvalidDesignerHost_TestData))] - public void CollectionEditor_DestroyInstance_WithContextWithInvalidDesignerHot_CallsDispose(object host) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(host); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Dispose()) - .Verifiable(); - editor.DestroyInstance(mockComponent.Object); - mockComponent.Verify(c => c.Dispose(), Times.Once()); - } - - [Fact] - public void CollectionEditor_DestroyInstance_WithContextWithInvalidHost_CallsDestroyComponent() - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Dispose()) - .Verifiable(); - - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns((DesignerTransaction)null); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockHost - .Setup(h => h.DestroyComponent(mockComponent.Object)) - .Verifiable(); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - editor.DestroyInstance(mockComponent.Object); - mockComponent.Verify(c => c.Dispose(), Times.Never()); - mockHost.Verify(c => c.DestroyComponent(mockComponent.Object), Times.Once()); - } - - [Fact] - public void CollectionEditor_DestroyInstance_IComponentWithoutHost_CallsDispose() - { - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Dispose()) - .Verifiable(); - - SubCollectionEditor editor = new(null); - editor.DestroyInstance(mockComponent.Object); - mockComponent.Verify(c => c.Dispose(), Times.Once()); - } - - [Fact] - public void CollectionEditor_DestroyInstance_IDisposable_CallsDispose() - { - Mock mockDisposable = new(MockBehavior.Strict); - mockDisposable - .Setup(d => d.Dispose()) - .Verifiable(); - - SubCollectionEditor editor = new(null); - editor.DestroyInstance(mockDisposable.Object); - mockDisposable.Verify(d => d.Dispose(), Times.Once()); - } - - [Theory] - [MemberData(nameof(InvalidDesignerHost_TestData))] - public void CollectionEditor_EditValue_ValidProviderInvalidHost_ReturnsValue(object host) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(host); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - mockEditorService.Verify(s => s.ShowDialog(It.IsAny()), Times.Once()); - } - - [Theory] - [MemberData(nameof(InvalidDesignerHost_TestData))] - public void CollectionEditor_EditValue_ValidProviderValidHost_ReturnsValue(object changeService) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns((DesignerTransaction)null); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(changeService); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(changeService); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - mockEditorService.Verify(s => s.ShowDialog(It.IsAny()), Times.Once()); - } - - [Fact] - public void CollectionEditor_EditValue_ValidProviderValidHostWithTransactionOK_CallsOnCommit() - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockTransaction = new(MockBehavior.Strict); - mockTransaction - .Protected() - .Setup("Dispose", It.IsAny()); - mockTransaction - .Protected() - .Setup("OnCommit") - .Verifiable(); - - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns(mockTransaction.Object); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - mockEditorService.Verify(s => s.ShowDialog(It.IsAny()), Times.Once()); - mockTransaction.Protected().Verify("OnCommit", Times.Once()); - } - - [Fact] - public void CollectionEditor_EditValue_ValidProviderValidHostWithTransactionNotOK_CallsOnCancel() - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.Cancel); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockTransaction = new(MockBehavior.Strict); - mockTransaction - .Protected() - .Setup("Dispose", It.IsAny()); - mockTransaction - .Protected() - .Setup("OnCancel") - .Verifiable(); - - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns(mockTransaction.Object); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - mockEditorService.Verify(s => s.ShowDialog(It.IsAny()), Times.Once()); - mockTransaction.Protected().Verify("OnCancel", Times.Once()); - } - - [Fact] - public void CollectionEditor_EditValue_ValidProviderValidHostWithIComponentChangeService_ReturnsValue() - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockChangeService = new(MockBehavior.Strict); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns((DesignerTransaction)null); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(mockChangeService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(mockChangeService.Object); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - mockEditorService.Verify(s => s.ShowDialog(It.IsAny()), Times.Once()); - } - - [Fact] - public void CollectionEditor_EditValue_NullType_ThrowsArgumentNullException() - { - Mock mockEditorService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns((IDesignerHost)null); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - - SubCollectionEditor editor = new(null); - object value = new(); - Assert.Throws("type", () => editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void CollectionEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - SubCollectionEditor editor = new(null); - Assert.Same(value, editor.EditValue(null, provider, value)); - Assert.Null(editor.Context); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void CollectionEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - CollectionEditor editor = new(null); - Assert.Equal(UITypeEditorEditStyle.Modal, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void CollectionEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - CollectionEditor editor = new(null); - Assert.False(editor.GetPaintValueSupported(context)); - } - - public static IEnumerable GetDisplayText_TestData() - { - yield return new object[] { null, null, string.Empty }; - yield return new object[] { null, string.Empty, "String" }; - yield return new object[] { null, "string", "string" }; - - yield return new object[] { null, new ClassWithStringName { Name = "CustomName" }, "CustomName" }; - yield return new object[] { null, new ClassWithStringName { Name = string.Empty }, "ClassWithStringName" }; - yield return new object[] { null, new ClassWithStringName { Name = null }, "ClassWithStringName" }; - yield return new object[] { null, new ClassWithNonStringName { Name = 1 }, "ClassWithNonStringName" }; - yield return new object[] { null, new ClassWithNullToString(), "ClassWithNullToString" }; - - yield return new object[] { typeof(int), null, string.Empty }; - yield return new object[] { typeof(int), "", "String" }; - yield return new object[] { typeof(int), "value", "value" }; - yield return new object[] { typeof(int), 1, "1" }; - yield return new object[] { typeof(int), new ClassWithStringDefaultProperty { DefaultProperty = "CustomName" }, "ClassWithStringDefaultProperty" }; - - yield return new object[] { typeof(ClassWithStringDefaultProperty), null, string.Empty }; - yield return new object[] { typeof(ClassWithStringDefaultProperty), new ClassWithStringDefaultProperty { DefaultProperty = "CustomName" }, "CustomName" }; - yield return new object[] { typeof(ClassWithStringDefaultProperty), new ClassWithStringDefaultProperty { DefaultProperty = string.Empty }, "ClassWithStringDefaultProperty" }; - yield return new object[] { typeof(ClassWithStringDefaultProperty), new ClassWithStringDefaultProperty { DefaultProperty = null }, "ClassWithStringDefaultProperty" }; - yield return new object[] { typeof(ClassWithNonStringDefaultProperty), new ClassWithNonStringDefaultProperty { DefaultProperty = 1 }, "ClassWithNonStringDefaultProperty" }; - yield return new object[] { typeof(ClassWithNoSuchDefaultProperty), new ClassWithNoSuchDefaultProperty { DefaultProperty = "CustomName" }, "ClassWithNoSuchDefaultProperty" }; - yield return new object[] { typeof(List), new ClassWithStringDefaultProperty { DefaultProperty = "CustomName" }, "ClassWithStringDefaultProperty" }; - } - - [Theory] - [MemberData(nameof(GetDisplayText_TestData))] - public void CollectionEditor_GetDisplayText_Invoke_ReturnsExpected(Type type, object value, string expected) - { - SubCollectionEditor editor = new(type); - Assert.Equal(expected, editor.GetDisplayText(value)); - } - - [Fact] - public void CollectionEditor_GetDisplayText_ValueDoesntMatchCollectionType_ThrowsTargetException() - { - SubCollectionEditor editor = new(typeof(ClassWithStringDefaultProperty)); - TargetInvocationException ex = Assert.Throws(() => editor.GetDisplayText(new ClassWithNonStringDefaultProperty())); - Assert.IsType(ex.InnerException); - } - - public static IEnumerable GetItems_TestData() - { - yield return new object[] { null, Array.Empty() }; - yield return new object[] { new object(), Array.Empty() }; - yield return new object[] { new int[] { 1, 2, 3 }, new object[] { 1, 2, 3, } }; - yield return new object[] { new ArrayList { 1, 2, 3 }, new object[] { 1, 2, 3, } }; - } - - [Theory] - [MemberData(nameof(GetItems_TestData))] - public void CollectionEditor_GetItems_Invoke_ReturnsExpected(object editValue, object[] expected) - { - SubCollectionEditor editor = new(null); - object[] items = editor.GetItems(editValue); - Assert.Equal(expected, items); - Assert.IsType(expected.GetType(), items); - Assert.NotSame(editValue, items); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void CollectionEditor_GetService_WithContext_CallsContextGetService(Type serviceType) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - object result = new(); - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockContext - .Setup(c => c.GetService(serviceType)) - .Returns(result); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - Assert.Same(result, editor.GetService(serviceType)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void CollectionEditor_GetService_InvokeWithoutContext_ReturnsNull(Type serviceType) - { - SubCollectionEditor editor = new(serviceType); - Assert.Null(editor.GetService(serviceType)); - } - - public static IEnumerable GetObjectsFromInstance_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(GetObjectsFromInstance_TestData))] - public void CollectionEditor_GetObjectsFromInstance_Invoke_ReturnsExpected(object instance) - { - SubCollectionEditor editor = new(null); - IList objects = editor.GetObjectsFromInstance(instance); - Assert.Equal(new object[] { instance }, objects); - Assert.IsType(objects); - Assert.NotSame(objects, editor.GetObjectsFromInstance(instance)); - } - - public static IEnumerable SetItems_TestData() - { - yield return new object[] { null, new object[] { 1, 2, 3 }, null }; - yield return new object[] { null, Array.Empty(), null }; - yield return new object[] { null, null, null }; - - object o = new(); - yield return new object[] { o, new object[] { 1, 2, 3 }, o }; - yield return new object[] { o, Array.Empty(), o }; - yield return new object[] { o, null, o }; - - yield return new object[] { new int[] { 1, 2, 3 }, Array.Empty(), new object[] { 0, 0, 0 } }; - yield return new object[] { new int[] { 1, 2, 3 }, null, new object[] { 0, 0, 0 } }; - - yield return new object[] { new ArrayList { 1, 2, 3 }, new object[] { 1 }, new object[] { 1 } }; - yield return new object[] { new ArrayList { 1, 2, 3 }, Array.Empty(), Array.Empty() }; - yield return new object[] { new ArrayList { 1, 2, 3 }, null, Array.Empty() }; - } - - [Theory] - [MemberData(nameof(SetItems_TestData))] - public void CollectionEditor_SetItems_Invoke_ReturnsExpected(object editValue, object[] value, object expected) - { - SubCollectionEditor editor = new(null); - object items = editor.SetItems(editValue, value); - Assert.Equal(expected, items); - Assert.Same(editValue, items); - } - - [Fact] - public void CollectionEditor_SetItems_InvokeArray_ThrowsNotSupportedException() - { - SubCollectionEditor editor = new(null); - Assert.Throws(() => editor.SetItems(new object[1], new object[1])); - } - - [Fact] - public void CollectionEditor_ShowHelp_NoContext_Nop() - { - SubCollectionEditor editor = new(typeof(List)); - editor.ShowHelp(); - } - - [Fact] - public void CollectionEditor_ShowHelp_ValidDesignerHost_CallsShowHelpFromKeyword() - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockHelpService = new(MockBehavior.Strict); - mockHelpService - .Setup(s => s.ShowHelpFromKeyword("net.ComponentModel.CollectionEditor")) - .Verifiable(); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IHelpService))) - .Returns(mockHelpService.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - editor.ShowHelp(); - - mockHelpService.Verify(s => s.ShowHelpFromKeyword("net.ComponentModel.CollectionEditor"), Times.Once()); - } - - [Theory] - [MemberData(nameof(InvalidDesignerHost_TestData))] - public void CollectionEditor_ShowHelp_InvalidHelpService_Nop(object helpService) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IHelpService))) - .Returns(helpService); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - editor.ShowHelp(); - } - - private class SubCollectionEditor : CollectionEditor - { - public SubCollectionEditor(Type type) : base(type) - { - } - - public new Type CollectionItemType => base.CollectionItemType; - - public new Type CollectionType => base.CollectionType; - - public new ITypeDescriptorContext Context => base.Context; - - public new string HelpTopic => base.HelpTopic; - - public new Type[] NewItemTypes => base.NewItemTypes; - - public new void CancelChanges() => base.CancelChanges(); - - public new bool CanRemoveInstance(object value) => base.CanRemoveInstance(value); - - public new bool CanSelectMultipleInstances() => base.CanSelectMultipleInstances(); - - public new Form CreateCollectionForm() => base.CreateCollectionForm(); - - public new Type CreateCollectionItemType() => base.CreateCollectionItemType(); - - public new object CreateInstance(Type itemType) => base.CreateInstance(itemType); - - public new Type[] CreateNewItemTypes() => base.CreateNewItemTypes(); - - public new void DestroyInstance(object instance) => base.DestroyInstance(instance); - - public new string GetDisplayText(object value) => base.GetDisplayText(value); - - public new object[] GetItems(object editValue) => base.GetItems(editValue); - - public new object GetService(Type serviceType) => base.GetService(serviceType); - - public new IList GetObjectsFromInstance(object instance) => base.GetObjectsFromInstance(instance); - - public new object SetItems(object editValue, object[] value) => base.SetItems(editValue, value); - - public new void ShowHelp() => base.ShowHelp(); - } - - private class ClassWithItem - { - public int Item { get; set; } - } - - private class ClassWithPrivateItem - { - private int Item { get; set; } - } - - private class ClassWithStaticItem - { - public static int Item { get; set; } - } - - private class ClassWithItems - { - public int Items { get; set; } - } - - private class ClassWithPrivateItems - { - private int Items { get; set; } - } - - private class ClassWithStaticItems - { - public static int Items { get; set; } - } - - private class ClassWithStringName - { - public string Name { get; set; } - - public override string ToString() => nameof(ClassWithStringName); - } - - private class ClassWithNonStringName - { - public int Name { get; set; } - - public override string ToString() => nameof(ClassWithNonStringName); - } - - private class ClassWithNullToString - { - public int Name { get; set; } - - public override string ToString() => null; - } - - [DefaultProperty(nameof(ClassWithStringDefaultProperty.DefaultProperty))] - private class ClassWithStringDefaultProperty - { - public string DefaultProperty { get; set; } - - public override string ToString() => nameof(ClassWithStringDefaultProperty); - } - - [DefaultProperty(nameof(ClassWithNonStringDefaultProperty.DefaultProperty))] - private class ClassWithNonStringDefaultProperty - { - public int DefaultProperty { get; set; } - - public override string ToString() => nameof(ClassWithNonStringDefaultProperty); - } - - [DefaultProperty("NoSuchProperty")] - private class ClassWithNoSuchDefaultProperty - { - public string DefaultProperty { get; set; } - - public override string ToString() => nameof(ClassWithNoSuchDefaultProperty); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/CollectionFormTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/CollectionFormTests.cs deleted file mode 100644 index bc8b6ca320a..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/CollectionFormTests.cs +++ /dev/null @@ -1,881 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms.Design; -using Moq; -using System.Windows.Forms.TestUtilities; - -namespace System.ComponentModel.Design.Tests; - -public class CollectionFormTests : CollectionEditor -{ - public CollectionFormTests() : base(typeof(List)) - { - } - - [Fact] - public void CollectionForm_Ctor_CollectionEditor() - { - CollectionEditor editor = new(typeof(List)); - SubCollectionForm form = new(editor); - Assert.Equal(typeof(int), form.CollectionItemType); - Assert.Same(form.CollectionItemType, form.CollectionItemType); - Assert.Equal(typeof(List), form.CollectionType); - Assert.Null(form.Context); - Assert.Null(form.EditValue); - Assert.Empty(form.Items); - Assert.Equal(new Type[] { typeof(int) }, form.NewItemTypes); - } - - [Fact] - public void CollectionForm_Ctor_NullEditor_ThrowsArgumentNullException() - { - Assert.Throws("editor", () => new SubCollectionForm(null)); - } - - [Theory] - [StringWithNullData] - public void CollectionForm_EditValue_Set_GetReturnsExpected(object value) - { - CollectionEditor editor = new(typeof(int[])); - SubCollectionForm form = new(editor) - { - EditValue = value - }; - Assert.Same(value, form.EditValue); - Assert.Equal(1, form.OnEditValueChangedCallCount); - - // Set same. - form.EditValue = value; - Assert.Same(value, form.EditValue); - Assert.Equal(2, form.OnEditValueChangedCallCount); - } - - public static IEnumerable Items_Set_TestData() - { - yield return new object[] { null }; - yield return new object[] { Array.Empty() }; - yield return new object[] { new object[] { 1, 2, 3 } }; - } - - [Theory] - [MemberData(nameof(Items_Set_TestData))] - public void CollectionForm_Items_SetWithoutContext_GetReturnsExpected(object[] value) - { - CollectionEditor editor = new(typeof(int[])); - SubCollectionForm form = new(editor) - { - Items = value - }; - Assert.Null(form.EditValue); - Assert.Empty(form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - - // Set same. - form.Items = value; - Assert.Null(form.EditValue); - Assert.Empty(form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - } - - [Theory] - [MemberData(nameof(Items_Set_TestData))] - public void CollectionForm_Items_SetWithEditValue_GetReturnsExpected(object[] value) - { - SubCollectionEditor editor = new(typeof(List)); - SubCollectionForm form = new(editor) - { - EditValue = new List { 1, 2 } - }; - form.OnEditValueChangedCallCount = 0; - - form.Items = value; - Assert.Equal(new object[] { 1, 2 }, form.EditValue); - Assert.Equal(new object[] { 1, 2 }, form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - - // Set same. - form.Items = value; - Assert.Equal(new object[] { 1, 2 }, form.EditValue); - Assert.Equal(new object[] { 1, 2 }, form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - } - - [Theory] - [MemberData(nameof(Items_Set_TestData))] - public void CollectionForm_Items_SetWithContext_GetReturnsExpected(object[] value) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockContext - .Setup(c => c.OnComponentChanging()) - .Returns(true) - .Verifiable(); - mockContext - .Setup(c => c.OnComponentChanged()) - .Verifiable(); - - SubCollectionEditor editor = new(typeof(List)); - object editValue = new(); - Assert.Same(editValue, editor.EditValue(mockContext.Object, mockServiceProvider.Object, editValue)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor) - { - Items = value - }; - Assert.Null(form.EditValue); - Assert.Empty(form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - mockContext.Verify(c => c.OnComponentChanging(), Times.Once()); - mockContext.Verify(c => c.OnComponentChanged(), Times.Once()); - - // Set same. - form.Items = value; - Assert.Null(form.EditValue); - Assert.Empty(form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - mockContext.Verify(c => c.OnComponentChanging(), Times.Exactly(2)); - mockContext.Verify(c => c.OnComponentChanged(), Times.Exactly(2)); - } - - [Theory] - [MemberData(nameof(Items_Set_TestData))] - public void CollectionForm_Items_SetWithContextWithEditValue_GetReturnsExpected(object[] value) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockContext - .Setup(c => c.OnComponentChanging()) - .Returns(true) - .Verifiable(); - mockContext - .Setup(c => c.OnComponentChanged()) - .Verifiable(); - - SubCollectionEditor editor = new(typeof(List)); - object editValue = new(); - Assert.Same(editValue, editor.EditValue(mockContext.Object, mockServiceProvider.Object, editValue)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor) - { - EditValue = new List { 1, 2 } - }; - form.OnEditValueChangedCallCount = 0; - - form.Items = value; - Assert.Equal(value ?? Array.Empty(), form.EditValue); - Assert.Equal(value ?? Array.Empty(), form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - mockContext.Verify(c => c.OnComponentChanging(), Times.Once()); - mockContext.Verify(c => c.OnComponentChanged(), Times.Once()); - - // Set same. - form.Items = value; - Assert.Equal(value ?? Array.Empty(), form.EditValue); - Assert.Equal(value ?? Array.Empty(), form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - mockContext.Verify(c => c.OnComponentChanging(), Times.Exactly(2)); - mockContext.Verify(c => c.OnComponentChanged(), Times.Exactly(2)); - } - - [Theory] - [MemberData(nameof(Items_Set_TestData))] - public void CollectionForm_Items_SetWithContextWithEditValueCustomSetItems_GetReturnsExpected(object[] value) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockContext - .Setup(c => c.OnComponentChanging()) - .Returns(true) - .Verifiable(); - mockContext - .Setup(c => c.OnComponentChanged()) - .Verifiable(); - - CustomSetItemsCollectionEditor editor = new(typeof(List)); - object editValue = new(); - Assert.Same(editValue, editor.EditValue(mockContext.Object, mockServiceProvider.Object, editValue)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor) - { - EditValue = new List { 1, 2 } - }; - form.OnEditValueChangedCallCount = 0; - - form.Items = value; - Assert.Equal("CustomSetItems", form.EditValue); - Assert.Empty(form.Items); - Assert.Equal(1, form.OnEditValueChangedCallCount); - mockContext.Verify(c => c.OnComponentChanging(), Times.Once()); - mockContext.Verify(c => c.OnComponentChanged(), Times.Once()); - - // Set same. - form.Items = value; - Assert.Equal("CustomSetItems", form.EditValue); - Assert.Empty(form.Items); - Assert.Equal(1, form.OnEditValueChangedCallCount); - mockContext.Verify(c => c.OnComponentChanging(), Times.Exactly(2)); - mockContext.Verify(c => c.OnComponentChanged(), Times.Exactly(2)); - } - - [Theory] - [MemberData(nameof(Items_Set_TestData))] - public void CollectionForm_Items_SetWithContextWithEditValueFalseOnChanging_GetReturnsExpected(object[] value) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockContext - .Setup(c => c.OnComponentChanging()) - .Returns(false) - .Verifiable(); - mockContext - .Setup(c => c.OnComponentChanged()) - .Verifiable(); - - SubCollectionEditor editor = new(typeof(List)); - object editValue = new(); - Assert.Same(editValue, editor.EditValue(mockContext.Object, mockServiceProvider.Object, editValue)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor) - { - EditValue = new List { 1, 2 } - }; - form.OnEditValueChangedCallCount = 0; - - form.Items = value; - Assert.Equal(new object[] { 1, 2 }, form.EditValue); - Assert.Equal(new object[] { 1, 2 }, form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - mockContext.Verify(c => c.OnComponentChanging(), Times.Once()); - mockContext.Verify(c => c.OnComponentChanged(), Times.Never()); - - // Set same. - form.Items = value; - Assert.Equal(new object[] { 1, 2 }, form.EditValue); - Assert.Equal(new object[] { 1, 2 }, form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - mockContext.Verify(c => c.OnComponentChanging(), Times.Exactly(2)); - mockContext.Verify(c => c.OnComponentChanged(), Times.Never()); - } - - [Theory] - [MemberData(nameof(Items_Set_TestData))] - public void CollectionForm_Items_SetWithContextWithEditValueThrowsCriticalExceptionOnChanging_Rethrows(object[] value) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockContext - .Setup(c => c.OnComponentChanging()) - .Returns(() => throw new StackOverflowException()) - .Verifiable(); - mockContext - .Setup(c => c.OnComponentChanged()) - .Verifiable(); - - SubCollectionEditor editor = new(typeof(List)); - object editValue = new(); - Assert.Same(editValue, editor.EditValue(mockContext.Object, mockServiceProvider.Object, editValue)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor) - { - EditValue = new List { 1, 2 } - }; - form.OnEditValueChangedCallCount = 0; - - Assert.Throws(() => form.Items = value); - } - - [Theory] - [MemberData(nameof(Items_Set_TestData))] - public void CollectionForm_Items_SetWithContextWithEditValueThrowsCriticalExceptionOnChanging_CallsDisplayError(object[] value) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - DivideByZeroException exception = new(); - Mock mockService = new(MockBehavior.Strict); - mockService - .Setup(s => s.ShowError(exception)) - .Verifiable(); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockContext - .Setup(c => c.OnComponentChanging()) - .Returns(() => throw exception) - .Verifiable(); - mockContext - .Setup(c => c.OnComponentChanged()) - .Verifiable(); - mockContext - .Setup(c => c.GetService(typeof(IUIService))) - .Returns(mockService.Object); - - SubCollectionEditor editor = new(typeof(List)); - object editValue = new(); - Assert.Same(editValue, editor.EditValue(mockContext.Object, mockServiceProvider.Object, editValue)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor) - { - EditValue = new List { 1, 2 } - }; - form.OnEditValueChangedCallCount = 0; - - form.Items = value; - Assert.Equal(new object[] { 1, 2 }, form.EditValue); - Assert.Equal(new object[] { 1, 2 }, form.Items); - Assert.Equal(0, form.OnEditValueChangedCallCount); - mockContext.Verify(c => c.OnComponentChanging(), Times.Once()); - mockContext.Verify(c => c.OnComponentChanged(), Times.Never()); - mockService.Verify(s => s.ShowError(exception), Times.Once()); - } - - public static IEnumerable CanRemoveInstance_TestData() - { - yield return new object[] { "some string" }; - yield return new object[] { 123 }; - yield return new object[] { null }; - yield return new object[] { new Component() }; - } - - [Theory] - [MemberData(nameof(CanRemoveInstance_TestData))] - public void CollectionForm_CanRemoveInstance_Invoke_ReturnsExpected(object value) - { - SubCollectionEditor editor = new(null); - SubCollectionForm form = new(editor); - Assert.True(form.CanRemoveInstance(value)); - } - - public static IEnumerable CanRemoveInstance_InheritanceAttribute_TestData() - { - yield return new object[] { new InheritanceAttribute(InheritanceLevel.Inherited - 1), false }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.Inherited), false }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.InheritedReadOnly), false }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.NotInherited), true }; - yield return new object[] { new InheritanceAttribute(InheritanceLevel.NotInherited + 1), false }; - } - - [Theory] - [MemberData(nameof(CanRemoveInstance_InheritanceAttribute_TestData))] - public void CollectionForm_CanRemoveInstance_InheritanceAttribute_ReturnsExpected(InheritanceAttribute attribute, bool expected) - { - using Component component = new(); - TypeDescriptor.AddAttributes(component, attribute); - SubCollectionEditor editor = new(null); - SubCollectionForm form = new(editor); - Assert.Equal(expected, form.CanRemoveInstance(component)); - } - - [Fact] - public void CollectionForm_CanSelectMultipleInstances_Invoke_ReturnsFalse() - { - SubCollectionEditor editor = new(null); - SubCollectionForm form = new(editor); - Assert.True(form.CanSelectMultipleInstances()); - } - - public static IEnumerable InvalidDesignerHost_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(InvalidDesignerHost_TestData))] - public void CollectionForm_CreateInstance_WithContextWithInvalidDesignerHost_ReturnsExpected(object host) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(host); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor); - Assert.IsType(form.CreateInstance(typeof(Component))); - } - - public static IEnumerable CreateInstance_HostDesigner_TestData() - { - yield return new object[] { null }; - - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner - .Setup(d => d.Dispose()); - yield return new object[] { mockDesigner.Object }; - } - - [Theory] - [MemberData(nameof(CreateInstance_HostDesigner_TestData))] - public void CollectionForm_CreateInstance_WithContextWithHostReturningComponent_CallsCreateComponent(IDesigner designer) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - using Component result = new(); - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns((DesignerTransaction)null); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockHost - .Setup(h => h.CreateComponent(typeof(Component), null)) - .Returns(result); - mockHost - .Setup(h => h.GetDesigner(result)) - .Returns(designer); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor); - Assert.Same(result, form.CreateInstance(typeof(Component))); - } - - [Theory] - [MemberData(nameof(CreateInstance_HostDesigner_TestData))] - public void CollectionForm_CreateInstance_WithContextWithHostReturningNullComponent_CallsCreateComponent(IDesigner designer) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns((DesignerTransaction)null); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockHost - .Setup(h => h.CreateComponent(typeof(Component), null)) - .Returns((IComponent)null); - mockHost - .Setup(h => h.GetDesigner(null)) - .Returns(designer); - mockHost - .Setup(c => c.GetService(typeof(TypeDescriptionProvider))) - .Returns(null); - - object result = new(); - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor); - Assert.IsType(form.CreateInstance(typeof(Component))); - } - - [Fact] - public void CollectionForm_CreateInstance_WithContextWithHostReturningComponentWithIComponentInitializerDesigner_CallsInitializeNewComponent() - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - using Component result = new(); - Mock mockDesigner = new(MockBehavior.Strict); - Mock mockComponentInitializer = mockDesigner.As(); - mockComponentInitializer - .Setup(d => d.InitializeNewComponent(null)) - .Verifiable(); - - Mock mockHost = new(MockBehavior.Strict); - mockHost - .Setup(h => h.CreateTransaction("Add or remove Int32 objects")) - .Returns((DesignerTransaction)null); - mockHost - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockHost - .Setup(h => h.CreateComponent(typeof(Component), null)) - .Returns(result); - mockHost - .Setup(h => h.GetDesigner(result)) - .Returns(mockDesigner.Object); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(mockHost.Object); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor); - Assert.Same(result, form.CreateInstance(typeof(Component))); - mockComponentInitializer.Verify(d => d.InitializeNewComponent(null), Times.Once()); - } - - [Fact] - public void CollectionForm_CreateInstance_InvokeWithoutContext_ReturnsExpected() - { - SubCollectionEditor editor = new(null); - SubCollectionForm form = new(editor); - Assert.Equal(0, form.CreateInstance(typeof(int))); - } - - [Fact] - public void CollectionForm_CreateInstance_NullItemType_ThrowsArgumentNullException() - { - SubCollectionEditor editor = new(null); - SubCollectionForm form = new(editor); - Assert.Throws("objectType", () => form.CreateInstance(null)); - } - - [Fact] - public void CollectionForm_DisplayError_InvokeWithContextWithIUIService_CallsShowError() - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - Exception exception = new(); - Mock mockService = new(MockBehavior.Strict); - mockService - .Setup(s => s.ShowError(exception)) - .Verifiable(); - - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IUIService))) - .Returns(mockService.Object); - - SubCollectionEditor editor = new(typeof(List)); - object editValue = new(); - Assert.Same(editValue, editor.EditValue(mockContext.Object, mockServiceProvider.Object, editValue)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor); - form.DisplayError(exception); - mockService.Verify(s => s.ShowError(exception), Times.Once()); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void CollectionForm_GetService_WithContext_CallsContextGetService(Type serviceType) - { - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(It.IsAny())) - .Returns(DialogResult.OK); - - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object); - - object result = new(); - Mock mockContext = new(MockBehavior.Strict); - mockContext - .Setup(c => c.GetService(typeof(IDesignerHost))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(AmbientProperties))) - .Returns(null); - mockContext - .Setup(c => c.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockContext - .Setup(c => c.GetService(serviceType)) - .Returns(result); - - SubCollectionEditor editor = new(typeof(List)); - object value = new(); - Assert.Same(value, editor.EditValue(mockContext.Object, mockServiceProvider.Object, value)); - Assert.Same(mockContext.Object, editor.Context); - - SubCollectionForm form = new(editor); - Assert.Same(result, form.GetService(serviceType)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void CollectionForm_GetService_InvokeWithoutContext_ReturnsNull(Type serviceType) - { - SubCollectionEditor editor = new(serviceType); - SubCollectionForm form = new(editor); - Assert.Null(form.GetService(serviceType)); - } - - [Fact] - public void CollectionForm_ShowEditorDialog_Invoke_Success() - { - SubCollectionEditor editor = new(typeof(List)); - SubCollectionForm form = new(editor); - - Mock mockEditorService = new(MockBehavior.Strict); - mockEditorService - .Setup(s => s.ShowDialog(form)) - .Returns(DialogResult.OK); - Assert.Equal(DialogResult.OK, form.ShowEditorDialog(mockEditorService.Object)); - mockEditorService.Verify(s => s.ShowDialog(form), Times.Once()); - } - - [Fact] - public void CollectionForm_ShowEditorDialog_NullEdSvc_ThrowsArgumentNullException() - { - SubCollectionEditor editor = new(typeof(List)); - SubCollectionForm form = new(editor); - Assert.Throws("edSvc", () => form.ShowEditorDialog(null)); - } - - private class SubCollectionEditor : CollectionEditor - { - public SubCollectionEditor(Type type) : base(type) - { - } - - public new ITypeDescriptorContext Context => base.Context; - } - - private class CustomSetItemsCollectionEditor : CollectionEditor - { - public CustomSetItemsCollectionEditor(Type type) : base(type) - { - } - - public new ITypeDescriptorContext Context => base.Context; - - protected override object SetItems(object editValue, object[] value) => "CustomSetItems"; - } - - private class SubCollectionForm : CollectionForm - { - public SubCollectionForm(CollectionEditor editor) : base(editor) - { - } - - public new Type CollectionItemType => base.CollectionItemType; - - public new Type CollectionType => base.CollectionType; - - public new ITypeDescriptorContext Context => base.Context; - - public new object[] Items - { - get => base.Items; - set => base.Items = value; - } - - public new Type[] NewItemTypes => base.NewItemTypes; - - public new bool CanRemoveInstance(object value) => base.CanRemoveInstance(value); - - public new bool CanSelectMultipleInstances() => base.CanSelectMultipleInstances(); - - public new object CreateInstance(Type itemType) => base.CreateInstance(itemType); - - public new void DestroyInstance(object instance) => base.DestroyInstance(instance); - - public new void DisplayError(Exception e) => base.DisplayError(e); - - public new object GetService(Type serviceType) => base.GetService(serviceType); - - public new DialogResult ShowEditorDialog(IWindowsFormsEditorService edSvc) => base.ShowEditorDialog(edSvc); - - public int OnEditValueChangedCallCount { get; set; } - - protected override void OnEditValueChanged() => OnEditValueChangedCallCount++; - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ComponentDesignerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ComponentDesignerTests.cs deleted file mode 100644 index dbf1d4bafdc..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ComponentDesignerTests.cs +++ /dev/null @@ -1,3032 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Configuration; -using Moq; -using Moq.Protected; -using System.Windows.Forms.TestUtilities; -using System.Windows.Forms.Design.Tests.Mocks; - -namespace System.ComponentModel.Design.Tests; - -public class ComponentDesignerTests -{ - [Fact] - public void ComponentDesigner_Ctor_Default() - { - using SubComponentDesigner designer = new(); - Assert.Empty(designer.ActionLists); - Assert.Same(designer.ActionLists, designer.ActionLists); - Assert.Empty(designer.AssociatedComponents); - Assert.Null(designer.Component); - Assert.Same(InheritanceAttribute.Default, designer.InheritanceAttribute); - Assert.Same(designer.InheritanceAttribute, designer.InheritanceAttribute); - Assert.False(designer.Inherited); - Assert.Null(designer.ParentComponent); - Assert.NotNull(designer.ShadowProperties); - Assert.Same(designer.ShadowProperties, designer.ShadowProperties); - Assert.Empty(designer.Verbs); - Assert.Same(designer.Verbs, designer.Verbs); - } - - [Fact] - public void ComponentDesigner_Children_GetDefault_ReturnsExpected() - { - using ComponentDesigner designer = new(); - ITreeDesigner treeDesigner = designer; - Assert.Empty(treeDesigner.Children); - } - - [Fact] - public void ComponentDesigner_GetService_ReturnsExpected() - { - using ComponentDesigner designer = new(); - - var service = designer.GetService(); - Assert.Null(service); - - using Component component = new(); - designer.Initialize(component); - - service = designer.GetService(); - Assert.Null(service); - - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(component); - var mockSite = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object); - component.Site = mockSite.Object; - designer.Initialize(component); - - service = designer.GetService(); - Assert.NotNull(service); - } - - [Fact] - public void ComponentDesigner_PostFilterProperties_Success() - { - using SubComponentDesigner designer = new(); - PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(CustomComponent))[0]; - Dictionary properties = new() - { - { "SettingsKey", descriptor } - }; - using IPersistComponentSettingsComponent component = new(); - designer.Initialize(component); - designer.PostFilterProperties(properties); - PropertyDescriptor result = (PropertyDescriptor)properties["SettingsKey"]; - Assert.Same(descriptor, result); - - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(component); - var mockSite = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object); - component.Site = mockSite.Object; - designer.Initialize(component); - - designer.PostFilterProperties(properties); - result = (PropertyDescriptor)properties["SettingsKey"]; - Assert.NotSame(descriptor, result); - } - - [Fact] - public void ComponentDesigner_Children_GetWithValidHostValidResult_ReturnsExpected() - { - Mock mockComponent1 = new(MockBehavior.Strict); - Mock mockComponent2 = new(MockBehavior.Strict); - Mock mockDesigner1 = new(MockBehavior.Strict); - Mock mockDesigner2 = new(MockBehavior.Strict); - using CustomAssociatedComponentsComponentDesigner designer = new( - new object[] { mockComponent1.Object, mockComponent2.Object }); - ITreeDesigner treeDesigner = designer; - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.GetDesigner(mockComponent1.Object)) - .Returns(mockDesigner1.Object) - .Verifiable(); - mockDesignerHost - .Setup(h => h.GetDesigner(mockComponent2.Object)) - .Returns(mockDesigner2.Object) - .Verifiable(); - - using Component component = new() - { - Site = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object).Object - }; - - designer.Initialize(component); - Assert.Equal(new object[] { mockDesigner1.Object, mockDesigner2.Object }, treeDesigner.Children); - mockDesignerHost.Verify(h => h.GetDesigner(mockComponent1.Object), Times.Once()); - mockDesignerHost.Verify(h => h.GetDesigner(mockComponent2.Object), Times.Once()); - - // Call again to test caching behavior. - Assert.Equal(new object[] { mockDesigner1.Object, mockDesigner2.Object }, treeDesigner.Children); - mockDesignerHost.Verify(h => h.GetDesigner(mockComponent1.Object), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.GetDesigner(mockComponent2.Object), Times.Exactly(2)); - } - - [Fact] - public void ComponentDesigner_Children_GetWithValidHostInvalidResult_ReturnsExpected() - { - Mock mockComponent1 = new(MockBehavior.Strict); - Mock mockComponent2 = new(MockBehavior.Strict); - Mock mockDesigner = new(MockBehavior.Strict); - using CustomAssociatedComponentsComponentDesigner designer = new( - new object[] { new object(), null, mockComponent1.Object, mockComponent2.Object }); - ITreeDesigner treeDesigner = designer; - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.GetDesigner(mockComponent1.Object)) - .Returns(mockDesigner.Object) - .Verifiable(); - mockDesignerHost - .Setup(h => h.GetDesigner(mockComponent2.Object)) - .Returns(null) - .Verifiable(); - - using Component component = new() - { - Site = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object).Object - }; - - designer.Initialize(component); - Assert.Equal(new object[] { mockDesigner.Object }, treeDesigner.Children); - mockDesignerHost.Verify(h => h.GetDesigner(mockComponent1.Object), Times.Once()); - mockDesignerHost.Verify(h => h.GetDesigner(mockComponent2.Object), Times.Once()); - - // Call again to test caching behavior. - Assert.Equal(new object[] { mockDesigner.Object }, treeDesigner.Children); - mockDesignerHost.Verify(h => h.GetDesigner(mockComponent1.Object), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.GetDesigner(mockComponent2.Object), Times.Exactly(2)); - } - - public static IEnumerable Children_GetInvalidService_TestData() - { - foreach (ICollection associatedComponents in new object[] { null, Array.Empty(), new object[] { new Component() } }) - { - yield return new object[] { associatedComponents, null }; - yield return new object[] { associatedComponents, new object() }; - } - } - - [Theory] - [MemberData(nameof(Children_GetInvalidService_TestData))] - public void ComponentDesigner_Children_GetWithInvalidDesignerHost_ReturnsEmpty(ICollection associatedComponents, object host) - { - using CustomAssociatedComponentsComponentDesigner designer = new(associatedComponents); - ITreeDesigner treeDesigner = designer; - - using Component component = new() - { - Site = MockSite.CreateMockSiteWithDesignerHost(host).Object - }; - - designer.Initialize(component); - Assert.Empty(treeDesigner.Children); - } - - public static IEnumerable InheritanceAttribute_GetValidService_TestData() - { - yield return new object[] { null, 3, 5 }; - yield return new object[] { new InheritanceAttribute(), 1, 1 }; - } - - private static Mock CreateMockSiteWithInheritanceService(object inheritanceService) - { - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(inheritanceService); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - return mockSite; - } - - [Theory] - [MemberData(nameof(InheritanceAttribute_GetValidService_TestData))] - public void ComponentDesigner_InheritanceAttribute_GetWithValidService_ReturnsDefault(InheritanceAttribute attributeResult, int expectedCallCount1, int expectedCallCount2) - { - using SubComponentDesigner designer = new(); - using Component component = new(); - Mock mockInheritanceService = new(MockBehavior.Strict); - mockInheritanceService - .Setup(s => s.GetInheritanceAttribute(component)) - .Returns(attributeResult) - .Verifiable(); - var mockSite = CreateMockSiteWithInheritanceService(mockInheritanceService.Object); - component.Site = mockSite.Object; - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IInheritanceService)), Times.Exactly(expectedCallCount1)); - - InheritanceAttribute attribute = designer.InheritanceAttribute; - Assert.Same(attributeResult, attribute); - Assert.Same(attribute, designer.InheritanceAttribute); - mockSite.Verify(s => s.GetService(typeof(IInheritanceService)), Times.Exactly(expectedCallCount2)); - } - - public static IEnumerable InheritanceAttribute_GetInvalidService_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(InheritanceAttribute_GetInvalidService_TestData))] - public void ComponentDesigner_InheritanceAttribute_GetWithInvalidService_ReturnsDefault(object inheritanceService) - { - using SubComponentDesigner designer = new(); - var mockSite = CreateMockSiteWithInheritanceService(inheritanceService); - - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IInheritanceService)), Times.Once()); - - InheritanceAttribute attribute = designer.InheritanceAttribute; - Assert.Same(InheritanceAttribute.Default, attribute); - Assert.Same(attribute, designer.InheritanceAttribute); - mockSite.Verify(s => s.GetService(typeof(IInheritanceService)), Times.Once()); - } - - public static IEnumerable Inherited_Get_TestData() - { - yield return new object[] { null, false }; - yield return new object[] { InheritanceAttribute.Default, false }; - yield return new object[] { InheritanceAttribute.Inherited, true }; - yield return new object[] { InheritanceAttribute.InheritedReadOnly, true }; - yield return new object[] { InheritanceAttribute.NotInherited, false }; - } - - [Theory] - [MemberData(nameof(Inherited_Get_TestData))] - public void ComponentDesigner_Inherited_Get_ReturnsExpected(InheritanceAttribute inheritanceAttribute, bool expected) - { - using CustomInheritanceAttributeComponentDesigner designer = new(inheritanceAttribute); - Assert.Equal(expected, designer.Inherited); - } - - public static IEnumerable ParentComponent_ValidService_TestData() - { - yield return new object[] { null }; - yield return new object[] { new Component() }; - } - - [Theory] - [MemberData(nameof(ParentComponent_ValidService_TestData))] - public void ComponentDesigner_ParentComponent_GetWithValidService_ReturnsExpected(Component rootComponent) - { - using SubComponentDesigner designer = new(); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(rootComponent); - var mockSite = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object); - - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - mockDesignerHost.Verify(h => h.RootComponent, Times.Once()); - - Assert.Same(rootComponent, designer.ParentComponent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.RootComponent, Times.Exactly(2)); - - // Get again. - Assert.Same(rootComponent, designer.ParentComponent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockDesignerHost.Verify(h => h.RootComponent, Times.Exactly(3)); - } - - [Fact] - public void ComponentDesigner_ParentComponent_GetWithValidServiceRootComponentEqual_ReturnsNull() - { - using SubComponentDesigner designer = new(); - using Component component = new(); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(component); - var mockSite = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object); - component.Site = mockSite.Object; - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - mockDesignerHost.Verify(h => h.RootComponent, Times.Once()); - - Assert.Null(designer.ParentComponent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.RootComponent, Times.Exactly(2)); - - // Get again. - Assert.Null(designer.ParentComponent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockDesignerHost.Verify(h => h.RootComponent, Times.Exactly(3)); - } - - public static IEnumerable ParentComponent_InvalidService_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(ParentComponent_InvalidService_TestData))] - public void ComponentDesigner_ParentComponent_GetWithInvalidService_ReturnsNull(object host) - { - using SubComponentDesigner designer = new(); - var mockSite = MockSite.CreateMockSiteWithDesignerHost(host); - - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - - Assert.Null(designer.ParentComponent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - - // Get again. - Assert.Null(designer.ParentComponent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - } - - [Theory] - [MemberData(nameof(ParentComponent_ValidService_TestData))] - public void ComponentDesigner_ITreeDesignerParent_GetWithValidService_ReturnsExpected(Component rootComponent) - { - using SubComponentDesigner designer = new(); - ITreeDesigner treeDesigner = designer; - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(rootComponent); - mockDesignerHost - .Setup(h => h.GetDesigner(rootComponent)) - .Returns(designer) - .Verifiable(); - var mockSite = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object); - - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - mockDesignerHost.Verify(h => h.RootComponent, Times.Once()); - mockDesignerHost.Verify(h => h.GetDesigner(rootComponent), Times.Never()); - - Assert.Same(rootComponent is null ? null : designer, treeDesigner.Parent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(rootComponent is null ? 2 : 3)); - mockDesignerHost.Verify(h => h.RootComponent, Times.Exactly(2)); - mockDesignerHost.Verify(h => h.GetDesigner(rootComponent), Times.Exactly(rootComponent is null ? 0 : 1)); - - // Get again. - Assert.Same(rootComponent is null ? null : designer, treeDesigner.Parent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(rootComponent is null ? 3 : 5)); - mockDesignerHost.Verify(h => h.RootComponent, Times.Exactly(3)); - mockDesignerHost.Verify(h => h.GetDesigner(rootComponent), Times.Exactly(rootComponent is null ? 0 : 2)); - } - - [Fact] - public void ComponentDesigner_ITreeDesignerParent_GetWithValidServiceRootComponentEqual_ReturnsNull() - { - using ComponentDesigner designer = new(); - ITreeDesigner treeDesigner = designer; - using Component component = new(); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(component); - var mockSite = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object); - component.Site = mockSite.Object; - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - mockDesignerHost.Verify(h => h.RootComponent, Times.Once()); - - Assert.Null(treeDesigner.Parent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.RootComponent, Times.Exactly(2)); - - // Get again. - Assert.Null(treeDesigner.Parent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockDesignerHost.Verify(h => h.RootComponent, Times.Exactly(3)); - } - - [Theory] - [MemberData(nameof(ParentComponent_InvalidService_TestData))] - public void ComponentDesigner_ITreeDesignerParent_GetWithInvalidServiceFirstCall_ReturnsNull(object host) - { - using SubComponentDesigner designer = new(); - ITreeDesigner treeDesigner = designer; - var mockSite = MockSite.CreateMockSiteWithDesignerHost(host); - - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - - Assert.Null(treeDesigner.Parent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - - // Get again. - Assert.Null(treeDesigner.Parent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - } - - [Theory] - [MemberData(nameof(ParentComponent_InvalidService_TestData))] - public void ComponentDesigner_ITreeDesignerParent_GetWithInvalidServiceSecondCall_ReturnsNull(object host) - { - using SubComponentDesigner designer = new(); - ITreeDesigner treeDesigner = designer; - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(new Component()); - Mock mockSite = new(MockBehavior.Strict); - int callCount = 0; - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(() => - { - callCount++; - if (callCount < 3) - { - return mockDesignerHost.Object; - } - else - { - return host; - } - }); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - - Assert.Null(treeDesigner.Parent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - - // Get again. - Assert.Null(treeDesigner.Parent); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(4)); - } - - [Fact] - public void ComponentDesigner_Dispose_InvokeWithComponent_Success() - { - using ComponentDesigner designer = new(); - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns((ISite)null); - mockComponent - .Setup(c => c.Dispose()) - .Verifiable(); - designer.Initialize(mockComponent.Object); - Assert.Same(mockComponent.Object, designer.Component); - - designer.Dispose(); - Assert.Null(designer.Component); - mockComponent.Verify(c => c.Dispose(), Times.Never()); - - // Dispose again. - designer.Dispose(); - Assert.Null(designer.Component); - mockComponent.Verify(c => c.Dispose(), Times.Never()); - } - - public static IEnumerable Dispose_InvokeWithComponentChangeService_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - yield return new object[] { new Mock(MockBehavior.Strict).Object }; - } - - private static Mock CreateMockSiteWithComponentChangeService(object componentChangeService) - { - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(componentChangeService); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - return mockSite; - } - - [Theory] - [MemberData(nameof(Dispose_InvokeWithComponentChangeService_TestData))] - public void ComponentDesigner_Dispose_InvokeWithComponentChangeService_Success(object componentChangeService) - { - using ComponentDesigner designer = new(); - using Component component = new() - { - Site = CreateMockSiteWithComponentChangeService(componentChangeService).Object - }; - designer.Initialize(component); - Assert.Same(component, designer.Component); - - designer.Dispose(); - Assert.Null(designer.Component); - - // Dispose again. - designer.Dispose(); - Assert.Null(designer.Component); - } - - [Fact] - public void ComponentDesigner_Dispose_InvokeWithoutComponent_Success() - { - using ComponentDesigner designer = new(); - designer.Dispose(); - Assert.Null(designer.Component); - - // Dispose again. - designer.Dispose(); - Assert.Null(designer.Component); - } - - [Theory] - [BoolData] - public void ComponentDesigner_Dispose_InvokeBoolWithComponent_Success(bool disposing) - { - using SubComponentDesigner designer = new(); - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns((ISite)null); - mockComponent - .Setup(c => c.Dispose()) - .Verifiable(); - designer.Initialize(mockComponent.Object); - Assert.Same(mockComponent.Object, designer.Component); - - designer.Dispose(disposing); - Assert.Same(disposing ? null : mockComponent.Object, designer.Component); - mockComponent.Verify(c => c.Dispose(), Times.Never()); - - // Dispose again. - designer.Dispose(disposing); - Assert.Same(disposing ? null : mockComponent.Object, designer.Component); - mockComponent.Verify(c => c.Dispose(), Times.Never()); - } - - public static IEnumerable Dispose_InvokeBoolWithComponentChangeService_TestData() - { - foreach (bool disposing in new bool[] { true, false }) - { - yield return new object[] { null, disposing }; - yield return new object[] { new object(), disposing }; - yield return new object[] { new Mock(MockBehavior.Strict), disposing }; - } - } - - [Theory] - [MemberData(nameof(Dispose_InvokeBoolWithComponentChangeService_TestData))] - public void ComponentDesigner_Dispose_InvokeBoolWithComponentChangeService_Success(object componentChangeService, bool disposing) - { - using SubComponentDesigner designer = new(); - using Component component = new() - { - Site = CreateMockSiteWithComponentChangeService(componentChangeService).Object - }; - designer.Initialize(component); - Assert.Same(component, designer.Component); - - designer.Dispose(disposing); - Assert.Same(disposing ? null : component, designer.Component); - - // Dispose again. - designer.Dispose(disposing); - Assert.Same(disposing ? null : component, designer.Component); - } - - [Theory] - [BoolData] - public void ComponentDesigner_Dispose_InvokeBoolWithoutComponent_Success(bool disposing) - { - using SubComponentDesigner designer = new(); - designer.Dispose(disposing); - Assert.Null(designer.Component); - - // Dispose again. - designer.Dispose(disposing); - Assert.Null(designer.Component); - } - - [Fact] - public void ComponentDesigner_DoDefaultAction_InvokeDefault_Nop() - { - using ComponentDesigner designer = new(); - designer.DoDefaultAction(); - - // Call again. - designer.DoDefaultAction(); - } - - public static IEnumerable DoDefaultAction_ValidProperty_TestData() - { - foreach (string property in new string[] { nameof(DefaultEventComponent.StringProperty) }) - { - yield return new object[] { property, null, 1, null }; - yield return new object[] { property, null, 1, string.Empty }; - yield return new object[] { property, null, 1, "UniqueMethod" }; - - yield return new object[] { property, Array.Empty(), 1, null }; - yield return new object[] { property, Array.Empty(), 1, string.Empty }; - yield return new object[] { property, Array.Empty(), 1, "UniqueMethod" }; - - yield return new object[] { property, new object[] { null, new object(), "NoSuchStringValue" }, 1, null }; - yield return new object[] { property, new object[] { null, new object(), "NoSuchStringValue" }, 1, string.Empty }; - yield return new object[] { property, new object[] { null, new object(), "NoSuchStringValue" }, 1, "UniqueMethod" }; - - // Should not call if in the compatible methods list. - yield return new object[] { property, new object[] { "StringValue" }, 0, null }; - yield return new object[] { property, new object[] { "StringValue" }, 0, string.Empty }; - yield return new object[] { property, new object[] { "StringValue" }, 0, "UniqueMethod" }; - } - } - - [Theory] - [MemberData(nameof(DoDefaultAction_ValidProperty_TestData))] - public void ComponentDesigner_DoDefaultAction_InvokeWithComponentWithHostValidProperty_Success(string property, ICollection compatibleMethods, int expectedSetCallCount, string uniqueMethodName) - { - using ComponentDesigner designer = new(); - using DefaultEventComponent component1 = new() - { - StringProperty = "StringValue" - }; - using DefaultEventComponent component2 = new() - { - StringProperty = string.Empty - }; - using DefaultEventComponent component3 = new() - { - StringProperty = null - }; - Mock mockEventBindingService = new(MockBehavior.Strict); - mockEventBindingService - .Setup(s => s.GetEventProperty(It.IsAny())) - .Returns(TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[property]) - .Verifiable(); - mockEventBindingService - .Setup(s => s.CreateUniqueMethodName(component3, It.IsAny())) - .Returns(uniqueMethodName) - .Verifiable(); - mockEventBindingService - .Setup(s => s.GetCompatibleMethods(It.IsAny())) - .Returns(compatibleMethods) - .Verifiable(); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(new object[] { component1, component2, component3 }); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.CreateTransaction(It.IsAny())) - .Returns(null) - .Verifiable(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - using Component rootComponent = new() - { - Site = mockSite.Object - }; - designer.Initialize(rootComponent); - component1.StringPropertySetCount = 0; - component2.StringPropertySetCount = 0; - component3.StringPropertySetCount = 0; - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(3)); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Exactly(3)); - mockEventBindingService.Verify(s => s.CreateUniqueMethodName(component3, It.IsAny()), Times.Once()); - mockEventBindingService.Verify(s => s.GetCompatibleMethods(It.IsAny()), Times.Exactly(2)); - Assert.Equal("StringValue", component1.StringProperty); - Assert.Equal(expectedSetCallCount, component1.StringPropertySetCount); - Assert.Empty(component2.StringProperty); - Assert.Equal(1, component2.StringPropertySetCount); - Assert.Equal(uniqueMethodName, component3.StringProperty); - Assert.Equal(1, component3.StringPropertySetCount); - - // Call again. - component1.StringProperty = "StringValue"; - component2.StringProperty = string.Empty; - component3.StringProperty = null; - component1.StringPropertySetCount = 0; - component2.StringPropertySetCount = 0; - component3.StringPropertySetCount = 0; - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(6)); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Exactly(6)); - mockEventBindingService.Verify(s => s.CreateUniqueMethodName(component3, It.IsAny()), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetCompatibleMethods(It.IsAny()), Times.Exactly(4)); - Assert.Equal("StringValue", component1.StringProperty); - Assert.Equal(expectedSetCallCount, component1.StringPropertySetCount); - Assert.Empty(component2.StringProperty); - Assert.Equal(1, component2.StringPropertySetCount); - Assert.Equal(uniqueMethodName, component3.StringProperty); - Assert.Equal(1, component3.StringPropertySetCount); - } - - [Theory] - [InlineData(null, null, 0)] - [InlineData(null, "", 1)] - [InlineData(null, "name", 1)] - [InlineData("", "", 1)] - [InlineData("name", "name", 1)] - public void ComponentDesigner_DoDefaultAction_InvokeWithRootComponent_CallsShowCode(string value, string uniqueName, int expectedCallCount) - { - using ComponentDesigner designer = new(); - using DefaultEventComponent component = new() - { - StringProperty = value - }; - Mock mockEventBindingService = new(MockBehavior.Strict); - mockEventBindingService - .Setup(s => s.GetEventProperty(It.IsAny())) - .Returns(TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[nameof(DefaultEventComponent.StringProperty)]) - .Verifiable(); - mockEventBindingService - .Setup(s => s.GetCompatibleMethods(It.IsAny())) - .Returns(Array.Empty()); - mockEventBindingService - .Setup(s => s.CreateUniqueMethodName(component, It.IsAny())) - .Returns(uniqueName); - mockEventBindingService - .Setup(s => s.ShowCode(component, It.IsAny())) - .Returns(false) - .Verifiable(); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(new object[] { component }); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.CreateTransaction(It.IsAny())) - .Returns(null) - .Verifiable(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .Setup(s => s.Name) - .Returns("Name"); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - component.Site = mockSite.Object; - designer.Initialize(component); - component.StringPropertySetCount = 0; - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Once()); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Once()); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Once()); - mockEventBindingService.Verify(s => s.ShowCode(component, It.IsAny()), Times.Exactly(expectedCallCount)); - Assert.Equal(uniqueName, component.StringProperty); - Assert.Equal(1, component.StringPropertySetCount); - - // Call again. - component.StringPropertySetCount = 0; - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.ShowCode(component, It.IsAny()), Times.Exactly(expectedCallCount * 2)); - Assert.Equal(uniqueName, component.StringProperty); - Assert.Equal(1, component.StringPropertySetCount); - } - - [Theory] - [MemberData(nameof(DoDefaultAction_ValidProperty_TestData))] - public void ComponentDesigner_DoDefaultAction_InvokeWithComponentWithHostValidPropertyWithTransaction_Success(string property, ICollection compatibleMethods, int expectedSetCallCount, string uniqueMethodName) - { - using ComponentDesigner designer = new(); - using DefaultEventComponent component1 = new() - { - StringProperty = "StringValue" - }; - using DefaultEventComponent component2 = new() - { - StringProperty = string.Empty - }; - using DefaultEventComponent component3 = new() - { - StringProperty = null - }; - Mock mockTransaction = new(MockBehavior.Strict); - mockTransaction - .Protected() - .Setup("OnCommit") - .Verifiable(); - Mock mockEventBindingService = new(MockBehavior.Strict); - mockEventBindingService - .Setup(s => s.GetEventProperty(It.IsAny())) - .Returns(TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[property]) - .Verifiable(); - mockEventBindingService - .Setup(s => s.CreateUniqueMethodName(component3, It.IsAny())) - .Returns(uniqueMethodName) - .Verifiable(); - mockEventBindingService - .Setup(s => s.GetCompatibleMethods(It.IsAny())) - .Returns(compatibleMethods) - .Verifiable(); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(new object[] { null, new object(), component1, component2, component3 }); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.CreateTransaction(It.IsAny())) - .Returns(mockTransaction.Object) - .Verifiable(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - using Component rootComponent = new() - { - Site = mockSite.Object - }; - - designer.Initialize(rootComponent); - component1.StringPropertySetCount = 0; - component2.StringPropertySetCount = 0; - component3.StringPropertySetCount = 0; - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Once()); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(3)); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Once()); - mockEventBindingService.Verify(s => s.CreateUniqueMethodName(component3, It.IsAny()), Times.Once()); - mockEventBindingService.Verify(s => s.GetCompatibleMethods(It.IsAny()), Times.Exactly(2)); - mockTransaction.Protected().Verify("OnCommit", Times.Once()); - Assert.Equal("StringValue", component1.StringProperty); - Assert.Equal(expectedSetCallCount, component1.StringPropertySetCount); - Assert.Empty(component2.StringProperty); - Assert.Equal(1, component2.StringPropertySetCount); - Assert.Equal(uniqueMethodName, component3.StringProperty); - Assert.Equal(1, component3.StringPropertySetCount); - - // Call again. - component1.StringProperty = "StringValue"; - component2.StringProperty = string.Empty; - component3.StringProperty = null; - component1.StringPropertySetCount = 0; - component2.StringPropertySetCount = 0; - component3.StringPropertySetCount = 0; - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(6)); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.CreateUniqueMethodName(component3, It.IsAny()), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetCompatibleMethods(It.IsAny()), Times.Exactly(4)); - mockTransaction.Protected().Verify("OnCommit", Times.Once()); - Assert.Equal("StringValue", component1.StringProperty); - Assert.Equal(expectedSetCallCount, component1.StringPropertySetCount); - Assert.Empty(component2.StringProperty); - Assert.Equal(1, component2.StringPropertySetCount); - Assert.Equal(uniqueMethodName, component3.StringProperty); - Assert.Equal(1, component3.StringPropertySetCount); - } - - [Fact] - public void ComponentDesigner_DoDefaultAction_InvokeWithCanceledThrowingCreateTransaction_Success() - { - using ComponentDesigner designer = new(); - using DefaultEventComponent component = new() - { - StringProperty = "StringValue" - }; - Mock mockEventBindingService = new(MockBehavior.Strict); - mockEventBindingService - .Setup(s => s.GetEventProperty(It.IsAny())) - .Returns(TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[nameof(DefaultEventComponent.StringProperty)]) - .Verifiable(); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(new object[] { component, new DefaultEventComponent() }); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.CreateTransaction(It.IsAny())) - .Throws(CheckoutException.Canceled) - .Verifiable(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - using Component rootComponent = new() - { - Site = mockSite.Object - }; - - designer.Initialize(rootComponent); - component.StringPropertySetCount = 0; - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Once()); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Once()); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Once()); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - - // Call again. - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Exactly(2)); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - } - - public static IEnumerable DoDefaultAction_NotCanceledException_TestData() - { - yield return new object[] { new CheckoutException() }; - yield return new object[] { new DivideByZeroException() }; - } - - [Theory] - [MemberData(nameof(DoDefaultAction_NotCanceledException_TestData))] - public void ComponentDesigner_DoDefaultAction_InvokeWithNotCanceledThrowingCreateTransaction_Rethrows(Exception exception) - { - using ComponentDesigner designer = new(); - using DefaultEventComponent component = new() - { - StringProperty = "StringValue" - }; - Mock mockEventBindingService = new(MockBehavior.Strict); - mockEventBindingService - .Setup(s => s.GetEventProperty(It.IsAny())) - .Returns(TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[nameof(DefaultEventComponent.StringProperty)]) - .Verifiable(); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(new object[] { component, new DefaultEventComponent() }); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.CreateTransaction(It.IsAny())) - .Throws(exception) - .Verifiable(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - using Component rootComponent = new() - { - Site = mockSite.Object - }; - - designer.Initialize(rootComponent); - component.StringPropertySetCount = 0; - - Assert.Throws(exception.GetType(), () => designer.DoDefaultAction()); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Once()); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Once()); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Once()); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - - // Call again. - Assert.Throws(exception.GetType(), () => designer.DoDefaultAction()); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Exactly(2)); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - } - - [Fact] - public void ComponentDesigner_DoDefaultAction_InvokeWithInvalidOperationExceptionThrowingCreateTransaction_Catches() - { - using ComponentDesigner designer = new(); - using DefaultEventComponent component = new() - { - StringProperty = "StringValue" - }; - Mock mockTransaction = new(MockBehavior.Strict); - mockTransaction - .Protected() - .Setup("OnCancel") - .Verifiable(); - Mock mockEventBindingService = new(MockBehavior.Strict); - mockEventBindingService - .Setup(s => s.GetEventProperty(It.IsAny())) - .Returns(TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[nameof(DefaultEventComponent.StringProperty)]) - .Verifiable(); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(new object[] { component, new DefaultEventComponent() }); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.CreateTransaction(It.IsAny())) - .Throws(new InvalidOperationException()) - .Verifiable(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - using Component rootComponent = new() - { - Site = mockSite.Object - }; - designer.Initialize(rootComponent); - component.StringPropertySetCount = 0; - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Once()); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Once()); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Once()); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - - // Call again. - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Exactly(2)); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - } - - [Fact] - public void ComponentDesigner_DoDefaultAction_InvokeThrowsInvalidOperationException_CallsCancel() - { - using ComponentDesigner designer = new(); - using DefaultEventComponent component = new() - { - StringProperty = "StringValue" - }; - Mock mockTransaction = new(MockBehavior.Strict); - mockTransaction - .Protected() - .Setup("OnCancel") - .Verifiable(); - Mock mockEventBindingService = new(MockBehavior.Strict); - mockEventBindingService - .Setup(s => s.GetEventProperty(It.IsAny())) - .Returns(TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[nameof(DefaultEventComponent.StringProperty)]) - .Verifiable(); - mockEventBindingService - .Setup(s => s.GetCompatibleMethods(It.IsAny())) - .Throws(new InvalidOperationException()) - .Verifiable(); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(new object[] { component, new DefaultEventComponent() }); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.CreateTransaction(It.IsAny())) - .Returns(mockTransaction.Object) - .Verifiable(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - using Component rootComponent = new() - { - Site = mockSite.Object - }; - - designer.Initialize(rootComponent); - component.StringPropertySetCount = 0; - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Once()); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Once()); - mockEventBindingService.Verify(s => s.GetCompatibleMethods(It.IsAny()), Times.Once()); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Once()); - mockTransaction.Protected().Verify("OnCancel", Times.Once()); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - - // Call again. - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetCompatibleMethods(It.IsAny()), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Exactly(2)); - mockTransaction.Protected().Verify("OnCancel", Times.Once()); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - } - - public static IEnumerable DoDefaultAction_NonInvalidOperationException_TestData() - { - yield return new object[] { new CheckoutException() }; - yield return new object[] { CheckoutException.Canceled }; - yield return new object[] { new DivideByZeroException() }; - } - - [Theory] - [MemberData(nameof(DoDefaultAction_NonInvalidOperationException_TestData))] - public void ComponentDesigner_DoDefaultAction_InvokeThrowsNonInvalidOperationException_CallsCommit(Exception exception) - { - using ComponentDesigner designer = new(); - using DefaultEventComponent component = new() - { - StringProperty = "StringValue" - }; - Mock mockTransaction = new(MockBehavior.Strict); - mockTransaction - .Protected() - .Setup("OnCommit") - .Verifiable(); - Mock mockEventBindingService = new(MockBehavior.Strict); - mockEventBindingService - .Setup(s => s.GetEventProperty(It.IsAny())) - .Returns(TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[nameof(DefaultEventComponent.StringProperty)]) - .Verifiable(); - mockEventBindingService - .Setup(s => s.GetCompatibleMethods(It.IsAny())) - .Throws(exception) - .Verifiable(); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(new object[] { component, new DefaultEventComponent() }); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.CreateTransaction(It.IsAny())) - .Returns(mockTransaction.Object) - .Verifiable(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - using Component rootComponent = new() - { - Site = mockSite.Object - }; - - designer.Initialize(rootComponent); - component.StringPropertySetCount = 0; - - Assert.Throws(exception.GetType(), () => designer.DoDefaultAction()); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Once()); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Once()); - mockEventBindingService.Verify(s => s.GetCompatibleMethods(It.IsAny()), Times.Once()); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Once()); - mockTransaction.Protected().Verify("OnCommit", Times.Once()); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - - // Call again. - Assert.Throws(exception.GetType(), () => designer.DoDefaultAction()); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetCompatibleMethods(It.IsAny()), Times.Exactly(2)); - mockDesignerHost.Verify(h => h.CreateTransaction(It.IsAny()), Times.Exactly(2)); - mockTransaction.Protected().Verify("OnCommit", Times.Once()); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - } - - public static IEnumerable DoDefaultAction_InvalidProperty_TestData() - { - yield return new object[] { null }; - yield return new object[] { TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[nameof(DefaultEventComponent.ReadOnlyProperty)] }; - yield return new object[] { TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[nameof(DefaultEventComponent.IntProperty)] }; - } - - [Theory] - [MemberData(nameof(DoDefaultAction_InvalidProperty_TestData))] - public void ComponentDesigner_DoDefaultAction_InvokeWithComponentWithHostInvalidProperty_Success(PropertyDescriptor property) - { - using ComponentDesigner designer = new(); - using DefaultEventComponent component = new() - { - StringProperty = "StringValue" - }; - Mock mockEventBindingService = new(MockBehavior.Strict); - mockEventBindingService - .Setup(s => s.GetEventProperty(It.IsAny())) - .Returns(property) - .Verifiable(); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(new object[] { component }); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - mockDesignerHost - .Setup(h => h.CreateTransaction(It.IsAny())) - .Returns(null) - .Verifiable(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - using Component rootComponent = new() - { - Site = mockSite.Object - }; - designer.Initialize(rootComponent); - component.StringPropertySetCount = 0; - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Once()); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Once()); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - - // Call again. - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(2)); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(0, component.StringPropertySetCount); - } - - public static IEnumerable DoDefaultAction_InvalidSelectedComponents_TestData() - { - yield return new object[] { null }; - yield return new object[] { Array.Empty() }; - yield return new object[] { new object[] { null, new object() } }; - } - - [Theory] - [MemberData(nameof(DoDefaultAction_InvalidSelectedComponents_TestData))] - public void ComponentDesigner_DoDefaultAction_InvokeWithComponentWithHostInvalidSelectedComponents_Success(ICollection selectedComponents) - { - using ComponentDesigner designer = new(); - Mock mockEventBindingService = new(MockBehavior.Strict); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(selectedComponents); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(null); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - using Component rootComponent = new() - { - Site = mockSite.Object - }; - designer.Initialize(rootComponent); - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Once()); - - // Call again. - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Exactly(2)); - } - - public static IEnumerable DoDefaultAction_InvalidEventBindingService_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(DoDefaultAction_InvalidEventBindingService_TestData))] - public void ComponentDesigner_DoDefaultAction_InvokeInvalidEventBindingService_Nop(object eventBindingService) - { - using ComponentDesigner designer = new(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(eventBindingService) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - - // Call again. - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - } - - public static IEnumerable DoDefaultAction_InvalidSelectionService_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(DoDefaultAction_InvalidSelectionService_TestData))] - public void ComponentDesigner_DoDefaultAction_InvokeInvalidSelectionService_Nop(object selectionService) - { - using ComponentDesigner designer = new(); - Mock mockEventBindingService = new(MockBehavior.Strict); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(selectionService) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - using Component component = new() - { - Site = mockSite.Object - }; - designer.Initialize(component); - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - - // Call again. - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - } - - public static IEnumerable DoDefaultAction_InvalidDesignerHost_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(DoDefaultAction_InvalidDesignerHost_TestData))] - public void ComponentDesigner_DoDefaultAction_InvokeInvalidDesignerHost_Success(object designerHost) - { - using DefaultEventComponent component = new() - { - StringProperty = "StringValue" - }; - using ComponentDesigner designer = new(); - Mock mockEventBindingService = new(MockBehavior.Strict); - Mock mockSelectionService = new(MockBehavior.Strict); - mockSelectionService - .Setup(s => s.GetSelectedComponents()) - .Returns(new object[] { component }); - mockEventBindingService - .Setup(s => s.GetEventProperty(It.IsAny())) - .Returns(TypeDescriptor.GetProperties(typeof(DefaultEventComponent))[nameof(DefaultEventComponent.StringProperty)]) - .Verifiable(); - mockEventBindingService - .Setup(s => s.GetCompatibleMethods(It.IsAny())) - .Returns(Array.Empty()) - .Verifiable(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(designerHost); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IEventBindingService))) - .Returns(mockEventBindingService.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - using Component rootComponent = new() - { - Site = mockSite.Object - }; - designer.Initialize(rootComponent); - component.StringPropertySetCount = 0; - - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Once()); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Once()); - mockEventBindingService.Verify(s => s.GetCompatibleMethods(It.IsAny()), Times.Once()); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(1, component.StringPropertySetCount); - - // Call again. - component.StringPropertySetCount = 0; - designer.DoDefaultAction(); - mockSite.Verify(s => s.GetService(typeof(IEventBindingService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(ISelectionService)), Times.Exactly(2)); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Exactly(3)); - mockSelectionService.Verify(s => s.GetSelectedComponents(), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetEventProperty(It.IsAny()), Times.Exactly(2)); - mockEventBindingService.Verify(s => s.GetCompatibleMethods(It.IsAny()), Times.Exactly(2)); - Assert.Equal("StringValue", component.StringProperty); - Assert.Equal(1, component.StringPropertySetCount); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void ComponentDesigner_GetService_InvokeWithComponentWithSite_ReturnsNull(Type serviceType) - { - object service = new(); - using SubComponentDesigner designer = new(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(serviceType)) - .Returns(service) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - Assert.Same(service, designer.GetService(serviceType)); - mockSite.Verify(s => s.GetService(serviceType), Times.Once()); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void ComponentDesigner_GetService_InvokeWithComponentWithoutSite_ReturnsNull(Type serviceType) - { - using SubComponentDesigner designer = new(); - using Component component = new(); - designer.Initialize(component); - Assert.Null(designer.GetService(serviceType)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void ComponentDesigner_GetService_InvokeWithoutComponent_ReturnsNull(Type serviceType) - { - using SubComponentDesigner designer = new(); - Assert.Null(designer.GetService(serviceType)); - } - - [Fact] - public void ComponentDesigner_Initialize_Invoke_Success() - { - using ComponentDesigner designer = new(); - using Component component = new(); - designer.Initialize(component); - Assert.Same(component, designer.Component); - Assert.Empty(designer.AssociatedComponents); - - // Override with null. - designer.Initialize(null); - Assert.Null(designer.Component); - Assert.Empty(designer.AssociatedComponents); - } - - [Fact] - public void ComponentDesigner_Initialize_RootComponent_Success() - { - using Component component = new(); - using ComponentDesigner designer = new(); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(component); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null) - .Verifiable(); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - component.Site = mockSite.Object; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IInheritanceService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IDictionaryService)), Times.Exactly(4)); - mockSite.Verify(s => s.GetService(typeof(IExtenderListService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(ITypeDescriptorFilterService)), Times.Once()); - } - - public static IEnumerable Initialize_NonRootComponent_TestData() - { - yield return new object[] { null, null }; - yield return new object[] { new object(), new object() }; - - Mock mockNullDesignerHost = new(MockBehavior.Strict); - mockNullDesignerHost - .Setup(h => h.RootComponent) - .Returns((IComponent)null); - yield return new object[] { mockNullDesignerHost.Object, null }; - - Mock mockNonNullDesignerHost = new(MockBehavior.Strict); - mockNonNullDesignerHost - .Setup(h => h.RootComponent) - .Returns(new Component()); - yield return new object[] { mockNonNullDesignerHost.Object, null }; - } - - [Theory] - [MemberData(nameof(Initialize_NonRootComponent_TestData))] - public void ComponentDesigner_Initialize_NonRootComponent_Success(object host, object componentChangeService) - { - using ComponentDesigner designer = new(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(host); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(componentChangeService); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(null) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(DesignerCommandSet)), Times.Never()); - } - - [Fact] - public void ComponentDesigner_Initialize_NullInheritanceAttribute_Success() - { - using CustomInheritanceAttributeComponentDesigner designer = new(null); - using Component component = new(); - designer.Initialize(component); - Assert.Same(component, designer.Component); - Assert.Empty(designer.AssociatedComponents); - } - - [Fact] - public void ComponentDesigner_Initialize_InvokeIServiceContainerSiteWithNullDesignerCommandSet_CallsAddService() - { - using ComponentDesigner designer = new(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(null) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - DesignerCommandSet set = null; - mockSite - .As() - .Setup(c => c.AddService(typeof(DesignerCommandSet), It.IsAny())) - .Callback((t, s) => set = Assert.IsAssignableFrom(s)) - .Verifiable(); - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(DesignerCommandSet)), Times.Once()); - mockSite.As().Verify(s => s.AddService(typeof(DesignerCommandSet), set), Times.Once()); - Assert.Same(designer.ActionLists, set.GetCommands("ActionLists")); - Assert.Same(designer.Verbs, set.GetCommands("Verbs")); - Assert.Null(set.GetCommands("Other")); - Assert.Null(set.GetCommands(string.Empty)); - Assert.Null(set.GetCommands(null)); - } - - public static IEnumerable Initialize_NonNullDesignerCommandSet_TestData() - { - yield return new object[] { new object() }; - yield return new object[] { new DesignerCommandSet() }; - } - - [Theory] - [MemberData(nameof(Initialize_NonNullDesignerCommandSet_TestData))] - public void ComponentDesigner_Initialize_InvokeIServiceContainerSiteWithNonNullDesignerCommandSet_DoesNotCallAddService(object designerCommandSet) - { - using ComponentDesigner designer = new(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(designerCommandSet) - .Verifiable(); - mockSite - .As() - .Setup(c => c.AddService(typeof(DesignerCommandSet), It.IsAny())) - .Verifiable(); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - using Component component = new() - { - Site = mockSite.Object - }; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IDesignerHost)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Once()); - mockSite.Verify(s => s.GetService(typeof(DesignerCommandSet)), Times.Once()); - mockSite.As().Verify(s => s.AddService(typeof(DesignerCommandSet), It.IsAny()), Times.Never()); - } - - [Fact] - public void ComponentDesigner_ParentComponent_GetWithHost_ReturnsExpected() - { - using SubComponentDesigner designer = new(); - using Component component = new(); - designer.Initialize(component); - } - - public static IEnumerable IDictionary_TestData() - { - yield return new object[] { null }; - yield return new object[] { new Dictionary() }; - } - - [Theory] - [MemberData(nameof(IDictionary_TestData))] - public void ComponentDesigner_InitializeExistingComponent_Invoke_ThrowsNotImplementedException(IDictionary defaultValues) - { - using ComponentDesigner designer = new(); - Assert.Throws(() => designer.InitializeExistingComponent(defaultValues)); - } - - [Theory] - [MemberData(nameof(IDictionary_TestData))] - public void ComponentDesigner_InitializeNewComponent_Invoke_Nop(IDictionary defaultValues) - { - using ComponentDesigner designer = new(); - designer.InitializeNewComponent(defaultValues); - } - -#pragma warning disable 0618 - [Fact] - public void ComponentDesigner_InitializeNonDefault_Invoke_Nop() - { - using ComponentDesigner designer = new(); - designer.InitializeNonDefault(); - } -#pragma warning restore 0618 - - [Fact] - public void ComponentDesigner_InvokeGetInheritanceAttribute_InvokeNonNullToInvoke_ReturnsExpected() - { - using SubComponentDesigner designer = new(); - Assert.Same(designer.InheritanceAttribute, designer.InvokeGetInheritanceAttribute(designer)); - } - - [Fact] - public void ComponentDesigner_InvokeGetInheritanceAttribute_InvokeNullToInvoke_ReturnsNull() - { - using SubComponentDesigner designer = new(); - Assert.Null(designer.InvokeGetInheritanceAttribute(null)); - } - - public static IEnumerable PreFilterProperties_ComponentWithoutKey_TestData() - { - yield return new object[] { null }; - yield return new object[] { new Dictionary() }; - yield return new object[] { new Dictionary { { "SettingsKey", new object() } } }; - yield return new object[] { new Dictionary { { "SettingsKey", null } } }; - } - - [Fact] - public void ComponentDesigner_PreFilterProperties_WithComponentWithKey_Success() - { - using SubComponentDesigner designer = new(); - PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(CustomComponent))[0]; - Dictionary properties = new() - { - { "SettingsKey", descriptor } - }; - using IPersistComponentSettingsComponent component = new(); - designer.Initialize(component); - designer.PreFilterProperties(properties); - PropertyDescriptor result = (PropertyDescriptor)properties["SettingsKey"]; - Assert.NotSame(descriptor, result); - Assert.Equal(typeof(ComponentDesigner), result.ComponentType); - Assert.Equal(descriptor.Name, result.Name); - Assert.True(descriptor.Attributes.Count >= 7); - Assert.True(result.Attributes.Count >= 8); - } - - [Fact] - public void ComponentDesigner_PreFilterProperties_WithIPersistComponentSettingsComponentWithKey_Success() - { - using SubComponentDesigner designer = new(); - PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(CustomComponent))[0]; - Dictionary properties = new() - { - { "SettingsKey", descriptor } - }; - using IPersistComponentSettingsComponent component = new(); - designer.Initialize(component); - designer.PreFilterProperties(properties); - PropertyDescriptor result = (PropertyDescriptor)properties["SettingsKey"]; - Assert.NotSame(descriptor, result); - Assert.Equal(typeof(ComponentDesigner), result.ComponentType); - Assert.Equal(descriptor.Name, result.Name); - Assert.True(descriptor.Attributes.Count >= 7); - Assert.True(result.Attributes.Count >= 8); - } - - [Theory] - [MemberData(nameof(PreFilterProperties_ComponentWithoutKey_TestData))] - public void ComponentDesigner_PreFilterProperties_WithIPersistComponentSettingsComponentWithoutKey_Success(IDictionary properties) - { - using SubComponentDesigner designer = new(); - PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(CustomComponent))[0]; - object oldValue = properties?["SettingsKey"]; - using IPersistComponentSettingsComponent component = new(); - designer.Initialize(component); - designer.PreFilterProperties(properties); - Assert.Same(oldValue, properties?["SettingsKey"]); - } - - [Fact] - public void ComponentDesigner_PreFilterProperties_WithNonIPersistComponentSettingsComponent_Nop() - { - using SubComponentDesigner designer = new(); - PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(CustomComponent))[0]; - Dictionary properties = new() - { - { "SettingsKey", descriptor } - }; - using Component component = new(); - designer.Initialize(component); - designer.PreFilterProperties(properties); - Assert.Same(descriptor, properties["SettingsKey"]); - } - - [Theory] - [MemberData(nameof(IDictionary_TestData))] - public void ComponentDesigner_PreFilterProperties_WithoutComponent_Nop(IDictionary properties) - { - using SubComponentDesigner designer = new(); - designer.PreFilterProperties(properties); - } - - public static IEnumerable PostFilterAttributes_NoInheritanceAttribute_TestData() - { - yield return new object[] { null, null, null }; - yield return new object[] { null, new Dictionary(), null }; - yield return new object[] { InheritanceAttribute.Default, null, null }; - yield return new object[] { InheritanceAttribute.Default, new Dictionary(), null }; - yield return new object[] { InheritanceAttribute.Inherited, null, null }; - yield return new object[] { InheritanceAttribute.Inherited, new Dictionary(), InheritanceAttribute.Inherited }; - yield return new object[] { InheritanceAttribute.InheritedReadOnly, null, null }; - yield return new object[] { InheritanceAttribute.InheritedReadOnly, new Dictionary(), InheritanceAttribute.InheritedReadOnly }; - yield return new object[] { InheritanceAttribute.NotInherited, null, null }; - yield return new object[] { InheritanceAttribute.NotInherited, new Dictionary(), null }; - } - - [Theory] - [MemberData(nameof(PostFilterAttributes_NoInheritanceAttribute_TestData))] - public void ComponentDesigner_PostFilterAttributes_NoInheritanceAttribute_AddsToAttributes(InheritanceAttribute attribute, IDictionary attributes, object expected) - { - using CustomInheritanceAttributeComponentDesigner designer = new(attribute); - designer.PostFilterAttributes(attributes); - Assert.Same(expected, attributes?[typeof(InheritanceAttribute)]); - } - - public static IEnumerable PostFilterAttributes_TestData() - { - yield return new object[] { null, InheritanceAttribute.Default }; - yield return new object[] { new Dictionary(), InheritanceAttribute.Default }; - yield return new object[] { new Dictionary { { typeof(InheritanceAttribute), null } }, InheritanceAttribute.Default }; - yield return new object[] { new Dictionary { { typeof(InheritanceAttribute), new object() } }, InheritanceAttribute.Default }; - InheritanceAttribute attribute = new(); - yield return new object[] { new Dictionary { { typeof(InheritanceAttribute), attribute } }, attribute }; - } - - [Theory] - [MemberData(nameof(PostFilterAttributes_TestData))] - public void ComponentDesigner_PostFilterAttributes_HasInheritanceAttributeKey_Sets(IDictionary attributes, object expected) - { - using SubComponentDesigner designer = new(); - designer.PostFilterAttributes(attributes); - Assert.Same(expected, designer.InheritanceAttribute); - } - - public static IEnumerable PostFilterEvents_HasEvents_TestData() - { - yield return new object[] { null, false }; - yield return new object[] { InheritanceAttribute.Default, false }; - yield return new object[] { InheritanceAttribute.Inherited, false }; - yield return new object[] { InheritanceAttribute.InheritedReadOnly, true }; - yield return new object[] { InheritanceAttribute.NotInherited, false }; - } - - [Theory] - [MemberData(nameof(PostFilterEvents_HasEvents_TestData))] - public void ComponentDesigner_PostFilterEvents_InvokeWithEvents_Success(InheritanceAttribute inheritanceAttribute, bool valid) - { - EventDescriptor descriptor = TypeDescriptor.GetEvents(typeof(CustomComponent))[0]; - Dictionary events = new() { { "key1", descriptor }, { "Key2", null } }; - using CustomInheritanceAttributeComponentDesigner designer = new(inheritanceAttribute); - designer.PostFilterEvents(events); - if (valid) - { - EventDescriptor result = Assert.IsAssignableFrom(events["Event"]); - Assert.Equal(typeof(CustomComponent), result.ComponentType); - Assert.Equal("Event", result.Name); - Assert.True(Assert.IsType(result.Attributes[typeof(ReadOnlyAttribute)]).IsReadOnly); - Assert.Equal(new Dictionary { { "key1", descriptor }, { "Key2", null }, { "Event", result } }, events); - } - else - { - Assert.Equal(new Dictionary { { "key1", descriptor }, { "Key2", null } }, events); - } - } - - public static IEnumerable PostFilterEvents_NoEvents_TestData() - { - yield return new object[] { null, null, null }; - yield return new object[] { null, new Dictionary(), new Dictionary() }; - yield return new object[] { InheritanceAttribute.Default, new Dictionary(), new Dictionary() }; - yield return new object[] { InheritanceAttribute.Default, new Dictionary(), new Dictionary() }; - yield return new object[] { InheritanceAttribute.Inherited, null, null }; - yield return new object[] { InheritanceAttribute.Inherited, new Dictionary(), new Dictionary() }; - yield return new object[] { InheritanceAttribute.InheritedReadOnly, null, null }; - yield return new object[] { InheritanceAttribute.InheritedReadOnly, new Dictionary(), new Dictionary() }; - yield return new object[] { InheritanceAttribute.NotInherited, null, null }; - yield return new object[] { InheritanceAttribute.NotInherited, new Dictionary(), new Dictionary() }; - } - - [Theory] - [MemberData(nameof(PostFilterEvents_NoEvents_TestData))] - public void ComponentDesigner_PostFilterEvents_InvokeWithoutEvents_Success(InheritanceAttribute inheritanceAttribute, IDictionary events, IDictionary expected) - { - using CustomInheritanceAttributeComponentDesigner designer = new(inheritanceAttribute); - designer.PostFilterEvents(events); - Assert.Equal(expected, events); - } - - [Fact] - public void ComponentDesigner_PostFilterEvents_InvokeWithInvalidEvents_ThrowsArrayTypeMismatchException() - { - using CustomInheritanceAttributeComponentDesigner designer = new(InheritanceAttribute.InheritedReadOnly); - Assert.Throws(() => designer.PostFilterEvents(new Dictionary { { "key", new object() } })); - } - - public static IEnumerable RaiseComponentChanged_TestData() - { - yield return new object[] { null, null, null }; - yield return new object[] { TypeDescriptor.GetProperties(typeof(CustomComponent))[0], new object(), new object() }; - } - - [Theory] - [MemberData(nameof(RaiseComponentChanged_TestData))] - public void ComponentDesigner_RaiseComponentChanged_InvokeWithValidService_CallsOnOnComponentChanged(MemberDescriptor member, object oldValue, object newValue) - { - using SubComponentDesigner designer = new(); - using Component component = new(); - Mock mockComponentChangeService = new(MockBehavior.Strict); - mockComponentChangeService - .Setup(s => s.OnComponentChanged(component, member, oldValue, newValue)) - .Verifiable(); - var mockSite = CreateMockSiteWithComponentChangeService(mockComponentChangeService.Object); - component.Site = mockSite.Object; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Once()); - designer.RaiseComponentChanged(member, oldValue, newValue); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Exactly(2)); - mockComponentChangeService.Verify(s => s.OnComponentChanged(component, member, oldValue, newValue), Times.Once()); - } - - public static IEnumerable RaiseComponentChanged_InvalidService_TestData() - { - foreach (object componentChangeService in new object[] { null, new object() }) - { - yield return new object[] { componentChangeService, null, null, null }; - yield return new object[] { componentChangeService, TypeDescriptor.GetProperties(typeof(CustomComponent))[0], new object(), new object() }; - } - } - - [Theory] - [MemberData(nameof(RaiseComponentChanged_InvalidService_TestData))] - public void ComponentDesigner_RaiseComponentChanged_InvokeWithInvalidService_CallsOnOnComponentChanged(object componentChangeService, MemberDescriptor member, object oldValue, object newValue) - { - using SubComponentDesigner designer = new(); - using Component component = new(); - var mockSite = CreateMockSiteWithComponentChangeService(componentChangeService); - component.Site = mockSite.Object; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Once()); - designer.RaiseComponentChanged(member, oldValue, newValue); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Exactly(2)); - } - - [Theory] - [MemberData(nameof(RaiseComponentChanged_TestData))] - public void ComponentDesigner_RaiseComponentChanged_InvokeWithoutComponent_Nop(MemberDescriptor member, object oldValue, object newValue) - { - using SubComponentDesigner designer = new(); - designer.RaiseComponentChanged(member, oldValue, newValue); - } - - public static IEnumerable RaiseComponentChanging_TestData() - { - yield return new object[] { null }; - yield return new object[] { TypeDescriptor.GetProperties(typeof(CustomComponent))[0] }; - } - - [Theory] - [MemberData(nameof(RaiseComponentChanging_TestData))] - public void ComponentDesigner_RaiseComponentChanging_InvokeWithValidService_CallsOnOnComponentChanged(MemberDescriptor member) - { - using SubComponentDesigner designer = new(); - using Component component = new(); - Mock mockComponentChangeService = new(MockBehavior.Strict); - mockComponentChangeService - .Setup(s => s.OnComponentChanging(component, member)) - .Verifiable(); - var mockSite = CreateMockSiteWithComponentChangeService(mockComponentChangeService.Object); - component.Site = mockSite.Object; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Once()); - designer.RaiseComponentChanging(member); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Exactly(2)); - mockComponentChangeService.Verify(s => s.OnComponentChanging(component, member), Times.Once()); - } - - public static IEnumerable RaiseComponentChanging_InvalidService_TestData() - { - foreach (object componentChangeService in new object[] { null, new object() }) - { - yield return new object[] { componentChangeService, null }; - yield return new object[] { componentChangeService, TypeDescriptor.GetProperties(typeof(CustomComponent))[0] }; - } - } - - [Theory] - [MemberData(nameof(RaiseComponentChanging_InvalidService_TestData))] - public void ComponentDesigner_RaiseComponentChanging_InvokeWithInvalidService_CallsOnOnComponentChanged(object componentChangeService, MemberDescriptor member) - { - using SubComponentDesigner designer = new(); - using Component component = new(); - var mockSite = CreateMockSiteWithComponentChangeService(componentChangeService); - component.Site = mockSite.Object; - - designer.Initialize(component); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Once()); - designer.RaiseComponentChanging(member); - mockSite.Verify(s => s.GetService(typeof(IComponentChangeService)), Times.Exactly(2)); - } - - [Theory] - [MemberData(nameof(RaiseComponentChanging_TestData))] - public void ComponentDesigner_RaiseComponentChanging_InvokeWithoutComponent_Nop(MemberDescriptor member) - { - using SubComponentDesigner designer = new(); - designer.RaiseComponentChanging(member); - } - -#pragma warning disable 0618 - [Theory] - [InlineData(null, null, null)] - [InlineData(null, "", "")] - [InlineData(null, "NewValue", "NewValue")] - [InlineData("", null, null)] - [InlineData("", "", "")] - [InlineData("", "NewValue", "NewValue")] - [InlineData("OldValue", null, "OldValue")] - [InlineData("OldValue", "", "OldValue")] - [InlineData("OldValue", "NewValue", "OldValue")] - public void ComponentDesigner_OnSetComponentDefaults_InvokeWithComponentWithDefaultProperty_Nop(string oldValue, string siteName, string expectedValue) - { - using ComponentDesigner designer = new(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.Name) - .Returns(siteName); - mockSite - .SetupGet(s => s.Container) - .Returns((IContainer)null); - using StringDefaultPropertyComponent component = new() - { - Site = mockSite.Object, - Value = oldValue - }; - designer.Initialize(component); - designer.OnSetComponentDefaults(); - Assert.Equal(expectedValue, component.Value); - } - - public static IEnumerable OnSetComponentDefaults_InvalidComponent_TestData() - { - yield return new object[] { new Component() }; - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(IDesignerHost))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IInheritanceService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - mockSite - .Setup(s => s.Container) - .Returns((IContainer)null); - yield return new object[] { new Component { Site = mockSite.Object } }; - yield return new object[] { new IntDefaultPropertyComponent { Site = mockSite.Object } }; - } - - [Theory] - [MemberData(nameof(OnSetComponentDefaults_InvalidComponent_TestData))] - public void ComponentDesigner_OnSetComponentDefaults_InvokeWithInvalidComponent_Nop(Component component) - { - using ComponentDesigner designer = new(); - designer.Initialize(component); - designer.OnSetComponentDefaults(); - } - - [Fact] - public void ComponentDesigner_OnSetComponentDefaults_InvokeWithComponentWithoutSite_Nop() - { - using ComponentDesigner designer = new(); - using Component component = new(); - designer.Initialize(component); - designer.OnSetComponentDefaults(); - } - - [Fact] - public void ComponentDesigner_OnSetComponentDefaults_InvokeWithoutComponent_Nop() - { - using ComponentDesigner designer = new(); - designer.OnSetComponentDefaults(); - } -#pragma warning restore 0618 - - [Fact] - public void ComponentDesigner_IDesignerFilterPreFilterAttributes_Invoke_CallsProtectedVirtualMethod() - { - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner - .Protected() - .Setup("PreFilterAttributes", ItExpr.IsAny()) - .Verifiable(); - IDesignerFilter filter = mockDesigner.Object; - - filter.PreFilterAttributes(new Dictionary()); - - mockDesigner.Protected().Verify("PreFilterAttributes", Times.Once(), ItExpr.IsAny()); - } - - [Fact] - public void ComponentDesigner_IDesignerFilterPreFilterEvents_Invoke_CallsProtectedVirtualMethod() - { - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner - .Protected() - .Setup("PreFilterEvents", ItExpr.IsAny()) - .Verifiable(); - IDesignerFilter filter = mockDesigner.Object; - - filter.PreFilterEvents(new Dictionary()); - - mockDesigner.Protected().Verify("PreFilterEvents", Times.Once(), ItExpr.IsAny()); - } - - [Fact] - public void ComponentDesigner_IDesignerFilterPreFilterProperties_WithComponentWithKey_Success() - { - using SubComponentDesigner designer = new(); - IDesignerFilter filter = designer; - PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(CustomComponent))[0]; - Dictionary properties = new() - { - { "SettingsKey", descriptor } - }; - using IPersistComponentSettingsComponent component = new(); - designer.Initialize(component); - filter.PreFilterProperties(properties); - PropertyDescriptor result = (PropertyDescriptor)properties["SettingsKey"]; - Assert.NotSame(descriptor, result); - Assert.Equal(typeof(ComponentDesigner), result.ComponentType); - Assert.Equal(descriptor.Name, result.Name); - Assert.True(descriptor.Attributes.Count >= 7); - Assert.True(result.Attributes.Count >= 8); - } - - [Fact] - public void ComponentDesigner_IDesignerFilterPreFilterProperties_WithIPersistComponentSettingsComponentWithKey_Success() - { - using SubComponentDesigner designer = new(); - IDesignerFilter filter = designer; - PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(CustomComponent))[0]; - Dictionary properties = new() - { - { "SettingsKey", descriptor } - }; - using IPersistComponentSettingsComponent component = new(); - designer.Initialize(component); - filter.PreFilterProperties(properties); - PropertyDescriptor result = (PropertyDescriptor)properties["SettingsKey"]; - Assert.NotSame(descriptor, result); - Assert.Equal(typeof(ComponentDesigner), result.ComponentType); - Assert.Equal(descriptor.Name, result.Name); - Assert.True(descriptor.Attributes.Count >= 7); - Assert.True(result.Attributes.Count >= 8); - } - - [Theory] - [MemberData(nameof(PreFilterProperties_ComponentWithoutKey_TestData))] - public void ComponentDesigner_IDesignerFilterPreFilterProperties_WithIPersistComponentSettingsComponentWithoutKey_Success(IDictionary properties) - { - using SubComponentDesigner designer = new(); - IDesignerFilter filter = designer; - PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(CustomComponent))[0]; - object oldValue = properties?["SettingsKey"]; - using IPersistComponentSettingsComponent component = new(); - designer.Initialize(component); - filter.PreFilterProperties(properties); - Assert.Same(oldValue, properties?["SettingsKey"]); - } - - [Fact] - public void ComponentDesigner_IDesignerFilterPreFilterProperties_WithNonIPersistComponentSettingsComponent_Nop() - { - using ComponentDesigner designer = new(); - IDesignerFilter filter = designer; - PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(CustomComponent))[0]; - Dictionary properties = new() - { - { "SettingsKey", descriptor } - }; - using Component component = new(); - designer.Initialize(component); - filter.PreFilterProperties(properties); - Assert.Same(descriptor, properties["SettingsKey"]); - } - - [Theory] - [MemberData(nameof(IDictionary_TestData))] - public void ComponentDesigner_IDesignerFilterPreFilterProperties_WithoutComponent_Nop(IDictionary properties) - { - using ComponentDesigner designer = new(); - IDesignerFilter filter = designer; - filter.PreFilterProperties(properties); - } - - [Fact] - public void IDesignerFilterPreFilterProperties_Invoke_CallsProtectedVirtualMethod() - { - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner - .Protected() - .Setup("PreFilterProperties", ItExpr.IsAny()) - .Verifiable(); - IDesignerFilter filter = mockDesigner.Object; - - filter.PreFilterProperties(new Dictionary()); - - mockDesigner.Protected().Verify("PreFilterProperties", Times.Once(), ItExpr.IsAny()); - } - - [Theory] - [MemberData(nameof(PostFilterAttributes_NoInheritanceAttribute_TestData))] - public void ComponentDesigner_IDesignerFilterPostFilterAttributes_NoInheritanceAttribute_AddsToAttributes(InheritanceAttribute attribute, IDictionary attributes, object expected) - { - using CustomInheritanceAttributeComponentDesigner designer = new(attribute); - IDesignerFilter filter = designer; - filter.PostFilterAttributes(attributes); - Assert.Same(expected, attributes?[typeof(InheritanceAttribute)]); - } - - [Theory] - [MemberData(nameof(PostFilterAttributes_TestData))] - public void ComponentDesigner_IDesignerFilterPostFilterAttributes_HasInheritanceAttributeKey_Sets(IDictionary attributes, object expected) - { - using SubComponentDesigner designer = new(); - IDesignerFilter filter = designer; - filter.PostFilterAttributes(attributes); - Assert.Same(expected, designer.InheritanceAttribute); - } - - [Fact] - public void ComponentDesigner_IDesignerFilterPostFilterAttributes_Invoke_CallsProtectedVirtualMethod() - { - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner - .Protected() - .SetupGet("InheritanceAttribute") - .Returns(InheritanceAttribute.Default); - mockDesigner - .Protected() - .Setup("PostFilterAttributes", ItExpr.IsAny()) - .Verifiable(); - IDesignerFilter filter = mockDesigner.Object; - - filter.PostFilterAttributes(new Dictionary()); - - mockDesigner.Protected().Verify("PostFilterAttributes", Times.Once(), ItExpr.IsAny()); - } - - [Theory] - [MemberData(nameof(PostFilterEvents_HasEvents_TestData))] - public void ComponentDesigner_IDesignerFilterPostFilterEvents_InvokeWithEvents_Success(InheritanceAttribute inheritanceAttribute, bool valid) - { - EventDescriptor descriptor = TypeDescriptor.GetEvents(typeof(CustomComponent))[0]; - Dictionary events = new() { { "key1", descriptor }, { "Key2", null } }; - using CustomInheritanceAttributeComponentDesigner designer = new(inheritanceAttribute); - IDesignerFilter filter = designer; - filter.PostFilterEvents(events); - if (valid) - { - EventDescriptor result = Assert.IsAssignableFrom(events["Event"]); - Assert.Equal(typeof(CustomComponent), result.ComponentType); - Assert.Equal("Event", result.Name); - Assert.True(Assert.IsType(result.Attributes[typeof(ReadOnlyAttribute)]).IsReadOnly); - Assert.Equal(new Dictionary { { "key1", descriptor }, { "Key2", null }, { "Event", result } }, events); - } - else - { - Assert.Equal(new Dictionary { { "key1", descriptor }, { "Key2", null } }, events); - } - } - - [Theory] - [MemberData(nameof(PostFilterEvents_NoEvents_TestData))] - public void ComponentDesigner_IDesignerFilterPostFilterEvents_InvokeWithoutEvents_Success(InheritanceAttribute inheritanceAttribute, IDictionary events, IDictionary expected) - { - using CustomInheritanceAttributeComponentDesigner designer = new(inheritanceAttribute); - IDesignerFilter filter = designer; - filter.PostFilterEvents(events); - Assert.Equal(expected, events); - } - - [Fact] - public void ComponentDesigner_IDesignerFilterPostFilterEvents_InvokeWithInvalidEvents_ThrowsArrayTypeMismatchException() - { - CustomInheritanceAttributeComponentDesigner designer = new(InheritanceAttribute.InheritedReadOnly); - IDesignerFilter filter = designer; - Assert.Throws(() => filter.PostFilterEvents(new Dictionary { { "key", new object() } })); - } - - [Fact] - public void PostFilterEvents_Invoke_CallsProtectedVirtualMethod() - { - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner - .Protected() - .SetupGet("InheritanceAttribute") - .Returns(InheritanceAttribute.Default); - mockDesigner - .Protected() - .Setup("PostFilterEvents", ItExpr.IsAny()) - .Verifiable(); - IDesignerFilter filter = mockDesigner.Object; - - filter.PostFilterEvents(new Dictionary()); - - mockDesigner.Protected().Verify("PostFilterEvents", Times.Once(), ItExpr.IsAny()); - } - - private class SubComponentDesigner : ComponentDesigner - { - public new InheritanceAttribute InheritanceAttribute => base.InheritanceAttribute; - - public new bool Inherited => base.Inherited; - - public new IComponent ParentComponent => base.ParentComponent; - - public new object ShadowProperties => base.ShadowProperties; - - public new void Dispose(bool disposing) => base.Dispose(disposing); - - public new object GetService(Type serviceType) => base.GetService(serviceType); - - public new InheritanceAttribute InvokeGetInheritanceAttribute(ComponentDesigner toInvoke) => base.InvokeGetInheritanceAttribute(toInvoke); - - public new void PreFilterAttributes(IDictionary attributes) => base.PreFilterAttributes(attributes); - - public new void PreFilterEvents(IDictionary events) => base.PreFilterEvents(events); - - public new void PreFilterProperties(IDictionary properties) => base.PreFilterProperties(properties); - - public new void PostFilterAttributes(IDictionary attributes) => base.PostFilterAttributes(attributes); - - public new void PostFilterEvents(IDictionary events) => base.PostFilterEvents(events); - - public new void PostFilterProperties(IDictionary properties) => base.PostFilterProperties(properties); - - public new void RaiseComponentChanged(MemberDescriptor member, object oldValue, object newValue) - { - base.RaiseComponentChanged(member, oldValue, newValue); - } - - public new void RaiseComponentChanging(MemberDescriptor member) => base.RaiseComponentChanging(member); - } - - private class CustomAssociatedComponentsComponentDesigner : ComponentDesigner - { - private readonly ICollection _associatedComponents; - - public CustomAssociatedComponentsComponentDesigner(ICollection associatedComponents) - { - _associatedComponents = associatedComponents; - } - - public override ICollection AssociatedComponents => _associatedComponents; - } - - private class CustomInheritanceAttributeComponentDesigner : ComponentDesigner - { - private InheritanceAttribute _inheritanceAttribute; - - public CustomInheritanceAttributeComponentDesigner(InheritanceAttribute inheritanceAttribute) : base() - { - _inheritanceAttribute = inheritanceAttribute; - } - - protected override InheritanceAttribute InheritanceAttribute => _inheritanceAttribute; - - public new bool Inherited => base.Inherited; - - public new void PostFilterAttributes(IDictionary attributes) => base.PostFilterAttributes(attributes); - - public new void PostFilterEvents(IDictionary events) => base.PostFilterEvents(events); - - public new void PostFilterProperties(IDictionary events) => base.PostFilterProperties(events); - } - - private class IPersistComponentSettingsComponent : Component, IPersistComponentSettings - { - public bool SaveSettings { get; set; } - - public string SettingsKey { get; set; } - - public void LoadComponentSettings() => throw new NotImplementedException(); - - public void ResetComponentSettings() => throw new NotImplementedException(); - - public void SaveComponentSettings() => throw new NotImplementedException(); - } - - private class CustomComponent : Component - { - [EditorBrowsable(EditorBrowsableState.Advanced)] - public int Property { get; set; } - - public event EventHandler Event - { - add { } - remove { } - } - } - - [DefaultProperty(nameof(StringDefaultPropertyComponent.Value))] - private class StringDefaultPropertyComponent : Component - { - public string Value { get; set; } - } - - [DefaultProperty(nameof(IntDefaultPropertyComponent.Value))] - private class IntDefaultPropertyComponent : Component - { - public int Value { get; set; } - } - - [DefaultEvent(nameof(DefaultEventComponent.Event))] - private class DefaultEventComponent : Component - { - private string _stringProperty; - - public event EventHandler Event - { - add { } - remove { } - } - - public object ObjectProperty - { - get => StringProperty; - set => StringProperty = (string)value; - } - - public string StringProperty - { - get => _stringProperty; - set - { - StringPropertySetCount++; - _stringProperty = value; - } - } - - public int StringPropertySetCount { get; set; } - - public int IntProperty { get; set; } - - public object ReadOnlyProperty { get; } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignSurfaceTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignSurfaceTests.cs deleted file mode 100644 index 5109bcfb2a9..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignSurfaceTests.cs +++ /dev/null @@ -1,1895 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design.Serialization; -using System.Reflection; -using System.Windows.Forms.Design; -using Moq; - -namespace System.ComponentModel.Design.Tests; - -public class DesignSurfaceTests -{ - [WinFormsFact] - public void DesignSurface_Ctor_Default() - { - using SubDesignSurface surface = new(); - Assert.NotNull(surface.ComponentContainer); - Assert.Empty(surface.ComponentContainer.Components); - Assert.False(surface.DtelLoading); - Assert.False(surface.Host.CanReloadWithErrors); - Assert.Same(surface.Host, surface.Host.Container); - Assert.False(surface.Host.Loading); - Assert.False(surface.Host.IgnoreErrorsDuringReload); - Assert.False(surface.Host.InTransaction); - Assert.False(((IDesignerHostTransactionState)surface.Host).IsClosingTransaction); - Assert.Null(surface.Host.RootComponent); - Assert.Null(surface.Host.RootComponentClassName); - Assert.Null(surface.Host.TransactionDescription); - Assert.False(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.NotNull(surface.ServiceContainer); - Assert.Throws(() => surface.View); - } - - public static IEnumerable Ctor_IServiceProvider_TestData() - { - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IHelpService))) - .Returns(null); - yield return new object[] { null }; - yield return new object[] { mockServiceProvider.Object }; - } - - [WinFormsTheory] - [MemberData(nameof(Ctor_IServiceProvider_TestData))] - public void DesignSurface_Ctor_IServiceProvider(IServiceProvider parentProvider) - { - using SubDesignSurface surface = new(parentProvider); - Assert.NotNull(surface.ComponentContainer); - Assert.Empty(surface.ComponentContainer.Components); - Assert.False(surface.DtelLoading); - Assert.False(surface.Host.CanReloadWithErrors); - Assert.Same(surface.Host, surface.Host.Container); - Assert.False(surface.Host.Loading); - Assert.False(surface.Host.IgnoreErrorsDuringReload); - Assert.False(surface.Host.InTransaction); - Assert.False(((IDesignerHostTransactionState)surface.Host).IsClosingTransaction); - Assert.Null(surface.Host.RootComponent); - Assert.Null(surface.Host.RootComponentClassName); - Assert.Null(surface.Host.TransactionDescription); - Assert.False(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.NotNull(surface.ServiceContainer); - Assert.Throws(() => surface.View); - } - - [WinFormsFact] - public void DesignSurface_Ctor_Type() - { - using SubDesignSurface surface = new(typeof(RootDesignerComponent)); - Assert.NotNull(surface.ComponentContainer); - Assert.Single(surface.ComponentContainer.Components); - Assert.False(surface.DtelLoading); - Assert.False(surface.Host.CanReloadWithErrors); - Assert.Same(surface.Host, surface.Host.Container); - Assert.False(surface.Host.Loading); - Assert.False(surface.Host.IgnoreErrorsDuringReload); - Assert.False(surface.Host.InTransaction); - Assert.False(((IDesignerHostTransactionState)surface.Host).IsClosingTransaction); - Assert.IsType(surface.Host.RootComponent); - Assert.Equal(typeof(RootDesignerComponent).FullName, surface.Host.RootComponentClassName); - Assert.Null(surface.Host.TransactionDescription); - Assert.True(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.NotNull(surface.ServiceContainer); - Assert.Same(RootComponentDesigner.View, surface.View); - } - - [WinFormsFact] - public void DesignSurface_Ctor_IServiceProvider_Type_NullParentProvider() - { - using SubDesignSurface surface = new(null, typeof(RootDesignerComponent)); - Assert.NotNull(surface.ComponentContainer); - Assert.Single(surface.ComponentContainer.Components); - Assert.False(surface.DtelLoading); - Assert.False(surface.Host.CanReloadWithErrors); - Assert.Same(surface.Host, surface.Host.Container); - Assert.False(surface.Host.Loading); - Assert.False(surface.Host.IgnoreErrorsDuringReload); - Assert.False(surface.Host.InTransaction); - Assert.False(((IDesignerHostTransactionState)surface.Host).IsClosingTransaction); - Assert.IsType(surface.Host.RootComponent); - Assert.Equal(typeof(RootDesignerComponent).FullName, surface.Host.RootComponentClassName); - Assert.Null(surface.Host.TransactionDescription); - Assert.True(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.NotNull(surface.ServiceContainer); - Assert.Same(RootComponentDesigner.View, surface.View); - } - - [WinFormsFact] - public void DesignSurface_Ctor_IServiceProvider_Type_CustomParentProvider() - { - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProvider))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IHelpService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - using SubDesignSurface surface = new(mockServiceProvider.Object, typeof(RootDesignerComponent)); - Assert.NotNull(surface.ComponentContainer); - Assert.Single(surface.ComponentContainer.Components); - Assert.False(surface.DtelLoading); - Assert.False(surface.Host.CanReloadWithErrors); - Assert.Same(surface.Host, surface.Host.Container); - Assert.False(surface.Host.Loading); - Assert.False(surface.Host.IgnoreErrorsDuringReload); - Assert.False(surface.Host.InTransaction); - Assert.False(((IDesignerHostTransactionState)surface.Host).IsClosingTransaction); - Assert.IsType(surface.Host.RootComponent); - Assert.Equal(typeof(RootDesignerComponent).FullName, surface.Host.RootComponentClassName); - Assert.Null(surface.Host.TransactionDescription); - Assert.True(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.NotNull(surface.ServiceContainer); - Assert.Same(RootComponentDesigner.View, surface.View); - } - - [WinFormsFact] - public void DesignSurface_Ctor_NullRootComponentType_ThrowsArgumentNullException() - { - Mock mockServiceProvider = new(MockBehavior.Strict); - Assert.Throws("rootComponentType", () => new DesignSurface((Type)null)); - Assert.Throws("rootComponentType", () => new DesignSurface(mockServiceProvider.Object, (Type)null)); - } - - [WinFormsFact] - public void DesignSurface_ComponentContainer_GetDisposed_ThrowsObjectDisposedException() - { - using DesignSurface surface = new(); - surface.Dispose(); - Assert.Throws(() => surface.ComponentContainer); - } - - [WinFormsTheory] - [BoolData] - public void DesignSurface_DtelLoading_Set_GetReturnsExpected(bool value) - { - using DesignSurface surface = new() - { - DtelLoading = value - }; - Assert.Equal(value, surface.DtelLoading); - - // Set same - surface.DtelLoading = value; - Assert.Equal(value, surface.DtelLoading); - - // Set different - surface.DtelLoading = !value; - Assert.Equal(!value, surface.DtelLoading); - } - - [WinFormsFact] - public void DesignSurface_ServiceContainer_Get_ReturnsSame() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.NotNull(container); - Assert.Same(container, surface.ServiceContainer); - } - - [WinFormsFact] - public void DesignSurface_ServiceContainer_GetISelectionService_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - ISelectionService service = Assert.IsAssignableFrom(container.GetService(typeof(ISelectionService))); - Assert.Null(service.PrimarySelection); - Assert.Equal(0, service.SelectionCount); - } - - [WinFormsFact] - public void DesignSurface_ServiceContainer_GetIExtenderProviderService_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.IsAssignableFrom(container.GetService(typeof(IExtenderProviderService))); - } - - [WinFormsFact] - public void DesignSurface_ServiceContainer_GetIExtenderListService_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.IsAssignableFrom(container.GetService(typeof(IExtenderListService))); - Assert.IsAssignableFrom(container.GetService(typeof(IExtenderListService))); - } - - [WinFormsFact] - public void DesignSurface_ServiceContainer_GetITypeDescriptorFilterService_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.IsAssignableFrom(container.GetService(typeof(ITypeDescriptorFilterService))); - } - - [WinFormsFact] - public void DesignSurface_ServiceContainer_GetIReferenceService_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.IsAssignableFrom(container.GetService(typeof(IReferenceService))); - } - - [WinFormsFact] - public void DesignSurface_ServiceContainer_GetDesignSurfaceService_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.Same(surface, container.GetService(typeof(DesignSurface))); - } - - [WinFormsFact] - public void DesignSurface_ServiceContainer_GetInstanceTypeService_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.Same(container, container.GetService(container.GetType())); - } - - public static IEnumerable ServiceContainer_FixedService_TestData() - { - yield return new object[] { typeof(IDesignerHost) }; - yield return new object[] { typeof(IContainer) }; - yield return new object[] { typeof(IComponentChangeService) }; - yield return new object[] { typeof(IDesignerLoaderHost2) }; - } - - [WinFormsTheory] - [MemberData(nameof(ServiceContainer_FixedService_TestData))] - public void DesignSurface_ServiceContainer_GetFixedService_ReturnsExpected(Type serviceType) - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.Same(surface.Host, container.GetService(serviceType)); - } - - [WinFormsTheory] - [MemberData(nameof(ServiceContainer_FixedService_TestData))] - public void DesignSurface_ServiceContainer_RemoveFixedService_ThrowsInvalidOperationException(Type serviceType) - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.Throws(() => container.RemoveService(serviceType)); - } - - [WinFormsTheory] - [InlineData(typeof(ISelectionService))] - [InlineData(typeof(IExtenderProviderService))] - [InlineData(typeof(IExtenderListService))] - [InlineData(typeof(ITypeDescriptorFilterService))] - [InlineData(typeof(IReferenceService))] - [InlineData(typeof(DesignSurface))] - public void DesignSurface_ServiceContainer_RemoveNonFixedServiceType_ThrowsArgumentNullException(Type serviceType) - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.NotNull(container.GetService(serviceType)); - container.RemoveService(serviceType); - Assert.Null(container.GetService(serviceType)); - - // Remove again. - container.RemoveService(serviceType); - Assert.Null(container.GetService(serviceType)); - } - - [WinFormsFact] - public void DesignSurface_ServiceContainer_RemoveNullServiceType_ThrowsArgumentNullException() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.Throws("serviceType", () => container.RemoveService(null)); - } - - [WinFormsFact] - public void DesignSurface_ServiceContainer_GetDisposed_ThrowsObjectDisposedException() - { - using SubDesignSurface surface = new(); - surface.Dispose(); - Assert.Throws(() => surface.ServiceContainer); - } - - [WinFormsTheory] - [InlineData(typeof(NullSupportedTechnologiesRootDesignerComponent))] - [InlineData(typeof(EmptySupportedTechnologiesRootDesignerComponent))] - public void DesignSurface_View_GetWithInvalidSupportedTechnologies_ThrowsNotSupportedException(Type rootComponentType) - { - using SubDesignSurface surface = new(); - surface.BeginLoad(rootComponentType); - Assert.Throws(() => surface.View); - } - - [WinFormsFact] - public void DesignSurface_View_GetDisposed_ThrowsObjectDisposedException() - { - using DesignSurface surface = new(); - surface.Dispose(); - Assert.Throws(() => surface.View); - } - - [WinFormsFact] - public void DesignSurface_View_GetWithExceptionLoadErrors_ThrowsInvalidOperationException() - { - Exception exception = new(); - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Throws(exception); - surface.BeginLoad(mockLoader.Object); - Assert.Same(exception, Assert.Throws(() => surface.View).InnerException); - } - - public static IEnumerable View_GetLoadError_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new object[] { new Exception() } }; - yield return new object[] { new object[] { "Error" } }; - yield return new object[] { new object[] { null } }; - } - - [WinFormsTheory] - [MemberData(nameof(View_GetLoadError_TestData))] - public void DesignSurface_View_GetWithLoadErrors_ThrowsInvalidOperationException(object[] errorCollection) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - host.EndLoad("BaseClassName", false, errorCollection); - Assert.Throws(() => surface.View); - } - - public static IEnumerable BeginLoad_TestData() - { - yield return new object[] { null }; - - Mock nullMockServiceProvider = new(MockBehavior.Strict); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(null); - yield return new object[] { nullMockServiceProvider.Object }; - - Mock invalidMockServiceProvider = new(MockBehavior.Strict); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(new object()); - yield return new object[] { invalidMockServiceProvider.Object }; - - Mock mockDesignerEventService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(mockDesignerEventService.Object); - yield return new object[] { mockServiceProvider.Object }; - } - - [WinFormsTheory] - [MemberData(nameof(BeginLoad_TestData))] - public void DesignSurface_BeginLoad_Invoke_Success(IServiceProvider parentProvider) - { - SubDesignSurface surface = new(parentProvider); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Verifiable(); - surface.BeginLoad(mockLoader.Object); - Assert.False(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.True(surface.Host.Loading); - Assert.True(host.Loading); - Assert.Null(host.RootComponent); - Assert.Null(host.RootComponentClassName); - Assert.Throws(() => surface.View); - mockLoader.Verify(l => l.BeginLoad(host), Times.Once()); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_ThrowsException_SetsLoadErrors() - { - Exception exception = new(); - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Throws(exception); - mockLoader - .Setup(l => l.Loading) - .Returns(false); - surface.BeginLoad(mockLoader.Object); - Assert.False(surface.IsLoaded); - Assert.False(surface.Host.Loading); - Assert.Same(exception, Assert.Single(surface.LoadErrors)); - } - - [WinFormsTheory] - [NullAndEmptyStringData] - public void DesignSurface_BeginLoad_ThrowsExceptionWithoutMessage_SetsLoadErrors(string message) - { - Mock mockException = new(MockBehavior.Strict); - mockException - .Setup(e => e.Message) - .Returns(message); - mockException - .Setup(e => e.ToString()) - .Returns("ExceptionText"); - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Throws(mockException.Object); - mockLoader - .Setup(l => l.Loading) - .Returns(false); - surface.BeginLoad(mockLoader.Object); - Assert.False(surface.IsLoaded); - Exception error = Assert.IsType(Assert.Single(surface.LoadErrors)); - Assert.Contains("ExceptionText", error.Message); - Assert.False(surface.Host.Loading); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_ThrowsTargetInvocationException_SetsLoadErrors() - { - Exception exception = new(); - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Throws(new TargetInvocationException(exception)); - mockLoader - .Setup(l => l.Loading) - .Returns(false); - surface.BeginLoad(mockLoader.Object); - Assert.False(surface.IsLoaded); - Assert.Same(exception, Assert.Single(surface.LoadErrors)); - Assert.False(surface.Host.Loading); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_InvokeWithLoading_CallsHandler() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - int loadingCallCount = 0; - surface.Loading += (sender, e) => - { - Assert.Same(surface, sender); - Assert.Same(EventArgs.Empty, e); - loadingCallCount++; - }; - int loadedCallCount = 0; - surface.Loaded += (sender, e) => loadedCallCount++; - int unloadingCallCount = 0; - surface.Unloading += (sender, e) => unloadingCallCount++; - int unloadedCallCount = 0; - surface.Unloaded += (sender, e) => unloadedCallCount++; - int flushedCallCount = 0; - surface.Flushed += (sender, e) => flushedCallCount++; - - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Verifiable(); - surface.BeginLoad(mockLoader.Object); - Assert.False(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.True(surface.Host.Loading); - Assert.Equal(1, loadingCallCount); - Assert.Equal(0, loadedCallCount); - Assert.Equal(0, unloadingCallCount); - Assert.Equal(0, unloadedCallCount); - Assert.Equal(0, flushedCallCount); - mockLoader.Verify(l => l.BeginLoad(host), Times.Once()); - - // Reload. - surface.BeginLoad(mockLoader.Object); - Assert.False(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.True(surface.Host.Loading); - Assert.Equal(2, loadingCallCount); - Assert.Equal(0, loadedCallCount); - Assert.Equal(0, unloadingCallCount); - Assert.Equal(0, unloadedCallCount); - Assert.Equal(0, flushedCallCount); - mockLoader.Verify(l => l.BeginLoad(host), Times.Exactly(2)); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_InvokeErrorWithUnloading_CallsHandler() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - int unloadingCallCount = 0; - surface.Unloading += (sender, e) => - { - Assert.Same(surface, sender); - Assert.Same(EventArgs.Empty, e); - unloadingCallCount++; - }; - int unloadedCallCount = 0; - surface.Unloaded += (sender, e) => - { - Assert.Same(surface, sender); - Assert.Same(EventArgs.Empty, e); - Assert.True(unloadedCallCount < unloadingCallCount); - unloadedCallCount++; - }; - int loadedCallCount = 0; - surface.Loaded += (sender, e) => - { - Assert.Same(surface, sender); - Assert.False(e.HasSucceeded); - Assert.Same(surface.LoadErrors, e.Errors); - Assert.True(loadedCallCount < unloadingCallCount); - loadedCallCount++; - }; - int flushedCallCount = 0; - surface.Flushed += (sender, e) => flushedCallCount++; - - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Throws(new Exception()) - .Verifiable(); - mockLoader - .Setup(l => l.Loading) - .Returns(false); - surface.BeginLoad(mockLoader.Object); - Assert.False(surface.IsLoaded); - Assert.Single(surface.LoadErrors); - Assert.False(surface.Host.Loading); - Assert.Equal(1, unloadingCallCount); - Assert.Equal(1, unloadedCallCount); - Assert.Equal(1, loadedCallCount); - Assert.Equal(0, flushedCallCount); - mockLoader.Verify(l => l.BeginLoad(host), Times.Once()); - - // Reload. - surface.BeginLoad(mockLoader.Object); - Assert.False(surface.IsLoaded); - Assert.False(surface.Host.Loading); - Assert.Single(surface.LoadErrors); - Assert.Equal(2, unloadingCallCount); - Assert.Equal(2, unloadedCallCount); - Assert.Equal(2, loadedCallCount); - Assert.Equal(0, flushedCallCount); - mockLoader.Verify(l => l.BeginLoad(host), Times.Exactly(2)); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_InvokeDefaultIExtenderProvider_Success() - { - Mock mockExtenderProviderService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(mockExtenderProviderService.Object) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(null) - .Verifiable(); - SubDesignSurface surface = new(mockServiceProvider.Object); - IExtenderListService defaultProviderService = (IExtenderListService)surface.GetService(typeof(IExtenderListService)); - IDesignerLoaderHost2 host = surface.Host; - - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Verifiable(); - var mockExtenderProvider = mockLoader.As(); - surface.BeginLoad(mockLoader.Object); - mockLoader.Verify(l => l.BeginLoad(host), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerEventService)), Times.Once()); - Assert.Same(mockExtenderProvider.Object, Assert.Single(defaultProviderService.GetExtenderProviders())); - - // Reload. - surface.BeginLoad(mockLoader.Object); - mockLoader.Verify(l => l.BeginLoad(host), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerEventService)), Times.Once()); - Assert.Same(mockExtenderProvider.Object, Assert.Single(defaultProviderService.GetExtenderProviders())); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_InvokeValidIExtenderProvider_CallsAddExtenderProvider() - { - Mock mockExtenderProviderService = new(MockBehavior.Strict); - mockExtenderProviderService - .Setup(s => s.AddExtenderProvider(It.IsAny())) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(mockExtenderProviderService.Object) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(null) - .Verifiable(); - SubDesignSurface surface = new(mockServiceProvider.Object); - IExtenderListService defaultProviderService = (IExtenderListService)surface.GetService(typeof(IExtenderListService)); - surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService)); - IDesignerLoaderHost2 host = surface.Host; - - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Verifiable(); - var mockExtenderProvider = mockLoader.As(); - surface.BeginLoad(mockLoader.Object); - mockLoader.Verify(l => l.BeginLoad(host), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerEventService)), Times.Once()); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(mockExtenderProvider.Object), Times.Once()); - Assert.Empty(defaultProviderService.GetExtenderProviders()); - - // Reload. - surface.BeginLoad(mockLoader.Object); - mockLoader.Verify(l => l.BeginLoad(host), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerEventService)), Times.Once()); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(mockExtenderProvider.Object), Times.Once()); - Assert.Empty(defaultProviderService.GetExtenderProviders()); - } - - public static IEnumerable BeginLoad_InvalidIExtenderProvider_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [WinFormsTheory] - [MemberData(nameof(BeginLoad_InvalidIExtenderProvider_TestData))] - public void DesignSurface_BeginLoad_InvokeInvalidIExtenderProvider_Success(object service) - { - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(service) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(null) - .Verifiable(); - SubDesignSurface surface = new(mockServiceProvider.Object); - IExtenderListService defaultProviderService = (IExtenderListService)surface.GetService(typeof(IExtenderListService)); - surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService)); - IDesignerLoaderHost2 host = surface.Host; - - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Verifiable(); - var mockExtenderProvider = mockLoader.As(); - surface.BeginLoad(mockLoader.Object); - mockLoader.Verify(l => l.BeginLoad(host), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerEventService)), Times.Once()); - Assert.Empty(defaultProviderService.GetExtenderProviders()); - - // Reload. - surface.BeginLoad(mockLoader.Object); - mockLoader.Verify(l => l.BeginLoad(host), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerEventService)), Times.Once()); - Assert.Empty(defaultProviderService.GetExtenderProviders()); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_InvokeWithoutIDesignerEventServiceWithActivated_CallsHandler() - { - SubDesignSurface surface = new(); - int callCount = 0; - IDesignerLoaderHost2 host = surface.Host; - host.Activated += (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(EventArgs.Empty, e); - callCount++; - }; - - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Verifiable(); - surface.BeginLoad(mockLoader.Object); - Assert.Equal(1, callCount); - mockLoader.Verify(l => l.BeginLoad(host), Times.Once()); - - // Reload. - surface.BeginLoad(mockLoader.Object); - Assert.Equal(2, callCount); - mockLoader.Verify(l => l.BeginLoad(host), Times.Exactly(2)); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_InvokeWithIDesignerEventServiceWithActivated_DoesNotCallHandler() - { - Mock mockDesignerEventService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(mockDesignerEventService.Object) - .Verifiable(); - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - int callCount = 0; - host.Activated += (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(EventArgs.Empty, e); - callCount++; - }; - - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)) - .Verifiable(); - surface.BeginLoad(mockLoader.Object); - Assert.Equal(0, callCount); - mockLoader.Verify(l => l.BeginLoad(host), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerEventService)), Times.Once()); - - // Reload. - surface.BeginLoad(mockLoader.Object); - Assert.Equal(0, callCount); - mockLoader.Verify(l => l.BeginLoad(host), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerEventService)), Times.Once()); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_DisposeInLoading_DoesCallFlush() - { - using SubDesignSurface surface = new(); - int loadingCallCount = 0; - surface.Loading += (sender, e) => - { - // Catch the InvalidOperationException thrown. - try - { - surface.Dispose(); - } - catch - { - } - - Assert.Same(surface, sender); - Assert.Same(EventArgs.Empty, e); - loadingCallCount++; - }; - int loadedCallCount = 0; - surface.Loaded += (sender, e) => loadedCallCount++; - int unloadingCallCount = 0; - surface.Unloading += (sender, e) => unloadingCallCount++; - int unloadedCallCount = 0; - surface.Unloaded += (sender, e) => unloadedCallCount++; - int flushedCallCount = 0; - surface.Flushed += (sender, e) => flushedCallCount++; - - Mock mockLoader = new(MockBehavior.Strict); - surface.BeginLoad(mockLoader.Object); - Assert.Equal(1, loadingCallCount); - Assert.Equal(0, loadedCallCount); - Assert.Equal(0, unloadingCallCount); - Assert.Equal(0, unloadedCallCount); - Assert.Equal(0, flushedCallCount); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_DisposeInBeginLoad_DoesCallFlush() - { - using SubDesignSurface surface = new(); - int loadingCallCount = 0; - surface.Loading += (sender, e) => - { - Assert.Same(surface, sender); - Assert.Same(EventArgs.Empty, e); - loadingCallCount++; - }; - int loadedCallCount = 0; - surface.Loaded += (sender, e) => loadedCallCount++; - int unloadingCallCount = 0; - surface.Unloading += (sender, e) => unloadingCallCount++; - int unloadedCallCount = 0; - surface.Unloaded += (sender, e) => unloadedCallCount++; - int flushedCallCount = 0; - surface.Flushed += (sender, e) => flushedCallCount++; - - Mock mockLoader = new(MockBehavior.Strict); - IDesignerLoaderHost2 host = surface.Host; - mockLoader - .Setup(l => l.BeginLoad(host)) - .Callback(() => - { - // Catch the InvalidOperationException thrown. - try - { - surface.Dispose(); - } - catch - { - } - }); - surface.BeginLoad(mockLoader.Object); - Assert.Equal(1, loadingCallCount); - Assert.Equal(0, loadedCallCount); - Assert.Equal(0, unloadingCallCount); - Assert.Equal(0, unloadedCallCount); - Assert.Equal(0, flushedCallCount); - mockLoader.Verify(l => l.BeginLoad(host), Times.Once()); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_DisposeInBeginLoadThrowsException_DoesCallFlush() - { - using SubDesignSurface surface = new(); - int loadingCallCount = 0; - surface.Loading += (sender, e) => - { - Assert.Same(surface, sender); - Assert.Same(EventArgs.Empty, e); - loadingCallCount++; - }; - int loadedCallCount = 0; - surface.Loaded += (sender, e) => loadedCallCount++; - int unloadingCallCount = 0; - surface.Unloading += (sender, e) => unloadingCallCount++; - int unloadedCallCount = 0; - surface.Unloaded += (sender, e) => unloadedCallCount++; - int flushedCallCount = 0; - surface.Flushed += (sender, e) => flushedCallCount++; - - Mock mockLoader = new(MockBehavior.Strict); - IDesignerLoaderHost2 host = surface.Host; - mockLoader - .Setup(l => l.BeginLoad(host)) - .Callback(() => - { - // Catch the InvalidOperationException thrown. - try - { - surface.Dispose(); - } - catch - { - } - - throw new Exception(); - }); - surface.BeginLoad(mockLoader.Object); - Assert.Equal(1, loadingCallCount); - Assert.Equal(0, loadedCallCount); - Assert.Equal(0, unloadingCallCount); - Assert.Equal(0, unloadedCallCount); - Assert.Equal(0, flushedCallCount); - mockLoader.Verify(l => l.BeginLoad(host), Times.Once()); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_NullLoader_ThrowsArgumentNullException() - { - using DesignSurface surface = new(); - Assert.Throws("loader", () => surface.BeginLoad((DesignerLoader)null)); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_InvokeType_Success() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - surface.BeginLoad(typeof(RootDesignerComponent)); - Assert.True(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.False(surface.Host.Loading); - Assert.False(host.Loading); - Assert.IsType(host.RootComponent); - Assert.Equal(typeof(RootDesignerComponent).FullName, host.RootComponentClassName); - Assert.Same(RootComponentDesigner.View, surface.View); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_NullRootComponentType_ThrowsArgumentNullException() - { - using DesignSurface surface = new(); - Assert.Throws("rootComponentType", () => surface.BeginLoad((Type)null)); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_AlreadyCalled_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - Mock otherMockLoader = new(MockBehavior.Strict); - otherMockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - Assert.Throws(() => surface.BeginLoad(typeof(RootDesignerComponent))); - Assert.Throws(() => surface.BeginLoad(otherMockLoader.Object)); - } - - [WinFormsFact] - public void DesignSurface_BeginLoad_Disposed_ThrowsObjectDisposedException() - { - using DesignSurface surface = new(); - surface.Dispose(); - Mock mockLoader = new(MockBehavior.Strict); - Assert.Throws(() => surface.BeginLoad(typeof(RootDesignerComponent))); - Assert.Throws(() => surface.BeginLoad(mockLoader.Object)); - } - - [WinFormsTheory] - [InlineData(false)] - [InlineData(true)] - public void DesignSurface_CreateDesigner_InvokeNoDesigner_ReturnsExpected(bool rootDesigner) - { - using SubDesignSurface surface = new(); - using Component component = new(); - - Assert.NotNull(surface.CreateDesigner(component, rootDesigner)); - } - - [WinFormsFact] - public void DesignSurface_CreateDesigner_InvokeIDesigner_ReturnsExpected() - { - using SubDesignSurface surface = new(); - using DesignerComponent component = new(); - - Assert.IsType(surface.CreateDesigner(component, rootDesigner: true)); - Assert.IsType(surface.CreateDesigner(component, rootDesigner: false)); - } - - [WinFormsFact] - public void DesignSurface_CreateDesigner_InvokeIRootDesigner_ReturnsExpected() - { - using SubDesignSurface surface = new(); - using RootDesignerComponent component = new(); - Assert.IsType(surface.CreateDesigner(component, rootDesigner: true)); - Assert.IsType(surface.CreateDesigner(component, rootDesigner: false)); - } - - [WinFormsFact] - public void DesignSurface_CreateDesigner_NullComponent_ThrowsArgumentNullException() - { - using SubDesignSurface surface = new(); - Assert.Throws("component", () => surface.CreateDesigner(null, true)); - Assert.Throws("component", () => surface.CreateDesigner(null, false)); - } - - [WinFormsFact] - public void DesignSurface_CreateDesigner_Disposed_ThrowsObjectDisposedException() - { - using SubDesignSurface surface = new(); - surface.Dispose(); - Assert.Throws(() => surface.CreateDesigner(new Component(), true)); - Assert.Throws(() => surface.CreateDesigner(new Component(), false)); - } - - [WinFormsFact] - public void DesignSurface_CreateComponent_IComponentWithPublicDefaultConstructor_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ComponentWithPublicConstructor instance = Assert.IsType(surface.CreateComponent(typeof(ComponentWithPublicConstructor))); - Assert.Null(instance.Container); - } - - [WinFormsFact] - public void DesignSurface_CreateComponent_IComponentWithPrivateDefaultConstructor_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ComponentWithPrivateDefaultConstructor instance = Assert.IsType(surface.CreateComponent(typeof(ComponentWithPrivateDefaultConstructor))); - Assert.Null(instance.Container); - } - - [WinFormsFact] - public void DesignSurface_CreateComponent_IComponentWithIContainerConstructor_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ComponentWithIContainerConstructor instance = Assert.IsType(surface.CreateComponent(typeof(ComponentWithIContainerConstructor))); - Assert.Same(surface.ComponentContainer, instance.Container); - } - - [WinFormsTheory] - [InlineData(typeof(ClassWithPublicConstructor))] - [InlineData(typeof(ClassWithPrivateDefaultConstructor))] - public void DesignSurface_CreateComponent_NonIComponent_ReturnsNull(Type type) - { - using SubDesignSurface surface = new(); - Assert.Null(surface.CreateComponent(type)); - } - - [WinFormsTheory] - [InlineData(typeof(ClassWithIContainerConstructor))] - [InlineData(typeof(ClassWithNoMatchingConstructor))] - [InlineData(typeof(ComponentWithPrivateIContainerConstructor))] - [InlineData(typeof(ComponentWithNoMatchingConstructor))] - public void DesignSurface_CreateComponent_TypeWithNoMatchingConstructor_ThrowsMissingMethodException(Type type) - { - using SubDesignSurface surface = new(); - Assert.Throws(() => surface.CreateComponent(type)); - } - - [WinFormsFact] - public void DesignSurface_CreateComponent_NullType_ThrowsArgumentNullException() - { - using SubDesignSurface surface = new(); - Assert.Throws("type", () => surface.CreateComponent(null)); - } - - [WinFormsFact] - public void DesignSurface_CreateInstance_NonIComponentWithPublicDefaultConstructor_ReturnsExpected() - { - using SubDesignSurface surface = new(); - Assert.IsType(surface.CreateInstance(typeof(ClassWithPublicConstructor))); - } - - [WinFormsFact] - public void DesignSurface_CreateInstance_NonIComponentWithPrivateDefaultConstructor_ReturnsExpected() - { - using SubDesignSurface surface = new(); - Assert.IsType(surface.CreateInstance(typeof(ClassWithPrivateDefaultConstructor))); - } - - [WinFormsFact] - public void DesignSurface_CreateInstance_IComponentWithPublicDefaultConstructor_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ComponentWithPublicConstructor instance = Assert.IsType(surface.CreateInstance(typeof(ComponentWithPublicConstructor))); - Assert.Null(instance.Container); - } - - [WinFormsFact] - public void DesignSurface_CreateInstance_IComponentWithPrivateDefaultConstructor_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ComponentWithPrivateDefaultConstructor instance = Assert.IsType(surface.CreateInstance(typeof(ComponentWithPrivateDefaultConstructor))); - Assert.Null(instance.Container); - } - - [WinFormsFact] - public void DesignSurface_CreateInstance_IComponentWithIContainerConstructor_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ComponentWithIContainerConstructor instance = Assert.IsType(surface.CreateInstance(typeof(ComponentWithIContainerConstructor))); - Assert.Same(surface.ComponentContainer, instance.Container); - } - - [WinFormsTheory] - [InlineData(typeof(ClassWithIContainerConstructor))] - [InlineData(typeof(ClassWithNoMatchingConstructor))] - [InlineData(typeof(ComponentWithPrivateIContainerConstructor))] - [InlineData(typeof(ComponentWithNoMatchingConstructor))] - public void DesignSurface_CreateInstance_TypeWithNoMatchingConstructor_ThrowsMissingMethodException(Type type) - { - using SubDesignSurface surface = new(); - Assert.Throws(() => surface.CreateInstance(type)); - } - - [WinFormsFact] - public void DesignSurface_CreateInstance_NullType_ThrowsArgumentNullException() - { - using SubDesignSurface surface = new(); - Assert.Throws("type", () => surface.CreateInstance(null)); - } - - [WinFormsFact] - public void DesignSurface_CreateNestedContainer_InvokeObject_ReturnsExpected() - { - using DesignSurface surface = new(); - using Component ownerComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(ownerComponent); - Assert.Empty(container.Components); - Assert.Same(ownerComponent, container.Owner); - } - - [WinFormsTheory] - [StringData] - public void DesignSurface_CreateNestedContainer_InvokeObjectString_ReturnsExpected(string containerName) - { - using DesignSurface surface = new(); - using Component ownerComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(ownerComponent, containerName); - Assert.Empty(container.Components); - Assert.Same(ownerComponent, container.Owner); - } - - [WinFormsFact] - public void DesignSurface_CreateNestedContainer_NullOwningComponent_ThrowsArgumentNullException() - { - using DesignSurface surface = new(); - Assert.Throws("owningComponent", () => surface.CreateNestedContainer(null)); - Assert.Throws("owningComponent", () => surface.CreateNestedContainer(null, "name")); - } - - [WinFormsFact] - public void DesignSurface_CreateNestedContainer_Disposed_ThrowsObjectDisposedException() - { - using DesignSurface surface = new(); - surface.Dispose(); - Assert.Throws(() => surface.CreateNestedContainer(null, "name")); - } - - [WinFormsFact] - public void DesignSurface_Dispose_InvokeMultipleTimes_Success() - { - using DesignSurface surface = new(); - surface.Dispose(); - surface.Dispose(); - } - - [WinFormsFact] - public void DesignSurface_Dispose_Invoke_RemovesDesignSurfaceService() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.Same(surface, container.GetService(typeof(DesignSurface))); - - surface.Dispose(); - Assert.Null(container.GetService(typeof(DesignSurface))); - } - - [WinFormsFact] - public void DesignSurface_Dispose_InvokeHasLoader_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - Assert.Throws(() => surface.Dispose()); - Assert.True(host.Loading); - - // Should not throw again. - surface.Dispose(); - Assert.True(host.Loading); - } - - [WinFormsFact] - public void DesignSurface_Dispose_InvokeHasHostWithTransactions_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction = host.CreateTransaction("Transaction1"); - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - Assert.True(host.Loading); - Assert.True(host.InTransaction); - Assert.Equal("Transaction1", host.TransactionDescription); - Assert.Throws(() => surface.Dispose()); - Assert.True(host.Loading); - Assert.True(host.InTransaction); - Assert.Equal("Transaction1", host.TransactionDescription); - - // Should not throw again. - surface.Dispose(); - Assert.True(host.Loading); - Assert.True(host.InTransaction); - Assert.Equal("Transaction1", host.TransactionDescription); - } - - [WinFormsFact] - public void Dispose_InvokeWithDisposed_CallsHandler() - { - using DesignSurface surface = new(); - surface.Dispose(); - - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(surface, sender); - Assert.Equal(EventArgs.Empty, e); - callCount++; - }; - surface.Disposed += handler; - - // Call with handler. - surface.Dispose(); - Assert.Equal(1, callCount); - - // Call again. - surface.Dispose(); - Assert.Equal(2, callCount); - - // Remove handler. - surface.Disposed -= handler; - surface.Dispose(); - Assert.Equal(2, callCount); - } - - [WinFormsTheory] - [BoolData] - public void DesignSurface_Dispose_InvokeDisposingMultipleTimes_Success(bool disposing) - { - using SubDesignSurface surface = new(); - surface.Dispose(disposing); - surface.Dispose(disposing); - } - - [WinFormsFact] - public void DesignSurface_Dispose_InvokeDisposing_RemovesDesignSurfaceService() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.Same(surface, container.GetService(typeof(DesignSurface))); - - surface.Dispose(true); - Assert.Null(container.GetService(typeof(DesignSurface))); - } - - [WinFormsFact] - public void DesignSurface_Dispose_InvokeNotDisposing_DoesNotRemoveDesignSurfaceService() - { - using SubDesignSurface surface = new(); - ServiceContainer container = surface.ServiceContainer; - Assert.Same(surface, container.GetService(typeof(DesignSurface))); - - surface.Dispose(false); - Assert.Same(surface, container.GetService(typeof(DesignSurface))); - } - - [WinFormsFact] - public void DesignSurface_Dispose_InvokeDisposingHasLoader_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - Assert.Throws(() => surface.Dispose(true)); - Assert.True(host.Loading); - - // Should not throw again. - surface.Dispose(true); - Assert.True(host.Loading); - } - - [WinFormsFact] - public void DesignSurface_Dispose_InvokeNotDisposingHasLoader_Nop() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - surface.Dispose(false); - Assert.True(host.Loading); - - // Should not throw again. - surface.Dispose(false); - Assert.True(host.Loading); - } - - [WinFormsFact] - public void DesignSurface_Dispose_InvokeDisposingHasHostWithTransactions_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction = host.CreateTransaction("Transaction1"); - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - Assert.True(host.Loading); - Assert.True(host.InTransaction); - Assert.Equal("Transaction1", host.TransactionDescription); - Assert.Throws(() => surface.Dispose(true)); - Assert.True(host.Loading); - Assert.True(host.InTransaction); - Assert.Equal("Transaction1", host.TransactionDescription); - - // Should not throw again. - surface.Dispose(true); - Assert.True(host.Loading); - Assert.True(host.InTransaction); - Assert.Equal("Transaction1", host.TransactionDescription); - } - - [WinFormsFact] - public void DesignSurface_Dispose_InvokeNotDisposingHasHostWithTransactions_Nop() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction = host.CreateTransaction("Transaction1"); - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - Assert.True(host.Loading); - Assert.True(host.InTransaction); - Assert.Equal("Transaction1", host.TransactionDescription); - surface.Dispose(false); - Assert.True(host.Loading); - Assert.True(host.InTransaction); - Assert.Equal("Transaction1", host.TransactionDescription); - - // Should not throw again. - surface.Dispose(false); - Assert.True(host.Loading); - Assert.True(host.InTransaction); - Assert.Equal("Transaction1", host.TransactionDescription); - } - - [WinFormsTheory] - [InlineData(true, 1)] - [InlineData(false, 0)] - public void Dispose_InvokeDisposingWithDisposed_CallsHandler(bool disposing, int expectedCallCount) - { - using SubDesignSurface surface = new(); - surface.Dispose(); - - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(surface, sender); - Assert.Equal(EventArgs.Empty, e); - callCount++; - }; - surface.Disposed += handler; - - // Call with handler. - surface.Dispose(disposing); - Assert.Equal(expectedCallCount, callCount); - - // Call again. - surface.Dispose(disposing); - Assert.Equal(expectedCallCount * 2, callCount); - - // Remove handler. - surface.Disposed -= handler; - surface.Dispose(disposing); - Assert.Equal(expectedCallCount * 2, callCount); - } - - [WinFormsFact] - public void DesignSurface_Flush_InvokeWithHostWithLoader_CallsLoaderFlush() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - mockLoader - .Setup(l => l.Flush()) - .Verifiable(); - surface.BeginLoad(mockLoader.Object); - - surface.Flush(); - mockLoader.Verify(l => l.Flush(), Times.Once()); - - // Flush again. - surface.Flush(); - mockLoader.Verify(l => l.Flush(), Times.Exactly(2)); - } - - [WinFormsFact] - public void DesignSurface_Flush_InvokeWithHostWithoutLoader_Nop() - { - using DesignSurface surface = new(); - surface.Flush(); - - // Flush again. - surface.Flush(); - } - - [WinFormsFact] - public void DesignSurface_Flush_InvokeDisposed_Nop() - { - using DesignSurface surface = new(); - surface.Dispose(); - surface.Flush(); - - // Flush again. - surface.Flush(); - } - - [WinFormsFact] - public void DesignSurface_Flush_InvokeWithFlushed_CallsHandler() - { - using DesignSurface surface = new(); - int callCount = 0; - surface.Flushed += (sender, e) => - { - Assert.Same(surface, sender); - Assert.Same(EventArgs.Empty, e); - callCount++; - }; - - surface.Flush(); - Assert.Equal(1, callCount); - - // Flush again. - surface.Flush(); - Assert.Equal(2, callCount); - - // Flush when disposed. - surface.Dispose(); - surface.Flush(); - Assert.Equal(3, callCount); - } - - [WinFormsFact] - public void DesignSurface_GetService_InvokeWithServiceProvider_ReturnsExpected() - { - object service = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(int))) - .Returns(service) - .Verifiable(); - using DesignSurface surface = new(mockServiceProvider.Object); - Assert.Same(service, surface.GetService(typeof(int))); - mockServiceProvider.Verify(p => p.GetService(typeof(int)), Times.Once()); - } - - [WinFormsFact] - public void DesignSurface_GetService_GetISelectionService_ReturnsExpected() - { - using SubDesignSurface surface = new(); - ISelectionService service = Assert.IsAssignableFrom(surface.GetService(typeof(ISelectionService))); - Assert.Null(service.PrimarySelection); - Assert.Equal(0, service.SelectionCount); - } - - [WinFormsFact] - public void DesignSurface_GetService_GetIExtenderProviderService_ReturnsExpected() - { - using SubDesignSurface surface = new(); - Assert.IsAssignableFrom(surface.GetService(typeof(IExtenderProviderService))); - } - - [WinFormsFact] - public void DesignSurface_GetService_GetIExtenderListService_ReturnsExpected() - { - using DesignSurface surface = new(); - Assert.IsAssignableFrom(surface.GetService(typeof(IExtenderListService))); - Assert.IsAssignableFrom(surface.GetService(typeof(IExtenderListService))); - } - - [WinFormsFact] - public void DesignSurface_GetService_GetITypeDescriptorFilterService_ReturnsExpected() - { - using DesignSurface surface = new(); - Assert.IsAssignableFrom(surface.GetService(typeof(ITypeDescriptorFilterService))); - } - - [WinFormsFact] - public void DesignSurface_GetService_GetIReferenceService_ReturnsExpected() - { - using DesignSurface surface = new(); - Assert.IsAssignableFrom(surface.GetService(typeof(IReferenceService))); - } - - [WinFormsFact] - public void DesignSurface_GetService_GetDesignSurfaceService_ReturnsExpected() - { - using DesignSurface surface = new(); - Assert.Same(surface, surface.GetService(typeof(DesignSurface))); - } - - [WinFormsFact] - public void DesignSurface_GetService_GetInstanceTypeService_ReturnsExpected() - { - using SubDesignSurface surface = new(); - Assert.Same(surface.ServiceContainer, surface.GetService(surface.ServiceContainer.GetType())); - } - - [WinFormsTheory] - [InlineData(typeof(IServiceContainer))] - [InlineData(typeof(ServiceContainer))] - public void DesignSurface_GetService_IServiceContainer_ReturnsExpected(Type serviceType) - { - using SubDesignSurface surface = new(); - Assert.Same(surface.ServiceContainer, surface.GetService(serviceType)); - } - - [WinFormsTheory] - [MemberData(nameof(ServiceContainer_FixedService_TestData))] - public void DesignSurface_GetService_GetFixedService_ReturnsExpected(Type serviceType) - { - using SubDesignSurface surface = new(); - Assert.Same(surface.Host, surface.GetService(serviceType)); - } - - [WinFormsFact] - public void DesignSurface_GetService_InvokeWithoutServiceProvider_ReturnsNull() - { - using DesignSurface surface = new(); - Assert.Null(surface.GetService(typeof(int))); - } - - [WinFormsTheory] - [MemberData(nameof(ServiceContainer_FixedService_TestData))] - public void DesignSurface_GetService_Disposed_ReturnsNull(Type serviceType) - { - using SubDesignSurface surface = new(); - surface.Dispose(); - Assert.Null(surface.GetService(serviceType)); - } - - [WinFormsTheory] - [NewAndDefaultData] - public void DesignSurface_OnLoading_Invoke_Success(EventArgs eventArgs) - { - using SubDesignSurface surface = new(); - - // No handler. - surface.OnLoading(eventArgs); - - // Handler. - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Equal(surface, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - surface.Loading += handler; - surface.OnLoading(eventArgs); - Assert.Equal(1, callCount); - - // Should not call if the handler is removed. - surface.Loading -= handler; - surface.OnLoading(eventArgs); - Assert.Equal(1, callCount); - } - - public static IEnumerable LoadedEventArgs_TestData() - { - yield return new object[] { null }; - yield return new object[] { new LoadedEventArgs(false, null) }; - } - - [WinFormsTheory] - [MemberData(nameof(LoadedEventArgs_TestData))] - public void DesignSurface_OnLoaded_Invoke_Success(LoadedEventArgs eventArgs) - { - using SubDesignSurface surface = new(); - - // No handler. - surface.OnLoaded(eventArgs); - - // Handler. - int callCount = 0; - LoadedEventHandler handler = (sender, e) => - { - Assert.Equal(surface, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - surface.Loaded += handler; - surface.OnLoaded(eventArgs); - Assert.Equal(1, callCount); - - // Should not call if the handler is removed. - surface.Loaded -= handler; - surface.OnLoaded(eventArgs); - Assert.Equal(1, callCount); - } - - [WinFormsTheory] - [NewAndDefaultData] - public void DesignSurface_OnUnloaded_Invoke_Success(EventArgs eventArgs) - { - using SubDesignSurface surface = new(); - - // No handler. - surface.OnUnloaded(eventArgs); - - // Handler. - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Equal(surface, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - surface.Unloaded += handler; - surface.OnUnloaded(eventArgs); - Assert.Equal(1, callCount); - - // Should not call if the handler is removed. - surface.Unloaded -= handler; - surface.OnUnloaded(eventArgs); - Assert.Equal(1, callCount); - } - - [WinFormsTheory] - [NewAndDefaultData] - public void DesignSurface_OnUnloading_Invoke_Success(EventArgs eventArgs) - { - using SubDesignSurface surface = new(); - - // No handler. - surface.OnUnloading(eventArgs); - - // Handler. - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Equal(surface, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - surface.Unloading += handler; - surface.OnUnloading(eventArgs); - Assert.Equal(1, callCount); - - // Should not call if the handler is removed. - surface.Unloading -= handler; - surface.OnUnloading(eventArgs); - Assert.Equal(1, callCount); - } - - [WinFormsTheory] - [NewAndDefaultData] - public void DesignSurface_OnViewActivate_Invoke_Success(EventArgs eventArgs) - { - using SubDesignSurface surface = new(); - - // No handler. - surface.OnViewActivate(eventArgs); - - // Handler. - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Equal(surface, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - - surface.ViewActivated += handler; - surface.OnViewActivate(eventArgs); - Assert.Equal(1, callCount); - - // Should not call if the handler is removed. - surface.ViewActivated -= handler; - surface.OnViewActivate(eventArgs); - Assert.Equal(1, callCount); - } - - private class SubDesignSurface : DesignSurface - { - public SubDesignSurface() : base() - { - } - - public SubDesignSurface(IServiceProvider parentProvider) : base(parentProvider) - { - } - - public SubDesignSurface(Type rootComponentType) : base(rootComponentType) - { - } - - public SubDesignSurface(IServiceProvider parentProvider, Type rootComponentType) : base(parentProvider, rootComponentType) - { - } - - public new ServiceContainer ServiceContainer => base.ServiceContainer; - - public IDesignerLoaderHost2 Host => Assert.IsAssignableFrom(ComponentContainer); - -#pragma warning disable 0618 - public new IComponent CreateComponent(Type componentType) => base.CreateComponent(componentType); -#pragma warning restore 0618 - - public new IDesigner CreateDesigner(IComponent component, bool rootDesigner) => base.CreateDesigner(component, rootDesigner); - - public new object CreateInstance(Type type) => base.CreateInstance(type); - - public new void Dispose(bool disposing) => base.Dispose(disposing); - - public new void OnLoading(EventArgs e) => base.OnLoading(e); - - public new void OnLoaded(LoadedEventArgs e) => base.OnLoaded(e); - - public new void OnUnloading(EventArgs e) => base.OnUnloading(e); - - public new void OnUnloaded(EventArgs e) => base.OnUnloaded(e); - - public new void OnViewActivate(EventArgs e) => base.OnViewActivate(e); - } - - [Designer(typeof(ComponentDesigner))] - private class DesignerComponent : Component - { - } - - private class RootComponentDesigner : ComponentDesigner, IRootDesigner - { - public static object View { get; } = new object(); - - public ViewTechnology[] SupportedTechnologies => new ViewTechnology[] { ViewTechnology.Default + 1 }; - public object GetView(ViewTechnology technology) - { - Assert.Equal(ViewTechnology.Default + 1, technology); - return View; - } - } - - [Designer(typeof(RootComponentDesigner), typeof(IRootDesigner))] - private class RootDesignerComponent : Component - { - } - - private class NullSupportedTechnologiesRootComponentDesigner : ComponentDesigner, IRootDesigner - { - public ViewTechnology[] SupportedTechnologies => null; - public object GetView(ViewTechnology technology) => throw new NotImplementedException(); - } - - [Designer(typeof(NullSupportedTechnologiesRootComponentDesigner), typeof(IRootDesigner))] - private class NullSupportedTechnologiesRootDesignerComponent : Component - { - } - - private class EmptySupportedTechnologiesRootComponentDesigner : ComponentDesigner, IRootDesigner - { - public ViewTechnology[] SupportedTechnologies => Array.Empty(); - public object GetView(ViewTechnology technology) => throw new NotImplementedException(); - } - - [Designer(typeof(EmptySupportedTechnologiesRootComponentDesigner), typeof(IRootDesigner))] - private class EmptySupportedTechnologiesRootDesignerComponent : Component - { - } - - private class ClassWithPublicConstructor - { - public ClassWithPublicConstructor() - { - } - - public ClassWithPublicConstructor(IContainer container) - { - throw new NotImplementedException(); - } - } - - private class ComponentWithPublicConstructor : Component - { - public ComponentWithPublicConstructor() - { - } - - public ComponentWithPublicConstructor(IContainer container) - { - throw new NotImplementedException(); - } - } - - private class ClassWithPrivateDefaultConstructor - { - private ClassWithPrivateDefaultConstructor() - { - } - - private ClassWithPrivateDefaultConstructor(IContainer container) - { - throw new NotImplementedException(); - } - } - - private class ComponentWithPrivateDefaultConstructor : Component - { - private ComponentWithPrivateDefaultConstructor() - { - } - - private ComponentWithPrivateDefaultConstructor(IContainer container) - { - throw new NotImplementedException(); - } - } - - private class ComponentWithIContainerConstructor : Component - { - public new IContainer Container { get; set; } - - public ComponentWithIContainerConstructor(IContainer container) - { - Container = container; - } - } - - private class ClassWithIContainerConstructor - { - public IContainer Container { get; set; } - - public ClassWithIContainerConstructor(IContainer container) - { - Container = container; - } - } - - private class ClassWithNoMatchingConstructor - { - private ClassWithNoMatchingConstructor(bool value) - { - } - } - - private class ComponentWithNoMatchingConstructor : Component - { - private ComponentWithNoMatchingConstructor(bool value) - { - } - } - - private class ClassWithPrivateIContainerConstructor - { - private ClassWithPrivateIContainerConstructor(IContainer container) - { - } - } - - private class ComponentWithPrivateIContainerConstructor : Component - { - private ComponentWithPrivateIContainerConstructor(IContainer container) - { - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionHeaderItemTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionHeaderItemTests.cs deleted file mode 100644 index 235ab214a8b..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionHeaderItemTests.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Specialized; - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionHeaderItemTests -{ - [Theory] - [InlineData("displayName", "category", "displayName")] - [InlineData("displa(&a)yName", "cate(&a)gory", "displayName")] - [InlineData("", "", "")] - [InlineData(null, null, null)] - public void DesignerActionItem_Ctor_String_String(string displayName, string category, string expectedDisplayName) - { - DesignerActionHeaderItem item = new(displayName, category); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Equal(category, item.Category); - Assert.Null(item.Description); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - } - - [Theory] - [InlineData("displayName", "displayName")] - [InlineData("displa(&a)yName", "displayName")] - [InlineData("", "")] - [InlineData(null, null)] - public void DesignerActionItem_Ctor_String(string displayName, string expectedDisplayName) - { - DesignerActionHeaderItem item = new(displayName); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Equal(displayName, item.Category); - Assert.Null(item.Description); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionItemCollectionTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionItemCollectionTests.cs deleted file mode 100644 index d7b0207cabb..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionItemCollectionTests.cs +++ /dev/null @@ -1,170 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionItemCollectionTests -{ - [Fact] - public void DesignerActionItemCollection_Ctor_Default() - { - DesignerActionItemCollection collection = new(); - Assert.Empty(collection); - } - - [Fact] - public void DesignerActionItemCollection_Add_DesignerActionItem_Success() - { - DesignerActionItemCollection collection = new(); - - SubDesignerActionItem value1 = new("displayName", "category", "description"); - collection.Add(value1); - Assert.Same(value1, Assert.Single(collection)); - Assert.Same(value1, collection[0]); - Assert.True(collection.Contains(value1)); - Assert.Equal(0, collection.IndexOf(value1)); - - SubDesignerActionItem value2 = new("displayName", "category", "description"); - collection.Add(value2); - Assert.Equal(new object[] { value1, value2 }, collection.Cast()); - Assert.True(collection.Contains(value2)); - Assert.Equal(1, collection.IndexOf(value2)); - } - - [Fact] - public void DesignerActionItemCollection_Add_NullValue_ThrowsArgumentNullException() - { - DesignerActionItemCollection collection = new(); - Assert.Throws("value", () => collection.Add(null)); - } - - [Fact] - public void DesignerActionItemCollection_Insert_DesignerActionItem_Success() - { - DesignerActionItemCollection collection = new(); - - SubDesignerActionItem value1 = new("displayName", "category", "description"); - collection.Insert(0, value1); - Assert.Same(value1, Assert.Single(collection)); - Assert.Same(value1, collection[0]); - Assert.True(collection.Contains(value1)); - Assert.Equal(0, collection.IndexOf(value1)); - - SubDesignerActionItem value2 = new("displayName", "category", "description"); - collection.Insert(0, value2); - Assert.Equal(new object[] { value2, value1 }, collection.Cast()); - Assert.True(collection.Contains(value2)); - Assert.Equal(0, collection.IndexOf(value2)); - } - - [Fact] - public void DesignerActionItemCollection_Insert_NullValue_ThrowsArgumentNullException() - { - DesignerActionItemCollection collection = new(); - Assert.Throws("value", () => collection.Insert(0, null)); - } - - [Fact] - public void DesignerActionItemCollection_Remove_Invoke_Success() - { - DesignerActionItemCollection collection = new(); - SubDesignerActionItem value = new("displayName", "category", "description"); - collection.Add(value); - Assert.Same(value, Assert.Single(collection)); - - collection.Remove(value); - Assert.Empty(collection); - Assert.False(collection.Contains(value)); - Assert.Equal(-1, collection.IndexOf(value)); - } - - [Fact] - public void DesignerActionItemCollection_Remove_NullValue_ThrowsArgumentNullException() - { - DesignerActionItemCollection collection = new(); - Assert.Throws("value", () => collection.Remove(null)); - } - - [Fact] - public void DesignerActionItemCollection_Item_Set_GetReturnsExpected() - { - DesignerActionItemCollection collection = new(); - SubDesignerActionItem value1 = new("displayName", "category", "description"); - SubDesignerActionItem value2 = new("displayName", "category", "description"); - collection.Add(value1); - Assert.Same(value1, Assert.Single(collection)); - - collection[0] = value2; - Assert.Same(value2, Assert.Single(collection)); - Assert.Same(value2, collection[0]); - Assert.False(collection.Contains(value1)); - Assert.Equal(-1, collection.IndexOf(value1)); - Assert.True(collection.Contains(value2)); - Assert.Equal(0, collection.IndexOf(value2)); - } - - [Fact] - public void DesignerActionItemCollection_Item_SetNull_ThrowsArgumentNullException() - { - DesignerActionItemCollection collection = new(); - SubDesignerActionItem value = new("displayName", "category", "description"); - collection.Add(value); - Assert.Throws("value", () => collection[0] = null); - } - - [Fact] - public void DesignerActionItemCollection_CopyTo_Invoke_Success() - { - DesignerActionItemCollection collection = new(); - SubDesignerActionItem value = new("displayName", "category", "description"); - collection.Add(value); - - var array = new DesignerActionItem[3]; - collection.CopyTo(array, 1); - Assert.Equal(new DesignerActionItem[] { null, value, null }, array); - } - - [Fact] - public void DesignerActionItemCollection_Contains_NoSuchValue_ReturnsFalse() - { - DesignerActionItemCollection collection = new(); - SubDesignerActionItem value = new("displayName", "category", "description"); - collection.Add(value); - - Assert.False(collection.Contains(new SubDesignerActionItem("displayName", "category", "description"))); - Assert.False(collection.Contains(null)); - } - - [Fact] - public void DesignerActionItemCollection_IndexOf_NoSuchValue_ReturnsNegativeOne() - { - DesignerActionItemCollection collection = new(); - SubDesignerActionItem value = new("displayName", "category", "description"); - collection.Add(value); - - Assert.Equal(-1, collection.IndexOf(new SubDesignerActionItem("displayName", "category", "description"))); - Assert.Equal(-1, collection.IndexOf(null)); - } - - [Fact] - public void DesignerActionItemCollection_Clear_Success() - { - DesignerActionItemCollection collection = new(); - SubDesignerActionItem value = new("displayName", "category", "description"); - collection.Add(value); - - collection.Clear(); - Assert.Empty(collection); - - // Clear again. - collection.Clear(); - Assert.Empty(collection); - } - - private class SubDesignerActionItem : DesignerActionItem - { - public SubDesignerActionItem(string displayName, string category, string description) : base(displayName, category, description) - { - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionItemTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionItemTests.cs deleted file mode 100644 index 59ddc25aa8d..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionItemTests.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Specialized; - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionItemTests -{ - [Theory] - [InlineData("displayName", "category", "description", "displayName")] - [InlineData("displa(&a)yName", "cate(&a)gory", "descr(&a)iption", "displayName")] - [InlineData("", "", "", "")] - [InlineData(null, null, null, null)] - public void DesignerActionItem_Ctor_String_String_String(string displayName, string category, string description, string expectedDisplayName) - { - SubDesignerActionItem item = new(displayName, category, description); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Equal(category, item.Category); - Assert.Equal(description, item.Description); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - } - - [Theory] - [BoolData] - public void DesignerActionItem_AllowAssociate_Set_GetReturnsExpected(bool value) - { - SubDesignerActionItem item = new("displayName", "category", "description") - { - AllowAssociate = value - }; - Assert.Equal(value, item.AllowAssociate); - - // Set same. - item.AllowAssociate = value; - Assert.Equal(value, item.AllowAssociate); - } - - [Theory] - [BoolData] - public void DesignerActionItem_ShowInSourceView_Set_GetReturnsExpected(bool value) - { - SubDesignerActionItem item = new("displayName", "category", "description") - { - ShowInSourceView = value - }; - Assert.Equal(value, item.ShowInSourceView); - - // Set same. - item.ShowInSourceView = value; - Assert.Equal(value, item.ShowInSourceView); - } - - private class SubDesignerActionItem : DesignerActionItem - { - public SubDesignerActionItem(string displayName, string category, string description) : base(displayName, category, description) - { - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionListCollectionTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionListCollectionTests.cs deleted file mode 100644 index 86051c4b169..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionListCollectionTests.cs +++ /dev/null @@ -1,211 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionListCollectionTests -{ - [Fact] - public void DesignerActionListCollection_Ctor_Default() - { - DesignerActionListCollection collection = new(); - Assert.Empty(collection); - } - - public static IEnumerable Ctor_DesignerActionListArray_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new DesignerActionList[] { new DesignerActionList(null), null } }; - } - - [Theory] - [MemberData(nameof(Ctor_DesignerActionListArray_TestData))] - public void DesignerActionListCollection_Ctor_DesignerActionListArray(DesignerActionList[] value) - { - DesignerActionListCollection collection = new(value); - Assert.Equal(value, collection.Cast()); - } - - [Fact] - public void DesignerActionListCollection_Ctor_NullValue_ThrowsArgumentNullException() - { - Assert.Throws("value", () => new DesignerActionListCollection(null)); - } - - [Fact] - public void DesignerActionListCollection_Add_DesignerActionList_Success() - { - DesignerActionListCollection collection = new(); - - DesignerActionList value1 = new(null); - collection.Add(value1); - Assert.Same(value1, Assert.Single(collection)); - Assert.Same(value1, collection[0]); - Assert.True(collection.Contains(value1)); - Assert.Equal(0, collection.IndexOf(value1)); - - DesignerActionList value2 = new(null); - collection.Add(value2); - Assert.Equal(new object[] { value1, value2 }, collection.Cast()); - Assert.True(collection.Contains(value2)); - Assert.Equal(1, collection.IndexOf(value2)); - - collection.Add(null); - Assert.Equal(new object[] { value1, value2, null }, collection.Cast()); - Assert.True(collection.Contains(null)); - Assert.Equal(2, collection.IndexOf(null)); - } - - [Theory] - [MemberData(nameof(Ctor_DesignerActionListArray_TestData))] - public void DesignerActionListCollection_AddRange_DesignerActionListArray_Success(DesignerActionList[] value) - { - DesignerActionListCollection collection = new(); - collection.AddRange(value); - Assert.Equal(value, collection.Cast()); - - // Add again. - collection.AddRange(value); - Assert.Equal(value.Concat(value), collection.Cast()); - } - - [Theory] - [MemberData(nameof(Ctor_DesignerActionListArray_TestData))] - public void DesignerActionListCollection_AddRange_DesignerActionListCollection_Success(DesignerActionList[] value) - { - DesignerActionListCollection collection = new(); - collection.AddRange(new DesignerActionListCollection(value)); - Assert.Equal(value, collection.Cast()); - - // Add again. - collection.AddRange(new DesignerActionListCollection(value)); - Assert.Equal(value.Concat(value), collection.Cast()); - } - - [Fact] - public void DesignerActionListCollection_AddRange_NullValue_ThrowsArgumentNullException() - { - DesignerActionListCollection collection = new(); - Assert.Throws("value", () => collection.AddRange((DesignerActionList[])null)); - Assert.Throws("value", () => collection.AddRange((DesignerActionListCollection)null)); - } - - [Fact] - public void DesignerActionListCollection_Insert_DesignerActionList_Success() - { - DesignerActionListCollection collection = new(); - - DesignerActionList value1 = new(null); - collection.Insert(0, value1); - Assert.Same(value1, Assert.Single(collection)); - Assert.Same(value1, collection[0]); - Assert.True(collection.Contains(value1)); - Assert.Equal(0, collection.IndexOf(value1)); - - DesignerActionList value2 = new(null); - collection.Insert(0, value2); - Assert.Equal(new object[] { value2, value1 }, collection.Cast()); - Assert.True(collection.Contains(value2)); - Assert.Equal(0, collection.IndexOf(value2)); - - collection.Insert(1, null); - Assert.Equal(new object[] { value2, null, value1 }, collection.Cast()); - Assert.True(collection.Contains(null)); - Assert.Equal(1, collection.IndexOf(null)); - } - - [Fact] - public void DesignerActionListCollection_Remove_Invoke_Success() - { - DesignerActionListCollection collection = new(); - DesignerActionList value = new(null); - collection.Add(value); - Assert.Same(value, Assert.Single(collection)); - - collection.Remove(value); - Assert.Empty(collection); - Assert.False(collection.Contains(value)); - Assert.Equal(-1, collection.IndexOf(value)); - - collection.Add(null); - collection.Remove(null); - Assert.Empty(collection); - Assert.False(collection.Contains(null)); - Assert.Equal(-1, collection.IndexOf(null)); - } - - [Fact] - public void DesignerActionListCollection_Item_Set_GetReturnsExpected() - { - DesignerActionListCollection collection = new(); - DesignerActionList value1 = new(null); - DesignerActionList value2 = new(null); - collection.Add(value1); - Assert.Same(value1, Assert.Single(collection)); - - collection[0] = value2; - Assert.Same(value2, Assert.Single(collection)); - Assert.Same(value2, collection[0]); - Assert.False(collection.Contains(value1)); - Assert.Equal(-1, collection.IndexOf(value1)); - Assert.True(collection.Contains(value2)); - Assert.Equal(0, collection.IndexOf(value2)); - - collection[0] = null; - Assert.Null(Assert.Single(collection)); - Assert.Null(collection[0]); - Assert.False(collection.Contains(value2)); - Assert.Equal(-1, collection.IndexOf(value2)); - Assert.True(collection.Contains(null)); - Assert.Equal(0, collection.IndexOf(null)); - } - - [Fact] - public void DesignerActionListCollection_CopyTo_Invoke_Success() - { - DesignerActionListCollection collection = new(); - DesignerActionList value = new(null); - collection.Add(value); - - var array = new DesignerActionList[3]; - collection.CopyTo(array, 1); - Assert.Equal(new DesignerActionList[] { null, value, null }, array); - } - - [Fact] - public void DesignerActionListCollection_Contains_NoSuchValue_ReturnsFalse() - { - DesignerActionListCollection collection = new(); - DesignerActionList value = new(null); - collection.Add(value); - - Assert.False(collection.Contains(new DesignerActionList(null))); - Assert.False(collection.Contains(null)); - } - - [Fact] - public void DesignerActionListCollection_IndexOf_NoSuchValue_ReturnsNegativeOne() - { - DesignerActionListCollection collection = new(); - DesignerActionList value = new(null); - collection.Add(value); - - Assert.Equal(-1, collection.IndexOf(new DesignerActionList(null))); - Assert.Equal(-1, collection.IndexOf(null)); - } - - [Fact] - public void DesignerActionListCollection_Clear_Success() - { - DesignerActionListCollection collection = new(); - DesignerActionList value = new(null); - collection.Add(value); - - collection.Clear(); - Assert.Empty(collection); - - // Clear again. - collection.Clear(); - Assert.Empty(collection); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionListTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionListTests.cs deleted file mode 100644 index 3bc45ebbb20..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionListTests.cs +++ /dev/null @@ -1,198 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; -using Moq; - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionListTests -{ - public static IEnumerable Ctor_IComponent_TestDat() - { - yield return new object[] { null }; - yield return new object[] { new Component() }; - } - - [Theory] - [MemberData(nameof(Ctor_IComponent_TestDat))] - public void DesignerActionList_Ctor_IComponent(IComponent component) - { - DesignerActionList list = new(component); - Assert.Equal(component, list.Component); - Assert.False(list.AutoShow); - } - - [Theory] - [BoolData] - public void DesignerActionList_AutoShow_Set_GetReturnsExpected(bool value) - { - DesignerActionList list = new(new Component()) - { - AutoShow = value - }; - Assert.Equal(value, list.AutoShow); - - // Set same. - list.AutoShow = value; - Assert.Equal(value, list.AutoShow); - } - - public static IEnumerable GetService_TestData() - { - yield return new object[] { null, null }; - yield return new object[] { new Component(), null }; - - object o = new(); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.GetService(typeof(int))) - .Returns(o); - mockSite - .Setup(s => s.Container) - .Returns((IContainer)null); - yield return new object[] { new Component { Site = mockSite.Object }, o }; - } - - [Theory] - [MemberData(nameof(GetService_TestData))] - public void DesignerActionList_GetService_Invoke_ReturnsExpected(Component component, object expected) - { - DesignerActionList list = new(component); - Assert.Equal(expected, list.GetService(typeof(int))); - } - - [Fact] - public void DesignerActionList_GetSortedActionItems_CustomClass_ReturnsExpected() - { - SubDesignerActionList list = new(); - DesignerActionItemCollection items = list.GetSortedActionItems(); - Assert.Equal(8, items.Count); - - DesignerActionMethodItem item1 = Assert.IsType(items[0]); - Assert.Equal("AnnotatedMethod", item1.MemberName); - Assert.Equal("DisplayName", item1.DisplayName); - Assert.Equal("Description", item1.Description); - Assert.Equal("Category", item1.Category); - - DesignerActionPropertyItem item2 = Assert.IsType(items[1]); - Assert.Equal("AnnotatedProperty", item2.MemberName); - Assert.Equal("DisplayName", item2.DisplayName); - Assert.Equal("Description", item2.Description); - Assert.Equal("Category", item2.Category); - - DesignerActionMethodItem item3 = Assert.IsType(items[2]); - Assert.Equal("EmptyAnnotatedMethod", item3.MemberName); - Assert.Equal("EmptyAnnotatedMethod", item3.DisplayName); - Assert.Empty(item3.Description); - Assert.Empty(item3.Category); - - DesignerActionPropertyItem item4 = Assert.IsType(items[3]); - Assert.Equal("EmptyAnnotatedProperty", item4.MemberName); - Assert.Equal("EmptyAnnotatedProperty", item4.DisplayName); - Assert.Empty(item4.Description); - Assert.Empty(item4.Category); - - DesignerActionMethodItem item5 = Assert.IsType(items[4]); - Assert.Equal("NullAnnotatedMethod", item5.MemberName); - Assert.Equal("NullAnnotatedMethod", item5.DisplayName); - Assert.Null(item5.Description); - Assert.Null(item5.Category); - - DesignerActionPropertyItem item6 = Assert.IsType(items[5]); - Assert.Equal("NullAnnotatedProperty", item6.MemberName); - Assert.Equal("NullAnnotatedProperty", item6.DisplayName); - Assert.Null(item6.Description); - Assert.Null(item6.Category); - - DesignerActionMethodItem item7 = Assert.IsType(items[6]); - Assert.Equal("PublicMethod", item7.MemberName); - Assert.Equal("PublicMethod", item7.DisplayName); - Assert.Empty(item7.Description); - Assert.Empty(item7.Category); - - DesignerActionPropertyItem item8 = Assert.IsType(items[7]); - Assert.Equal("PublicProperty", item8.MemberName); - Assert.Equal("PublicProperty", item8.DisplayName); - Assert.Empty(item8.Description); - Assert.Empty(item8.Category); - } - - [Fact] - public void DesignerActionList_GetSortedActionItems_BaseClass_ReturnsEmpty() - { - DesignerActionList list = new(null); - DesignerActionItemCollection items = list.GetSortedActionItems(); - Assert.Empty(items); - } - - private class SubDesignerActionList : DesignerActionList - { - public SubDesignerActionList() : base(null) - { - } - - public void PublicMethod() - { - } - - [Description("Description")] - [DisplayName("DisplayName")] - [Category("Category")] - public void AnnotatedMethod() - { - } - - [Description("")] - [DisplayName("")] - [Category("")] - public void EmptyAnnotatedMethod() - { - } - - [Description(null)] - [DisplayName(null)] - [Category(null)] - public void NullAnnotatedMethod() - { - } - - private void PrivateMethod() - { - } - - public void MethodWithParameters(object o) - { - } - - [SpecialName] - public void MethodWithSpecialName() - { - } - - public static void StaticMethod() - { - } - - public int PublicProperty { get; set; } - - [Description("Description")] - [DisplayName("DisplayName")] - [Category("Category")] - public int AnnotatedProperty { get; set; } - - [Description("")] - [DisplayName("")] - [Category("")] - public int EmptyAnnotatedProperty { get; set; } - - [Description(null)] - [DisplayName(null)] - [Category(null)] - public int NullAnnotatedProperty { get; set; } - - private int PrivateProperty { get; set; } - - public static int StaticProperty { get; set; } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionListsChangedEventArgsTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionListsChangedEventArgsTests.cs deleted file mode 100644 index 8552fd326e4..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionListsChangedEventArgsTests.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionListsChangedEventArgsTests -{ - public static IEnumerable Ctor_Object_DesignerActionListsChangedType_DesignerActionListCollection_TestData() - { - yield return new object[] { null, DesignerActionListsChangedType.ActionListsAdded - 1, null }; - yield return new object[] { new object(), DesignerActionListsChangedType.ActionListsAdded, new DesignerActionListCollection() }; - } - - [Theory] - [MemberData(nameof(Ctor_Object_DesignerActionListsChangedType_DesignerActionListCollection_TestData))] - public void Ctor_Object_DesignerActionListsChangedType_DesignerActionListCollection(object relatedObject, DesignerActionListsChangedType changeType, DesignerActionListCollection actionLists) - { - DesignerActionListsChangedEventArgs e = new(relatedObject, changeType, actionLists); - Assert.Same(relatedObject, e.RelatedObject); - Assert.Equal(changeType, e.ChangeType); - Assert.Same(actionLists, e.ActionLists); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionMethodItemTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionMethodItemTests.cs deleted file mode 100644 index c8f934527bf..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionMethodItemTests.cs +++ /dev/null @@ -1,268 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Specialized; -using System.Reflection; - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionMethodItemTests -{ - public static IEnumerable Ctor_DesignerActionList_String_String_String_String_Bool_TestData() - { - yield return new object[] { new DesignerActionList(null), "memberName", "displayName", "category", "description", false, "displayName" }; - yield return new object[] { new DesignerActionList(null), "member(&a)Name", "displa(&a)yName", "cate(&a)gory", "description", true, "displayName" }; - yield return new object[] { null, string.Empty, string.Empty, string.Empty, string.Empty, false, string.Empty }; - yield return new object[] { null, null, null, null, null, false, null }; - } - - [Theory] - [MemberData(nameof(Ctor_DesignerActionList_String_String_String_String_Bool_TestData))] - public void DesignerActionMethodItem_Ctor_DesignerActionList_String_String_String_String_Bool(DesignerActionList actionList, string memberName, string displayName, string category, string description, bool includeAsDesignerVerb, string expectedDisplayName) - { - DesignerActionMethodItem item = new(actionList, memberName, displayName, category, description, includeAsDesignerVerb); - Assert.Equal(memberName, item.MemberName); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Equal(category, item.Category); - Assert.Equal(description, item.Description); - Assert.Equal(includeAsDesignerVerb, item.IncludeAsDesignerVerb); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - Assert.Null(item.RelatedComponent); - } - - public static IEnumerable Ctor_DesignerActionList_String_String_String_String_TestData() - { - yield return new object[] { new DesignerActionList(null), "memberName", "displayName", "category", "description", "displayName" }; - yield return new object[] { new DesignerActionList(null), "member(&a)Name", "displa(&a)yName", "cate(&a)gory", "description", "displayName" }; - yield return new object[] { null, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty }; - yield return new object[] { null, null, null, null, null, null }; - } - - [Theory] - [MemberData(nameof(Ctor_DesignerActionList_String_String_String_String_TestData))] - public void DesignerActionMethodItem_Ctor_DesignerActionList_String_String_String_String(DesignerActionList actionList, string memberName, string displayName, string category, string description, string expectedDisplayName) - { - DesignerActionMethodItem item = new(actionList, memberName, displayName, category, description); - Assert.Equal(memberName, item.MemberName); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Equal(category, item.Category); - Assert.Equal(description, item.Description); - Assert.False(item.IncludeAsDesignerVerb); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - Assert.Null(item.RelatedComponent); - } - - public static IEnumerable Ctor_DesignerActionList_String_String_String_Bool_TestData() - { - yield return new object[] { new DesignerActionList(null), "memberName", "displayName", "category", false, "displayName" }; - yield return new object[] { new DesignerActionList(null), "member(&a)Name", "displa(&a)yName", "cate(&a)gory", true, "displayName" }; - yield return new object[] { null, string.Empty, string.Empty, string.Empty, false, string.Empty }; - yield return new object[] { null, null, null, null, false, null }; - } - - [Theory] - [MemberData(nameof(Ctor_DesignerActionList_String_String_String_Bool_TestData))] - public void DesignerActionMethodItem_Ctor_DesignerActionList_String_String_String_Bool(DesignerActionList actionList, string memberName, string displayName, string category, bool includeAsDesignerVerb, string expectedDisplayName) - { - DesignerActionMethodItem item = new(actionList, memberName, displayName, category, includeAsDesignerVerb); - Assert.Equal(memberName, item.MemberName); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Equal(category, item.Category); - Assert.Null(item.Description); - Assert.Equal(includeAsDesignerVerb, item.IncludeAsDesignerVerb); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - Assert.Null(item.RelatedComponent); - } - - public static IEnumerable Ctor_DesignerActionList_String_String_String_TestData() - { - yield return new object[] { new DesignerActionList(null), "memberName", "displayName", "category", "displayName" }; - yield return new object[] { new DesignerActionList(null), "member(&a)Name", "displa(&a)yName", "cate(&a)gory", "displayName" }; - yield return new object[] { null, string.Empty, string.Empty, string.Empty, string.Empty }; - yield return new object[] { null, null, null, null, null }; - } - - [Theory] - [MemberData(nameof(Ctor_DesignerActionList_String_String_String_TestData))] - public void DesignerActionMethodItem_Ctor_DesignerActionList_String_String_String(DesignerActionList actionList, string memberName, string displayName, string category, string expectedDisplayName) - { - DesignerActionMethodItem item = new(actionList, memberName, displayName, category); - Assert.Equal(memberName, item.MemberName); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Equal(category, item.Category); - Assert.Null(item.Description); - Assert.False(item.IncludeAsDesignerVerb); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - Assert.Null(item.RelatedComponent); - } - - public static IEnumerable Ctor_DesignerActionList_String_String_Bool_TestData() - { - yield return new object[] { new DesignerActionList(null), "memberName", "displayName", false, "displayName" }; - yield return new object[] { new DesignerActionList(null), "member(&a)Name", "displa(&a)yName", true, "displayName" }; - yield return new object[] { null, string.Empty, string.Empty, false, string.Empty }; - yield return new object[] { null, null, null, false, null }; - } - - [Theory] - [MemberData(nameof(Ctor_DesignerActionList_String_String_Bool_TestData))] - public void DesignerActionMethodItem_Ctor_DesignerActionList_String_String_Bool(DesignerActionList actionList, string memberName, string displayName, bool includeAsDesignerVerb, string expectedDisplayName) - { - DesignerActionMethodItem item = new(actionList, memberName, displayName, includeAsDesignerVerb); - Assert.Equal(memberName, item.MemberName); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Null(item.Category); - Assert.Null(item.Description); - Assert.Equal(includeAsDesignerVerb, item.IncludeAsDesignerVerb); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - Assert.Null(item.RelatedComponent); - } - - public static IEnumerable Ctor_DesignerActionList_String_String_TestData() - { - yield return new object[] { new DesignerActionList(null), "memberName", "displayName", "displayName" }; - yield return new object[] { new DesignerActionList(null), "member(&a)Name", "displa(&a)yName", "displayName" }; - yield return new object[] { null, string.Empty, string.Empty, string.Empty }; - yield return new object[] { null, null, null, null }; - } - - [Theory] - [MemberData(nameof(Ctor_DesignerActionList_String_String_TestData))] - public void DesignerActionMethodItem_Ctor_DesignerActionList_String_String(DesignerActionList actionList, string memberName, string displayName, string expectedDisplayName) - { - DesignerActionMethodItem item = new(actionList, memberName, displayName); - Assert.Equal(memberName, item.MemberName); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Null(item.Category); - Assert.Null(item.Description); - Assert.False(item.IncludeAsDesignerVerb); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - Assert.Null(item.RelatedComponent); - } - - public static IEnumerable RelatedComponent_Set_TestData() - { - yield return new object[] { new Component() }; - yield return new object[] { null }; - } - - [Theory] - [MemberData(nameof(RelatedComponent_Set_TestData))] - public void DesignerActionMethodItem_RelatedComponent_Set_GetReturnsExpected(IComponent value) - { - DesignerActionMethodItem item = new(null, "memberName", "displayName", "category", "description") - { - RelatedComponent = value - }; - Assert.Same(value, item.RelatedComponent); - - // Set same. - item.RelatedComponent = value; - Assert.Same(value, item.RelatedComponent); - } - - [Theory] - [InlineData(nameof(SubDesignerActionList.PublicMethod))] - [InlineData("PrivateMethod")] - public void Invoke_ValidMemberName_ReturnsExpected(string memberName) - { - SubDesignerActionList list = new(); - DesignerActionMethodItem item = new(list, memberName, "displayName", "category", "description"); - item.Invoke(); - Assert.Equal(memberName, list.CalledMethod); - - // Call again to test caching behaviour. - list.CalledMethod = null; - item.Invoke(); - Assert.Equal(memberName, list.CalledMethod); - } - - [Fact] - public void Invoke_NullActionList_ThrowsInvalidOperationException() - { - DesignerActionMethodItem item = new(null, "memberName", "displayName", "category", "description"); - Assert.Throws(() => item.Invoke()); - } - - [Theory] - [InlineData("")] - [InlineData("NoSuchMember")] - [InlineData(nameof(SubDesignerActionList.StaticMethod))] - public void Invoke_NoSuchMemberName_ThrowsInvalidOperationException(string memberName) - { - SubDesignerActionList list = new(); - DesignerActionMethodItem item = new(list, memberName, "displayName", "category", "description"); - Assert.Throws(() => item.Invoke()); - } - - [Fact] - public void Invoke_NullMemberName_ThrowsArgumentNullException() - { - SubDesignerActionList list = new(); - DesignerActionMethodItem item = new(list, null, "displayName", "category", "description"); - Assert.Throws("name", () => item.Invoke()); - } - - [Fact] - public void Invoke_MemberWithParameters_ThrowsTargetParameterCountException() - { - SubDesignerActionList list = new(); - DesignerActionMethodItem item = new(list, nameof(SubDesignerActionList.MethodWithParameters), "displayName", "category", "description"); - Assert.Throws(() => item.Invoke()); - } - - private class SubDesignerActionList : DesignerActionList - { - public SubDesignerActionList() : base(null) - { - } - - public string CalledMethod { get; set; } - - public void PublicMethod() - { - Assert.Null(CalledMethod); - CalledMethod = nameof(PublicMethod); - } - - private void PrivateMethod() - { - Assert.Null(CalledMethod); - CalledMethod = nameof(PrivateMethod); - } - - public static void StaticMethod() - { - throw new InvalidOperationException(); - } - - public void MethodWithParameters(object o) - { - throw new InvalidOperationException(); - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionPropertyItemTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionPropertyItemTests.cs deleted file mode 100644 index e2ae8200248..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionPropertyItemTests.cs +++ /dev/null @@ -1,90 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Specialized; - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionPropertyItemTests -{ - [Theory] - [InlineData("memberName", "displayName", "category", "description", "displayName")] - [InlineData("member(&a)Name", "displa(&a)yName", "cate(&a)gory", "descr(&a)iption", "displayName")] - [InlineData("", "", "", "", "")] - [InlineData(null, null, null, null, null)] - public void DesignerActionPropertyItem_Ctor_String_String_String_String(string memberName, string displayName, string category, string description, string expectedDisplayName) - { - DesignerActionPropertyItem item = new(memberName, displayName, category, description); - Assert.Equal(memberName, item.MemberName); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Equal(category, item.Category); - Assert.Equal(description, item.Description); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - Assert.Null(item.RelatedComponent); - } - - [Theory] - [InlineData("memberName", "displayName", "category", "displayName")] - [InlineData("member(&a)Name", "displa(&a)yName", "cate(&a)gory", "displayName")] - [InlineData("", "", "", "")] - [InlineData(null, null, null, null)] - public void DesignerActionPropertyItem_Ctor_String_String_String(string memberName, string displayName, string category, string expectedDisplayName) - { - DesignerActionPropertyItem item = new(memberName, displayName, category); - Assert.Equal(memberName, item.MemberName); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Equal(category, item.Category); - Assert.Null(item.Description); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - Assert.Null(item.RelatedComponent); - } - - [Theory] - [InlineData("memberName", "displayName", "displayName")] - [InlineData("member(&a)Name", "displa(&a)yName", "displayName")] - [InlineData("", "", "")] - [InlineData(null, null, null)] - public void DesignerActionPropertyItem_Ctor_String_String(string memberName, string displayName, string expectedDisplayName) - { - DesignerActionPropertyItem item = new(memberName, displayName); - Assert.Equal(memberName, item.MemberName); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Null(item.Category); - Assert.Null(item.Description); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - Assert.Null(item.RelatedComponent); - } - - public static IEnumerable RelatedComponent_Set_TestData() - { - yield return new object[] { new Component() }; - yield return new object[] { null }; - } - - [Theory] - [MemberData(nameof(RelatedComponent_Set_TestData))] - public void DesignerActionPropertyItem_RelatedComponent_Set_GetReturnsExpected(IComponent value) - { - DesignerActionPropertyItem item = new("memberName", "displayName", "category", "description") - { - RelatedComponent = value - }; - Assert.Same(value, item.RelatedComponent); - - // Set same. - item.RelatedComponent = value; - Assert.Same(value, item.RelatedComponent); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionServiceTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionServiceTests.cs deleted file mode 100644 index b925d15d202..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionServiceTests.cs +++ /dev/null @@ -1,1079 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Collections.Specialized; -using System.Windows.Forms.Design; -using Moq; - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionServiceTests -{ - [Fact] - public void Ctor_IServiceProvider() - { - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.AddService(typeof(DesignerActionService), It.IsAny())) - .Verifiable(); - Mock mockComponentChangeService = new(MockBehavior.Strict); - Mock mockSelectionService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(IComponentChangeService))) - .Returns(mockComponentChangeService.Object) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object) - .Verifiable(); - DesignerActionService service = new(mockServiceProvider.Object); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerHost)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IComponentChangeService)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(ISelectionService)), Times.Once()); - mockDesignerHost.Verify(h => h.AddService(typeof(DesignerActionService), service), Times.Once()); - } - - public static IEnumerable Add_ComponentDesignerActionList_TestData() - { - CustomDesignerActionList actionList = new(null); - yield return new object[] { null, new DesignerActionListCollection() }; - yield return new object[] { new DesignerActionList(null), new DesignerActionListCollection() }; - yield return new object[] { new NullCustomDesignerActionList(null), new DesignerActionListCollection() }; - yield return new object[] { actionList, new DesignerActionListCollection { actionList } }; - } - - [Theory] - [MemberData(nameof(Add_ComponentDesignerActionList_TestData))] - public void Add_ComponentDesignerActionList_Success(DesignerActionList actionList, DesignerActionListCollection expected) - { - SubDesignerActionService service = new(null); - using Component component = new(); - service.Add(component, actionList); - Assert.True(service.Contains(component)); - Assert.Equal(expected, service.GetComponentActions(component)); - Assert.Equal(expected, service.GetComponentActions(component, ComponentActionsType.All)); - Assert.Equal(expected, service.GetComponentActions(component, ComponentActionsType.Service)); - Assert.Empty(service.GetComponentActions(component, ComponentActionsType.Component)); - - DesignerActionListCollection actionListBuffer1 = new(); - service.GetComponentDesignerActions(component, actionListBuffer1); - Assert.Empty(actionListBuffer1); - - DesignerActionListCollection actionListBuffer2 = new(); - service.GetComponentServiceActions(component, actionListBuffer2); - Assert.Equal(expected, actionListBuffer2); - } - - [Fact] - public void Add_ComponentDesignerActionListExisting_Success() - { - SubDesignerActionService service = new(null); - Component component = new(); - CustomDesignerActionList actionList1 = new(null); - CustomDesignerActionList actionList2 = new(null); - service.Add(component, actionList1); - service.Add(component, actionList2); - service.Add(component, (DesignerActionList)null); - - Assert.True(service.Contains(component)); - Assert.Equal(new DesignerActionListCollection { actionList1, actionList2 }, service.GetComponentActions(component)); - Assert.Equal(new DesignerActionListCollection { actionList1, actionList2 }, service.GetComponentActions(component, ComponentActionsType.All)); - Assert.Equal(new DesignerActionListCollection { actionList1, actionList2 }, service.GetComponentActions(component, ComponentActionsType.Service)); - Assert.Empty(service.GetComponentActions(component, ComponentActionsType.Component)); - - DesignerActionListCollection actionListBuffer1 = new(); - service.GetComponentDesignerActions(component, actionListBuffer1); - Assert.Empty(actionListBuffer1); - - DesignerActionListCollection actionListBuffer2 = new(); - service.GetComponentServiceActions(component, actionListBuffer2); - Assert.Equal(new DesignerActionListCollection { actionList1, actionList2 }, actionListBuffer2); - } - - [Fact] - public void Add_NullComponent_ThrowsArgumentNullException() - { - DesignerActionService service = new(null); - Assert.Throws("comp", () => service.Add((IComponent)null, (DesignerActionListCollection)null)); - Assert.Throws("comp", () => service.Add((IComponent)null, (DesignerActionList)null)); - } - - [Theory] - [MemberData(nameof(Add_ComponentDesignerActionList_TestData))] - public void Add_ComponentDesignerActionListCollection_Success(DesignerActionList actionList, DesignerActionListCollection expected) - { - SubDesignerActionService service = new(null); - using Component component = new(); - service.Add(component, new DesignerActionListCollection { actionList }); - Assert.True(service.Contains(component)); - Assert.Equal(expected, service.GetComponentActions(component)); - Assert.Equal(expected, service.GetComponentActions(component, ComponentActionsType.All)); - Assert.Equal(expected, service.GetComponentActions(component, ComponentActionsType.Service)); - Assert.Empty(service.GetComponentActions(component, ComponentActionsType.Component)); - - DesignerActionListCollection actionListBuffer1 = new(); - service.GetComponentDesignerActions(component, actionListBuffer1); - Assert.Empty(actionListBuffer1); - - DesignerActionListCollection actionListBuffer2 = new(); - service.GetComponentServiceActions(component, actionListBuffer2); - Assert.Equal(expected, actionListBuffer2); - } - - [Fact] - public void Add_ComponentDesignerActionListCollectionExisting_Success() - { - SubDesignerActionService service = new(null); - using Component component = new(); - CustomDesignerActionList actionList1 = new(null); - CustomDesignerActionList actionList2 = new(null); - service.Add(component, new DesignerActionListCollection { actionList1 }); - service.Add(component, new DesignerActionListCollection { actionList2 }); - service.Add(component, new DesignerActionListCollection { (DesignerActionList)null }); - - Assert.True(service.Contains(component)); - Assert.Equal(new DesignerActionListCollection { actionList1, actionList2 }, service.GetComponentActions(component)); - Assert.Equal(new DesignerActionListCollection { actionList1, actionList2 }, service.GetComponentActions(component, ComponentActionsType.All)); - Assert.Equal(new DesignerActionListCollection { actionList1, actionList2 }, service.GetComponentActions(component, ComponentActionsType.Service)); - Assert.Empty(service.GetComponentActions(component, ComponentActionsType.Component)); - - DesignerActionListCollection actionListBuffer1 = new(); - service.GetComponentDesignerActions(component, actionListBuffer1); - Assert.Empty(actionListBuffer1); - - DesignerActionListCollection actionListBuffer2 = new(); - service.GetComponentServiceActions(component, actionListBuffer2); - Assert.Equal(new DesignerActionListCollection { actionList1, actionList2 }, actionListBuffer2); - } - - [Fact] - public void Add_NullDesignerActionListCollection_ThrowsArgumentNullException() - { - DesignerActionService service = new(null); - Assert.Throws("designerActionListCollection", () => service.Add(new Component(), (DesignerActionListCollection)null)); - } - - [Fact] - public void Clear_NotEmpty_Success() - { - SubDesignerActionService service = new(null); - Component component = new(); - service.Add(component, new CustomDesignerActionList(null)); - Assert.NotEmpty(service.GetComponentActions(component)); - Assert.True(service.Contains(component)); - - service.Clear(); - Assert.Empty(service.GetComponentActions(component)); - Assert.False(service.Contains(component)); - - // Clear again. - service.Clear(); - Assert.Empty(service.GetComponentActions(component)); - Assert.False(service.Contains(component)); - } - - [Fact] - public void Clear_Empty_Success() - { - SubDesignerActionService service = new(null); - service.Clear(); - - // Clear again. - service.Clear(); - } - - [Fact] - public void Clear_InvokeWithDesignerActionListsChanged_CallsHandler() - { - SubDesignerActionService service = new(null); - using Component component1 = new(); - using Component component2 = new(); - CustomDesignerActionList actionList = new(null); - service.Add(component1, actionList); - service.Add(component2, new DesignerActionListCollection()); - - int callCount = 0; - DesignerActionListsChangedEventHandler handler = (sender, e) => - { - Assert.Same(service, sender); - Assert.True(e.RelatedObject == component1 || e.RelatedObject == component2); - Assert.Equal(DesignerActionListsChangedType.ActionListsRemoved, e.ChangeType); - //Assert.Same(actionList, Assert.Single(e.ActionLists)); - callCount++; - }; - service.DesignerActionListsChanged += handler; - - service.Clear(); - Assert.Equal(2, callCount); - - // Remove again. - service.Clear(); - Assert.Equal(2, callCount); - - // Remove handler. - service.DesignerActionListsChanged -= handler; - service.Add(component1, actionList); - service.Add(component2, new DesignerActionListCollection()); - service.Remove(component2); - Assert.Equal(2, callCount); - } - - [Fact] - public void Contains_NoSuchComponentEmpty_ReturnsFalse() - { - DesignerActionService service = new(null); - Assert.False(service.Contains(new Component())); - } - - [Fact] - public void Contains_NoSuchComponentNotEmpty_ReturnsFalse() - { - DesignerActionService service = new(null); - service.Add(new Component(), new DesignerActionListCollection()); - Assert.False(service.Contains(new Component())); - } - - [Fact] - public void Contains_NullComponent_ThrowsArgumentNullException() - { - DesignerActionService service = new(null); - Assert.Throws("comp", () => service.Contains(null)); - } - - [Fact] - public void Dispose_Invoke_Success() - { - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.AddService(typeof(DesignerActionService), It.IsAny())); - mockDesignerHost - .Setup(h => h.RemoveService(typeof(DesignerActionService))); - Mock mockComponentChangeService = new(MockBehavior.Strict); - Mock mockSelectionService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockServiceProvider - .Setup(p => p.GetService(typeof(IComponentChangeService))) - .Returns(mockComponentChangeService.Object); - mockServiceProvider - .Setup(p => p.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object); - DesignerActionService service = new(mockServiceProvider.Object); - service.Dispose(); - mockDesignerHost.Verify(h => h.RemoveService(typeof(DesignerActionService)), Times.Once()); - - // Dispose again. - service.Dispose(); - mockDesignerHost.Verify(h => h.RemoveService(typeof(DesignerActionService)), Times.Exactly(2)); - } - - [Theory] - [InlineData(true, 1)] - [InlineData(false, 0)] - public void Dispose_InvokeDisposing_Success(bool disposing, int expectedRemoveCallCount) - { - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.AddService(typeof(DesignerActionService), It.IsAny())); - mockDesignerHost - .Setup(h => h.RemoveService(typeof(DesignerActionService))); - Mock mockComponentChangeService = new(MockBehavior.Strict); - Mock mockSelectionService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockServiceProvider - .Setup(p => p.GetService(typeof(IComponentChangeService))) - .Returns(mockComponentChangeService.Object); - mockServiceProvider - .Setup(p => p.GetService(typeof(ISelectionService))) - .Returns(mockSelectionService.Object); - SubDesignerActionService service = new(mockServiceProvider.Object); - service.Dispose(disposing); - mockDesignerHost.Verify(h => h.RemoveService(typeof(DesignerActionService)), Times.Exactly(expectedRemoveCallCount)); - - // Dispose again. - service.Dispose(disposing); - mockDesignerHost.Verify(h => h.RemoveService(typeof(DesignerActionService)), Times.Exactly(expectedRemoveCallCount * 2)); - } - - public static IEnumerable Dispose_InvalidServiceProvider_TestData() - { - yield return new object[] { null }; - - Mock nullMockServiceProvider = new(MockBehavior.Strict); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns((IDesignerHost)null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(IComponentChangeService))) - .Returns((IComponentChangeService)null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(ISelectionService))) - .Returns((IComponentChangeService)null); - yield return new object[] { nullMockServiceProvider.Object }; - - Mock invalidMockServiceProvider = new(MockBehavior.Strict); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(new object()); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(IComponentChangeService))) - .Returns(new object()); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ISelectionService))) - .Returns(new object()); - yield return new object[] { invalidMockServiceProvider.Object }; - } - - [Theory] - [MemberData(nameof(Dispose_InvalidServiceProvider_TestData))] - public void Dispose_InvalidServiceProvider_Success(IServiceProvider serviceProvider) - { - DesignerActionService service = new(serviceProvider); - service.Dispose(); - - // Dispose again. - service.Dispose(); - } - - [Theory] - [EnumData] - [InvalidEnumData] - public void GetComponentActions_NoSuchComponentNotEmpty_ReturnsEmpty(ComponentActionsType type) - { - SubDesignerActionService service = new(null); - using Component component = new(); - CustomDesignerActionList actionList = new(null); - service.Add(component, actionList); - Assert.Empty(service.GetComponentActions(new Component(), type)); - Assert.Empty(service.GetComponentActions(new Component(), type)); - } - - [Theory] - [EnumData] - [InvalidEnumData] - public void GetComponentActions_NoSuchComponentEmpty_ReturnsEmpty(ComponentActionsType type) - { - SubDesignerActionService service = new(null); - Assert.Empty(service.GetComponentActions(new Component(), type)); - } - - [Theory] - [InvalidEnumData] - public void GetComponentActions_NoSuchAction_ReturnsEmpty(ComponentActionsType type) - { - SubDesignerActionService service = new(null); - using Component component = new(); - CustomDesignerActionList actionList = new(null); - service.Add(component, actionList); - Assert.Empty(service.GetComponentActions(component, type)); - } - - [Fact] - public void GetComponentActions_NullComponent_ThrowsArgumentNullException() - { - DesignerActionService service = new(null); - Assert.Throws("component", () => service.GetComponentActions(null)); - Assert.Throws("component", () => service.GetComponentActions(null, ComponentActionsType.All)); - } - - public static IEnumerable GetComponentDesignerActions_TestData() - { - yield return new object[] { null, new DesignerActionListCollection() }; - - Mock mockSite = new(MockBehavior.Strict); - yield return new object[] { mockSite.Object, new DesignerActionListCollection() }; - - Mock nullMockSite = new(MockBehavior.Strict); - nullMockSite - .As() - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(null); - yield return new object[] { nullMockSite.Object, new DesignerActionListCollection() }; - - Mock invalidMockSite = new(MockBehavior.Strict); - invalidMockSite - .As() - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(new object()); - yield return new object[] { invalidMockSite.Object, new DesignerActionListCollection() }; - - Mock nullMockDesignerCommandSet = new(MockBehavior.Strict); - nullMockDesignerCommandSet - .Setup(c => c.GetCommands("ActionLists")) - .Returns((ICollection)null); - nullMockDesignerCommandSet - .Setup(c => c.GetCommands("Verbs")) - .Returns((ICollection)null); - Mock nullCommandSetMockSite = new(MockBehavior.Strict); - nullCommandSetMockSite - .As() - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(nullMockDesignerCommandSet.Object); - yield return new object[] { nullCommandSetMockSite.Object, new DesignerActionListCollection() }; - - Mock emptyMockDesignerCommandSet = new(MockBehavior.Strict); - emptyMockDesignerCommandSet - .Setup(c => c.GetCommands("ActionLists")) - .Returns(new DesignerActionListCollection()); - emptyMockDesignerCommandSet - .Setup(c => c.GetCommands("Verbs")) - .Returns(new DesignerVerbCollection()); - Mock emptyCommandSetMockSite = new(MockBehavior.Strict); - emptyCommandSetMockSite - .As() - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(emptyMockDesignerCommandSet.Object); - yield return new object[] { emptyCommandSetMockSite.Object, new DesignerActionListCollection() }; - - DesignerVerb verb = new(null, null); - DesignerVerbCollection verbs = new() { null, verb }; - CustomDesignerActionList actionList = new(null); - DesignerActionListCollection actionLists = new() { null, new DesignerActionList(null), new NullCustomDesignerActionList(null), actionList }; - - Mock actionListsMockDesignerCommandSet = new(MockBehavior.Strict); - actionListsMockDesignerCommandSet - .Setup(c => c.GetCommands("ActionLists")) - .Returns(actionLists); - actionListsMockDesignerCommandSet - .Setup(c => c.GetCommands("Verbs")) - .Returns(verbs); - Mock actionListsCommandSetMockSite = new(MockBehavior.Strict); - actionListsCommandSetMockSite - .As() - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(actionListsMockDesignerCommandSet.Object); - yield return new object[] { actionListsCommandSetMockSite.Object, new DesignerActionListCollection { actionList } }; - } - - [Theory] - [MemberData(nameof(GetComponentDesignerActions_TestData))] - public void GetComponentDesignerActions_Invoke_ReturnsExpected(ISite site, DesignerActionListCollection expected) - { - SubDesignerActionService service = new(null); - Component component = new() - { - Site = site - }; - - DesignerActionListCollection actionListBuffer = new(); - service.GetComponentDesignerActions(component, actionListBuffer); - Assert.Equal(expected, actionListBuffer); - } - - [Fact] - public void GetComponentDesignerActions_InvokeVerbs_ReturnsExpected() - { - DesignerVerb verb = new(null, null); - DesignerVerbCollection verbs = new() { null, new DesignerVerb(null, null) { Enabled = false }, new DesignerVerb(null, null) { Visible = false }, verb }; - Mock verbsMockDesignerCommandSet = new(MockBehavior.Strict); - verbsMockDesignerCommandSet - .Setup(c => c.GetCommands("ActionLists")) - .Returns(new DesignerActionListCollection()); - verbsMockDesignerCommandSet - .Setup(c => c.GetCommands("Verbs")) - .Returns(verbs); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .As() - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(verbsMockDesignerCommandSet.Object); - SubDesignerActionService service = new(null); - Component component = new() - { - Site = mockSite.Object - }; - - DesignerActionListCollection actionListBuffer = new(); - service.GetComponentDesignerActions(component, actionListBuffer); - DesignerActionList actionList = Assert.IsAssignableFrom(Assert.Single(actionListBuffer)); - Assert.False(actionList.AutoShow); - Assert.Null(actionList.Component); - - DesignerActionItemCollection verbActionActionItems = actionList.GetSortedActionItems(); - DesignerActionMethodItem actionItem = Assert.IsAssignableFrom(Assert.Single(verbActionActionItems)); - Assert.Equal("Verbs", actionItem.Category); - Assert.False(actionItem.AllowAssociate); - Assert.Null(actionItem.Description); - Assert.False(actionItem.IncludeAsDesignerVerb); - Assert.Null(actionItem.MemberName); - Assert.Empty(actionItem.DisplayName); - Assert.Empty(actionItem.Properties); - Assert.Same(actionItem.Properties, actionItem.Properties); - Assert.IsType(actionItem.Properties); - Assert.Null(actionItem.RelatedComponent); - Assert.True(actionItem.ShowInSourceView); - } - - [Fact] - public void GetComponentDesignerActionsVerbs_GetSortedActionItems_ReturnsExpected() - { - DesignerVerb verb = new(null, null); - DesignerVerbCollection verbs = new() { null, new DesignerVerb(null, null) { Enabled = false }, new DesignerVerb(null, null) { Visible = false }, verb }; - Mock verbsMockDesignerCommandSet = new(MockBehavior.Strict); - verbsMockDesignerCommandSet - .Setup(c => c.GetCommands("ActionLists")) - .Returns(new DesignerActionListCollection()); - verbsMockDesignerCommandSet - .Setup(c => c.GetCommands("Verbs")) - .Returns(verbs); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .As() - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(verbsMockDesignerCommandSet.Object); - SubDesignerActionService service = new(null); - Component component = new() - { - Site = mockSite.Object - }; - - DesignerActionListCollection actionListBuffer = new(); - service.GetComponentDesignerActions(component, actionListBuffer); - DesignerActionList actionList = Assert.IsAssignableFrom(Assert.Single(actionListBuffer)); - Assert.Single(actionList.GetSortedActionItems()); - - // Not Disabled. - verb.Enabled = false; - Assert.Empty(actionList.GetSortedActionItems()); - verb.Enabled = true; - - // Not Visible. - verb.Visible = false; - Assert.Empty(actionList.GetSortedActionItems()); - verb.Visible = true; - - // Not Supported. - verb.Supported = false; - Assert.Empty(actionList.GetSortedActionItems()); - verb.Supported = true; - - // Back to normal. - Assert.Single(actionList.GetSortedActionItems()); - } - - [Fact] - public void GetComponentDesignerActionsVerbs_InvokeActionItem_CallsVerbInvoke() - { - DesignerVerb verb = null; - int invokeCallCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(verb, sender); - Assert.Same(EventArgs.Empty, e); - invokeCallCount++; - }; - verb = new DesignerVerb("text", handler); - - DesignerVerbCollection verbs = new() { null, new DesignerVerb(null, null) { Enabled = false }, new DesignerVerb(null, null) { Visible = false }, verb }; - Mock verbsMockDesignerCommandSet = new(MockBehavior.Strict); - verbsMockDesignerCommandSet - .Setup(c => c.GetCommands("ActionLists")) - .Returns(new DesignerActionListCollection()); - verbsMockDesignerCommandSet - .Setup(c => c.GetCommands("Verbs")) - .Returns(verbs); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .As() - .Setup(s => s.GetService(typeof(DesignerCommandSet))) - .Returns(verbsMockDesignerCommandSet.Object); - SubDesignerActionService service = new(null); - Component component = new() - { - Site = mockSite.Object - }; - - DesignerActionListCollection actionListBuffer = new(); - service.GetComponentDesignerActions(component, actionListBuffer); - DesignerActionList actionList = Assert.IsAssignableFrom(Assert.Single(actionListBuffer)); - DesignerActionItemCollection verbActionActionItems = actionList.GetSortedActionItems(); - DesignerActionMethodItem actionItem = Assert.IsAssignableFrom(Assert.Single(actionList.GetSortedActionItems())); - - Assert.Equal(0, invokeCallCount); - actionItem.Invoke(); - Assert.Equal(1, invokeCallCount); - } - - [Fact] - public void GetComponentDesignerActions_NullComponent_ThrowsArgumentNullException() - { - SubDesignerActionService service = new(null); - Assert.Throws("component", () => service.GetComponentDesignerActions(null, null)); - } - - [Fact] - public void GetComponentDesignerActions_NullActionLists_ThrowsArgumentNullException() - { - SubDesignerActionService service = new(null); - Assert.Throws("actionLists", () => service.GetComponentDesignerActions(new Component(), null)); - } - - [Fact] - public void GetComponentServiceActions_NoSuchComponentNotEmpty_ReturnsEmpty() - { - SubDesignerActionService service = new(null); - Component component = new(); - CustomDesignerActionList actionList = new(null); - service.Add(component, actionList); - DesignerActionListCollection actionListBuffer = new(); - service.GetComponentServiceActions(new Component(), actionListBuffer); - Assert.Empty(actionListBuffer); - } - - [Fact] - public void GetComponentServiceActions_NoSuchComponentEmpty_ReturnsEmpty() - { - SubDesignerActionService service = new(null); - DesignerActionListCollection actionListBuffer = new(); - service.GetComponentServiceActions(new Component(), actionListBuffer); - Assert.Empty(actionListBuffer); - } - - [Fact] - public void GetComponentServiceActions_NullComponent_ThrowsArgumentNullException() - { - SubDesignerActionService service = new(null); - Assert.Throws("component", () => service.GetComponentServiceActions(null, null)); - } - - [Fact] - public void GetComponentServiceActions_NullActionLists_ThrowsArgumentNullException() - { - SubDesignerActionService service = new(null); - Assert.Throws("actionLists", () => service.GetComponentServiceActions(new Component(), null)); - } - - [Fact] - public void Remove_InvokeComponent_Success() - { - DesignerActionService service = new(null); - using Component component = new(); - service.Add(component, new CustomDesignerActionList(null)); - Assert.NotEmpty(service.GetComponentActions(component)); - Assert.True(service.Contains(component)); - - service.Remove(component); - Assert.Empty(service.GetComponentActions(component)); - Assert.False(service.Contains(component)); - - // Remove again. - service.Remove(component); - Assert.Empty(service.GetComponentActions(component)); - Assert.False(service.Contains(component)); - } - - [Fact] - public void Remove_InvokeComponentWithDesignerActionListsChanged_CallsHandler() - { - DesignerActionService service = new(null); - using Component component1 = new(); - using Component component2 = new(); - CustomDesignerActionList actionList = new(null); - service.Add(component1, actionList); - service.Add(component2, new DesignerActionListCollection()); - - int callCount = 0; - DesignerActionListsChangedEventHandler handler = (sender, e) => - { - Assert.Same(service, sender); - Assert.Same(component1, e.RelatedObject); - Assert.Equal(DesignerActionListsChangedType.ActionListsRemoved, e.ChangeType); - Assert.Empty(e.ActionLists); - callCount++; - }; - service.DesignerActionListsChanged += handler; - - service.Remove(component1); - Assert.False(service.Contains(component1)); - Assert.Equal(1, callCount); - - // Remove again. - service.Remove(component1); - Assert.False(service.Contains(component1)); - Assert.Equal(1, callCount); - - // Remove handler. - service.DesignerActionListsChanged -= handler; - service.Remove(component2); - Assert.False(service.Contains(component2)); - Assert.Equal(1, callCount); - } - - [Fact] - public void Remove_NoSuchComponentNotEmpty_Nop() - { - DesignerActionService service = new(null); - service.Add(new Component(), new DesignerActionListCollection()); - service.Remove(new Component()); - } - - [Fact] - public void Remove_NoSuchComponentEmpty_Nop() - { - DesignerActionService service = new(null); - service.Remove(new Component()); - } - - [Fact] - public void Remove_InvokeDesignerActionList_Success() - { - DesignerActionService service = new(null); - using Component component1 = new(); - using Component component2 = new(); - using Component component3 = new(); - using Component component4 = new(); - CustomDesignerActionList actionList1 = new(null); - CustomDesignerActionList actionList2 = new(null); - CustomDesignerActionList actionList3 = new(null); - CustomDesignerActionList actionList4 = new(null); - service.Add(component1, actionList1); - service.Add(component2, actionList2); - service.Add(component2, actionList3); - service.Add(component3, actionList3); - service.Add(component4, actionList4); - service.Add(component4, actionList4); - - service.Remove(actionList1); - Assert.Empty(service.GetComponentActions(component1)); - Assert.Equal(new DesignerActionListCollection { actionList2, actionList3 }, service.GetComponentActions(component2)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component3)); - Assert.Equal(new DesignerActionListCollection { actionList4, actionList4 }, service.GetComponentActions(component4)); - Assert.False(service.Contains(component1)); - Assert.True(service.Contains(component2)); - Assert.True(service.Contains(component3)); - Assert.True(service.Contains(component4)); - - // Remove again. - service.Remove(actionList1); - Assert.Empty(service.GetComponentActions(component1)); - Assert.Equal(new DesignerActionListCollection { actionList2, actionList3 }, service.GetComponentActions(component2)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component3)); - Assert.Equal(new DesignerActionListCollection { actionList4, actionList4 }, service.GetComponentActions(component4)); - Assert.False(service.Contains(component1)); - Assert.True(service.Contains(component2)); - Assert.True(service.Contains(component3)); - Assert.True(service.Contains(component4)); - - // Remove partial. - service.Remove(actionList2); - Assert.Empty(service.GetComponentActions(component1)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component2)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component3)); - Assert.Equal(new DesignerActionListCollection { actionList4, actionList4 }, service.GetComponentActions(component4)); - Assert.False(service.Contains(component1)); - Assert.True(service.Contains(component2)); - Assert.True(service.Contains(component3)); - Assert.True(service.Contains(component4)); - - // Remove across multiple components. - service.Remove(actionList3); - Assert.Empty(service.GetComponentActions(component1)); - // Random based off ordering of Dictionary keys. - if (service.GetComponentActions(component2).Count == 1) - { - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component2)); - Assert.Empty(service.GetComponentActions(component3)); - } - else - { - Assert.Empty(service.GetComponentActions(component2)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component3)); - } - - Assert.Equal(new DesignerActionListCollection { actionList4, actionList4 }, service.GetComponentActions(component4)); - Assert.False(service.Contains(component1)); - if (service.GetComponentActions(component2).Count == 1) - { - Assert.True(service.Contains(component2)); - Assert.False(service.Contains(component3)); - } - else - { - Assert.False(service.Contains(component2)); - Assert.True(service.Contains(component3)); - } - - Assert.True(service.Contains(component4)); - - // Remove duplicates. - service.Remove(actionList4); - Assert.Empty(service.GetComponentActions(component1)); - // Random based off ordering of Dictionary keys. - if (service.GetComponentActions(component2).Count == 1) - { - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component2)); - Assert.Empty(service.GetComponentActions(component3)); - } - else - { - Assert.Empty(service.GetComponentActions(component2)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component3)); - } - - Assert.Empty(service.GetComponentActions(component4)); - Assert.False(service.Contains(component1)); - if (service.GetComponentActions(component2).Count == 1) - { - Assert.True(service.Contains(component2)); - Assert.False(service.Contains(component3)); - } - else - { - Assert.False(service.Contains(component2)); - Assert.True(service.Contains(component3)); - } - - Assert.True(service.Contains(component4)); - } - - [Fact] - public void Remove_NoSuchActionListNotEmpty_Nop() - { - DesignerActionService service = new(null); - Component component = new(); - service.Add(component, new CustomDesignerActionList(null)); - service.Remove(new CustomDesignerActionList(null)); - Assert.Single(service.GetComponentActions(component)); - } - - [Fact] - public void Remove_NoSuchActionListEmpty_Nop() - { - DesignerActionService service = new(null); - service.Remove(new CustomDesignerActionList(null)); - } - - [Fact] - public void Remove_InvokeDesignerActionListWithDesignerActionListsChanged_CallsHandler() - { - DesignerActionService service = new(null); - using Component component1 = new(); - using Component component2 = new(); - CustomDesignerActionList actionList1 = new(null); - CustomDesignerActionList actionList2 = new(null); - service.Add(component1, actionList1); - service.Add(component2, actionList2); - - int callCount = 0; - DesignerActionListsChangedEventHandler handler = (sender, e) => - { - Assert.Same(service, sender); - Assert.Same(component1, e.RelatedObject); - Assert.Equal(DesignerActionListsChangedType.ActionListsRemoved, e.ChangeType); - Assert.Empty(e.ActionLists); - callCount++; - }; - service.DesignerActionListsChanged += handler; - - service.Remove(actionList1); - Assert.False(service.Contains(component1)); - Assert.Equal(1, callCount); - - // Remove again. - service.Remove(actionList1); - Assert.False(service.Contains(component1)); - Assert.Equal(1, callCount); - - // Remove handler. - service.DesignerActionListsChanged -= handler; - service.Remove(actionList2); - Assert.False(service.Contains(component2)); - Assert.Equal(1, callCount); - } - - [Fact] - public void Remove_InvokeComponentDesignerActionList_Success() - { - DesignerActionService service = new(null); - using Component component1 = new(); - using Component component2 = new(); - using Component component3 = new(); - using Component component4 = new(); - CustomDesignerActionList actionList1 = new(null); - CustomDesignerActionList actionList2 = new(null); - CustomDesignerActionList actionList3 = new(null); - CustomDesignerActionList actionList4 = new(null); - service.Add(component1, actionList1); - service.Add(component2, actionList2); - service.Add(component2, actionList3); - service.Add(component3, actionList3); - service.Add(component4, actionList4); - service.Add(component4, actionList4); - - service.Remove(component1, actionList1); - Assert.Empty(service.GetComponentActions(component1)); - Assert.Equal(new DesignerActionListCollection { actionList2, actionList3 }, service.GetComponentActions(component2)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component3)); - Assert.Equal(new DesignerActionListCollection { actionList4, actionList4 }, service.GetComponentActions(component4)); - Assert.False(service.Contains(component1)); - Assert.True(service.Contains(component2)); - Assert.True(service.Contains(component3)); - Assert.True(service.Contains(component4)); - - // Remove again. - service.Remove(component1, actionList1); - Assert.Empty(service.GetComponentActions(component1)); - Assert.Equal(new DesignerActionListCollection { actionList2, actionList3 }, service.GetComponentActions(component2)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component3)); - Assert.Equal(new DesignerActionListCollection { actionList4, actionList4 }, service.GetComponentActions(component4)); - Assert.False(service.Contains(component1)); - Assert.True(service.Contains(component2)); - Assert.True(service.Contains(component3)); - Assert.True(service.Contains(component4)); - - // Remove partial. - service.Remove(component2, actionList2); - Assert.Empty(service.GetComponentActions(component1)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component2)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component3)); - Assert.Equal(new DesignerActionListCollection { actionList4, actionList4 }, service.GetComponentActions(component4)); - Assert.False(service.Contains(component1)); - Assert.True(service.Contains(component2)); - Assert.True(service.Contains(component3)); - Assert.True(service.Contains(component4)); - - // Remove across multiple components. - service.Remove(component2, actionList3); - Assert.Empty(service.GetComponentActions(component1)); - Assert.Empty(service.GetComponentActions(component2)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component3)); - Assert.Equal(new DesignerActionListCollection { actionList4, actionList4 }, service.GetComponentActions(component4)); - Assert.False(service.Contains(component1)); - Assert.False(service.Contains(component2)); - Assert.True(service.Contains(component3)); - Assert.True(service.Contains(component4)); - - // Remove duplicates. - service.Remove(actionList4); - Assert.Empty(service.GetComponentActions(component1)); - Assert.Empty(service.GetComponentActions(component2)); - Assert.Equal(new DesignerActionListCollection { actionList3 }, service.GetComponentActions(component3)); - Assert.Empty(service.GetComponentActions(component4)); - Assert.False(service.Contains(component1)); - Assert.False(service.Contains(component2)); - Assert.True(service.Contains(component3)); - Assert.True(service.Contains(component4)); - } - - [Fact] - public void Remove_NoSuchComponentActionListNotEmpty_Nop() - { - DesignerActionService service = new(null); - using Component component = new(); - service.Add(component, new CustomDesignerActionList(null)); - service.Remove(new Component(), new CustomDesignerActionList(null)); - service.Remove(component, new CustomDesignerActionList(null)); - Assert.Single(service.GetComponentActions(component)); - } - - [Fact] - public void Remove_NoSuchComponentActionListEmpty_Nop() - { - DesignerActionService service = new(null); - service.Remove(new Component(), new CustomDesignerActionList(null)); - } - - [Fact] - public void Remove_InvokeComponentDesignerActionListWithDesignerActionListsChanged_CallsHandler() - { - DesignerActionService service = new(null); - using Component component1 = new(); - using Component component2 = new(); - CustomDesignerActionList actionList1 = new(null); - CustomDesignerActionList actionList2 = new(null); - service.Add(component1, actionList1); - service.Add(component2, actionList2); - - int callCount = 0; - DesignerActionListsChangedEventHandler handler = (sender, e) => - { - Assert.Same(service, sender); - Assert.Same(component1, e.RelatedObject); - Assert.Equal(DesignerActionListsChangedType.ActionListsRemoved, e.ChangeType); - Assert.Empty(e.ActionLists); - callCount++; - }; - service.DesignerActionListsChanged += handler; - - service.Remove(component1, actionList1); - Assert.False(service.Contains(component1)); - Assert.Equal(1, callCount); - - // Remove again. - service.Remove(component1, actionList1); - Assert.False(service.Contains(component1)); - Assert.Equal(1, callCount); - - // Remove handler. - service.DesignerActionListsChanged -= handler; - service.Remove(component2, actionList2); - Assert.False(service.Contains(component2)); - Assert.Equal(1, callCount); - } - - [Fact] - public void Remove_NullComponent_ThrowsArgumentNullException() - { - DesignerActionService service = new(null); - Assert.Throws("comp", () => service.Remove((IComponent)null)); - Assert.Throws("comp", () => service.Remove((IComponent)null, null)); - } - - [Fact] - public void Remove_NullActionList_ThrowsArgumentNullException() - { - DesignerActionService service = new(null); - Assert.Throws("actionList", () => service.Remove((DesignerActionList)null)); - Assert.Throws("actionList", () => service.Remove(new Component(), (DesignerActionList)null)); - } - - private class SubDesignerActionService : DesignerActionService - { - public SubDesignerActionService(IServiceProvider serviceProvider) : base(serviceProvider) - { - } - - public new void Dispose(bool disposing) => base.Dispose(disposing); - - public new void GetComponentDesignerActions(IComponent component, DesignerActionListCollection actionLists) - { - base.GetComponentDesignerActions(component, actionLists); - } - - public new void GetComponentServiceActions(IComponent component, DesignerActionListCollection actionLists) - { - base.GetComponentServiceActions(component, actionLists); - } - } - - private class CustomDesignerActionList : DesignerActionList - { - public CustomDesignerActionList(IComponent component) : base(component) - { - } - - public void PublicMethod() - { - } - } - - private class NullCustomDesignerActionList : DesignerActionList - { - public NullCustomDesignerActionList(IComponent component) : base(component) - { - } - - public override DesignerActionItemCollection GetSortedActionItems() => null; - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionTextItemTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionTextItemTests.cs deleted file mode 100644 index 3067851f318..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionTextItemTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Specialized; - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionTextItemTests -{ - [Theory] - [InlineData("displayName", "category", "displayName")] - [InlineData("displa(&a)yName", "cate(&a)gory", "displayName")] - [InlineData("", "", "")] - [InlineData(null, null, null)] - public void DesignerActionItem_Ctor_String_String(string displayName, string category, string expectedDisplayName) - { - DesignerActionTextItem item = new(displayName, category); - Assert.Equal(expectedDisplayName, item.DisplayName); - Assert.Equal(category, item.Category); - Assert.Null(item.Description); - Assert.False(item.AllowAssociate); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.IsType(item.Properties); - Assert.True(item.ShowInSourceView); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionUIStateChangeEventArgsTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionUIStateChangeEventArgsTests.cs deleted file mode 100644 index b86c5e824c1..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionUIStateChangeEventArgsTests.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.ComponentModel.Design.Tests; - -public class DesignerActionUIStateChangeEventArgsTests -{ - public static IEnumerable Ctor_Object_DesignerActionUIStateChangeType_TestData() - { - yield return new object[] { null, DesignerActionUIStateChangeType.Show - 1 }; - yield return new object[] { new object(), DesignerActionUIStateChangeType.Show }; - } - - [Theory] - [MemberData(nameof(Ctor_Object_DesignerActionUIStateChangeType_TestData))] - public void Ctor_Object_DesignerActionUIStateChangeType(object relatedObject, DesignerActionUIStateChangeType changeType) - { - DesignerActionUIStateChangeEventArgs e = new(relatedObject, changeType); - Assert.Same(relatedObject, e.RelatedObject); - Assert.Equal(changeType, e.ChangeType); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerCommandSetTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerCommandSetTests.cs deleted file mode 100644 index e5c158c268b..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerCommandSetTests.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Moq; - -namespace System.ComponentModel.Design.Tests; - -public class DesignerCommandSetTests -{ - [Fact] - public void DesignerCommandSet_Ctor_Default() - { - DesignerCommandSet set = new(); - Assert.Null(set.ActionLists); - Assert.Null(set.Verbs); - } - - [Theory] - [StringWithNullData] - public void DesignerCommandSet_GetCommands_Invoke_ReturnsNull(string name) - { - DesignerCommandSet set = new(); - Assert.Null(set.GetCommands(name)); - } - - [Fact] - public void DesignerCommandSet_Verbs_OverridenGetCommands_ReturnsExpected() - { - DesignerVerbCollection collection = new(); - Mock mockSet = new(MockBehavior.Strict); - mockSet - .Setup(s => s.GetCommands("Verbs")) - .Returns(collection); - Assert.Same(collection, mockSet.Object.Verbs); - } - - [Fact] - public void DesignerCommandSet_Verbs_InvalidOverridenGetCommands_ThrowsInvalidCastException() - { - Mock mockSet = new(MockBehavior.Strict); - mockSet - .Setup(s => s.GetCommands("Verbs")) - .Returns(Array.Empty()); - Assert.Throws(() => mockSet.Object.Verbs); - } - - [Fact] - public void DesignerCommandSet_ActionLists_OverridenGetCommands_ReturnsExpected() - { - DesignerActionListCollection collection = new(); - Mock mockSet = new(MockBehavior.Strict); - mockSet - .Setup(s => s.GetCommands("ActionLists")) - .Returns(collection); - Assert.Same(collection, mockSet.Object.ActionLists); - } - - [Fact] - public void DesignerCommandSet_ActionLists_InvalidOverridenGetCommands_ThrowsInvalidCastException() - { - Mock mockSet = new(MockBehavior.Strict); - mockSet - .Setup(s => s.GetCommands("ActionLists")) - .Returns(Array.Empty()); - Assert.Throws(() => mockSet.Object.ActionLists); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerHostTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerHostTests.cs deleted file mode 100644 index 3f3796e49ee..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerHostTests.cs +++ /dev/null @@ -1,3307 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.ComponentModel.Design.Serialization; -using System.Reflection; -using Moq; - -namespace System.ComponentModel.Design.Tests; - -public class DesignerHostTests -{ - [WinFormsTheory] - [BoolData] - public void DesignerHost_CanReloadWithErrors_Set_GetReturnsExpected(bool value) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - host.CanReloadWithErrors = value; - Assert.Equal(value, host.CanReloadWithErrors); - - // Set same. - host.CanReloadWithErrors = value; - Assert.Equal(value, host.CanReloadWithErrors); - - // Set different. - host.CanReloadWithErrors = !value; - Assert.Equal(!value, host.CanReloadWithErrors); - } - - [WinFormsFact] - public void DesignerHost_Container_Get_ReturnsHost() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.Same(host, host.Container); - } - - [WinFormsTheory] - [BoolData] - public void DesignerHost_IgnoreErrorsDuringReload_Set_GetReturnsExpected(bool value) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - host.IgnoreErrorsDuringReload = value; - Assert.False(host.IgnoreErrorsDuringReload); - - // Set same. - host.IgnoreErrorsDuringReload = value; - Assert.False(host.IgnoreErrorsDuringReload); - - // Set different. - host.IgnoreErrorsDuringReload = !value; - Assert.False(host.IgnoreErrorsDuringReload); - } - - [WinFormsTheory] - [BoolData] - public void DesignerHost_IgnoreErrorsDuringReload_SetWithCanReloadWithErrors_GetReturnsExpected(bool value) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - host.CanReloadWithErrors = true; - - host.IgnoreErrorsDuringReload = value; - Assert.Equal(value, host.IgnoreErrorsDuringReload); - - // Set same. - host.IgnoreErrorsDuringReload = value; - Assert.Equal(value, host.IgnoreErrorsDuringReload); - - // Set different. - host.IgnoreErrorsDuringReload = !value; - Assert.Equal(!value, host.IgnoreErrorsDuringReload); - } - - [WinFormsFact] - public void DesignerHost_InTransaction_GetWithoutTransactions_ReturnsFalse() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.False(host.InTransaction); - } - - [WinFormsFact] - public void DesignerHost_IsClosingTransaction_GetWithoutTransaction_ReturnsFalse() - { - using SubDesignSurface surface = new(); - IDesignerHostTransactionState hostTransactionState = Assert.IsAssignableFrom(surface.Host); - Assert.False(hostTransactionState.IsClosingTransaction); - } - - [WinFormsFact] - public void DesignerHost_Loading_GetWithoutComponent_ReturnsFalse() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.False(host.Loading); - } - - [WinFormsTheory] - [BoolData] - public void DesignerHost_Loading_GetWithLoader_ReturnsExpected(bool loading) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - mockLoader - .Setup(l => l.Loading) - .Returns(loading); - surface.BeginLoad(mockLoader.Object); - Assert.True(host.Loading); - mockLoader.Verify(l => l.Loading, Times.Never()); - - host.EndLoad(null, true, null); - Assert.Equal(loading, host.Loading); - mockLoader.Verify(l => l.Loading, Times.Once()); - } - - [WinFormsFact] - public void DesignerHost_RootComponent_GetWithoutComponent_ReturnsNull() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.Null(host.RootComponent); - } - - [WinFormsFact] - public void DesignerHost_RootComponentClassName_GetWithoutComponent_ReturnsNull() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.Null(host.RootComponentClassName); - } - - [WinFormsFact] - public void DesignerHost_TransactionDescription_GetWithoutTransactions_ReturnsNull() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.Null(host.TransactionDescription); - } - - [WinFormsFact] - public void DesignerHost_Activate_Invoke_CallsViewActivated() - { - using SubDesignSurface surface = new(); - int viewActivatedCallCount = 0; - int activatedCallCount = 0; - surface.ViewActivated += (sender, e) => - { - Assert.Same(surface, sender); - Assert.Same(EventArgs.Empty, e); - viewActivatedCallCount++; - }; - IDesignerLoaderHost2 host = surface.Host; - host.Activated += (sender, e) => activatedCallCount++; - host.Activate(); - Assert.Equal(1, viewActivatedCallCount); - Assert.Equal(0, activatedCallCount); - } - - [WinFormsFact] - public void DesignerHost_Activate_InvokeDisposed_Nop() - { - using SubDesignSurface surface = new(); - int viewActivatedCallCount = 0; - int activatedCallCount = 0; - surface.ViewActivated += (sender, e) => - { - Assert.Same(surface, sender); - Assert.Same(EventArgs.Empty, e); - viewActivatedCallCount++; - }; - IDesignerLoaderHost2 host = surface.Host; - surface.Dispose(); - host.Activated += (sender, e) => activatedCallCount++; - host.Activate(); - Assert.Equal(0, viewActivatedCallCount); - Assert.Equal(0, activatedCallCount); - } - - public static IEnumerable Add_InvalidNameCreationServiceParentProvider_TestData() - { - yield return new object[] { null }; - - Mock nullMockServiceProvider = new(MockBehavior.Strict); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(new object()); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(new object()); - yield return new object[] { nullMockServiceProvider.Object }; - - Mock invalidMockServiceProvider = new(MockBehavior.Strict); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(new object()); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(new object()); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(new object()); - yield return new object[] { invalidMockServiceProvider.Object }; - } - - public static IEnumerable Add_ComponentParentProvider_TestData() - { - foreach (object[] testData in Add_InvalidNameCreationServiceParentProvider_TestData()) - { - yield return new object[] { testData[0], string.Empty }; - } - - foreach (string name in new string[] { null, string.Empty, "name" }) - { - Mock mockNameCreationService = new(MockBehavior.Strict); - mockNameCreationService - .Setup(s => s.CreateName(It.IsAny(), It.IsAny())) - .Returns(name); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(mockNameCreationService.Object); - yield return new object[] { mockServiceProvider.Object, name }; - } - } - - [WinFormsTheory] - [MemberData(nameof(Add_ComponentParentProvider_TestData))] - public void DesignerHost_Add_ComponentWithRootDesigner_Success(IServiceProvider parentProvider, string expectedName) - { - using SubDesignSurface surface = new(parentProvider); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component1 = new(); - using RootDesignerComponent component2 = new(); - using DesignerComponent component3 = new(); - using Component component4 = new(); - - host.Container.Add(component1); - Assert.Same(component1, Assert.Single(host.Container.Components)); - Assert.Same(expectedName, host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(host, component1.Container); - Assert.Same(component1, component1.Site.Component); - Assert.Same(host, component1.Site.Container); - Assert.True(component1.Site.DesignMode); - Assert.Equal(expectedName, component1.Site.Name); - - // Add different - root designer. - host.Container.Add(component2); - Assert.Equal(new IComponent[] { component1, component2 }, host.Container.Components.Cast()); - Assert.Same(expectedName, host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(host, component2.Container); - Assert.Same(component2, component2.Site.Component); - Assert.Same(host, component2.Site.Container); - Assert.True(component2.Site.DesignMode); - Assert.Equal(expectedName, component2.Site.Name); - - // Add different - non root designer. - host.Container.Add(component3); - Assert.Equal(new IComponent[] { component1, component2, component3 }, host.Container.Components.Cast()); - Assert.Same(expectedName, host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(host, component3.Container); - Assert.Same(component3, component3.Site.Component); - Assert.Same(host, component3.Site.Container); - Assert.True(component3.Site.DesignMode); - Assert.Equal(expectedName, component3.Site.Name); - - // Add different - non designer. - host.Container.Add(component4); - Assert.Equal(new IComponent[] { component1, component2, component3, component4 }, host.Container.Components.Cast()); - Assert.Same(expectedName, host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(host, component4.Container); - Assert.Same(component4, component4.Site.Component); - Assert.Same(host, component4.Site.Container); - Assert.True(component4.Site.DesignMode); - Assert.Equal(expectedName, component4.Site.Name); - } - - [WinFormsTheory] - [MemberData(nameof(Add_InvalidNameCreationServiceParentProvider_TestData))] - public void DesignerHost_Add_ComponentStringWithRootDesigner_Success(IServiceProvider parentProvider) - { - using SubDesignSurface surface = new(parentProvider); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component1 = new(); - using RootDesignerComponent component2 = new(); - using DesignerComponent component3 = new(); - using Component component4 = new(); - - host.Container.Add(component1, "name1"); - Assert.Same(component1, Assert.Single(host.Container.Components)); - Assert.Equal("name1", host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(host, component1.Container); - Assert.Same(component1, component1.Site.Component); - Assert.Same(host, component1.Site.Container); - Assert.True(component1.Site.DesignMode); - Assert.Equal("name1", component1.Site.Name); - - // Add different - root designer. - host.Container.Add(component2, "name2"); - Assert.Equal(new IComponent[] { component1, component2 }, host.Container.Components.Cast()); - Assert.Same(host, component2.Container); - Assert.Equal("name1", host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(component2, component2.Site.Component); - Assert.Same(host, component2.Site.Container); - Assert.True(component2.Site.DesignMode); - Assert.Equal("name2", component2.Site.Name); - - // Add different - non root designer. - host.Container.Add(component3, string.Empty); - Assert.Equal(new IComponent[] { component1, component2, component3 }, host.Container.Components.Cast()); - Assert.Same(host, component3.Container); - Assert.Equal("name1", host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(component3, component3.Site.Component); - Assert.Same(host, component3.Site.Container); - Assert.True(component3.Site.DesignMode); - Assert.Empty(component3.Site.Name); - - // Add different - non designer. - host.Container.Add(component4, null); - Assert.Equal(new IComponent[] { component1, component2, component3, component4 }, host.Container.Components.Cast()); - Assert.Same(host, component4.Container); - Assert.Equal("name1", host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(component4, component4.Site.Component); - Assert.Same(host, component4.Site.Container); - Assert.True(component4.Site.DesignMode); - Assert.Empty(component4.Site.Name); - } - - public static IEnumerable Add_IExtenderProviderServiceWithoutDefault_TestData() - { - yield return new object[] { new RootDesignerComponent(), 0 }; - yield return new object[] { new RootExtenderProviderDesignerComponent(), 1 }; - - RootExtenderProviderDesignerComponent readOnlyComponent = new(); - TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly)); - yield return new object[] { readOnlyComponent, 0 }; - - RootExtenderProviderDesignerComponent inheritedComponent = new(); - TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited)); - yield return new object[] { inheritedComponent, 1 }; - - RootExtenderProviderDesignerComponent notInheritedComponent = new(); - TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited)); - yield return new object[] { notInheritedComponent, 1 }; - } - - [WinFormsTheory] - [MemberData(nameof(Add_IExtenderProviderServiceWithoutDefault_TestData))] - public void DesignerHost_Add_IExtenderProviderServiceWithoutDefault_Success(Component component, int expectedCallCount) - { - Mock mockExtenderProviderService = new(MockBehavior.Strict); - mockExtenderProviderService - .Setup(s => s.AddExtenderProvider(component as IExtenderProvider)) - .Verifiable(); - mockExtenderProviderService - .Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider)); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(mockExtenderProviderService.Object) - .Verifiable(); - - using SubDesignSurface surface = new(mockServiceProvider.Object); - surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService)); - IDesignerLoaderHost2 host = surface.Host; - - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Empty(component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedCallCount)); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedCallCount)); - - // Add again. - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Empty(component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedCallCount)); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedCallCount)); - - // Add again with name. - host.Container.Add(component, "name"); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Equal("name", component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedCallCount)); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedCallCount)); - } - - public static IEnumerable Add_IExtenderProviderServiceWithDefault_TestData() - { - yield return new object[] { new RootDesignerComponent() }; - yield return new object[] { new RootExtenderProviderDesignerComponent() }; - - RootExtenderProviderDesignerComponent readOnlyComponent = new(); - TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly)); - yield return new object[] { readOnlyComponent }; - - RootExtenderProviderDesignerComponent inheritedComponent = new(); - TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited)); - yield return new object[] { inheritedComponent }; - - RootExtenderProviderDesignerComponent notInheritedComponent = new(); - TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited)); - yield return new object[] { notInheritedComponent }; - } - - [WinFormsTheory] - [MemberData(nameof(Add_IExtenderProviderServiceWithDefault_TestData))] - public void DesignerHost_Add_IExtenderProviderServiceWithDefault_DoesNotCallGetService(Component component) - { - Mock mockExtenderProviderService = new(MockBehavior.Strict); - mockExtenderProviderService - .Setup(s => s.AddExtenderProvider(component as IExtenderProvider)) - .Verifiable(); - mockExtenderProviderService - .Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider)); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(mockExtenderProviderService.Object) - .Verifiable(); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Empty(component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never()); - - // Add again. - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Empty(component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never()); - - // Add again with name. - host.Container.Add(component, "name"); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Equal("name", component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never()); - } - - public static IEnumerable InvalidIExtenderProviderService_TestData() - { - yield return new object[] { null }; - - Mock nullMockServiceProvider = new(MockBehavior.Strict); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(null) - .Verifiable(); - yield return new object[] { nullMockServiceProvider }; - - Mock invalidMockServiceProvider = new(MockBehavior.Strict); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(new object()) - .Verifiable(); - yield return new object[] { invalidMockServiceProvider }; - } - - [WinFormsTheory] - [MemberData(nameof(InvalidIExtenderProviderService_TestData))] - public void DesignerHost_Add_InvalidIExtenderProviderServiceWithoutDefault_CallsParentGetService(Mock mockParentProvider) - { - using SubDesignSurface surface = new(mockParentProvider?.Object); - surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService)); - IDesignerLoaderHost2 host = surface.Host; - using RootExtenderProviderDesignerComponent component = new(); - - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Once()); - } - - [WinFormsTheory] - [MemberData(nameof(InvalidIExtenderProviderService_TestData))] - public void DesignerHost_Add_InvalidIExtenderProviderServiceWithDefault_DoesNotCallParentGetService(Mock mockParentProvider) - { - using SubDesignSurface surface = new(mockParentProvider?.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootExtenderProviderDesignerComponent component = new(); - - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - } - - [WinFormsFact] - public void DesignerHost_Add_SameComponent_Success() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Empty(component.Site.Name); - - // Add again. - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Empty(component.Site.Name); - - // Add again with name. - host.Container.Add(component, "name"); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Equal("name", component.Site.Name); - } - - [WinFormsFact] - public void DesignerHost_Add_ComponentWithNameCreationServiceWithoutName_CallsCreateName() - { - Mock mockNameCreationService = new(MockBehavior.Strict); - mockNameCreationService - .Setup(s => s.CreateName(It.IsAny(), It.IsAny())) - .Returns("name") - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(mockNameCreationService.Object); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - - host.Container.Add(component); - Assert.Equal("name", component.Site.Name); - mockNameCreationService.Verify(s => s.CreateName(host.Container, typeof(RootDesignerComponent)), Times.Once()); - - host.Container.Add(component, null); - Assert.Equal("name", component.Site.Name); - mockNameCreationService.Verify(s => s.CreateName(host.Container, typeof(RootDesignerComponent)), Times.Once()); - } - - [WinFormsFact] - public void DesignerHost_Add_ComponentWithNameCreationServiceWithCustomReflectionType_CallsCreateName() - { - using CustomTypeDescriptionProviderComponent component = new(); - Mock mockCustomTypeDescriptor = new(MockBehavior.Strict); - mockCustomTypeDescriptor - .Setup(d => d.GetAttributes()) - .Returns(TypeDescriptor.GetAttributes(typeof(CustomTypeDescriptionProviderComponent))); - Mock mockProvider = new(MockBehavior.Strict); - mockProvider - .Setup(p => p.GetReflectionType(typeof(CustomTypeDescriptionProviderComponent), component)) - .Returns(typeof(RootDesignerComponent)) - .Verifiable(); - mockProvider - .Setup(p => p.GetTypeDescriptor(typeof(CustomTypeDescriptionProviderComponent), component)) - .Returns(mockCustomTypeDescriptor.Object); - mockProvider - .Setup(p => p.GetCache(component)) - .CallBase(); - mockProvider - .Setup(p => p.GetExtendedTypeDescriptor(component)) - .CallBase(); - TypeDescriptor.AddProvider(mockProvider.Object, component); - - Mock mockNameCreationService = new(MockBehavior.Strict); - mockNameCreationService - .Setup(s => s.CreateName(It.IsAny(), It.IsAny())) - .Returns("name") - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(mockNameCreationService.Object); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - - host.Container.Add(component); - Assert.Equal("name", component.Site.Name); - mockNameCreationService.Verify(s => s.CreateName(host.Container, typeof(RootDesignerComponent)), Times.Once()); - - host.Container.Add(component, null); - Assert.Equal("name", component.Site.Name); - mockNameCreationService.Verify(s => s.CreateName(host.Container, typeof(RootDesignerComponent)), Times.Once()); - } - - [WinFormsTheory] - [StringData] - public void DesignerHost_Add_ComponentWithNameCreationServiceWithName_CallsValidateName(string name) - { - Mock mockNameCreationService = new(MockBehavior.Strict); - mockNameCreationService - .Setup(s => s.ValidateName(It.IsAny())) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(mockNameCreationService.Object) - .Verifiable(); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component1 = new(); - host.Container.Add(component1, name); - Assert.Same(name, component1.Site.Name); - mockNameCreationService.Verify(s => s.ValidateName(name), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(INameCreationService)), Times.Once()); - - // Add another. - using DesignerComponent component2 = new(); - host.Container.Add(component2, "name2"); - Assert.Equal("name2", component2.Site.Name); - mockNameCreationService.Verify(s => s.ValidateName("name2"), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(INameCreationService)), Times.Exactly(2)); - } - - [WinFormsFact] - public void DesignerHost_Add_ComponentWithTypeDescriptionProviderServiceWithoutProjectTargetFrameworkAttribute_AddsProvider() - { - ICustomTypeDescriptor descriptor = TypeDescriptor.GetProvider(typeof(RootDesignerComponent)).GetTypeDescriptor(typeof(RootDesignerComponent)); - Mock mockTypeDescriptionProvider = new(MockBehavior.Strict); - mockTypeDescriptionProvider - .Setup(p => p.IsSupportedType(typeof(int))) - .Returns(false) - .Verifiable(); - mockTypeDescriptionProvider - .Setup(p => p.GetTypeDescriptor(It.IsAny(), It.IsAny())) - .Returns(descriptor); - mockTypeDescriptionProvider - .Setup(p => p.GetCache(It.IsAny())) - .CallBase(); - mockTypeDescriptionProvider - .Setup(p => p.GetExtendedTypeDescriptor(It.IsAny())) - .CallBase(); - Mock mockTypeDescriptionProviderService = new(MockBehavior.Strict); - mockTypeDescriptionProviderService - .Setup(s => s.GetProvider(It.IsAny())) - .Returns(mockTypeDescriptionProvider.Object) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(mockTypeDescriptionProviderService.Object) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(null); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component1 = new(); - host.Container.Add(component1, "name1"); - Assert.Equal("name1", component1.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Once()); - mockTypeDescriptionProviderService.Verify(s => s.GetProvider(component1), Times.Once()); - - // Make sure we added the TypeDescriptionProvider. - Assert.False(TypeDescriptor.GetProvider(component1).IsSupportedType(typeof(int))); - mockTypeDescriptionProvider.Verify(p => p.IsSupportedType(typeof(int)), Times.Once()); - - // Add again. - using DesignerComponent component2 = new(); - host.Container.Add(component2, "name2"); - Assert.Equal("name2", component2.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Once()); - mockTypeDescriptionProviderService.Verify(s => s.GetProvider(component2), Times.Once()); - - // Make sure we added the TypeDescriptionProvider. - Assert.False(TypeDescriptor.GetProvider(component2).IsSupportedType(typeof(int))); - mockTypeDescriptionProvider.Verify(p => p.IsSupportedType(typeof(int)), Times.Exactly(2)); - } - - [WinFormsFact] - public void DesignerHost_Add_ComponentWithNullTypeDescriptionProviderService_Success() - { - Mock mockTypeDescriptionProviderService = new(MockBehavior.Strict); - mockTypeDescriptionProviderService - .Setup(s => s.GetProvider(It.IsAny())) - .Returns(null) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(mockTypeDescriptionProviderService.Object) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component, "name1"); - Assert.Equal("name1", component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Once()); - mockTypeDescriptionProviderService.Verify(s => s.GetProvider(component), Times.Once()); - } - - [WinFormsFact] - public void DesignerHost_Add_ComponentWithTypeDescriptionProviderServiceWithProjectTargetFrameworkAttribute_DoesNotAddProvider() - { - using RootDesignerComponent component = new(); - ICustomTypeDescriptor descriptor = TypeDescriptor.GetProvider(typeof(RootDesignerComponent)).GetTypeDescriptor(typeof(RootDesignerComponent)); - Mock mockTypeDescriptionProvider = new(MockBehavior.Strict); - mockTypeDescriptionProvider - .Setup(p => p.GetTypeDescriptor(It.IsAny(), It.IsAny())) - .Returns(descriptor); - mockTypeDescriptionProvider - .Setup(p => p.GetCache(component)) - .CallBase(); - mockTypeDescriptionProvider - .Setup(p => p.GetExtendedTypeDescriptor(It.IsAny())) - .CallBase(); - mockTypeDescriptionProvider - .Setup(p => p.GetReflectionType(typeof(object), null)) - .Returns(typeof(ClassWithProjectTargetFrameworkAttribute)); - TypeDescriptor.AddProvider(mockTypeDescriptionProvider.Object, component); - - Mock mockTypeDescriptionProviderService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(mockTypeDescriptionProviderService.Object) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - host.Container.Add(component, "name1"); - Assert.Equal("name1", component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Once()); - mockTypeDescriptionProviderService.Verify(s => s.GetProvider(component), Times.Never()); - } - - [WinFormsFact(Skip = "Unstable test, see: https://github.com/dotnet/winforms/issues/1460")] - public void DesignerHost_Add_DuringUnload_ThrowsException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - surface.BeginLoad(typeof(RootDesignerComponent)); - - using DesignerComponent component = new(); - host.Container.Add(component); - int callCount = 0; - component.Disposed += (sender, e) => - { - using DesignerComponent newComponent = new(); - Assert.Throws(() => host.Container.Add(newComponent)); - callCount++; - }; - surface.Dispose(); - Assert.Equal(1, callCount); - Assert.False(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.False(host.Loading); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIDictionaryServiceGetKey_NoDictionary_ReturnsNull() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - - IDictionaryService service = Assert.IsAssignableFrom(component.Site); - Assert.Null(service.GetKey(null)); - Assert.Null(service.GetKey(new object())); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIDictionaryServiceGetKey_NoSuchKeyWithDictionary_ReturnsNull() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - - IDictionaryService service = Assert.IsAssignableFrom(component.Site); - object key1 = new(); - object value1 = new(); - service.SetValue(key1, value1); - Assert.Same(key1, service.GetKey(value1)); - Assert.Same(value1, service.GetValue(key1)); - - Assert.Null(service.GetKey(null)); - Assert.Null(service.GetKey(new object())); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIDictionaryServiceGetValue_NoDictionary_ReturnsNull() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - - IDictionaryService service = Assert.IsAssignableFrom(component.Site); - Assert.Null(service.GetValue(new object())); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIDictionaryServiceGetValue_NoSuchValueWithDictionary_ReturnsNull() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - - IDictionaryService service = Assert.IsAssignableFrom(component.Site); - object key1 = new(); - object value1 = new(); - service.SetValue(key1, value1); - Assert.Same(key1, service.GetKey(value1)); - Assert.Same(value1, service.GetValue(key1)); - - Assert.Null(service.GetValue(new object())); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIDictionaryServiceGetValue_NullValueNoDictionary_ReturnsNull() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - - IDictionaryService service = Assert.IsAssignableFrom(component.Site); - Assert.Throws("key", () => service.GetValue(null)); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIDictionaryServiceGetValue_NullValueWithDictionary_ThrowsArgumentNullException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - - IDictionaryService service = Assert.IsAssignableFrom(component.Site); - object key1 = new(); - object value1 = new(); - service.SetValue(key1, value1); - Assert.Same(key1, service.GetKey(value1)); - Assert.Same(value1, service.GetValue(key1)); - - Assert.Throws("key", () => service.GetValue(null)); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIDictionaryServiceSetValue_Invoke_GetKeyValueReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - IDictionaryService service = Assert.IsAssignableFrom(component.Site); - - object key1 = new(); - object value1 = new(); - service.SetValue(key1, value1); - Assert.Same(key1, service.GetKey(value1)); - Assert.Same(value1, service.GetValue(key1)); - - // Add another. - object key2 = new(); - object value2 = new(); - service.SetValue(key2, value2); - Assert.Same(key2, service.GetKey(value2)); - Assert.Same(value2, service.GetValue(key2)); - - // Add same. - object value3 = new(); - service.SetValue(key1, value3); - Assert.Same(key1, service.GetKey(value3)); - Assert.Null(service.GetKey(value1)); - Assert.Same(value3, service.GetValue(key1)); - - // Add null value. - service.SetValue(key1, null); - Assert.Null(service.GetKey(null)); - Assert.Null(service.GetKey(value3)); - Assert.Null(service.GetValue(key1)); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIDictionaryServiceSetValue_NullKey_ThrowsArgumentNullException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - IDictionaryService service = Assert.IsAssignableFrom(component.Site); - Assert.Throws("key", () => service.SetValue(null, new object())); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIServiceContainerAddService_InvokeObject_ReturnsExpected() - { - object service = new(); - object otherService = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(object))) - .Returns(otherService); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - IServiceContainer container = Assert.IsAssignableFrom(component.Site); - container.AddService(typeof(object), service); - Assert.Same(service, container.GetService(typeof(object))); - Assert.Same(otherService, surface.GetService(typeof(object))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIServiceContainerAddService_InvokeObjectPromote_ReturnsExpected() - { - object service = new(); - object otherService = new(); - ServiceContainer otherContainer = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(object))) - .Returns(otherService); - mockServiceProvider - .Setup(p => p.GetService(typeof(IServiceContainer))) - .Returns(otherContainer); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - IServiceContainer container = Assert.IsAssignableFrom(component.Site); - container.AddService(typeof(object), service, true); - Assert.Same(otherService, container.GetService(typeof(object))); - Assert.Same(otherService, surface.GetService(typeof(object))); - Assert.Same(service, otherContainer.GetService(typeof(object))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIServiceContainerAddService_InvokeObjectNoPromote_ReturnsExpected() - { - object service = new(); - object otherService = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(object))) - .Returns(otherService); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - IServiceContainer container = Assert.IsAssignableFrom(component.Site); - container.AddService(typeof(object), service, false); - Assert.Same(service, container.GetService(typeof(object))); - Assert.Same(otherService, surface.GetService(typeof(object))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIServiceContainerAddService_InvokeServiceCreatorCallback_ReturnsExpected() - { - object service = new(); - ServiceCreatorCallback callback = (c, serviceType) => - { - Assert.Same(typeof(object), serviceType); - return service; - }; - object otherService = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(object))) - .Returns(otherService); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - IServiceContainer container = Assert.IsAssignableFrom(component.Site); - container.AddService(typeof(object), callback); - Assert.Same(service, container.GetService(typeof(object))); - Assert.Same(otherService, surface.GetService(typeof(object))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIServiceContainerAddService_InvokeServiceCreatorCallbackPromote_ReturnsExpected() - { - object service = new(); - ServiceCreatorCallback callback = (c, serviceType) => - { - Assert.Same(typeof(object), serviceType); - return service; - }; - object otherService = new(); - ServiceContainer otherContainer = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(object))) - .Returns(otherService); - mockServiceProvider - .Setup(p => p.GetService(typeof(IServiceContainer))) - .Returns(otherContainer); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - IServiceContainer container = Assert.IsAssignableFrom(component.Site); - container.AddService(typeof(object), callback, true); - Assert.Same(otherService, container.GetService(typeof(object))); - Assert.Same(otherService, surface.GetService(typeof(object))); - Assert.Same(service, otherContainer.GetService(typeof(object))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentIServiceContainerAddService_InvokeServiceCreatorCallbackNoPromote_ReturnsExpected() - { - object service = new(); - ServiceCreatorCallback callback = (c, serviceType) => - { - Assert.Same(typeof(object), serviceType); - return service; - }; - object otherService = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(object))) - .Returns(otherService); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - IServiceContainer container = Assert.IsAssignableFrom(component.Site); - container.AddService(typeof(object), callback, false); - Assert.Same(service, container.GetService(typeof(object))); - Assert.Same(otherService, surface.GetService(typeof(object))); - } - - public static IEnumerable AddComponentISiteName_Set_TestData() - { - foreach (object[] testData in Add_InvalidNameCreationServiceParentProvider_TestData()) - { - foreach (string oldName in new string[] { null, string.Empty, "oldName" }) - { - yield return new object[] { testData[0], oldName, null, string.Empty }; - yield return new object[] { testData[0], oldName, string.Empty, string.Empty }; - yield return new object[] { testData[0], oldName, "name", "name" }; - yield return new object[] { testData[0], oldName, "ldName", "ldName" }; - yield return new object[] { testData[0], oldName, "ldName", "ldName" }; - } - } - } - - [WinFormsTheory] - [MemberData(nameof(AddComponentISiteName_Set_TestData))] - public void DesignerHost_AddComponentISiteName_SetRootComponent_GetReturnsExpected(IServiceProvider parentProvider, string oldName, string value, string expectedName) - { - using SubDesignSurface surface = new(parentProvider); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component, oldName); - component.Site.Name = value; - Assert.Same(expectedName, component.Site.Name); - Assert.Same(expectedName, host.RootComponentClassName); - - // Set same. - component.Site.Name = value; - Assert.Same(expectedName, component.Site.Name); - Assert.Same(expectedName, host.RootComponentClassName); - } - - [WinFormsFact] - public void DesignerHost_AddComponentISiteName_SetDifferentCase_GetReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component, "name"); - component.Site.Name = "NAME"; - Assert.Equal("NAME", component.Site.Name); - - // Set same. - component.Site.Name = "NAME"; - Assert.Equal("NAME", component.Site.Name); - } - - [WinFormsTheory] - [StringWithNullData] - public void DesignerHost_AddComponentISiteName_SetWithMultipleComponents_GetReturnsExpected(string value) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component1 = new(); - using RootDesignerComponent component2 = new(); - using RootDesignerComponent component3 = new(); - host.Container.Add(component1); - host.Container.Add(component2, null); - host.Container.Add(component3, "name3"); - - component1.Site.Name = value; - Assert.Same(value ?? string.Empty, component1.Site.Name); - - // Set same. - component1.Site.Name = value; - Assert.Same(value ?? string.Empty, component1.Site.Name); - } - - public static IEnumerable AddComponentISiteName_SetWithNamespaceInRootComponentClassName_TestData() - { - yield return new object[] { string.Empty, "oldName", null, string.Empty, string.Empty }; - yield return new object[] { string.Empty, "oldName", string.Empty, string.Empty, string.Empty }; - yield return new object[] { string.Empty, "oldName", "newName", "newName", "newName" }; - - yield return new object[] { "oldName", "oldName", null, string.Empty, string.Empty }; - yield return new object[] { "oldName", "oldName", string.Empty, string.Empty, string.Empty }; - yield return new object[] { "oldName", "oldName", "newName", "newName", "newName" }; - yield return new object[] { "oldName", "oldName", "oldName", "oldName", "oldName" }; - - yield return new object[] { "namespace.oldName", "oldName", null, string.Empty, "namespace." }; - yield return new object[] { "namespace.oldName", "oldName", string.Empty, string.Empty, "namespace." }; - yield return new object[] { "namespace.oldName", "oldName", "newName", "newName", "namespace.newName" }; - yield return new object[] { "namespace.oldName", "oldName", "oldName", "oldName", "namespace.oldName" }; - yield return new object[] { "namespace.oldName", "ldName", "ldName", "ldName", "namespace.oldName" }; - - yield return new object[] { "namespace.oldName", "namespace.oldName", null, string.Empty, string.Empty }; - yield return new object[] { "namespace.oldName", "namespace.oldName", string.Empty, string.Empty, string.Empty }; - yield return new object[] { "namespace.oldName", "namespace.oldName", "newName", "newName", "newName" }; - yield return new object[] { "namespace.oldName", "namespace.oldName", "oldName", "oldName", "oldName" }; - yield return new object[] { "namespace.oldName", "namespace.oldName", "ldName", "ldName", "ldName" }; - - yield return new object[] { "namespace.oldName", "name", null, string.Empty, string.Empty }; - yield return new object[] { "namespace.oldName", "name", string.Empty, string.Empty, string.Empty }; - yield return new object[] { "namespace.oldName", "name", "newName", "newName", "newName" }; - yield return new object[] { "namespace.oldName", "name", "oldName", "oldName", "oldName" }; - } - - [WinFormsTheory] - [MemberData(nameof(AddComponentISiteName_SetWithNamespaceInRootComponentClassName_TestData))] - public void DesignerHost_AddComponentISiteName_SetWithNamespaceInRootComponentClassName_GetReturnsExpected(string oldRootComponentClassName, string oldName, string value, string expectedName, string expectedRootComponentClassName) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - - host.EndLoad(oldRootComponentClassName, true, null); - Assert.Equal(oldRootComponentClassName, host.RootComponentClassName); - Assert.Null(host.RootComponent); - - host.Container.Add(component, oldName); - Assert.Equal(oldName, component.Site.Name); - Assert.Equal(oldRootComponentClassName, host.RootComponentClassName); - Assert.Same(component, host.RootComponent); - - component.Site.Name = value; - Assert.Equal(expectedName, component.Site.Name); - Assert.Equal(expectedRootComponentClassName, host.RootComponentClassName); - Assert.Same(component, host.RootComponent); - } - - [WinFormsTheory] - [StringWithNullData] - public void DesignerHost_AddComponentISiteName_SetNameWithComponentRename_CallsHandler(string value) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - using RootDesignerComponent component = new(); - - int callCount = 0; - ComponentRenameEventHandler handler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(component, e.Component); - Assert.Equal("oldName", e.OldName); - Assert.Same(value ?? string.Empty, e.NewName); - callCount++; - }; - changeService.ComponentRename += handler; - host.Container.Add(component, "oldName"); - - component.Site.Name = value; - Assert.Same(value ?? string.Empty, component.Site.Name); - Assert.Equal(1, callCount); - - // Set same. - component.Site.Name = value; - Assert.Same(value ?? string.Empty, component.Site.Name); - Assert.Equal(1, callCount); - - // Remove handler. - changeService.ComponentRename -= handler; - component.Site.Name = "name"; - Assert.Equal("name", component.Site.Name); - Assert.Equal(1, callCount); - } - - [WinFormsTheory] - [InlineData(null, "", 1)] - [InlineData("", "", 1)] - [InlineData("newName", "newName", 1)] - [InlineData("OLDNAME", "OLDNAME", 0)] - public void DesignerHost_AddComponentISite_SetNameWithINameCreateService_CallsValidateName(string value, string expectedName, int expectedCallCount) - { - Mock mockNameCreationService = new(MockBehavior.Strict); - mockNameCreationService - .Setup(s => s.ValidateName("oldName")) - .Verifiable(); - mockNameCreationService - .Setup(s => s.ValidateName(expectedName)) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(mockNameCreationService.Object); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component, "oldName"); - Assert.Equal("oldName", component.Site.Name); - mockNameCreationService.Verify(s => s.ValidateName("oldName"), Times.Once()); - - component.Site.Name = value; - Assert.Equal(expectedName, component.Site.Name); - mockNameCreationService.Verify(s => s.ValidateName(expectedName), Times.Exactly(expectedCallCount)); - } - - [WinFormsFact] - public void DesignerHost_AddComponentISiteName_SetSameAsOtherComponent_GetReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component1 = new(); - using RootDesignerComponent component2 = new(); - host.Container.Add(component1, "name1"); - host.Container.Add(component2, "name2"); - Assert.Throws(() => component1.Site.Name = "name2"); - Assert.Throws(() => component1.Site.Name = "NAME2"); - } - - [WinFormsFact] - public void DesignerHost_AddComponentISiteGetService_Invoke_ReturnsExpected() - { - object service = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(int))) - .Returns(service); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - Assert.Same(service, component.Site.GetService(typeof(int))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentISiteGetService_InvokeWithNestedContainer_ReturnsService() - { - object service = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(int))) - .Returns(service); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - INestedContainer nestedContainer = Assert.IsAssignableFrom(component.Site.GetService(typeof(INestedContainer))); - Assert.Same(service, component.Site.GetService(typeof(int))); - Assert.Same(component.Site, component.Site.GetService(typeof(IDictionaryService))); - Assert.Same(nestedContainer, component.Site.GetService(typeof(INestedContainer))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentISiteGetService_INestedContainer_ReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - INestedContainer container = Assert.IsAssignableFrom(component.Site.GetService(typeof(INestedContainer))); - Assert.Same(container, component.Site.GetService(typeof(INestedContainer))); - Assert.Empty(container.Components); - Assert.Same(component, container.Owner); - } - - [WinFormsFact] - public void DesignerHost_AddComponentISiteGetServiceINestedContainerGetService_Invoke_ReturnsExpected() - { - object service = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(int))) - .Returns(service); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - NestedContainer container = Assert.IsAssignableFrom(component.Site.GetService(typeof(INestedContainer))); - using Component nestedComponent = new(); - container.Add(nestedComponent); - Assert.Same(service, nestedComponent.Site.GetService(typeof(int))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentISiteGetService_IDictionaryService_ReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - Assert.Same(component.Site, component.Site.GetService(typeof(IDictionaryService))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentISiteGetService_IServiceContainerReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - Assert.Same(surface.ServiceContainer, component.Site.GetService(typeof(IServiceContainer))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentISiteGetService_IContainerReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - Assert.Same(host, component.Site.GetService(typeof(IContainer))); - } - - [WinFormsFact] - public void DesignerHost_AddComponentISiteGetService_NullServiceType_ThrowsArgumentNullException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - Assert.Throws("service", () => component.Site.GetService(null)); - } - - [WinFormsFact] - public void DesignerHost_Add_IComponentWithComponentAddingAndAdded_CallsHandler() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - - using RootDesignerComponent component = new(); - int componentAddingCallCount = 0; - ComponentEventHandler componentAddingHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(component, e.Component); - componentAddingCallCount++; - }; - changeService.ComponentAdding += componentAddingHandler; - int componentAddedCallCount = 0; - ComponentEventHandler componentAddedHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(component, e.Component); - Assert.True(componentAddedCallCount < componentAddingCallCount); - componentAddedCallCount++; - }; - changeService.ComponentAdded += componentAddedHandler; - - // With handler. - host.Container.Add(component); - Assert.Same(host.Container, component.Container); - Assert.Equal(1, componentAddingCallCount); - Assert.Equal(1, componentAddedCallCount); - - // Add again. - host.Container.Add(component); - Assert.Same(host.Container, component.Container); - Assert.Equal(1, componentAddingCallCount); - Assert.Equal(1, componentAddedCallCount); - - // Remove handler. - changeService.ComponentAdding -= componentAddingHandler; - changeService.ComponentAdded -= componentAddedHandler; - host.Container.Add(component); - Assert.Same(host.Container, component.Container); - Assert.Equal(1, componentAddingCallCount); - Assert.Equal(1, componentAddedCallCount); - } - - public static IEnumerable Add_NoRootDesigner_TestData() - { - yield return new object[] { new Component() }; - yield return new object[] { new DesignerComponent() }; - } - - [WinFormsTheory] - [MemberData(nameof(Add_NoRootDesigner_TestData))] - public void DesignerHost_Add_NoRootDesigner_ThrowsException(IComponent component) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.Throws(() => host.Container.Add(component)); - Assert.Throws(() => host.Container.Add(component, "name")); - Assert.Empty(host.Container.Components); - } - - [WinFormsFact] - public void DesignerHost_Add_CyclicRootDesigner_ThrowsException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component, component.GetType().FullName); - Assert.Equal(component.GetType().FullName, host.RootComponentClassName); - Assert.Throws(() => host.Container.Add(component)); - Assert.Throws(() => host.Container.Add(new RootDesignerComponent(), host.RootComponentClassName)); - } - - [WinFormsFact] - public void DesignerHost_Add_NonInitializingRootDesigner_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using NonInitializingDesignerComponent component = new(); - Assert.Throws(() => host.Container.Add(component)); - Assert.Throws(() => host.Container.Add(component, "name")); - } - - [WinFormsFact] - public void DesignerHost_Add_ThrowingInitializingRootDesigner_RethrowsException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using ThrowingInitializingDesignerComponent component = new(); - Assert.Throws(() => host.Container.Add(component)); - Assert.Null(component.Container); - Assert.Null(component.Site); - - Assert.Throws(() => host.Container.Add(component, "name")); - Assert.Null(component.Container); - Assert.Null(component.Site); - } - - [WinFormsFact] - public void DesignerHost_Add_CheckoutExceptionThrowingInitializingRootDesigner_RethrowsException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using CheckoutExceptionThrowingInitializingDesignerComponent component = new(); - // CheckoutException does not bubble up in xunit. - bool threwCheckoutException = false; - try - { - host.Container.Add(component); - } - catch (CheckoutException) - { - threwCheckoutException = true; - } - - Assert.True(threwCheckoutException); - Assert.Same(host.Container, component.Container); - Assert.Empty(component.Site.Name); - - host.Container.Add(component, "name"); - Assert.Same(host.Container, component.Container); - Assert.Equal("name", component.Site.Name); - } - - [WinFormsFact] - public void DesignerHost_AddService_InvokeObject_GetServiceReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - object service = new(); - host.AddService(typeof(object), service); - Assert.Same(service, surface.ServiceContainer.GetService(typeof(object))); - Assert.Same(service, surface.GetService(typeof(object))); - Assert.Same(service, host.GetService(typeof(object))); - } - - [WinFormsTheory] - [BoolData] - public void DesignerHost_AddService_InvokeObjectBool_GetServiceReturnsExpected(bool promote) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - object service = new(); - host.AddService(typeof(object), service, promote); - Assert.Same(service, surface.ServiceContainer.GetService(typeof(object))); - Assert.Same(service, surface.GetService(typeof(object))); - Assert.Same(service, host.GetService(typeof(object))); - } - - [WinFormsFact] - public void DesignerHost_AddService_InvokeCallback_GetServiceReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - object service = new(); - ServiceCreatorCallback callback = (container, serviceType) => service; - host.AddService(typeof(object), callback); - Assert.Same(service, surface.ServiceContainer.GetService(typeof(object))); - Assert.Same(service, surface.GetService(typeof(object))); - Assert.Same(service, host.GetService(typeof(object))); - } - - [WinFormsTheory] - [BoolData] - public void DesignerHost_AddService_InvokeObjectCallback_GetServiceReturnsExpected(bool promote) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - object service = new(); - ServiceCreatorCallback callback = (container, serviceType) => service; - host.AddService(typeof(object), callback, promote); - Assert.Same(service, surface.ServiceContainer.GetService(typeof(object))); - Assert.Same(service, surface.GetService(typeof(object))); - Assert.Same(service, host.GetService(typeof(object))); - } - - [WinFormsFact] - public void DesignerHost_AddService_InvokeDisposed_ThrowsObjectDisposedException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - surface.Dispose(); - ServiceCreatorCallback callback = (container, service) => new object(); - Assert.Throws(() => host.AddService(typeof(object), new object())); - Assert.Throws(() => host.AddService(typeof(object), new object(), true)); - Assert.Throws(() => host.AddService(typeof(object), new object(), false)); - Assert.Throws(() => host.AddService(typeof(object), callback)); - Assert.Throws(() => host.AddService(typeof(object), callback, true)); - Assert.Throws(() => host.AddService(typeof(object), callback, false)); - } - - [WinFormsFact] - public void DesignerHost_Dispose_Invoke_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - IDisposable disposable = Assert.IsAssignableFrom(host); - Assert.Throws(() => disposable.Dispose()); - } - - [WinFormsFact(Skip = "Unstable test, see: https://github.com/dotnet/winforms/issues/1460")] - public void DesignerHost_Add_DesignerDisposeThrowsDuringUnloadingDispose_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - surface.BeginLoad(typeof(RootDesignerComponent)); - - using ThrowingDesignerDisposeComponent component = new(); - host.Container.Add(component); - Assert.Throws(() => surface.Dispose()); - Assert.False(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.False(host.Loading); - } - - [WinFormsFact(Skip = "Unstable test, see: https://github.com/dotnet/winforms/issues/1151")] - public void DesignerHost_Add_ComponentDisposeThrowsDuringUnloadingDispose_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - surface.BeginLoad(typeof(RootDesignerComponent)); - - using ThrowingDisposeDesignerComponent component = new(); - host.Container.Add(component); - Assert.Throws(() => surface.Dispose()); - Assert.False(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.False(host.Loading); - } - - [WinFormsFact(Skip = "Unstable test, see: https://github.com/dotnet/winforms/issues/1460")] - public void DesignerHost_Add_RootDesignerDisposeThrowsDuringUnloadingDispose_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - surface.BeginLoad(typeof(ThrowingRootDesignerDisposeComponent)); - - Assert.Throws(() => surface.Dispose()); - Assert.False(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.False(host.Loading); - } - - [WinFormsFact(Skip = "Unstable test, see: https://github.com/dotnet/winforms/issues/1460")] - public void DesignerHost_Add_RootComponentDisposeThrowsDuringUnloadingDispose_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - surface.BeginLoad(typeof(ThrowingDisposeRootDesignerComponent)); - Assert.Throws(() => surface.Dispose()); - Assert.False(surface.IsLoaded); - Assert.Empty(surface.LoadErrors); - Assert.False(host.Loading); - } - - [WinFormsFact] - public void DesignerHost_CreateComponent_NullComponentType_ThrowsArgumentNullException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.Throws("componentType", () => host.CreateComponent(null)); - } - - [WinFormsFact] - public void DesignerHost_CreateTransaction_Invoke_ReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction1 = host.CreateTransaction(); - Assert.False(transaction1.Canceled); - Assert.False(transaction1.Committed); - Assert.Equal("No Description Available", transaction1.Description); - Assert.True(host.InTransaction); - Assert.Equal("No Description Available", host.TransactionDescription); - - DesignerTransaction transaction2 = host.CreateTransaction(); - Assert.False(transaction2.Canceled); - Assert.False(transaction2.Committed); - Assert.Equal("No Description Available", transaction2.Description); - Assert.True(host.InTransaction); - Assert.Equal("No Description Available", host.TransactionDescription); - - transaction2.Cancel(); - } - - [WinFormsTheory] - [InlineData(null, "No Description Available")] - [InlineData("", "")] - [InlineData("Description", "Description")] - public void DesignerHost_CreateTransaction_InvokeWithDescription_ReturnsExpected(string description, string expectedDescription) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction1 = host.CreateTransaction(description); - Assert.False(transaction1.Canceled); - Assert.False(transaction1.Committed); - Assert.Equal(expectedDescription, transaction1.Description); - Assert.True(host.InTransaction); - Assert.Equal(expectedDescription, host.TransactionDescription); - - DesignerTransaction transaction2 = host.CreateTransaction("CustomDescription"); - Assert.False(transaction2.Canceled); - Assert.False(transaction2.Committed); - Assert.Equal("CustomDescription", transaction2.Description); - Assert.True(host.InTransaction); - Assert.Equal("CustomDescription", host.TransactionDescription); - - transaction2.Cancel(); - } - - [WinFormsFact] - public void DesignerHost_CreateTransaction_InvokeWithTransactionOpeningAndTransactionOpened_CallsHandlers() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - int openingCallCount = 0; - EventHandler openingHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(EventArgs.Empty, e); - openingCallCount++; - }; - int openedCallCount = 0; - EventHandler openedHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(EventArgs.Empty, e); - Assert.True(openedCallCount < openingCallCount); - openedCallCount++; - }; - host.TransactionOpening += openingHandler; - host.TransactionOpened += openedHandler; - - // With handler. - DesignerTransaction transaction1 = host.CreateTransaction("Description1"); - Assert.Equal(1, openingCallCount); - Assert.Equal(1, openedCallCount); - - // Create again. - DesignerTransaction transaction2 = host.CreateTransaction("Description2"); - Assert.Equal(2, openingCallCount); - Assert.Equal(2, openedCallCount); - - // Remove handler. - host.TransactionOpening -= openingHandler; - host.TransactionOpened -= openedHandler; - DesignerTransaction transaction3 = host.CreateTransaction("Description2"); - Assert.Equal(2, openingCallCount); - Assert.Equal(2, openedCallCount); - - transaction3.Cancel(); - transaction2.Cancel(); - transaction1.Cancel(); - } - - [WinFormsFact] - public void DesignerHost_CreateTransaction_Cancel_Success() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction1 = host.CreateTransaction("Description1"); - DesignerTransaction transaction2 = host.CreateTransaction("Description2"); - - // Cancel first. - transaction2.Cancel(); - Assert.False(transaction1.Canceled); - Assert.False(transaction1.Committed); - Assert.Equal("Description1", transaction1.Description); - Assert.True(transaction2.Canceled); - Assert.False(transaction2.Committed); - Assert.Equal("Description2", transaction2.Description); - Assert.True(host.InTransaction); - Assert.Equal("Description1", host.TransactionDescription); - - // Cancel again. - transaction2.Cancel(); - Assert.False(transaction1.Canceled); - Assert.False(transaction1.Committed); - Assert.Equal("Description1", transaction1.Description); - Assert.True(transaction2.Canceled); - Assert.False(transaction2.Committed); - Assert.Equal("Description2", transaction2.Description); - Assert.True(host.InTransaction); - Assert.Equal("Description1", host.TransactionDescription); - - // Cancel second. - transaction1.Cancel(); - Assert.True(transaction1.Canceled); - Assert.False(transaction1.Committed); - Assert.Equal("Description1", transaction1.Description); - Assert.True(transaction2.Canceled); - Assert.False(transaction2.Committed); - Assert.Equal("Description2", transaction2.Description); - Assert.False(host.InTransaction); - Assert.Null(host.TransactionDescription); - } - - [WinFormsFact] - public void DesignerHost_CreateTransaction_CancelWithTransactionClosingAndTransactionClosed_CallsHandlers() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction1 = host.CreateTransaction("Description1"); - DesignerTransaction transaction2 = host.CreateTransaction("Description2"); - - bool expectedLastTransaction = false; - int closingCallCount = 0; - DesignerTransactionCloseEventHandler closingHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.False(e.TransactionCommitted); - Assert.Equal(expectedLastTransaction, e.LastTransaction); - closingCallCount++; - }; - int closedCallCount = 0; - DesignerTransactionCloseEventHandler closedHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.False(e.TransactionCommitted); - Assert.Equal(expectedLastTransaction, e.LastTransaction); - Assert.True(closedCallCount < closingCallCount); - closedCallCount++; - }; - host.TransactionClosing += closingHandler; - host.TransactionClosed += closedHandler; - - // With handler. - transaction2.Cancel(); - Assert.False(transaction1.Canceled); - Assert.True(transaction2.Canceled); - Assert.Equal(1, closingCallCount); - Assert.Equal(1, closedCallCount); - - // Cancel again. - transaction2.Cancel(); - Assert.False(transaction1.Canceled); - Assert.True(transaction2.Canceled); - Assert.Equal(1, closingCallCount); - Assert.Equal(1, closedCallCount); - - // Cancel second. - expectedLastTransaction = true; - transaction1.Cancel(); - Assert.True(transaction1.Canceled); - Assert.True(transaction2.Canceled); - Assert.Equal(2, closingCallCount); - Assert.Equal(2, closedCallCount); - - // Remove handler. - host.TransactionClosing -= closingHandler; - host.TransactionClosed -= closedHandler; - DesignerTransaction transaction3 = host.CreateTransaction("Description1"); - transaction3.Cancel(); - Assert.True(transaction3.Canceled); - Assert.Equal(2, closingCallCount); - Assert.Equal(2, closedCallCount); - } - - [WinFormsFact] - public void DesignerHost_CreateTransaction_CancelNested_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction1 = host.CreateTransaction("Description1"); - DesignerTransaction transaction2 = host.CreateTransaction("Description2"); - Assert.Throws(() => transaction1.Cancel()); - } - - [WinFormsFact] - public void DesignerHost_CreateTransaction_Commit_Success() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction1 = host.CreateTransaction("Description1"); - DesignerTransaction transaction2 = host.CreateTransaction("Description2"); - - // Commit first. - transaction2.Commit(); - Assert.False(transaction1.Canceled); - Assert.False(transaction1.Committed); - Assert.Equal("Description1", transaction1.Description); - Assert.False(transaction2.Canceled); - Assert.True(transaction2.Committed); - Assert.Equal("Description2", transaction2.Description); - Assert.True(host.InTransaction); - Assert.Equal("Description1", host.TransactionDescription); - - // Commit again. - transaction2.Commit(); - Assert.False(transaction1.Canceled); - Assert.False(transaction1.Committed); - Assert.Equal("Description1", transaction1.Description); - Assert.False(transaction2.Canceled); - Assert.True(transaction2.Committed); - Assert.Equal("Description2", transaction2.Description); - Assert.True(host.InTransaction); - Assert.Equal("Description1", host.TransactionDescription); - - // Commit second. - transaction1.Commit(); - Assert.False(transaction1.Canceled); - Assert.True(transaction1.Committed); - Assert.Equal("Description1", transaction1.Description); - Assert.False(transaction2.Canceled); - Assert.True(transaction2.Committed); - Assert.Equal("Description2", transaction2.Description); - Assert.False(host.InTransaction); - Assert.Null(host.TransactionDescription); - } - - [WinFormsFact] - public void DesignerHost_CreateTransaction_CommitWithTransactionClosingAndTransactionClosed_CallsHandlers() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction1 = host.CreateTransaction("Description1"); - DesignerTransaction transaction2 = host.CreateTransaction("Description2"); - - bool expectedLastTransaction = false; - int closingCallCount = 0; - DesignerTransactionCloseEventHandler closingHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.True(e.TransactionCommitted); - Assert.Equal(expectedLastTransaction, e.LastTransaction); - closingCallCount++; - }; - int closedCallCount = 0; - DesignerTransactionCloseEventHandler closedHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.True(e.TransactionCommitted); - Assert.Equal(expectedLastTransaction, e.LastTransaction); - Assert.True(closedCallCount < closingCallCount); - closedCallCount++; - }; - host.TransactionClosing += closingHandler; - host.TransactionClosed += closedHandler; - - // With handler. - transaction2.Commit(); - Assert.False(transaction1.Committed); - Assert.True(transaction2.Committed); - Assert.Equal(1, closingCallCount); - Assert.Equal(1, closedCallCount); - - // Commit again. - transaction2.Commit(); - Assert.False(transaction1.Committed); - Assert.True(transaction2.Committed); - Assert.Equal(1, closingCallCount); - Assert.Equal(1, closedCallCount); - - // Commit second. - expectedLastTransaction = true; - transaction1.Commit(); - Assert.True(transaction1.Committed); - Assert.True(transaction2.Committed); - Assert.Equal(2, closingCallCount); - Assert.Equal(2, closedCallCount); - - // Remove handler. - host.TransactionClosing -= closingHandler; - host.TransactionClosed -= closedHandler; - DesignerTransaction transaction3 = host.CreateTransaction("Description1"); - transaction3.Commit(); - Assert.True(transaction3.Committed); - Assert.Equal(2, closingCallCount); - Assert.Equal(2, closedCallCount); - } - - [WinFormsFact] - public void DesignerHost_CreateTransaction_CommitNested_ThrowsInvalidOperationException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - DesignerTransaction transaction1 = host.CreateTransaction("Description1"); - DesignerTransaction transaction2 = host.CreateTransaction("Description2"); - Assert.Throws(() => transaction1.Commit()); - } - - public static IEnumerable DesignerHost_EndLoad_TestData() - { - yield return new object[] { null, true, null }; - yield return new object[] { null, true, Array.Empty() }; - yield return new object[] { null, true, new object[] { new Exception() } }; - yield return new object[] { null, true, new object[] { "abc" } }; - yield return new object[] { null, true, new object[] { null } }; - yield return new object[] { null, false, null }; - yield return new object[] { null, false, Array.Empty() }; - yield return new object[] { null, false, new object[] { new Exception() } }; - yield return new object[] { null, false, new object[] { "abc" } }; - yield return new object[] { null, false, new object[] { null } }; - yield return new object[] { string.Empty, true, null }; - yield return new object[] { string.Empty, true, Array.Empty() }; - yield return new object[] { string.Empty, true, new object[] { new Exception() } }; - yield return new object[] { string.Empty, true, new object[] { "abc" } }; - yield return new object[] { string.Empty, true, new object[] { null } }; - yield return new object[] { string.Empty, false, null }; - yield return new object[] { string.Empty, false, Array.Empty() }; - yield return new object[] { string.Empty, false, new object[] { new Exception() } }; - yield return new object[] { string.Empty, false, new object[] { "abc" } }; - yield return new object[] { string.Empty, false, new object[] { null } }; - yield return new object[] { "baseClassName", true, null }; - yield return new object[] { "baseClassName", true, new object[] { new Exception() } }; - yield return new object[] { "baseClassName", true, new object[] { "abc" } }; - yield return new object[] { "baseClassName", true, new object[] { null } }; - yield return new object[] { "baseClassName", false, null }; - yield return new object[] { "baseClassName", false, new object[] { new Exception() } }; - yield return new object[] { "baseClassName", false, new object[] { "abc" } }; - yield return new object[] { "baseClassName", false, new object[] { null } }; - } - - [WinFormsTheory] - [MemberData(nameof(DesignerHost_EndLoad_TestData))] - public void DesignerHost_EndLoad_NotCalledBeginLoad_Success(string baseClassName, bool successful, ICollection errorCollection) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - host.EndLoad(baseClassName, successful, errorCollection); - Assert.False(surface.IsLoaded); - Assert.False(host.Loading); - Assert.Empty(surface.LoadErrors); - Assert.Null(host.RootComponent); - Assert.Same(baseClassName, host.RootComponentClassName); - } - - [WinFormsFact] - public void DesignerHost_GetComponents_Invoke_ReturnsFiltered() - { - ComponentCollection collection = new(new Component[] { new Component() }); - Mock mockFilterService = new(MockBehavior.Strict); - mockFilterService - .Setup(f => f.FilterComponents(new ComponentCollection(Array.Empty()))) - .Returns(collection); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(mockFilterService.Object); - using SubDesignSurface surface = new(mockServiceProvider.Object); - Assert.Same(collection, surface.ComponentContainer.Components); - } - - [WinFormsFact] - public void DesignerHost_GetDesigner_InvokeNonEmpty_ReturnsExpected() - { - using SubDesignSurface surface = new(); - IDesignerHost host = surface.Host; - using RootDesignerComponent component = new(); - host.Container.Add(component); - Assert.IsType(host.GetDesigner(component)); - Assert.Null(host.GetDesigner(new Component())); - Assert.Null(host.GetDesigner(new RootDesignerComponent())); - } - - [WinFormsFact] - public void DesignerHost_GetDesigner_InvokeEmpty_ReturnsExpected() - { - using SubDesignSurface surface = new(); - IDesignerHost host = surface.Host; - Assert.Null(host.GetDesigner(new Component())); - Assert.Null(host.GetDesigner(new RootDesignerComponent())); - } - - [WinFormsFact] - public void DesignerHost_GetDesigner_NullComponent_ThrowsArgumentNullException() - { - using SubDesignSurface surface = new(); - IDesignerHost host = surface.Host; - Assert.Throws("component", () => host.GetDesigner(null)); - } - - public static IEnumerable GetService_InvalidLoader_TestData() - { - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(It.IsAny())); - yield return new object[] { mockLoader.Object, null }; - - Mock mockNullServiceProviderLoader = new(MockBehavior.Strict); - mockNullServiceProviderLoader - .Setup(l => l.BeginLoad(It.IsAny())); - mockNullServiceProviderLoader - .As() - .Setup(p => p.GetService(typeof(IMultitargetHelperService))) - .Returns(null); - yield return new object[] { mockNullServiceProviderLoader.Object, null }; - - object o = new(); - Mock mockInvalidServiceProviderLoader = new(MockBehavior.Strict); - mockInvalidServiceProviderLoader - .Setup(l => l.BeginLoad(It.IsAny())); - mockInvalidServiceProviderLoader - .As() - .Setup(p => p.GetService(typeof(IMultitargetHelperService))) - .Returns(o); - yield return new object[] { mockInvalidServiceProviderLoader.Object, o }; - } - - [WinFormsTheory] - [MemberData(nameof(GetService_InvalidLoader_TestData))] - public void DesignerHost_GetService_IMultitargetHelperServiceWithLoader_ReturnsExpected(DesignerLoader loader, object expected) - { - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(null); - SubDesignSurface surface = new(mockServiceProvider.Object); - surface.BeginLoad(loader); - - IDesignerLoaderHost2 host = surface.Host; - Assert.Same(expected, host.GetService(typeof(IMultitargetHelperService))); - } - - [WinFormsFact] - public void DesignerHost_GetServiceIMultitargetHelperServiceWithoutLoader_ReturnsNull() - { - object service = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - Assert.Null(host.GetService(typeof(IMultitargetHelperService))); - } - - [WinFormsFact] - public void DesignerHost_GetService_InvokeWithServiceProvider_ReturnsExpected() - { - object service = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(int))) - .Returns(service) - .Verifiable(); - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - Assert.Same(service, host.GetService(typeof(int))); - mockServiceProvider.Verify(p => p.GetService(typeof(int)), Times.Once()); - } - - [WinFormsFact] - public void DesignerHost_GetService_InvokeWithoutServiceProvider_ReturnsNull() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.Null(host.GetService(typeof(int))); - } - - [WinFormsFact] - public void DesignerHost_GetService_IContainer_ReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.Same(host, host.GetService(typeof(IContainer))); - } - - [WinFormsTheory] - [InlineData(typeof(IServiceContainer))] - [InlineData(typeof(ServiceContainer))] - public void DesignerHost_GetService_IServiceContainer_ReturnsExpected(Type serviceType) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.Same(surface.ServiceContainer, host.GetService(serviceType)); - } - - [WinFormsFact] - public void DesignerHost_GetService_NullType_ThrowsArgumentNullException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - Assert.Throws("service", () => host.GetService(null)); - } - - [WinFormsTheory] - [InlineData("", null)] - [InlineData("", typeof(int))] - [InlineData("typeName", null)] - [InlineData("typeName", typeof(int))] - [InlineData("System.Object", null)] - [InlineData("System.Object", typeof(int))] - public void DesignerHost_GetType_InvokeWithTypeResolutionService_ReturnsExpected(string typeName, Type expected) - { - Mock mockTypeResolutionService = new(MockBehavior.Strict); - mockTypeResolutionService - .Setup(s => s.GetType(typeName)) - .Returns(expected) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(mockTypeResolutionService.Object) - .Verifiable(); - using SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerHost host = surface.Host; - Assert.Equal(expected, host.GetType(typeName)); - mockServiceProvider.Verify(p => p.GetService(typeof(ITypeResolutionService)), Times.Once()); - mockTypeResolutionService.Verify(s => s.GetType(typeName), Times.Once()); - } - - public static IEnumerable GetType_InvalidTypeResolutionService_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [WinFormsTheory] - [MemberData(nameof(GetType_InvalidTypeResolutionService_TestData))] - public void DesignerHost_GetType_InvokeWithInvalidTypeResolutionService_ReturnsExpected(object service) - { - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(service) - .Verifiable(); - using SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerHost host = surface.Host; - Assert.Equal(typeof(int), host.GetType(typeof(int).FullName)); - mockServiceProvider.Verify(p => p.GetService(typeof(ITypeResolutionService)), Times.Once()); - } - - [WinFormsFact] - public void DesignerHost_GetType_NullTypeName_ThrowsArgumentNullException() - { - using SubDesignSurface surface = new(); - IDesignerHost host = surface.Host; - Assert.Throws("typeName", () => host.GetType(null)); - } - - private static readonly IDesignerHost s_placeholderHost = new Mock(MockBehavior.Strict).Object; - - public static IEnumerable ChangeActiveDesigner_TestData() - { - IDesignerLoaderHost2 otherHost = new SubDesignSurface().Host; - - yield return new object[] { null, 0, 0, 0 }; - - yield return new object[] { new ActiveDesignerEventArgs(s_placeholderHost, s_placeholderHost), 0, 1, 1 }; - yield return new object[] { new ActiveDesignerEventArgs(s_placeholderHost, otherHost), 0, 1, 1 }; - yield return new object[] { new ActiveDesignerEventArgs(s_placeholderHost, null), 0, 1, 1 }; - - yield return new object[] { new ActiveDesignerEventArgs(otherHost, s_placeholderHost), 1, 0, 0 }; - yield return new object[] { new ActiveDesignerEventArgs(otherHost, otherHost), 0, 0, 0 }; - yield return new object[] { new ActiveDesignerEventArgs(otherHost, null), 0, 0, 0 }; - - yield return new object[] { new ActiveDesignerEventArgs(null, s_placeholderHost), 1, 0, 0 }; - yield return new object[] { new ActiveDesignerEventArgs(null, otherHost), 0, 0, 0 }; - yield return new object[] { new ActiveDesignerEventArgs(null, null), 0, 0, 0 }; - } - - [WinFormsTheory] - [MemberData(nameof(ChangeActiveDesigner_TestData))] - public void DesignerHost_ChangeActiveDesigner_Invoke_Success(ActiveDesignerEventArgs eventArgs, int expectedActivatedCallCount, int expectedDeactivatedCallCount, int expectedFlushCount) - { - Mock mockDesignerEventService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerEventService))) - .Returns(mockDesignerEventService.Object); - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - - int activatedCallCount = 0; - EventHandler activatedHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(EventArgs.Empty, e); - activatedCallCount++; - }; - host.Activated += activatedHandler; - int deactivatedCallCount = 0; - EventHandler deactivatedHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(EventArgs.Empty, e); - deactivatedCallCount++; - }; - host.Deactivated += deactivatedHandler; - int flushCallCount = 0; - EventHandler flushedHandler = (sender, e) => - { - Assert.Same(surface, sender); - Assert.Same(EventArgs.Empty, e); - flushCallCount++; - }; - surface.Flushed += flushedHandler; - - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad((IDesignerLoaderHost)surface.ComponentContainer)); - mockLoader - .Setup(l => l.Flush()); - surface.BeginLoad(mockLoader.Object); - Assert.Equal(0, activatedCallCount); - Assert.Equal(0, deactivatedCallCount); - Assert.Equal(0, flushCallCount); - - // Replace placeholders for "this" - ActiveDesignerEventArgs actualEventArgs = null; - if (eventArgs is not null) - { - IDesignerHost newDesigner = eventArgs.NewDesigner == s_placeholderHost ? host : eventArgs.NewDesigner; - IDesignerHost oldDesigner = eventArgs.OldDesigner == s_placeholderHost ? host : eventArgs.OldDesigner; - actualEventArgs = new ActiveDesignerEventArgs(oldDesigner, newDesigner); - } - - mockDesignerEventService.Raise(s => s.ActiveDesignerChanged += null, actualEventArgs); - Assert.Equal(expectedActivatedCallCount, activatedCallCount); - Assert.Equal(expectedDeactivatedCallCount, deactivatedCallCount); - Assert.Equal(expectedFlushCount, flushCallCount); - - // Should not invoke if removed. - host.Activated -= activatedHandler; - host.Deactivated -= deactivatedHandler; - surface.Flushed -= flushedHandler; - mockDesignerEventService.Raise(s => s.ActiveDesignerChanged += null, actualEventArgs); - Assert.Equal(expectedActivatedCallCount, activatedCallCount); - Assert.Equal(expectedDeactivatedCallCount, deactivatedCallCount); - Assert.Equal(expectedFlushCount, flushCallCount); - } - - [WinFormsFact] - public void DesignerHost_Remove_Invoke_Success() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - using RootDesignerComponent rootComponent = new(); - using DesignerComponent component = new(); - host.Container.Add(rootComponent); - host.Container.Add(component); - host.Container.Remove(rootComponent); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Null(host.RootComponent); - Assert.Null(host.RootComponentClassName); - Assert.Null(host.GetDesigner(rootComponent)); - Assert.NotNull(host.GetDesigner(component)); - Assert.Null(rootComponent.Container); - Assert.Null(rootComponent.Site); - Assert.Same(host.Container, component.Container); - Assert.NotNull(component.Site); - - // Remove again. - host.Container.Remove(rootComponent); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Null(host.RootComponent); - Assert.Null(host.RootComponentClassName); - Assert.Null(host.GetDesigner(rootComponent)); - Assert.NotNull(host.GetDesigner(component)); - Assert.Null(rootComponent.Container); - Assert.Null(rootComponent.Site); - Assert.Same(host.Container, component.Container); - Assert.NotNull(component.Site); - - // Remove other. - host.Container.Remove(component); - Assert.Empty(host.Container.Components); - Assert.Null(host.RootComponent); - Assert.Null(host.RootComponentClassName); - Assert.Null(host.GetDesigner(rootComponent)); - Assert.Null(host.GetDesigner(component)); - Assert.Null(rootComponent.Container); - Assert.Null(rootComponent.Site); - Assert.Null(component.Container); - Assert.Null(component.Site); - } - - public static IEnumerable Remove_IExtenderProviderServiceWithoutDefault_TestData() - { - yield return new object[] { new RootDesignerComponent(), 0, 0 }; - yield return new object[] { new RootExtenderProviderDesignerComponent(), 1, 1 }; - - RootExtenderProviderDesignerComponent readOnlyComponent = new(); - TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly)); - yield return new object[] { readOnlyComponent, 0, 1 }; - - RootExtenderProviderDesignerComponent inheritedComponent = new(); - TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited)); - yield return new object[] { inheritedComponent, 1, 1 }; - - RootExtenderProviderDesignerComponent notInheritedComponent = new(); - TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited)); - yield return new object[] { notInheritedComponent, 1, 1 }; - } - - [WinFormsTheory] - [MemberData(nameof(Remove_IExtenderProviderServiceWithoutDefault_TestData))] - public void DesignerHost_Remove_IExtenderProviderServiceWithoutDefault_Success(Component component, int expectedAddCallCount, int expectedRemoveCallCount) - { - Mock mockExtenderProviderService = new(MockBehavior.Strict); - mockExtenderProviderService - .Setup(s => s.AddExtenderProvider(component as IExtenderProvider)); - mockExtenderProviderService - .Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider)) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(mockExtenderProviderService.Object) - .Verifiable(); - - using SubDesignSurface surface = new(mockServiceProvider.Object); - surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService)); - IDesignerLoaderHost2 host = surface.Host; - - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Same(host, component.Container); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedAddCallCount)); - - // Remove. - host.Container.Remove(component); - Assert.Empty(host.Container.Components); - Assert.Null(component.Container); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedAddCallCount + expectedRemoveCallCount)); - mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedRemoveCallCount)); - - // Remove again. - host.Container.Remove(component); - Assert.Empty(host.Container.Components); - Assert.Null(component.Container); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedAddCallCount + expectedRemoveCallCount)); - mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedRemoveCallCount)); - } - - public static IEnumerable Remove_IExtenderProviderServiceWithDefault_TestData() - { - yield return new object[] { new RootDesignerComponent() }; - yield return new object[] { new RootExtenderProviderDesignerComponent() }; - - RootExtenderProviderDesignerComponent readOnlyComponent = new(); - TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly)); - yield return new object[] { readOnlyComponent }; - - RootExtenderProviderDesignerComponent inheritedComponent = new(); - TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited)); - yield return new object[] { inheritedComponent }; - - RootExtenderProviderDesignerComponent notInheritedComponent = new(); - TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited)); - yield return new object[] { notInheritedComponent }; - } - - [WinFormsTheory] - [MemberData(nameof(Remove_IExtenderProviderServiceWithDefault_TestData))] - public void DesignerHost_Remove_IExtenderProviderServiceWithDefault_Success(Component component) - { - Mock mockExtenderProviderService = new(MockBehavior.Strict); - mockExtenderProviderService - .Setup(s => s.AddExtenderProvider(component as IExtenderProvider)) - .Verifiable(); - mockExtenderProviderService - .Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider)); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ContainerFilterService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(mockExtenderProviderService.Object) - .Verifiable(); - - SubDesignSurface surface = new(mockServiceProvider.Object); - IDesignerLoaderHost2 host = surface.Host; - - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - Assert.Empty(component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never()); - - // Remove. - host.Container.Remove(component); - Assert.Empty(host.Container.Components); - Assert.Null(component.Container); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Never()); - - // Remove again. - host.Container.Remove(component); - Assert.Empty(host.Container.Components); - Assert.Null(component.Container); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Never()); - } - - [WinFormsTheory] - [MemberData(nameof(InvalidIExtenderProviderService_TestData))] - public void DesignerHost_Remove_InvalidIExtenderProviderServiceWithoutDefault_CallsParentGetService(Mock mockParentProvider) - { - using SubDesignSurface surface = new(mockParentProvider?.Object); - surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService)); - IDesignerLoaderHost2 host = surface.Host; - using RootExtenderProviderDesignerComponent component = new(); - - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Once()); - - host.Container.Remove(component); - Assert.Empty(host.Container.Components); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(2)); - } - - [WinFormsTheory] - [MemberData(nameof(InvalidIExtenderProviderService_TestData))] - public void DesignerHost_Remove_InvalidIExtenderProviderServiceWithDefault_DoesNotCallParentGetService(Mock mockParentProvider) - { - using SubDesignSurface surface = new(mockParentProvider?.Object); - IDesignerLoaderHost2 host = surface.Host; - using RootExtenderProviderDesignerComponent component = new(); - - host.Container.Add(component); - Assert.Same(component, Assert.Single(host.Container.Components)); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - - host.Container.Remove(component); - Assert.Empty(host.Container.Components); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - } - - [WinFormsFact] - public void Remove_ComponentNotInContainerNonEmpty_Nop() - { - using SubDesignSurface surface1 = new(); - using SubDesignSurface surface2 = new(); - IDesignerLoaderHost2 host1 = surface1.Host; - IDesignerLoaderHost2 host2 = surface2.Host; - - RootDesignerComponent otherComponent = new(); - using RootDesignerComponent component = new(); - host1.Container.Add(otherComponent); - host2.Container.Add(component); - host2.Container.Remove(otherComponent); - host2.Container.Remove(new Component()); - Assert.Same(otherComponent, Assert.Single(host1.Container.Components)); - Assert.Same(component, Assert.Single(host2.Container.Components)); - } - - [WinFormsFact] - public void Remove_ComponentNotInContainerEmpty_Nop() - { - using SubDesignSurface surface1 = new(); - using SubDesignSurface surface2 = new(); - IDesignerLoaderHost2 host1 = surface1.Host; - IDesignerLoaderHost2 host2 = surface2.Host; - - using RootDesignerComponent otherComponent = new(); - host1.Container.Add(otherComponent); - host2.Container.Remove(otherComponent); - host2.Container.Remove(new Component()); - Assert.Same(otherComponent, Assert.Single(host1.Container.Components)); - Assert.Empty(host2.Container.Components); - } - - [WinFormsFact] - public void Remove_InvokeWithComponentRemoved_CallsHandler() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - - using RootDesignerComponent component1 = new(); - using DesignerComponent component2 = new(); - int componentRemovingCallCount = 0; - ComponentEventHandler componentRemovingHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(component1, e.Component); - Assert.NotNull(e.Component.Site); - componentRemovingCallCount++; - }; - changeService.ComponentRemoving += componentRemovingHandler; - - int componentRemovedCallCount = 0; - ComponentEventHandler componentRemovedHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(component1, e.Component); - Assert.NotNull(e.Component.Site); - Assert.True(componentRemovedCallCount < componentRemovingCallCount); - componentRemovedCallCount++; - }; - changeService.ComponentRemoved += componentRemovedHandler; - - host.Container.Add(component1); - host.Container.Add(component2); - - // With handler. - host.Container.Remove(component1); - Assert.Null(component1.Container); - Assert.Null(component1.Site); - Assert.Same(host.Container, component2.Container); - Assert.NotNull(component2.Site); - Assert.Same(component2, Assert.Single(host.Container.Components)); - Assert.Equal(1, componentRemovingCallCount); - Assert.Equal(1, componentRemovedCallCount); - - // Remove again. - host.Container.Remove(component1); - Assert.Null(component1.Container); - Assert.Null(component1.Site); - Assert.Same(host.Container, component2.Container); - Assert.NotNull(component2.Site); - Assert.Same(component2, Assert.Single(host.Container.Components)); - Assert.Equal(1, componentRemovingCallCount); - Assert.Equal(1, componentRemovedCallCount); - - // Remove handler. - changeService.ComponentRemoving -= componentRemovingHandler; - changeService.ComponentRemoved -= componentRemovedHandler; - host.Container.Remove(component2); - Assert.Null(component1.Container); - Assert.Null(component1.Site); - Assert.Null(component2.Container); - Assert.Null(component2.Site); - Assert.Empty(host.Container.Components); - Assert.Equal(1, componentRemovingCallCount); - Assert.Equal(1, componentRemovedCallCount); - } - - [WinFormsFact] - public void DesignerHost_Remove_SetSiteToNullInComponentRemoving_Success() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - - using RootDesignerComponent component = new(); - int componentRemovingCallCount = 0; - ComponentEventHandler componentRemovingHandler = (sender, e) => - { - component.Site = null; - componentRemovingCallCount++; - }; - changeService.ComponentRemoving += componentRemovingHandler; - - host.Container.Add(component); - host.Container.Remove(component); - Assert.Null(component.Container); - Assert.Null(component.Site); - } - - [WinFormsFact] - public void DesignerHost_Remove_SiteHasDictionary_ClearsDictionary() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - using RootDesignerComponent component = new(); - host.Container.Add(component); - IDictionaryService service = Assert.IsAssignableFrom(component.Site); - service.SetValue("key", "value"); - Assert.Equal("value", service.GetValue("key")); - - host.Container.Remove(component); - Assert.Null(service.GetValue("key")); - } - - [WinFormsFact] - public void DesignerHost_RemoveService_Invoke_GetServiceReturnsExpected() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - host.AddService(typeof(object), new object()); - host.RemoveService(typeof(object)); - Assert.Null(surface.ServiceContainer.GetService(typeof(object))); - Assert.Null(surface.GetService(typeof(object))); - Assert.Null(host.GetService(typeof(object))); - } - - [WinFormsTheory] - [BoolData] - public void DesignerHost_RemoveService_InvokeBool_GetServiceReturnsExpected(bool promote) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - - host.AddService(typeof(object), new object()); - host.RemoveService(typeof(object), promote); - Assert.Null(surface.ServiceContainer.GetService(typeof(object))); - Assert.Null(surface.GetService(typeof(object))); - Assert.Null(host.GetService(typeof(object))); - } - - [WinFormsFact] - public void DesignerHost_RemoveService_InvokeDisposed_ThrowsObjectDisposedException() - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - surface.Dispose(); - ServiceCreatorCallback callback = (container, service) => new object(); - Assert.Throws(() => host.RemoveService(typeof(object))); - Assert.Throws(() => host.RemoveService(typeof(object), true)); - Assert.Throws(() => host.RemoveService(typeof(object), false)); - } - - public static IEnumerable OnComponentChanging_TestData() - { - yield return new object[] { null, null }; - yield return new object[] { new object(), TypeDescriptor.GetProperties(typeof(string))[0] }; - } - - [WinFormsTheory] - [MemberData(nameof(OnComponentChanging_TestData))] - public void DesignerHost_IComponentChangeServiceOnComponentChanging_Invoke_CallsComponentChanging(object component, MemberDescriptor member) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - - int callCount = 0; - ComponentChangingEventHandler handler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(component, e.Component); - Assert.Same(member, e.Member); - callCount++; - }; - changeService.ComponentChanging += handler; - Assert.False(host.Loading); - - // With handler. - changeService.OnComponentChanging(component, member); - Assert.Equal(1, callCount); - - // Call again. - changeService.OnComponentChanging(component, member); - Assert.Equal(2, callCount); - - // Remove handler. - changeService.ComponentChanging -= handler; - changeService.OnComponentChanging(component, member); - Assert.Equal(2, callCount); - } - - [WinFormsTheory] - [MemberData(nameof(OnComponentChanging_TestData))] - public void DesignerHost_IComponentChangeServiceOnComponentChanging_InvokeLoading_DoesNotCallHandler(object component, MemberDescriptor member) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - - int callCount = 0; - ComponentChangingEventHandler handler = (sender, e) => callCount++; - changeService.ComponentChanging += handler; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - Assert.True(host.Loading); - - // With handler. - changeService.OnComponentChanging(component, member); - Assert.Equal(0, callCount); - - // Call again. - changeService.OnComponentChanging(component, member); - Assert.Equal(0, callCount); - - // Remove handler. - changeService.ComponentChanging -= handler; - changeService.OnComponentChanging(component, member); - Assert.Equal(0, callCount); - } - - public static IEnumerable OnComponentChanged_TestData() - { - yield return new object[] { null, null, null, null }; - yield return new object[] { new object(), TypeDescriptor.GetProperties(typeof(string))[0], new object(), new object() }; - } - - [WinFormsTheory] - [MemberData(nameof(OnComponentChanged_TestData))] - public void DesignerHost_IComponentChangeServiceOnComponentChanged_Invoke_CallsComponentChanged(object component, MemberDescriptor member, object oldValue, object newValue) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - - int callCount = 0; - ComponentChangedEventHandler handler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(component, e.Component); - Assert.Same(member, e.Member); - Assert.Same(oldValue, e.OldValue); - Assert.Same(newValue, e.NewValue); - callCount++; - }; - changeService.ComponentChanged += handler; - Assert.False(host.Loading); - - // With handler. - changeService.OnComponentChanged(component, member, oldValue, newValue); - Assert.Equal(1, callCount); - - // Call again. - changeService.OnComponentChanged(component, member, oldValue, newValue); - Assert.Equal(2, callCount); - - // Remove handler. - changeService.ComponentChanged -= handler; - changeService.OnComponentChanged(component, member, oldValue, newValue); - Assert.Equal(2, callCount); - } - - [WinFormsTheory] - [MemberData(nameof(OnComponentChanged_TestData))] - public void DesignerHost_IComponentChangeServiceOnComponentChanged_InvokeLoading_DoesNotCallHandler(object component, MemberDescriptor member, object oldValue, object newValue) - { - SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - - int callCount = 0; - ComponentChangedEventHandler handler = (sender, e) => callCount++; - changeService.ComponentChanged += handler; - Mock mockLoader = new(MockBehavior.Strict); - mockLoader - .Setup(l => l.BeginLoad(host)); - surface.BeginLoad(mockLoader.Object); - Assert.True(host.Loading); - - // With handler. - changeService.OnComponentChanged(component, member, oldValue, newValue); - Assert.Equal(0, callCount); - - // Call again. - changeService.OnComponentChanged(component, member, oldValue, newValue); - Assert.Equal(0, callCount); - - // Remove handler. - changeService.ComponentChanged -= handler; - changeService.OnComponentChanged(component, member, oldValue, newValue); - Assert.Equal(0, callCount); - } - - [WinFormsFact] - public void DesignerHost_IReflect_UnderlyingSystemType_ReturnsExpected() - { - using SubDesignSurface surface = new(); - IReflect reflect = Assert.IsAssignableFrom(surface.Host); - Assert.Equal(typeof(IDesignerHost), reflect.UnderlyingSystemType); - } - - [WinFormsFact] - public void DesignerHost_IReflect_GetField_Success() - { - using SubDesignSurface surface = new(); - IReflect reflect = Assert.IsAssignableFrom(surface.Host); - Assert.Equal(typeof(IDesignerHost).GetField(nameof(IDesignerHost.Activate)), reflect.GetField(nameof(IDesignerHost.Activate), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)); - } - - [WinFormsFact] - public void DesignerHost_IReflect_GetFields_Success() - { - using SubDesignSurface surface = new(); - IReflect reflect = Assert.IsAssignableFrom(surface.Host); - Assert.Equal(typeof(IDesignerHost).GetFields(), reflect.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)); - } - - [WinFormsFact] - public void DesignerHost_IReflect_GetMember_Success() - { - using SubDesignSurface surface = new(); - IReflect reflect = Assert.IsAssignableFrom(surface.Host); - Assert.Equal(typeof(IDesignerHost).GetMember(nameof(IDesignerHost.Container)), reflect.GetMember(nameof(IDesignerHost.Container), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)); - } - - [WinFormsFact] - public void DesignerHost_IReflect_GetMembers_Success() - { - using SubDesignSurface surface = new(); - IReflect reflect = Assert.IsAssignableFrom(surface.Host); - Assert.Equal(typeof(IDesignerHost).GetMembers(), reflect.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)); - } - - [WinFormsFact] - public void DesignerHost_IReflect_GetMethod_Success() - { - using SubDesignSurface surface = new(); - IReflect reflect = Assert.IsAssignableFrom(surface.Host); - Assert.Equal(typeof(IDesignerHost).GetMethod(nameof(IDesignerHost.Activate)), reflect.GetMethod(nameof(IDesignerHost.Activate), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)); - Assert.Equal(typeof(IDesignerHost).GetMethod(nameof(IDesignerHost.Activate)), reflect.GetMethod(nameof(IDesignerHost.Activate), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, Array.Empty(), Array.Empty())); - } - - [WinFormsFact] - public void DesignerHost_IReflect_GetMethods_Success() - { - using SubDesignSurface surface = new(); - IReflect reflect = Assert.IsAssignableFrom(surface.Host); - Assert.Equal(typeof(IDesignerHost).GetMethods(), reflect.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)); - } - - [WinFormsFact] - public void DesignerHost_IReflect_GetProperty_Success() - { - using SubDesignSurface surface = new(); - IReflect reflect = Assert.IsAssignableFrom(surface.Host); - Assert.Equal(typeof(IDesignerHost).GetProperty(nameof(IDesignerHost.Container)), reflect.GetProperty(nameof(IDesignerHost.Container), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)); - Assert.Equal(typeof(IDesignerHost).GetProperty(nameof(IDesignerHost.Container)), reflect.GetProperty(nameof(IDesignerHost.Container), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, typeof(IContainer), Array.Empty(), Array.Empty())); - } - - [WinFormsFact] - public void DesignerHost_IReflect_GetProperties_Success() - { - using SubDesignSurface surface = new(); - IReflect reflect = Assert.IsAssignableFrom(surface.Host); - Assert.Equal(typeof(IDesignerHost).GetProperties(), reflect.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)); - } - - [WinFormsFact] - public void DesignerHost_IReflect_InvokeMember_ReturnsExpected() - { - using SubDesignSurface surface = new(); - IReflect reflect = Assert.IsAssignableFrom(surface.Host); - Assert.Equal(surface.Host.Container, reflect.InvokeMember(nameof(IDesignerHost.Container), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty, null, surface.Host, Array.Empty(), Array.Empty(), null, Array.Empty())); - } - - private class SubDesignSurface : DesignSurface - { - public SubDesignSurface() : base() - { - } - - public SubDesignSurface(IServiceProvider parentProvider) : base(parentProvider) - { - } - - public IDesignerLoaderHost2 Host => Assert.IsAssignableFrom(ComponentContainer); - - public new ServiceContainer ServiceContainer => base.ServiceContainer; - } - - private abstract class CustomDesigner : IDesigner - { - protected IComponent _initializedComponent; - - public IComponent Component => _initializedComponent; - - public DesignerVerbCollection Verbs { get; } - - public void DoDefaultAction() - { - } - - public void Dispose() => Dispose(true); - - protected virtual void Dispose(bool disposing) - { - } - - public abstract void Initialize(IComponent component); - } - - private class Designer : CustomDesigner - { - public override void Initialize(IComponent component) => _initializedComponent = component; - } - - [Designer(typeof(Designer))] - private class DesignerComponent : Component - { - } - - private class RootDesigner : Designer, IRootDesigner - { - public ViewTechnology[] SupportedTechnologies { get; } - - public object GetView(ViewTechnology technology) => throw new NotImplementedException(); - } - - [Designer(typeof(RootDesigner), typeof(IRootDesigner))] - private class RootDesignerComponent : Component - { - } - - [ProjectTargetFramework("ProjectTargetFramework")] - private class ClassWithProjectTargetFrameworkAttribute - { - } - - [Designer(typeof(RootDesigner), typeof(IRootDesigner))] - private class RootExtenderProviderDesignerComponent : Component, IExtenderProvider - { - public bool CanExtend(object extendee) => throw new NotImplementedException(); - } - - private class NonInitializingDesigner : RootDesigner - { - public override void Initialize(IComponent component) - { - } - } - - [Designer(typeof(NonInitializingDesigner), typeof(IRootDesigner))] - private class NonInitializingDesignerComponent : Component - { - } - - private class ThrowingInitializingDesigner : RootDesigner - { - public override void Initialize(IComponent component) - { - throw new DivideByZeroException(); - } - } - - [Designer(typeof(ThrowingInitializingDesigner), typeof(IRootDesigner))] - private class ThrowingInitializingDesignerComponent : Component - { - } - - private class CheckoutExceptionThrowingInitializingDesigner : RootDesigner - { - public override void Initialize(IComponent component) - { - throw CheckoutException.Canceled; - } - } - - [Designer(typeof(CheckoutExceptionThrowingInitializingDesigner), typeof(IRootDesigner))] - private class CheckoutExceptionThrowingInitializingDesignerComponent : Component - { - } - - private class ThrowingDisposeComponentDesigner : Designer - { - protected override void Dispose(bool disposing) - { - throw new NotImplementedException(); - } - } - - [Designer(typeof(ThrowingDisposeComponentDesigner))] - private class ThrowingDesignerDisposeComponent : Component - { - } - - [Designer(typeof(Designer))] - private class ThrowingDisposeDesignerComponent : Component - { - protected override void Dispose(bool disposing) - { - if (disposing) - { - throw new NotImplementedException(); - } - } - } - - private class ThrowingDisposeRootComponentDesigner : RootDesigner - { - protected override void Dispose(bool disposing) - { - throw new NotImplementedException(); - } - } - - [Designer(typeof(ThrowingDisposeRootComponentDesigner), typeof(IRootDesigner))] - private class ThrowingRootDesignerDisposeComponent : Component - { - } - - [Designer(typeof(RootDesigner), typeof(IRootDesigner))] - private class ThrowingDisposeRootDesignerComponent : Component - { - protected override void Dispose(bool disposing) - { - if (disposing) - { - throw new NotImplementedException(); - } - } - } - - [Designer(typeof(RootDesigner), typeof(IRootDesigner))] - private class CustomTypeDescriptionProviderComponent : Component - { - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerVerbCollectionTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerVerbCollectionTests.cs deleted file mode 100644 index 763fee93188..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerVerbCollectionTests.cs +++ /dev/null @@ -1,211 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.ComponentModel.Design.Tests; - -public class DesignerVerbCollectionTests -{ - [Fact] - public void DesignerVerbCollection_Ctor_Default() - { - DesignerVerbCollection collection = new(); - Assert.Empty(collection); - } - - public static IEnumerable Ctor_DesignerVerbArray_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new DesignerVerb[] { new DesignerVerb(null, null), null } }; - } - - [Theory] - [MemberData(nameof(Ctor_DesignerVerbArray_TestData))] - public void DesignerVerbCollection_Ctor_DesignerVerbArray(DesignerVerb[] value) - { - DesignerVerbCollection collection = new(value); - Assert.Equal(value, collection.Cast()); - } - - [Fact] - public void DesignerVerbCollection_Ctor_NullValue_ThrowsArgumentNullException() - { - Assert.Throws("value", () => new DesignerVerbCollection(null)); - } - - [Fact] - public void DesignerVerbCollection_Add_DesignerVerb_Success() - { - DesignerVerbCollection collection = new(); - - DesignerVerb value1 = new(null, null); - collection.Add(value1); - Assert.Same(value1, Assert.Single(collection)); - Assert.Same(value1, collection[0]); - Assert.True(collection.Contains(value1)); - Assert.Equal(0, collection.IndexOf(value1)); - - DesignerVerb value2 = new(null, null); - collection.Add(value2); - Assert.Equal(new object[] { value1, value2 }, collection.Cast()); - Assert.True(collection.Contains(value2)); - Assert.Equal(1, collection.IndexOf(value2)); - - collection.Add(null); - Assert.Equal(new object[] { value1, value2, null }, collection.Cast()); - Assert.True(collection.Contains(null)); - Assert.Equal(2, collection.IndexOf(null)); - } - - [Theory] - [MemberData(nameof(Ctor_DesignerVerbArray_TestData))] - public void DesignerVerbCollection_AddRange_DesignerVerbArray_Success(DesignerVerb[] value) - { - DesignerVerbCollection collection = new(); - collection.AddRange(value); - Assert.Equal(value, collection.Cast()); - - // Add again. - collection.AddRange(value); - Assert.Equal(value.Concat(value), collection.Cast()); - } - - [Theory] - [MemberData(nameof(Ctor_DesignerVerbArray_TestData))] - public void DesignerVerbCollection_AddRange_DesignerVerbCollection_Success(DesignerVerb[] value) - { - DesignerVerbCollection collection = new(); - collection.AddRange(new DesignerVerbCollection(value)); - Assert.Equal(value, collection.Cast()); - - // Add again. - collection.AddRange(new DesignerVerbCollection(value)); - Assert.Equal(value.Concat(value), collection.Cast()); - } - - [Fact] - public void DesignerVerbCollection_AddRange_NullValue_ThrowsArgumentNullException() - { - DesignerVerbCollection collection = new(); - Assert.Throws("value", () => collection.AddRange((DesignerVerb[])null)); - Assert.Throws("value", () => collection.AddRange((DesignerVerbCollection)null)); - } - - [Fact] - public void DesignerVerbCollection_Insert_DesignerVerb_Success() - { - DesignerVerbCollection collection = new(); - - DesignerVerb value1 = new(null, null); - collection.Insert(0, value1); - Assert.Same(value1, Assert.Single(collection)); - Assert.Same(value1, collection[0]); - Assert.True(collection.Contains(value1)); - Assert.Equal(0, collection.IndexOf(value1)); - - DesignerVerb value2 = new(null, null); - collection.Insert(0, value2); - Assert.Equal(new object[] { value2, value1 }, collection.Cast()); - Assert.True(collection.Contains(value2)); - Assert.Equal(0, collection.IndexOf(value2)); - - collection.Insert(1, null); - Assert.Equal(new object[] { value2, null, value1 }, collection.Cast()); - Assert.True(collection.Contains(null)); - Assert.Equal(1, collection.IndexOf(null)); - } - - [Fact] - public void DesignerVerbCollection_Remove_Invoke_Success() - { - DesignerVerbCollection collection = new(); - DesignerVerb value = new(null, null); - collection.Add(value); - Assert.Same(value, Assert.Single(collection)); - - collection.Remove(value); - Assert.Empty(collection); - Assert.False(collection.Contains(value)); - Assert.Equal(-1, collection.IndexOf(value)); - - collection.Add(null); - collection.Remove(null); - Assert.Empty(collection); - Assert.False(collection.Contains(null)); - Assert.Equal(-1, collection.IndexOf(null)); - } - - [Fact] - public void DesignerVerbCollection_Item_Set_GetReturnsExpected() - { - DesignerVerbCollection collection = new(); - DesignerVerb value1 = new(null, null); - DesignerVerb value2 = new(null, null); - collection.Add(value1); - Assert.Same(value1, Assert.Single(collection)); - - collection[0] = value2; - Assert.Same(value2, Assert.Single(collection)); - Assert.Same(value2, collection[0]); - Assert.False(collection.Contains(value1)); - Assert.Equal(-1, collection.IndexOf(value1)); - Assert.True(collection.Contains(value2)); - Assert.Equal(0, collection.IndexOf(value2)); - - collection[0] = null; - Assert.Null(Assert.Single(collection)); - Assert.Null(collection[0]); - Assert.False(collection.Contains(value2)); - Assert.Equal(-1, collection.IndexOf(value2)); - Assert.True(collection.Contains(null)); - Assert.Equal(0, collection.IndexOf(null)); - } - - [Fact] - public void DesignerVerbCollection_CopyTo_Invoke_Success() - { - DesignerVerbCollection collection = new(); - DesignerVerb value = new(null, null); - collection.Add(value); - - var array = new DesignerVerb[3]; - collection.CopyTo(array, 1); - Assert.Equal(new DesignerVerb[] { null, value, null }, array); - } - - [Fact] - public void DesignerVerbCollection_Contains_NoSuchValue_ReturnsFalse() - { - DesignerVerbCollection collection = new(); - DesignerVerb value = new(null, null); - collection.Add(value); - - Assert.False(collection.Contains(new DesignerVerb(null, null))); - Assert.False(collection.Contains(null)); - } - - [Fact] - public void DesignerVerbCollection_IndexOf_NoSuchValue_ReturnsNegativeOne() - { - DesignerVerbCollection collection = new(); - DesignerVerb value = new(null, null); - collection.Add(value); - - Assert.Equal(-1, collection.IndexOf(new DesignerVerb(null, null))); - Assert.Equal(-1, collection.IndexOf(null)); - } - - [Fact] - public void DesignerVerbCollection_Clear_Success() - { - DesignerVerbCollection collection = new(); - DesignerVerb value = new(null, null); - collection.Add(value); - - collection.Clear(); - Assert.Empty(collection); - - // Clear again. - collection.Clear(); - Assert.Empty(collection); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ExceptionCollectionTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ExceptionCollectionTests.cs deleted file mode 100644 index 8087bf4a2c0..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ExceptionCollectionTests.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; - -namespace System.ComponentModel.Design.Tests; - -public class ExceptionCollectionTests -{ - public static IEnumerable Ctor_ArrayList_TestData() - { - yield return new object[] { null }; - yield return new object[] { new ArrayList() }; - yield return new object[] { new ArrayList { new Exception(), new Exception(), new Exception()} }; - } - - [Theory] - [MemberData(nameof(Ctor_ArrayList_TestData))] - public void ExceptionCollection_Ctor_ArrayList(ArrayList exceptions) - { - ExceptionCollection collection = new(exceptions); - if (exceptions is null) - { - Assert.Null(collection.Exceptions); - } - else - { - Assert.Equal(exceptions, collection.Exceptions); - Assert.NotSame(exceptions, collection.Exceptions); - Assert.Equal(collection.Exceptions, collection.Exceptions); - Assert.NotSame(collection.Exceptions, collection.Exceptions); - } - } - - [Fact] - public void ExceptionCollection_Ctor_ArguementException() - { - ArrayList exceptions = new() { 1, 2, 3 }; - Assert.Throws(() => new ExceptionCollection(exceptions)); - } - - [Theory] - [BoolData] - public void ExceptionCollection_Serialize_ThrowsSerializationException(bool formatterEnabled) - { - using BinaryFormatterScope formatterScope = new(enable: formatterEnabled); - using MemoryStream stream = new(); - BinaryFormatter formatter = new(); - ExceptionCollection collection = new(new ArrayList()); - if (formatterEnabled) - { - Assert.Throws(() => formatter.Serialize(stream, collection)); - } - else - { - Assert.Throws(() => formatter.Serialize(stream, collection)); - } - } - - [Fact] - public void ExceptionCollection_GetObjectData_ThrowsPlatformNotSupportedException() - { - ExceptionCollection collection = new(new ArrayList()); - Assert.Throws(() => collection.GetObjectData(null, new StreamingContext())); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ExtenderProviderServiceTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ExtenderProviderServiceTests.cs deleted file mode 100644 index 70a84a3e53c..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ExtenderProviderServiceTests.cs +++ /dev/null @@ -1,104 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Moq; - -namespace System.ComponentModel.Design.Tests; - -public class ExtenderProviderServiceTests -{ - [Fact] - public void ExtenderProviderService_GetExtenderProviders_Invoke_ReturnsEmpty() - { - DesignSurface surface = new(); - object service = surface.GetService(typeof(IExtenderListService)); - IExtenderListService listService = Assert.IsAssignableFrom(service); - Assert.Empty(listService.GetExtenderProviders()); - } - - [Fact] - public void ExtenderProviderService_AddExtenderProvider_Invoke_Success() - { - DesignSurface surface = new(); - object service = surface.GetService(typeof(IExtenderListService)); - IExtenderListService listService = Assert.IsAssignableFrom(service); - IExtenderProviderService providerService = Assert.IsAssignableFrom(service); - Mock mockExtenderProvider1 = new(MockBehavior.Strict); - Mock mockExtenderProvider2 = new(MockBehavior.Strict); - - providerService.AddExtenderProvider(mockExtenderProvider1.Object); - Assert.Equal(new IExtenderProvider[] { mockExtenderProvider1.Object }, listService.GetExtenderProviders()); - - // Add another. - providerService.AddExtenderProvider(mockExtenderProvider2.Object); - Assert.Equal(new IExtenderProvider[] { mockExtenderProvider1.Object, mockExtenderProvider2.Object }, listService.GetExtenderProviders()); - } - - [Fact] - public void ExtenderProviderService_AddExtenderProvider_NullProvider_ThrowsArgumentNullException() - { - DesignSurface surface = new(); - object service = surface.GetService(typeof(IExtenderListService)); - IExtenderProviderService providerService = Assert.IsAssignableFrom(service); - Assert.Throws("provider", () => providerService.AddExtenderProvider(null)); - } - - [Fact] - public void ExtenderProviderService_AddExtenderProvider_DuplicateProvider_ThrowsArgumentException() - { - DesignSurface surface = new(); - object service = surface.GetService(typeof(IExtenderListService)); - IExtenderListService listService = Assert.IsAssignableFrom(service); - IExtenderProviderService providerService = Assert.IsAssignableFrom(service); - Mock mockExtenderProvider = new(MockBehavior.Strict); - - providerService.AddExtenderProvider(mockExtenderProvider.Object); - Assert.Throws("provider", () => providerService.AddExtenderProvider(mockExtenderProvider.Object)); - } - - [Fact] - public void ExtenderProviderService_RemoveExtenderProvider_InvokeWithProviders_Success() - { - DesignSurface surface = new(); - object service = surface.GetService(typeof(IExtenderListService)); - IExtenderListService listService = Assert.IsAssignableFrom(service); - IExtenderProviderService providerService = Assert.IsAssignableFrom(service); - Mock mockExtenderProvider1 = new(MockBehavior.Strict); - Mock mockExtenderProvider2 = new(MockBehavior.Strict); - - providerService.AddExtenderProvider(mockExtenderProvider1.Object); - providerService.AddExtenderProvider(mockExtenderProvider2.Object); - - providerService.RemoveExtenderProvider(mockExtenderProvider1.Object); - Assert.Equal(new IExtenderProvider[] { mockExtenderProvider2.Object }, listService.GetExtenderProviders()); - - // Remove again. - providerService.RemoveExtenderProvider(mockExtenderProvider1.Object); - Assert.Equal(new IExtenderProvider[] { mockExtenderProvider2.Object }, listService.GetExtenderProviders()); - - // Remove other. - providerService.RemoveExtenderProvider(mockExtenderProvider2.Object); - Assert.Empty(listService.GetExtenderProviders()); - } - - [Fact] - public void ExtenderProviderService_RemoveExtenderProvider_InvokeWithoutProviders_Nop() - { - DesignSurface surface = new(); - object service = surface.GetService(typeof(IExtenderListService)); - IExtenderListService listService = Assert.IsAssignableFrom(service); - IExtenderProviderService providerService = Assert.IsAssignableFrom(service); - Mock mockExtenderProvider = new(MockBehavior.Strict); - providerService.RemoveExtenderProvider(mockExtenderProvider.Object); - Assert.Empty(listService.GetExtenderProviders()); - } - - [Fact] - public void ExtenderProviderService_RemoveExtenderProvider_NullProvider_ThrowsArgumentNullException() - { - DesignSurface surface = new(); - object service = surface.GetService(typeof(IExtenderListService)); - IExtenderProviderService providerService = Assert.IsAssignableFrom(service); - Assert.Throws("provider", () => providerService.RemoveExtenderProvider(null)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/InheritanceServiceTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/InheritanceServiceTests.cs deleted file mode 100644 index eb424834bb4..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/InheritanceServiceTests.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.ComponentModel.Design.Tests; - -public class InheritanceServicerTests -{ - [Fact] - public void InheritanceService_Constructor() - { - InheritanceService underTest = new(); - Assert.NotNull(underTest); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/LoadedEventArgsTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/LoadedEventArgsTests.cs deleted file mode 100644 index d3799e4a0f2..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/LoadedEventArgsTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; - -namespace System.ComponentModel.Design.Tests; - -public class LoadedEventArgsTests -{ - public static IEnumerable Ctor_Bool_ICollection_TestData() - { - yield return new object[] { true, null }; - yield return new object[] { false, Array.Empty() }; - yield return new object[] { true, new object[] { null } }; - } - - [Theory] - [MemberData(nameof(Ctor_Bool_ICollection_TestData))] - public void Ctor_Bool_ICollection(bool succeeded, ICollection errors) - { - LoadedEventArgs e = new(succeeded, errors); - Assert.Equal(succeeded, e.HasSucceeded); - if (errors is null) - { - Assert.Empty(e.Errors); - } - else - { - Assert.Same(errors, e.Errors); - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/MultilineStringEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/MultilineStringEditorTests.cs deleted file mode 100644 index debdb00f925..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/MultilineStringEditorTests.cs +++ /dev/null @@ -1,74 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Design; -using System.Windows.Forms.Design; -using Moq; -using System.Windows.Forms.TestUtilities; - -namespace System.ComponentModel.Design.Tests; - -public class MultilineStringEditorTests -{ - [Fact] - public void MultilineStringEditor_Ctor_Default() - { - MultilineStringEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - public static IEnumerable EditValue_TestData() - { - yield return new object[] { null }; - yield return new object[] { "value" }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(EditValue_TestData))] - public void MultilineStringEditor_EditValue_ValidProvider_ReturnsValue(object value) - { - MultilineStringEditor editor = new(); - Mock mockEditorService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object) - .Verifiable(); - mockEditorService - .Setup(e => e.DropDownControl(It.IsAny())) - .Verifiable(); - Assert.Same(string.Empty, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Once()); - mockEditorService.Verify(e => e.DropDownControl(It.IsAny()), Times.Once()); - - // Edit again. - Assert.Same(string.Empty, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void MultilineStringEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - MultilineStringEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void MultilineStringEditor_GetEditStyle_Invoke_ReturnsDropDown(ITypeDescriptorContext context) - { - MultilineStringEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.DropDown, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void MultilineStringEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - MultilineStringEditor editor = new(); - Assert.False(editor.GetPaintValueSupported(context)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ObjectSelectorEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ObjectSelectorEditorTests.cs deleted file mode 100644 index bd26eb592bf..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ObjectSelectorEditorTests.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Design; -using System.Windows.Forms.Design; -using Moq; -using System.Windows.Forms.TestUtilities; - -namespace System.ComponentModel.Design.Tests; - -public class ObjectSelectorEditorTests -{ - [Fact] - public void ObjectSelectorEditor_Ctor_Default() - { - SubObjectSelectorEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - Assert.False(editor.SubObjectSelector); - } - - [Theory] - [BoolData] - public void ObjectSelectorEditor_Ctor_Bool(bool subObjectSelector) - { - SubObjectSelectorEditor editor = new(subObjectSelector); - Assert.False(editor.IsDropDownResizable); - Assert.Equal(subObjectSelector, editor.SubObjectSelector); - } - - public static IEnumerable EditValue_TestData() - { - yield return new object[] { null }; - yield return new object[] { "value" }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(EditValue_TestData))] - public void ObjectSelectorEditor_EditValue_ValidProvider_ReturnsValue(object value) - { - SubObjectSelectorEditor editor = new(); - Mock mockEditorService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object) - .Verifiable(); - mockEditorService - .Setup(e => e.DropDownControl(It.IsAny())) - .Verifiable(); - Assert.Same(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Once()); - mockEditorService.Verify(e => e.DropDownControl(It.IsAny()), Times.Once()); - - // Edit again. - Assert.Same(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void ObjectSelectorEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - SubObjectSelectorEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void ObjectSelectorEditor_GetEditStyle_Invoke_ReturnsDropDown(ITypeDescriptorContext context) - { - SubObjectSelectorEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.DropDown, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void ObjectSelectorEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - SubObjectSelectorEditor editor = new(); - Assert.False(editor.GetPaintValueSupported(context)); - } - - [Theory] - [InlineData(null, true)] - [InlineData("value", false)] - public void ObjectSelectorEditor_EqualsToValue_InvokeWithoutValue_ReturnsExpected(object value, bool expected) - { - SubObjectSelectorEditor editor = new(); - Assert.Equal(expected, editor.EqualsToValue(value)); - } - - [Fact] - public void ObjectSelectorEditor_EqualsToValue_InvokeWithValue_ReturnsExpected() - { - SubObjectSelectorEditor editor = new(); - editor.SetValue("value"); - Assert.True(editor.EqualsToValue("value")); - Assert.False(editor.EqualsToValue("other value")); - Assert.False(editor.EqualsToValue(null)); - } - - [Fact] - public void ObjectSelectorEditor_Selector() - { - ObjectSelectorEditor.Selector underTest = new ObjectSelectorEditor.Selector(new SubObjectSelectorEditor()); - - Assert.NotNull(underTest); - underTest.AddNode("node", "value", null); - Assert.Single(underTest.Nodes); - Assert.True(underTest.SetSelection("value", null)); - Assert.False(underTest.SetSelection("other value", null)); - underTest.Clear(); - Assert.Empty(underTest.Nodes); - } - - private class SubObjectSelectorEditor : ObjectSelectorEditor - { - public SubObjectSelectorEditor() - { - } - - public SubObjectSelectorEditor(bool subObjectSelector) : base(subObjectSelector) - { - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ProjectTargetFrameworkAttributeTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ProjectTargetFrameworkAttributeTests.cs deleted file mode 100644 index 1a46eefee9c..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/ProjectTargetFrameworkAttributeTests.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.ComponentModel.Design.Tests; - -public class ProjectTargetFrameworkAttributeTests -{ - [Theory] - [StringWithNullData] - public void ProjectTargetFrameworkAttribute_Ctor_String(string targetFrameworkMoniker) - { - ProjectTargetFrameworkAttribute attribute = new(targetFrameworkMoniker); - Assert.Equal(targetFrameworkMoniker, attribute.TargetFrameworkMoniker); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/CodeDomComponentSerializationServiceTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/CodeDomComponentSerializationServiceTests.cs deleted file mode 100644 index da0bcaac799..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/CodeDomComponentSerializationServiceTests.cs +++ /dev/null @@ -1,1794 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.CodeDom; -using System.Collections; -using System.Reflection; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; -using System.Windows.Forms.Design; -using Moq; -using System.Windows.Forms.TestUtilities; - -namespace System.ComponentModel.Design.Serialization.Tests; - -public class CodeDomComponentSerializationServiceTests -{ - private Mock GetDefaultMockSite(string name) - { - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.Name) - .Returns(name); - mockSite - .Setup(s => s.Container) - .Returns(default(Container)); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(IExtenderListService))) - .Returns(null); - mockSite - .Setup(s => s.GetService(typeof(ITypeDescriptorFilterService))) - .Returns(null); - - return mockSite; - } - - public static IEnumerable Ctor_IServiceProvider_TestData() - { - yield return new object[] { null }; - yield return new object[] { new Mock(MockBehavior.Strict).Object }; - } - - [Theory] - [MemberData(nameof(Ctor_IServiceProvider_TestData))] - public void Ctor_IServiceProvider(IServiceProvider provider) - { - new CodeDomComponentSerializationService(provider); - } - - [Fact] - public void CreateStore_Invoke_ReturnsExpected() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - Assert.Empty(store.Errors); - Assert.NotSame(store.Errors, store.Errors); - } - - public static IEnumerable CreateStore_ServiceProvider_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - yield return new object[] { new Mock(MockBehavior.Strict) }; - } - - [Theory] - [MemberData(nameof(CreateStore_ServiceProvider_TestData))] - public void CreateStore_CloseWithProviderMultipleTimes_Success(object result) - { - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerSerializationManager))) - .Returns(result); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(null); - CodeDomComponentSerializationService service = new(mockServiceProvider.Object); - SerializationStore store = service.CreateStore(); - store.Close(); - Assert.Empty(store.Errors); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerSerializationManager)), Times.Once()); - - store.Close(); - Assert.Empty(store.Errors); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerSerializationManager)), Times.Once()); - } - - [Fact] - public void CreateStore_CloseSerialize_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - var mockSite1 = GetDefaultMockSite("name1"); - DataClass value1 = new() - { - IntValue = 1, - StringValue = "Value", - Site = mockSite1.Object - }; - var mockSite2 = GetDefaultMockSite("name2"); - DataClass value2 = new() - { - IntValue = 2, - StringValue = "OtherValue", - Site = mockSite2.Object - }; - service.Serialize(store, value1); - service.Serialize(store, value2); - store.Close(); - Assert.Empty(store.Errors); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - - Hashtable state = Assert.IsType(info.GetValue("State", typeof(Hashtable))); - Assert.Equal(2, state.Count); - object[] valueState1 = Assert.IsType(state["name1"]); - Assert.Equal(6, valueState1.Length); - CodeDomHelpers.AssertEqualCodeStatementCollection(new CodeStatementCollection(new CodeStatement[] - { - new CodeVariableDeclarationStatement(typeof(DataClass), "name1"), - new CodeAssignStatement(new CodeVariableReferenceExpression("name1"), new CodeObjectCreateExpression(typeof(DataClass))), - new CodeCommentStatement(string.Empty), - new CodeCommentStatement("name1"), - new CodeCommentStatement(string.Empty), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name1"), "DefaultStringValue"), new CodePrimitiveExpression(null)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name1"), "IntValue"), new CodePrimitiveExpression(1)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name1"), "StringValue"), new CodePrimitiveExpression("Value")) - }), Assert.IsType(valueState1[0])); - Assert.Null(valueState1[1]); - Assert.Null(valueState1[2]); - Assert.Null(valueState1[3]); - Assert.Null(valueState1[4]); - Assert.Null(valueState1[5]); - - object[] valueState2 = Assert.IsType(state["name2"]); - Assert.Equal(6, valueState2.Length); - CodeDomHelpers.AssertEqualCodeStatementCollection(new CodeStatementCollection(new CodeStatement[] - { - new CodeVariableDeclarationStatement(typeof(DataClass), "name2"), - new CodeAssignStatement(new CodeVariableReferenceExpression("name2"), new CodeObjectCreateExpression(typeof(DataClass))), - new CodeCommentStatement(string.Empty), - new CodeCommentStatement("name2"), - new CodeCommentStatement(string.Empty), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name2"), "DefaultStringValue"), new CodePrimitiveExpression(null)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name2"), "IntValue"), new CodePrimitiveExpression(2)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name2"), "StringValue"), new CodePrimitiveExpression("OtherValue")) - }), Assert.IsType(valueState2[0])); - Assert.Null(valueState2[1]); - Assert.Null(valueState2[2]); - Assert.Null(valueState2[3]); - Assert.Null(valueState2[4]); - Assert.Null(valueState2[5]); - - List names = Assert.IsType>(info.GetValue("Names", typeof(List))); - Assert.Equal(new List { "name1", "name2" }, names); - - AssemblyName[] assemblies = Assert.IsType(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Equal(typeof(DataClass).Assembly.GetName(true).FullName, Assert.Single(assemblies).FullName); - - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - public static IEnumerable CreateStore_CloseSerializeWithInvalidProvider_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(CreateStore_CloseSerializeWithInvalidProvider_TestData))] - public void CreateStore_CloseSerializeWithInvalidProvider_Success(object result) - { - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerSerializationManager))) - .Returns(result) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(result) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(result); - mockServiceProvider - .Setup(p => p.GetService(typeof(IEventBindingService))) - .Returns(result) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(ComponentCache))) - .Returns(result) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(IServiceContainer))) - .Returns(result) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(MemberRelationshipService))) - .Returns(result) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(result); - CodeDomComponentSerializationService service = new(mockServiceProvider.Object); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - var mockSite = GetDefaultMockSite("name"); - DataClass value = new() - { - IntValue = 1, - StringValue = "Value", - Site = mockSite.Object - }; - service.Serialize(store, value); - store.Close(); - Assert.Empty(store.Errors); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerSerializationManager)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(ComponentCache)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IServiceContainer)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(MemberRelationshipService)), Times.Exactly(3)); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - - Hashtable state = Assert.IsType(info.GetValue("State", typeof(Hashtable))); - object[] valueState = Assert.IsType(state["name"]); - Assert.Equal(6, valueState.Length); - CodeDomHelpers.AssertEqualCodeStatementCollection(new CodeStatementCollection(new CodeStatement[] - { - new CodeVariableDeclarationStatement(typeof(DataClass), "name"), - new CodeAssignStatement(new CodeVariableReferenceExpression("name"), new CodeObjectCreateExpression(typeof(DataClass))), - new CodeCommentStatement(string.Empty), - new CodeCommentStatement("name"), - new CodeCommentStatement(string.Empty), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "DefaultStringValue"), new CodePrimitiveExpression(null)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "IntValue"), new CodePrimitiveExpression(1)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "StringValue"), new CodePrimitiveExpression("Value")) - }), Assert.IsType(valueState[0])); - Assert.Null(valueState[1]); - Assert.Null(valueState[2]); - Assert.Null(valueState[3]); - Assert.Null(valueState[4]); - Assert.Null(valueState[5]); - - List names = Assert.IsType>(info.GetValue("Names", typeof(List))); - Assert.Equal("name", Assert.Single(names)); - - AssemblyName[] assemblies = Assert.IsType(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Equal(typeof(DataClass).Assembly.GetName(true).FullName, Assert.Single(assemblies).FullName); - - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - public static IEnumerable CreateStore_CloseSerializeWithValidProvider_TestData() - { - yield return new object[] { null, null }; - yield return new object[] { new object(), new object() }; - - Mock mockComponentChangeService = new(MockBehavior.Strict); - yield return new object[] { mockComponentChangeService.Object, new WindowsFormsDesignerOptionService() }; - } - - [Theory] - [MemberData(nameof(CreateStore_CloseSerializeWithValidProvider_TestData))] - public void CreateStore_CloseSerializeWithValidProvider_Success(object componentChangeService, object designerOptionService) - { - DesignerSerializationManager manager = new(); - ServiceContainer container = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerSerializationManager))) - .Returns(manager) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(null) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IEventBindingService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ComponentCache))) - .Returns(null) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(IServiceContainer))) - .Returns(container) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(MemberRelationshipService))) - .Returns(null) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IComponentChangeService))) - .Returns(componentChangeService) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(DesignerOptionService))) - .Returns(designerOptionService) - .Verifiable(); - CodeDomComponentSerializationService service = new(mockServiceProvider.Object); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - var mockSite = GetDefaultMockSite("name"); - DataClass value = new() - { - IntValue = 1, - StringValue = "Value", - Site = mockSite.Object - }; - service.Serialize(store, value); - store.Close(); - Assert.Empty(store.Errors); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerSerializationManager)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IDesignerHost)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(ComponentCache)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(IServiceContainer)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(MemberRelationshipService)), Times.Exactly(3)); - mockServiceProvider.Verify(p => p.GetService(typeof(IComponentChangeService)), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(DesignerOptionService)), Times.Once()); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - - Hashtable state = Assert.IsType(info.GetValue("State", typeof(Hashtable))); - object[] valueState = Assert.IsType(state["name"]); - Assert.Equal(6, valueState.Length); - CodeDomHelpers.AssertEqualCodeStatementCollection(new CodeStatementCollection(new CodeStatement[] - { - new CodeVariableDeclarationStatement(typeof(DataClass), "name"), - new CodeAssignStatement(new CodeVariableReferenceExpression("name"), new CodeObjectCreateExpression(typeof(DataClass))), - new CodeCommentStatement(string.Empty), - new CodeCommentStatement("name"), - new CodeCommentStatement(string.Empty), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "DefaultStringValue"), new CodePrimitiveExpression(null)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "IntValue"), new CodePrimitiveExpression(1)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "StringValue"), new CodePrimitiveExpression("Value")) - }), Assert.IsType(valueState[0])); - Assert.Null(valueState[1]); - Assert.Null(valueState[2]); - Assert.Null(valueState[3]); - Assert.Null(valueState[4]); - Assert.Null(valueState[5]); - - List names = Assert.IsType>(info.GetValue("Names", typeof(List))); - Assert.Equal("name", Assert.Single(names)); - - AssemblyName[] assemblies = Assert.IsType(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Equal(typeof(DataClass).Assembly.GetName(true).FullName, Assert.Single(assemblies).FullName); - - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void CreateStore_CloseSerializeAbsolute_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - var mockSite = GetDefaultMockSite("name"); - DataClass value = new() - { - IntValue = 1, - StringValue = "Value", - Site = mockSite.Object - }; - service.SerializeAbsolute(store, value); - store.Close(); - Assert.Empty(store.Errors); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - - Hashtable state = Assert.IsType(info.GetValue("State", typeof(Hashtable))); - object[] valueState = Assert.IsType(state["name"]); - Assert.Equal(6, valueState.Length); - CodeDomHelpers.AssertEqualCodeStatementCollection(new CodeStatementCollection(new CodeStatement[] - { - new CodeVariableDeclarationStatement(typeof(DataClass), "name"), - new CodeAssignStatement(new CodeVariableReferenceExpression("name"), new CodeObjectCreateExpression(typeof(DataClass))), - new CodeCommentStatement(string.Empty), - new CodeCommentStatement("name"), - new CodeCommentStatement(string.Empty), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "DefaultStringValue"), new CodePrimitiveExpression(null)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "IntValue"), new CodePrimitiveExpression(1)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "StringValue"), new CodePrimitiveExpression("Value")) - }), Assert.IsType(valueState[0])); - Assert.Null(valueState[1]); - Assert.Null(valueState[2]); - Assert.Null(valueState[3]); - Assert.Null(valueState[4]); - Assert.Null(valueState[5]); - - List names = Assert.IsType>(info.GetValue("Names", typeof(List))); - Assert.Equal("name", Assert.Single(names)); - - AssemblyName[] assemblies = Assert.IsType(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Equal(typeof(DataClass).Assembly.GetName(true).FullName, Assert.Single(assemblies).FullName); - - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void CreateStore_CloseSerializeMember_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.DefaultStringValue)]; - MemberDescriptor member3 = TypeDescriptor.GetEvents(typeof(DataClass))[nameof(DataClass.Event)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - var mockSite = GetDefaultMockSite("name"); - DataClass value = new() - { - IntValue = 1, - StringValue = "Value", - Site = mockSite.Object - }; - service.SerializeMember(store, value, member1); - service.SerializeMember(store, value, member2); - service.SerializeMember(store, value, member1); - service.SerializeMember(store, value, member3); - store.Close(); - Assert.Empty(store.Errors); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - - Hashtable state = Assert.IsType(info.GetValue("State", typeof(Hashtable))); - object[] valueState = Assert.IsType(state["name"]); - Assert.Equal(6, valueState.Length); - CodeDomHelpers.AssertEqualCodeStatementCollection(new CodeStatementCollection(new CodeStatement[] - { - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "IntValue"), new CodePrimitiveExpression(1)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "DefaultStringValue"), new CodePrimitiveExpression(null)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "IntValue"), new CodePrimitiveExpression(1)), - }), Assert.IsType(valueState[0])); - Assert.Null(valueState[1]); - Assert.Null(valueState[2]); - Assert.Null(valueState[3]); - Assert.Null(valueState[4]); - Assert.Null(valueState[5]); - - List names = Assert.IsType>(info.GetValue("Names", typeof(List))); - Assert.Equal("name", Assert.Single(names)); - - AssemblyName[] assemblies = Assert.IsType(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Equal(typeof(DataClass).Assembly.GetName(true).FullName, Assert.Single(assemblies).FullName); - - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void CreateStore_CloseSerializeMemberAbsolute_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.DefaultStringValue)]; - MemberDescriptor member3 = TypeDescriptor.GetEvents(typeof(DataClass))[nameof(DataClass.Event)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - var mockSite = GetDefaultMockSite("name"); - DataClass value = new() - { - IntValue = 1, - StringValue = "Value", - Site = mockSite.Object - }; - service.SerializeMemberAbsolute(store, value, member1); - service.SerializeMemberAbsolute(store, value, member2); - service.SerializeMemberAbsolute(store, value, member1); - service.SerializeMemberAbsolute(store, value, member3); - store.Close(); - Assert.Empty(store.Errors); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - - Hashtable state = Assert.IsType(info.GetValue("State", typeof(Hashtable))); - object[] valueState = Assert.IsType(state["name"]); - Assert.Equal(6, valueState.Length); - CodeDomHelpers.AssertEqualCodeStatementCollection(new CodeStatementCollection(new CodeStatement[] - { - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "IntValue"), new CodePrimitiveExpression(1)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "DefaultStringValue"), new CodePrimitiveExpression(null)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "IntValue"), new CodePrimitiveExpression(1)) - }), Assert.IsType(valueState[0])); - Assert.Null(valueState[1]); - Assert.Null(valueState[2]); - Assert.Null(valueState[3]); - Assert.Null(valueState[4]); - Assert.Null(valueState[5]); - - List names = Assert.IsType>(info.GetValue("Names", typeof(List))); - Assert.Equal("name", Assert.Single(names)); - - AssemblyName[] assemblies = Assert.IsType(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Equal(typeof(DataClass).Assembly.GetName(true).FullName, Assert.Single(assemblies).FullName); - - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void CreateStore_CloseSerializeThenSerializeMember_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.DefaultStringValue)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - var mockSite = GetDefaultMockSite("name"); - DataClass value = new() - { - IntValue = 1, - StringValue = "Value", - Site = mockSite.Object - }; - service.Serialize(store, value); - service.SerializeMember(store, value, member1); - service.SerializeMember(store, value, member2); - store.Close(); - Assert.Empty(store.Errors); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - - Hashtable state = Assert.IsType(info.GetValue("State", typeof(Hashtable))); - object[] valueState = Assert.IsType(state["name"]); - Assert.Equal(6, valueState.Length); - CodeDomHelpers.AssertEqualCodeStatementCollection(new CodeStatementCollection(new CodeStatement[] - { - new CodeVariableDeclarationStatement(typeof(DataClass), "name"), - new CodeAssignStatement(new CodeVariableReferenceExpression("name"), new CodeObjectCreateExpression(typeof(DataClass))), - new CodeCommentStatement(string.Empty), - new CodeCommentStatement("name"), - new CodeCommentStatement(string.Empty), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "DefaultStringValue"), new CodePrimitiveExpression(null)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "IntValue"), new CodePrimitiveExpression(1)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "StringValue"), new CodePrimitiveExpression("Value")) - }), Assert.IsType(valueState[0])); - Assert.Null(valueState[1]); - Assert.Null(valueState[2]); - Assert.Null(valueState[3]); - Assert.Null(valueState[4]); - Assert.Null(valueState[5]); - - List names = Assert.IsType>(info.GetValue("Names", typeof(List))); - Assert.Equal("name", Assert.Single(names)); - - AssemblyName[] assemblies = Assert.IsType(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Equal(typeof(DataClass).Assembly.GetName(true).FullName, Assert.Single(assemblies).FullName); - - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void CreateStore_CloseSerializeMemberThenSerialize_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.DefaultStringValue)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - var mockSite = GetDefaultMockSite("name"); - DataClass value = new() - { - IntValue = 1, - StringValue = "Value", - Site = mockSite.Object - }; - service.SerializeMember(store, value, member1); - service.SerializeMember(store, value, member2); - service.Serialize(store, value); - store.Close(); - Assert.Empty(store.Errors); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - - Hashtable state = Assert.IsType(info.GetValue("State", typeof(Hashtable))); - object[] valueState = Assert.IsType(state["name"]); - Assert.Equal(6, valueState.Length); - CodeDomHelpers.AssertEqualCodeStatementCollection(new CodeStatementCollection(new CodeStatement[] - { - new CodeVariableDeclarationStatement(typeof(DataClass), "name"), - new CodeAssignStatement(new CodeVariableReferenceExpression("name"), new CodeObjectCreateExpression(typeof(DataClass))), - new CodeCommentStatement(string.Empty), - new CodeCommentStatement("name"), - new CodeCommentStatement(string.Empty), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "DefaultStringValue"), new CodePrimitiveExpression(null)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "IntValue"), new CodePrimitiveExpression(1)), - new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("name"), "StringValue"), new CodePrimitiveExpression("Value")) - }), Assert.IsType(valueState[0])); - Assert.Null(valueState[1]); - Assert.Null(valueState[2]); - Assert.Null(valueState[3]); - Assert.Null(valueState[4]); - Assert.Null(valueState[5]); - - List names = Assert.IsType>(info.GetValue("Names", typeof(List))); - Assert.Equal("name", Assert.Single(names)); - - AssemblyName[] assemblies = Assert.IsType(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Equal(typeof(DataClass).Assembly.GetName(true).FullName, Assert.Single(assemblies).FullName); - - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void CreateStore_CloseSerializeThrows_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.Name) - .Returns("name"); - mockSite - .Setup(s => s.GetService(typeof(IDictionaryService))) - .Throws(new DivideByZeroException()); - DataClass value = new() - { - IntValue = 1, - StringValue = "Value", - Site = mockSite.Object - }; - service.Serialize(store, value); - Assert.Throws(() => store.Close()); - Assert.Empty(store.Errors); - } - - [Fact] - public void CreateStore_CloseWithoutProviderMultipleTimes_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - store.Close(); - Assert.Empty(store.Errors); - - store.Close(); - Assert.Empty(store.Errors); - } - - [Fact] - public void CreateStore_ISerializableGetObjectDataDefault_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - - Assert.Null(info.GetValue("State", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Names", typeof(List)))); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void CreateStore_ISerializableGetObjectDataSerialized_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - object value = new(); - service.Serialize(store, value); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - Assert.NotEmpty(Assert.IsType>(info.GetValue("Names", typeof(List)))); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void CreateStore_ISerializableGetObjectDataDefaultNullInfo_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - Assert.Throws("info", () => serializable.GetObjectData(null, new StreamingContext())); - } - - [Theory] - [BoolData] - public void LoadStore_SerializedStore_ThrowsSerializationException(bool formatterEnabled) - { - using BinaryFormatterScope formatterScope = new(enable: formatterEnabled); - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - using MemoryStream stream = new(); - BinaryFormatter formatter = new(); - if (formatterEnabled) - { - Assert.Throws(() => formatter.Serialize(stream, store)); - } - else - { - Assert.Throws(() => formatter.Serialize(stream, store)); - } - } - - [Fact] - public void LoadStore_NullStream_ThrowsPlatformNotSupportedException() - { - CodeDomComponentSerializationService service = new(); - Assert.Throws(() => service.LoadStore(null)); - } - - [Fact] - public void Serialize_InvokeObject_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - - object value = new(); - service.Serialize(store, value); - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.Serialize(store, value); - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void Serialize_InvokeIComponentWithoutSite_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(null) - .Verifiable(); - - service.Serialize(store, mockComponent.Object); - mockComponent.Verify(c => c.Site, Times.Once()); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.Serialize(store, mockComponent.Object); - mockComponent.Verify(c => c.Site, Times.Once()); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Theory] - [InlineData(null, 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "^object_........_...._...._...._............$")] - [InlineData("name", 2, "^name$")] - public void Serialize_InvokeIComponentWithISite_Success(string name, int expectedCallCount, string expectedPattern) - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.Name) - .Returns(name) - .Verifiable(); - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(mockSite.Object) - .Verifiable(); - - service.Serialize(store, mockComponent.Object); - mockComponent.Verify(c => c.Site, Times.Once()); - mockSite.Verify(s => s.Name, Times.Exactly(expectedCallCount)); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.Serialize(store, mockComponent.Object); - mockComponent.Verify(c => c.Site, Times.Once()); - mockSite.Verify(s => s.Name, Times.Exactly(expectedCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Theory] - [InlineData(null, 1, null, 1, "^object_........_...._...._...._............$")] - [InlineData(null, 1, "", 1, "^object_........_...._...._...._............$")] - [InlineData(null, 1, "name", 2, "^name$")] - [InlineData("", 1, null, 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "", 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "name", 2, "^name$")] - [InlineData("fullName", 2, null, 0, "^fullName$")] - [InlineData("fullName", 2, "", 0, "^fullName$")] - [InlineData("fullName", 2, "name", 0, "^fullName$")] - public void Serialize_InvokeIComponentWithINestedSite_Success(string fullName, int expectedFullNameCallCount, string name, int expectedNameCallCount, string expectedPattern) - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockNestedSite = new(MockBehavior.Strict); - mockNestedSite - .Setup(s => s.Name) - .Returns(name) - .Verifiable(); - mockNestedSite - .Setup(s => s.FullName) - .Returns(fullName) - .Verifiable(); - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(mockNestedSite.Object) - .Verifiable(); - - service.Serialize(store, mockComponent.Object); - mockComponent.Verify(c => c.Site, Times.Once()); - mockNestedSite.Verify(s => s.Name, Times.Exactly(expectedNameCallCount)); - mockNestedSite.Verify(s => s.FullName, Times.Exactly(expectedFullNameCallCount)); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.Serialize(store, mockComponent.Object); - mockNestedSite.Verify(s => s.Name, Times.Exactly(expectedNameCallCount)); - mockNestedSite.Verify(s => s.FullName, Times.Exactly(expectedFullNameCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void Serialize_NullStore_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - Assert.Throws("store", () => service.Serialize(null, new object())); - } - - [Fact] - public void Serialize_NullValue_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - Mock mockStore = new(MockBehavior.Strict); - Assert.Throws("value", () => service.Serialize(mockStore.Object, null)); - } - - [Fact] - public void Serialize_InvalidStore_ThrowsInvalidOperationException() - { - CodeDomComponentSerializationService service = new(); - Mock mockStore = new(MockBehavior.Strict); - Assert.Throws(() => service.Serialize(mockStore.Object, new object())); - } - - [Fact] - public void Serialize_ClosedStore_ThrowsInvalidOperationException() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - store.Close(); - Assert.Throws(() => service.Serialize(store, new object())); - } - - [Fact] - public void SerializeAbsolute_InvokeObject_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - - object value = new(); - service.SerializeAbsolute(store, value); - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeAbsolute(store, value); - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void SerializeAbsolute_InvokeIComponentWithoutSite_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(null) - .Verifiable(); - - service.SerializeAbsolute(store, mockComponent.Object); - mockComponent.Verify(c => c.Site, Times.Once()); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeAbsolute(store, mockComponent.Object); - mockComponent.Verify(c => c.Site, Times.Once()); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Theory] - [InlineData(null, 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "^object_........_...._...._...._............$")] - [InlineData("name", 2, "^name$")] - public void SerializeAbsolute_InvokeIComponentWithISite_Success(string name, int expectedCallCount, string expectedPattern) - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.Name) - .Returns(name) - .Verifiable(); - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(mockSite.Object) - .Verifiable(); - - service.SerializeAbsolute(store, mockComponent.Object); - mockComponent.Verify(c => c.Site, Times.Once()); - mockSite.Verify(s => s.Name, Times.Exactly(expectedCallCount)); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeAbsolute(store, mockComponent.Object); - mockComponent.Verify(c => c.Site, Times.Once()); - mockSite.Verify(s => s.Name, Times.Exactly(expectedCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Theory] - [InlineData(null, 1, null, 1, "^object_........_...._...._...._............$")] - [InlineData(null, 1, "", 1, "^object_........_...._...._...._............$")] - [InlineData(null, 1, "name", 2, "^name$")] - [InlineData("", 1, null, 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "", 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "name", 2, "^name$")] - [InlineData("fullName", 2, null, 0, "^fullName$")] - [InlineData("fullName", 2, "", 0, "^fullName$")] - [InlineData("fullName", 2, "name", 0, "^fullName$")] - public void SerializeAbsolute_InvokeIComponentWithINestedSite_Success(string fullName, int expectedFullNameCallCount, string name, int expectedNameCallCount, string expectedPattern) - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockNestedSite = new(MockBehavior.Strict); - mockNestedSite - .Setup(s => s.Name) - .Returns(name) - .Verifiable(); - mockNestedSite - .Setup(s => s.FullName) - .Returns(fullName) - .Verifiable(); - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(mockNestedSite.Object) - .Verifiable(); - - service.SerializeAbsolute(store, mockComponent.Object); - mockComponent.Verify(c => c.Site, Times.Once()); - mockNestedSite.Verify(s => s.Name, Times.Exactly(expectedNameCallCount)); - mockNestedSite.Verify(s => s.FullName, Times.Exactly(expectedFullNameCallCount)); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeAbsolute(store, mockComponent.Object); - mockNestedSite.Verify(s => s.Name, Times.Exactly(expectedNameCallCount)); - mockNestedSite.Verify(s => s.FullName, Times.Exactly(expectedFullNameCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void SerializeAbsolute_NullStore_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - Assert.Throws("store", () => service.SerializeAbsolute(null, new object())); - } - - [Fact] - public void SerializeAbsolute_NullValue_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - Mock mockStore = new(MockBehavior.Strict); - Assert.Throws("value", () => service.SerializeAbsolute(mockStore.Object, null)); - } - - [Fact] - public void SerializeAbsolute_InvalidStore_ThrowsInvalidOperationException() - { - CodeDomComponentSerializationService service = new(); - Mock mockStore = new(MockBehavior.Strict); - Assert.Throws(() => service.SerializeAbsolute(mockStore.Object, new object())); - } - - [Fact] - public void SerializeAbsolute_ClosedStore_ThrowsInvalidOperationException() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - store.Close(); - Assert.Throws(() => service.SerializeAbsolute(store, new object())); - } - - [Fact] - public void SerializeMember_InvokeObject_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.StringValue)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - - object value = new(); - service.SerializeMember(store, value, member1); - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeMember(store, value, member1); - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize another. - service.SerializeMember(store, value, member2); - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void SerializeMember_InvokeIComponentWithoutSite_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.StringValue)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(null) - .Verifiable(); - - service.SerializeMember(store, mockComponent.Object, member1); - mockComponent.Verify(c => c.Site, Times.Once()); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeMember(store, mockComponent.Object, member1); - mockComponent.Verify(c => c.Site, Times.Once()); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize another. - service.SerializeMember(store, mockComponent.Object, member2); - mockComponent.Verify(c => c.Site, Times.Once()); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Theory] - [InlineData(null, 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "^object_........_...._...._...._............$")] - [InlineData("name", 2, "^name$")] - public void SerializeMember_InvokeIComponentWithISite_Success(string name, int expectedCallCount, string expectedPattern) - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.StringValue)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.Name) - .Returns(name) - .Verifiable(); - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(mockSite.Object) - .Verifiable(); - - service.SerializeMember(store, mockComponent.Object, member1); - mockComponent.Verify(c => c.Site, Times.Once()); - mockSite.Verify(s => s.Name, Times.Exactly(expectedCallCount)); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeMember(store, mockComponent.Object, member1); - mockComponent.Verify(c => c.Site, Times.Once()); - mockSite.Verify(s => s.Name, Times.Exactly(expectedCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize another. - service.SerializeMember(store, mockComponent.Object, member2); - mockComponent.Verify(c => c.Site, Times.Once()); - mockSite.Verify(s => s.Name, Times.Exactly(expectedCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Theory] - [InlineData(null, 1, null, 1, "^object_........_...._...._...._............$")] - [InlineData(null, 1, "", 1, "^object_........_...._...._...._............$")] - [InlineData(null, 1, "name", 2, "^name$")] - [InlineData("", 1, null, 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "", 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "name", 2, "^name$")] - [InlineData("fullName", 2, null, 0, "^fullName$")] - [InlineData("fullName", 2, "", 0, "^fullName$")] - [InlineData("fullName", 2, "name", 0, "^fullName$")] - public void SerializeMember_InvokeIComponentWithINestedSite_Success(string fullName, int expectedFullNameCallCount, string name, int expectedNameCallCount, string expectedPattern) - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.StringValue)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockNestedSite = new(MockBehavior.Strict); - mockNestedSite - .Setup(s => s.Name) - .Returns(name) - .Verifiable(); - mockNestedSite - .Setup(s => s.FullName) - .Returns(fullName) - .Verifiable(); - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(mockNestedSite.Object) - .Verifiable(); - - service.SerializeMember(store, mockComponent.Object, member1); - mockComponent.Verify(c => c.Site, Times.Once()); - mockNestedSite.Verify(s => s.Name, Times.Exactly(expectedNameCallCount)); - mockNestedSite.Verify(s => s.FullName, Times.Exactly(expectedFullNameCallCount)); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeMember(store, mockComponent.Object, member1); - mockNestedSite.Verify(s => s.Name, Times.Exactly(expectedNameCallCount)); - mockNestedSite.Verify(s => s.FullName, Times.Exactly(expectedFullNameCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize another. - service.SerializeMember(store, mockComponent.Object, member2); - mockNestedSite.Verify(s => s.Name, Times.Exactly(expectedNameCallCount)); - mockNestedSite.Verify(s => s.FullName, Times.Exactly(expectedFullNameCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void SerializeMember_NullStore_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - MemberDescriptor member = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - Assert.Throws("store", () => service.SerializeMember(null, new DataClass(), member)); - } - - [Fact] - public void SerializeMember_NullOwningObject_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - Assert.Throws("owningObject", () => service.SerializeMember(store, null, member)); - } - - [Fact] - public void SerializeMember_NullMember_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - Assert.Throws("member", () => service.SerializeMember(store, new DataClass(), null)); - } - - [Fact] - public void SerializeMember_InvalidStore_ThrowsInvalidOperationException() - { - CodeDomComponentSerializationService service = new(); - Mock mockStore = new(MockBehavior.Strict); - MemberDescriptor member = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - Assert.Throws(() => service.SerializeMember(mockStore.Object, new DataClass(), member)); - } - - [Fact] - public void SerializeMember_ClosedStore_ThrowsInvalidOperationException() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - store.Close(); - MemberDescriptor member = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - Assert.Throws(() => service.SerializeMember(store, new DataClass(), member)); - } - - [Fact] - public void SerializeMemberAbsolute_InvokeObject_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.StringValue)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - - object value = new(); - service.SerializeMemberAbsolute(store, value, member1); - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeMemberAbsolute(store, value, member1); - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize another. - service.SerializeMemberAbsolute(store, value, member2); - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void SerializeMemberAbsolute_InvokeIComponentWithoutSite_Success() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.StringValue)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(null) - .Verifiable(); - - service.SerializeMemberAbsolute(store, mockComponent.Object, member1); - mockComponent.Verify(c => c.Site, Times.Once()); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeMemberAbsolute(store, mockComponent.Object, member1); - mockComponent.Verify(c => c.Site, Times.Once()); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize another. - service.SerializeMemberAbsolute(store, mockComponent.Object, member2); - mockComponent.Verify(c => c.Site, Times.Once()); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches("^object_........_...._...._...._............$", nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Theory] - [InlineData(null, 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "^object_........_...._...._...._............$")] - [InlineData("name", 2, "^name$")] - public void SerializeMemberAbsolute_InvokeIComponentWithISite_Success(string name, int expectedCallCount, string expectedPattern) - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.StringValue)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.Name) - .Returns(name) - .Verifiable(); - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(mockSite.Object) - .Verifiable(); - - service.SerializeMemberAbsolute(store, mockComponent.Object, member1); - mockComponent.Verify(c => c.Site, Times.Once()); - mockSite.Verify(s => s.Name, Times.Exactly(expectedCallCount)); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeMemberAbsolute(store, mockComponent.Object, member1); - mockComponent.Verify(c => c.Site, Times.Once()); - mockSite.Verify(s => s.Name, Times.Exactly(expectedCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize another. - service.SerializeMemberAbsolute(store, mockComponent.Object, member2); - mockComponent.Verify(c => c.Site, Times.Once()); - mockSite.Verify(s => s.Name, Times.Exactly(expectedCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - Assert.Null(info.GetValue("State", typeof(Hashtable))); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Theory] - [InlineData(null, 1, null, 1, "^object_........_...._...._...._............$")] - [InlineData(null, 1, "", 1, "^object_........_...._...._...._............$")] - [InlineData(null, 1, "name", 2, "^name$")] - [InlineData("", 1, null, 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "", 1, "^object_........_...._...._...._............$")] - [InlineData("", 1, "name", 2, "^name$")] - [InlineData("fullName", 2, null, 0, "^fullName$")] - [InlineData("fullName", 2, "", 0, "^fullName$")] - [InlineData("fullName", 2, "name", 0, "^fullName$")] - public void SerializeMemberAbsolute_InvokeIComponentWithINestedSite_Success(string fullName, int expectedFullNameCallCount, string name, int expectedNameCallCount, string expectedPattern) - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member1 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - MemberDescriptor member2 = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.StringValue)]; - ISerializable serializable = Assert.IsAssignableFrom(store); - - Mock mockNestedSite = new(MockBehavior.Strict); - mockNestedSite - .Setup(s => s.Name) - .Returns(name) - .Verifiable(); - mockNestedSite - .Setup(s => s.FullName) - .Returns(fullName) - .Verifiable(); - Mock mockComponent = new(MockBehavior.Strict); - mockComponent - .Setup(c => c.Site) - .Returns(mockNestedSite.Object) - .Verifiable(); - - service.SerializeMemberAbsolute(store, mockComponent.Object, member1); - mockComponent.Verify(c => c.Site, Times.Once()); - mockNestedSite.Verify(s => s.Name, Times.Exactly(expectedNameCallCount)); - mockNestedSite.Verify(s => s.FullName, Times.Exactly(expectedFullNameCallCount)); - - SerializationInfo info = new(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - string nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize again. - service.SerializeMemberAbsolute(store, mockComponent.Object, member1); - mockNestedSite.Verify(s => s.Name, Times.Exactly(expectedNameCallCount)); - mockNestedSite.Verify(s => s.FullName, Times.Exactly(expectedFullNameCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - - // Serialize another. - service.SerializeMemberAbsolute(store, mockComponent.Object, member2); - mockNestedSite.Verify(s => s.Name, Times.Exactly(expectedNameCallCount)); - mockNestedSite.Verify(s => s.FullName, Times.Exactly(expectedFullNameCallCount)); - - info = new SerializationInfo(store.GetType(), new FormatterConverter()); - serializable.GetObjectData(info, new StreamingContext()); - nameResult = Assert.IsType(Assert.Single(Assert.IsType>(info.GetValue("Names", typeof(List))))); - Assert.Matches(expectedPattern, nameResult); - Assert.Null(info.GetValue("Assemblies", typeof(AssemblyName[]))); - Assert.Null(info.GetValue("Resources", typeof(Hashtable))); - Assert.Empty(Assert.IsType>(info.GetValue("Shim", typeof(List)))); - } - - [Fact] - public void SerializeMemberAbsolute_NullStore_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - MemberDescriptor member = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - Assert.Throws("store", () => service.SerializeMemberAbsolute(null, new DataClass(), member)); - } - - [Fact] - public void SerializeMemberAbsolute_NullOwningObject_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - MemberDescriptor member = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - Assert.Throws("owningObject", () => service.SerializeMemberAbsolute(store, null, member)); - } - - [Fact] - public void SerializeMemberAbsolute_NullMember_ThrowsArgumentNullException() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - Assert.Throws("member", () => service.SerializeMemberAbsolute(store, new DataClass(), null)); - } - - [Fact] - public void SerializeMemberAbsolute_InvalidStore_ThrowsInvalidOperationException() - { - CodeDomComponentSerializationService service = new(); - Mock mockStore = new(MockBehavior.Strict); - MemberDescriptor member = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - Assert.Throws(() => service.SerializeMemberAbsolute(mockStore.Object, new DataClass(), member)); - } - - [Fact] - public void SerializeMemberAbsolute_ClosedStore_ThrowsInvalidOperationException() - { - CodeDomComponentSerializationService service = new(); - SerializationStore store = service.CreateStore(); - store.Close(); - MemberDescriptor member = TypeDescriptor.GetProperties(typeof(DataClass))[nameof(DataClass.IntValue)]; - Assert.Throws(() => service.SerializeMemberAbsolute(store, new DataClass(), member)); - } - - private class DataClass : Component - { - public int IntValue { get; set; } - - public string StringValue { get; set; } - - public string DefaultStringValue { get; set; } - - public event EventHandler Event - { - add { } - remove { } - } - } - - private static void DumpState(Hashtable state) - { - Console.WriteLine("---- DUMPING ----"); - foreach (string key in state.Keys) - { - Console.WriteLine(key); - object[] valueState = (object[])state[key]; - CodeStatementCollection state0 = (CodeStatementCollection)valueState[0]; - if (state0 is null) - { - Console.WriteLine("- [0]: null"); - } - else - { - Console.WriteLine($"- [0]: {state0}, {state0.Count} elements"); - foreach (CodeStatement e in state0) - { - Console.WriteLine($" - {CodeDomHelpers.GetConstructionString(e)}"); - } - } - - object state1 = valueState[1]; - if (state1 is null) - { - Console.WriteLine("- [1]: null"); - } - else - { - Console.WriteLine($"- [1]: {state1}"); - } - - object state2 = valueState[2]; - if (state2 is null) - { - Console.WriteLine("- [2]: null"); - } - else - { - Console.WriteLine($"- [2]: {state2}"); - } - - object state3 = valueState[3]; - if (state3 is null) - { - Console.WriteLine("- [3]: null"); - } - else - { - Console.WriteLine($"- [3]: {state3}"); - } - - object state4 = valueState[4]; - if (state4 is null) - { - Console.WriteLine("- [4]: null"); - } - else - { - Console.WriteLine($"- [4]: {state4}"); - } - - object state5 = valueState[5]; - if (state5 is null) - { - Console.WriteLine("- [5]: null"); - } - else - { - Console.WriteLine($"- [5]: {state5}"); - } - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/CodeDomSerializerExceptionTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/CodeDomSerializerExceptionTests.cs deleted file mode 100644 index e4e6626aee5..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/CodeDomSerializerExceptionTests.cs +++ /dev/null @@ -1,112 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.CodeDom; -using System.ComponentModel.Design.Serialization; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; -using Moq; - -namespace System.Windows.Forms.Design.Serialization.Tests; - -public class CodeDomSerializerExceptionTests -{ - public static IEnumerable Ctor_String_CodeLinePragma_TestData() - { - yield return new object[] { "message", new CodeLinePragma() }; - yield return new object[] { null, null }; - } - - [Theory] - [MemberData(nameof(Ctor_String_CodeLinePragma_TestData))] - public void CodeDomSerializerException_Ctor_String_CodeLinePragma(string message, CodeLinePragma linePragma) - { - CodeDomSerializerException exception = new(message, linePragma); - Assert.NotEmpty(exception.Message); - Assert.Null(exception.InnerException); - Assert.Same(linePragma, exception.LinePragma); - } - - public static IEnumerable Ctor_Exception_CodeLinePragma_TestData() - { - yield return new object[] { new Exception(), new CodeLinePragma() }; - yield return new object[] { null, null }; - } - - [Theory] - [MemberData(nameof(Ctor_Exception_CodeLinePragma_TestData))] - public void CodeDomSerializerException_Ctor_Exception_CodeLinePragma(Exception innerException, CodeLinePragma linePragma) - { - CodeDomSerializerException exception = new(innerException, linePragma); - Assert.NotEmpty(exception.Message); - Assert.Same(innerException, exception.InnerException); - Assert.Same(linePragma, exception.LinePragma); - } - - public static IEnumerable Ctor_String_IDesignerSerializationManager_TestData() - { - Mock mockDesignerSerializationManager = new(MockBehavior.Strict); - yield return new object[] { "message", mockDesignerSerializationManager.Object }; - yield return new object[] { null, mockDesignerSerializationManager.Object }; - } - - [Theory] - [MemberData(nameof(Ctor_String_IDesignerSerializationManager_TestData))] - public void CodeDomSerializerException_Ctor_String_IDesignerSerializationManager(string message, IDesignerSerializationManager manager) - { - CodeDomSerializerException exception = new(message, manager); - Assert.NotEmpty(exception.Message); - Assert.Null(exception.InnerException); - Assert.Null(exception.LinePragma); - } - - public static IEnumerable Ctor_Exception_IDesignerSerializationManager_TestData() - { - Mock mockDesignerSerializationManager = new(MockBehavior.Strict); - yield return new object[] { new Exception(), mockDesignerSerializationManager.Object }; - yield return new object[] { null, mockDesignerSerializationManager.Object }; - } - - [Theory] - [MemberData(nameof(Ctor_Exception_IDesignerSerializationManager_TestData))] - public void CodeDomSerializerException_Ctor_Exception_IDesignerSerializationManager(Exception innerException, IDesignerSerializationManager manager) - { - CodeDomSerializerException exception = new(innerException, manager); - Assert.NotEmpty(exception.Message); - Assert.Same(innerException, exception.InnerException); - Assert.Null(exception.LinePragma); - } - - [Fact] - public void CodeDomSerializerException_NullManager_ThrowsArgumentNullException() - { - Assert.Throws("manager", () => new CodeDomSerializerException("message", (IDesignerSerializationManager)null)); - Assert.Throws("manager", () => new CodeDomSerializerException(new Exception(), (IDesignerSerializationManager)null)); - } - - [Theory] - [BoolData] - public void CodeDomSerializerException_Serialize_ThrowsSerializationException(bool formatterEnabled) - { - using BinaryFormatterScope formatterScope = new(enable: formatterEnabled); - using MemoryStream stream = new(); - BinaryFormatter formatter = new(); - CodeDomSerializerException exception = new("message", new CodeLinePragma("fileName.cs", 11)); - if (formatterEnabled) - { - Assert.Throws(() => formatter.Serialize(stream, exception)); - } - else - { - Assert.Throws(() => formatter.Serialize(stream, exception)); - } -#pragma warning restore SYSLIB0011 - } - - [Fact] - public void CodeDomSerializerException_GetObjectData_ThrowsPlatformNotSupportedException() - { - CodeDomSerializerException exception = new("message", new CodeLinePragma("fileName.cs", 11)); - Assert.Throws(() => exception.GetObjectData(null, new StreamingContext())); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/DesignerSerializationManagerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/DesignerSerializationManagerTests.cs deleted file mode 100644 index c09b7daa39b..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/DesignerSerializationManagerTests.cs +++ /dev/null @@ -1,2150 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using Moq; -using Moq.Protected; -using System.Windows.Forms.TestUtilities; - -namespace System.ComponentModel.Design.Serialization.Tests; - -public class DesignerSerializationManagerTests -{ - [Fact] - public void DesignerSerializationManager_Ctor_Default() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Null(manager.Container); - Assert.True(manager.PreserveNames); - Assert.Empty(iManager.Properties); - Assert.Same(iManager.Properties, iManager.Properties); - Assert.Null(manager.PropertyProvider); - Assert.False(manager.RecycleInstances); - Assert.True(manager.ValidateRecycledTypes); - ; - } - - public static IEnumerable Ctor_IServiceProvider_TestData() - { - Mock nullMockServiceProvider = new(MockBehavior.Strict); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns((IDesignerHost)null); - yield return new object[] { nullMockServiceProvider.Object, null }; - - Mock invalidMockServiceProvider = new(MockBehavior.Strict); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(new object()); - yield return new object[] { invalidMockServiceProvider.Object, null }; - - Container container = new(); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.Container) - .Returns(container); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - yield return new object[] { mockServiceProvider.Object, container }; - } - - [Theory] - [MemberData(nameof(Ctor_IServiceProvider_TestData))] - public void DesignerSerializationManager_Ctor_IServiceProvider(IServiceProvider provider, IContainer expectedContainer) - { - DesignerSerializationManager manager = new(provider); - IDesignerSerializationManager iManager = manager; - Assert.Same(expectedContainer, manager.Container); - Assert.Same(manager.Container, manager.Container); - Assert.True(manager.PreserveNames); - Assert.Empty(iManager.Properties); - Assert.Same(iManager.Properties, iManager.Properties); - Assert.Null(manager.PropertyProvider); - Assert.False(manager.RecycleInstances); - Assert.True(manager.ValidateRecycledTypes); - ; - } - - [Fact] - public void DesignerSerializationManager_Ctor_NullProvider_ThrowsArgumentNullException() - { - Assert.Throws("provider", () => new DesignerSerializationManager(null)); - } - - public static IEnumerable Container_Set_TestData() - { - yield return new object[] { null }; - yield return new object[] { new Container() }; - } - - [Theory] - [MemberData(nameof(Container_Set_TestData))] - public void DesignerSerializationManager_Container_Set_GetReturnsExpected(IContainer value) - { - SubDesignerSerializationManager manager = new() - { - Container = value - }; - Assert.Same(value, manager.Container); - Assert.Same(value, manager.GetService(typeof(IContainer))); - - // Set same. - manager.Container = value; - Assert.Same(value, manager.Container); - Assert.Same(value, manager.GetService(typeof(IContainer))); - } - - [Fact] - public void DesignerSerializationManager_Container_SetWithSession_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - manager.CreateSession(); - Assert.Throws(() => manager.Container = null); - } - - [Fact] - public void DesignerSerializationManager_Context_GetWithSession_ReturnsExpected() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - IDisposable session = manager.CreateSession(); - ContextStack context = iManager.Context; - Assert.Null(context.Current); - Assert.Same(context, iManager.Context); - } - - [Fact] - public void DesignerSerializationManager_Context_GetNoSessionAfterGetting_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - IDisposable session = manager.CreateSession(); - ContextStack context = iManager.Context; - Assert.NotNull(context); - Assert.Same(context, iManager.Context); - session.Dispose(); - Assert.Throws(() => iManager.Context); - } - - [Fact] - public void DesignerSerializationManager_Context_GetNoSession_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Throws(() => iManager.Context); - } - - [Fact] - public void DesignerSerializationManager_Errors_GetWithSession_ReturnsExpected() - { - DesignerSerializationManager manager = new(); - IDisposable session = manager.CreateSession(); - IList errors = manager.Errors; - Assert.Empty(errors); - Assert.Same(errors, manager.Errors); - Assert.IsAssignableFrom(errors); - } - - [Fact] - public void DesignerSerializationManager_Errors_NoSessionWithPreviousSession_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - IDisposable session = manager.CreateSession(); - Assert.Empty(manager.Errors); - session.Dispose(); - Assert.Throws(() => manager.Errors); - } - - [Fact] - public void DesignerSerializationManager_Errors_NoSession_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - Assert.Throws(() => manager.Errors); - } - - [Theory] - [BoolData] - public void DesignerSerializationManager_PreserveNames_Set_GetReturnsExpected(bool value) - { - DesignerSerializationManager manager = new() - { - PreserveNames = value - }; - Assert.Equal(value, manager.PreserveNames); - - // Set same - manager.PreserveNames = value; - Assert.Equal(value, manager.PreserveNames); - - // Set different - manager.PreserveNames = !value; - Assert.Equal(!value, manager.PreserveNames); - } - - [Theory] - [BoolData] - public void DesignerSerializationManager_PreserveNames_SetWithSession_ThrowsInvalidOperationException(bool value) - { - DesignerSerializationManager manager = new(); - manager.CreateSession(); - Assert.Throws(() => manager.PreserveNames = value); - Assert.True(manager.PreserveNames); - } - - [Fact] - public void DesignerSerializationManager_Properties_GetWithPropertyProvider_ReturnExpected() - { - PropertyProvider provider = new(); - DesignerSerializationManager manager = new() - { - PropertyProvider = provider - }; - IDesignerSerializationManager iManager = manager; - PropertyDescriptorCollection properties = iManager.Properties; - Assert.Same(properties, iManager.Properties); - PropertyDescriptor property = Assert.IsAssignableFrom(Assert.Single(properties)); - Assert.NotEmpty(property.Attributes); - Assert.Equal("Category", property.Category); - Assert.IsType(property.Converter); - Assert.Equal(typeof(PropertyProvider), property.ComponentType); - Assert.Equal("Description", property.Description); - Assert.True(property.DesignTimeOnly); - Assert.Equal("DisplayName", property.DisplayName); - Assert.True(property.IsBrowsable); - Assert.True(property.IsLocalizable); - Assert.False(property.IsReadOnly); - Assert.Equal("Value", property.Name); - Assert.Equal(typeof(int), property.PropertyType); - Assert.Equal(DesignerSerializationVisibility.Content, property.SerializationVisibility); - Assert.False(property.SupportsChangeEvents); - - // Should be wrapped. - Assert.False(property.CanResetValue(new Component())); - Assert.Equal(0, property.GetValue(new Component())); - property.SetValue(new Component(), 1); - Assert.Equal(1, property.GetValue(new Component())); - property.ResetValue(new Component()); - Assert.Equal(1, property.GetValue(new Component())); - Assert.True(property.ShouldSerializeValue(new Component())); - } - - [Fact] - public void DesignerSerializationManager_Properties_GetWithNullPropertyInPropertyProvider_ThrowsArgumentNullException() - { - object provider = new(); - DesignerSerializationManager manager = new() - { - PropertyProvider = provider - }; - IDesignerSerializationManager iManager = manager; - Mock mockCustomTypeDescriptor = new(MockBehavior.Strict); - mockCustomTypeDescriptor - .Setup(d => d.GetProperties()) - .Returns(new PropertyDescriptorCollection(new PropertyDescriptor[] { null })); - Mock mockProvider = new(MockBehavior.Strict); - mockProvider - .Setup(p => p.GetCache(provider)) - .CallBase(); - mockProvider - .Setup(p => p.GetExtendedTypeDescriptor(provider)) - .CallBase(); - mockProvider - .Setup(p => p.GetTypeDescriptor(typeof(object), provider)) - .Returns(mockCustomTypeDescriptor.Object); - TypeDescriptor.AddProvider(mockProvider.Object, provider); - - Assert.Same(provider, manager.PropertyProvider); - Assert.Throws("property", () => iManager.Properties); - - // Call again. - Assert.Throws("property", () => iManager.Properties); - } - - [Theory] - [StringWithNullData] - public void DesignerSerializationManager_PropertyProvider_Set_GetReturnsExpected(string value) - { - DesignerSerializationManager manager = new() - { - PropertyProvider = value - }; - Assert.Same(value, manager.PropertyProvider); - - // Set same - manager.PropertyProvider = value; - Assert.Same(value, manager.PropertyProvider); - } - - [Theory] - [StringWithNullData] - public void DesignerSerializationManager_PropertyProvider_SetWithSession_GetReturnsExpected(string value) - { - DesignerSerializationManager manager = new(); - manager.CreateSession(); - - manager.PropertyProvider = value; - Assert.Same(value, manager.PropertyProvider); - - // Set same - manager.PropertyProvider = value; - Assert.Same(value, manager.PropertyProvider); - } - - [Fact] - public void DesignerSerializationManager_Properties_SetWithExistingProperties_Resets() - { - DesignerSerializationManager manager = new() - { - PropertyProvider = new PropertyProvider() - }; - IDesignerSerializationManager iManager = manager; - PropertyDescriptorCollection properties = iManager.Properties; - PropertyDescriptor property = Assert.IsAssignableFrom(Assert.Single(properties)); - Assert.Equal(nameof(PropertyProvider.Value), property.Name); - Assert.Same(properties, iManager.Properties); - - OtherPropertyProvider provider = new(); - manager.PropertyProvider = provider; - Assert.Same(provider, manager.PropertyProvider); - PropertyDescriptorCollection otherProperties = iManager.Properties; - PropertyDescriptor otherProperty = Assert.IsAssignableFrom(Assert.Single(otherProperties)); - Assert.Equal(nameof(OtherPropertyProvider.OtherValue), otherProperty.Name); - Assert.Same(otherProperties, iManager.Properties); - - // Set same. - manager.PropertyProvider = provider; - Assert.Same(provider, manager.PropertyProvider); - Assert.Same(otherProperties, iManager.Properties); - } - - [Theory] - [BoolData] - public void DesignerSerializationManager_RecycleInstances_Set_GetReturnsExpected(bool value) - { - DesignerSerializationManager manager = new() - { - RecycleInstances = value - }; - Assert.Equal(value, manager.RecycleInstances); - - // Set same - manager.RecycleInstances = value; - Assert.Equal(value, manager.RecycleInstances); - - // Set different - manager.RecycleInstances = !value; - Assert.Equal(!value, manager.RecycleInstances); - } - - [Theory] - [BoolData] - public void DesignerSerializationManager_RecycleInstances_SetWithSession_ThrowsInvalidOperationException(bool value) - { - DesignerSerializationManager manager = new(); - manager.CreateSession(); - Assert.Throws(() => manager.RecycleInstances = value); - Assert.False(manager.RecycleInstances); - } - - [Theory] - [BoolData] - public void DesignerSerializationManager_ValidateRecycledTypes_Set_GetReturnsExpected(bool value) - { - DesignerSerializationManager manager = new() - { - ValidateRecycledTypes = value - }; - Assert.Equal(value, manager.ValidateRecycledTypes); - - // Set same - manager.ValidateRecycledTypes = value; - Assert.Equal(value, manager.ValidateRecycledTypes); - - // Set different - manager.ValidateRecycledTypes = !value; - Assert.Equal(!value, manager.ValidateRecycledTypes); - } - - [Theory] - [BoolData] - public void DesignerSerializationManager_ValidateRecycledTypes_SetWithSession_ThrowsInvalidOperationException(bool value) - { - DesignerSerializationManager manager = new(); - manager.CreateSession(); - Assert.Throws(() => manager.ValidateRecycledTypes = value); - Assert.True(manager.ValidateRecycledTypes); - } - - [Fact] - public void DesignerSerializationManager_ResolveName_AddNoSession_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - int callCount = 0; - ResolveNameEventHandler handler = (sender, e) => callCount++; - Assert.Throws(() => iManager.ResolveName += handler); - iManager.ResolveName -= handler; - Assert.Equal(0, callCount); - } - - [Fact] - public void DesignerSerializationManager_SerializationComplete_AddNoSession_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - int callCount = 0; - EventHandler handler = (sender, e) => callCount++; - Assert.Throws(() => iManager.SerializationComplete += handler); - iManager.SerializationComplete -= handler; - Assert.Equal(0, callCount); - } - - public static IEnumerable AddSerializationProvider_TestData() - { - yield return new object[] { null, null }; - yield return new object[] { null, new object() }; - yield return new object[] { typeof(int), null }; - yield return new object[] { typeof(int), new object() }; - } - - [Theory] - [MemberData(nameof(AddSerializationProvider_TestData))] - public void DesignerSerializationManager_AddSerializationProvider_NonNullProvider_GetSerializerReturnsExpected(Type objectType, object expected) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Mock mockDesignerSerializationProvider = new(MockBehavior.Strict); - mockDesignerSerializationProvider - .Setup(p => p.GetSerializer(manager, null, objectType, mockDesignerSerializationProvider.Object.GetType())) - .Returns(expected) - .Verifiable(); - iManager.AddSerializationProvider(mockDesignerSerializationProvider.Object); - Assert.Same(expected, iManager.GetSerializer(objectType, mockDesignerSerializationProvider.Object.GetType())); - mockDesignerSerializationProvider.Verify(p => p.GetSerializer(manager, null, objectType, mockDesignerSerializationProvider.Object.GetType()), Times.Once()); - - // Call again. - Assert.Same(expected, iManager.GetSerializer(objectType, mockDesignerSerializationProvider.Object.GetType())); - mockDesignerSerializationProvider.Verify(p => p.GetSerializer(manager, null, objectType, mockDesignerSerializationProvider.Object.GetType()), Times.Exactly(2)); - } - - [Fact] - public void DesignerSerializationManager_AddSerializationProvider_NullProvider_Nop() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - iManager.AddSerializationProvider(null); - } - - [Fact] - public void DesignerSerializationManager_CreateSession_Invoke_Success() - { - DesignerSerializationManager manager = new(); - IDisposable session = manager.CreateSession(); - Assert.NotNull(session); - session.Dispose(); - - // Get another. - IDisposable session2 = manager.CreateSession(); - Assert.NotNull(session2); - Assert.NotSame(session, session2); - session2.Dispose(); - } - - [Fact] - public void DesignerSerializationManager_CreateSession_DisposeMultipleTimes_Success() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - IDisposable session1 = manager.CreateSession(); - session1.Dispose(); - Assert.Throws(() => iManager.Context); - - // Dispose again without session. - session1.Dispose(); - Assert.Throws(() => iManager.Context); - - // Dispose with session. - IDisposable session2 = manager.CreateSession(); - session1.Dispose(); - Assert.Throws(() => iManager.Context); - } - - [Fact] - public void DesignerSerializationManager_CreateSession_Invoke_CallsOnSessionCreated() - { - Mock mockManager = new(MockBehavior.Strict); - mockManager - .Protected() - .Setup("OnSessionCreated", EventArgs.Empty) - .Verifiable(); - IDisposable session = mockManager.Object.CreateSession(); - mockManager.Protected().Verify("OnSessionCreated", Times.Once(), EventArgs.Empty); - } - - [Fact] - public void DesignerSerializationManager_CreateSession_InvokeWithSessionCreated_CallsHandler() - { - DesignerSerializationManager manager = new(); - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(manager, sender); - Assert.Equal(EventArgs.Empty, e); - callCount++; - }; - manager.SessionCreated += handler; - - IDisposable session = manager.CreateSession(); - Assert.NotNull(session); - Assert.Equal(1, callCount); - session.Dispose(); - - // Remove handler. - manager.SessionCreated -= handler; - session = manager.CreateSession(); - Assert.NotNull(session); - Assert.Equal(1, callCount); - } - - [Fact] - public void DesignerSerializationManager_CreateSession_Dispose_CallsOnSessionDisposed() - { - Mock mockManager = new(MockBehavior.Strict); - mockManager - .Protected() - .Setup("OnSessionCreated", EventArgs.Empty); - mockManager - .Protected() - .Setup("OnSessionDisposed", EventArgs.Empty) - .Verifiable(); - IDisposable session = mockManager.Object.CreateSession(); - session.Dispose(); - mockManager.Protected().Verify("OnSessionDisposed", Times.Once(), EventArgs.Empty); - - // Dispose again. - session.Dispose(); - mockManager.Protected().Verify("OnSessionDisposed", Times.Exactly(2), EventArgs.Empty); - } - - [Fact] - public void DesignerSerializationManager_CreateSession_Dispose_ClearsErrors() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - - IDisposable session1 = manager.CreateSession(); - IList errors1 = manager.Errors; - Assert.Empty(errors1); - Assert.Same(errors1, manager.Errors); - object errorInformation = new(); - iManager.ReportError(errorInformation); - Assert.Same(errorInformation, Assert.Single(errors1)); - - // Dispose, get another and ensure cleared. - session1.Dispose(); - IDisposable session2 = manager.CreateSession(); - IList errors2 = manager.Errors; - Assert.Empty(errors2); - Assert.Same(errors2, manager.Errors); - Assert.NotSame(errors1, errors2); - } - - [Fact] - public void DesignerSerializationManager_CreateSession_Dispose_ClearsContext() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - - IDisposable session1 = manager.CreateSession(); - ContextStack stack1 = iManager.Context; - Assert.NotNull(stack1); - Assert.Same(stack1, iManager.Context); - - // Dispose, get another and ensure cleared. - session1.Dispose(); - IDisposable session2 = manager.CreateSession(); - ContextStack stack2 = iManager.Context; - Assert.NotNull(stack2); - Assert.Same(stack2, iManager.Context); - Assert.NotSame(stack1, stack2); - } - - [Fact] - public void DesignerSerializationManager_CreateSession_Dispose_ClearsSerializers() - { - DesignerSerializationManager manager = new(); - - IDisposable session1 = manager.CreateSession(); - object serializer1 = manager.GetSerializer(typeof(ClassWithPublicDesignerSerializer), typeof(BaseClass)); - Assert.IsType(serializer1); - Assert.Same(serializer1, manager.GetSerializer(typeof(ClassWithPublicDesignerSerializer), typeof(PublicDesignerSerializationProvider))); - - // Dispose and ensure cleared. - session1.Dispose(); - object serializer2 = manager.GetSerializer(typeof(ClassWithPublicDesignerSerializer), typeof(BaseClass)); - Assert.IsType(serializer2); - Assert.NotSame(serializer1, serializer2); - Assert.NotSame(serializer2, manager.GetSerializer(typeof(ClassWithPublicDesignerSerializer), typeof(BaseClass))); - } - - [Theory] - [MemberData(nameof(ResolveNameEventArgs_TestData))] - public void DesignerSerializationManager_CreateSession_Dispose_ClearsResolveNameEventHandler(ResolveNameEventArgs eventArgs) - { - SubDesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - int callCount = 0; - ResolveNameEventHandler handler = (sender, e) => - { - Assert.Same(manager, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - IDisposable session = manager.CreateSession(); - iManager.ResolveName += handler; - - manager.OnResolveName(eventArgs); - Assert.Equal(1, callCount); - session.Dispose(); - - // Call again. - session = manager.CreateSession(); - manager.OnResolveName(eventArgs); - Assert.Equal(1, callCount); - } - - [Theory] - [NewAndDefaultData] - public void DesignerSerializationManager_CreateSession_Dispose_ClearsSerializationCompleteEventHandler(EventArgs eventArgs) - { - SubDesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(manager, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - IDisposable session = manager.CreateSession(); - iManager.SerializationComplete += handler; - manager.OnSessionDisposed(eventArgs); - Assert.Equal(1, callCount); - session.Dispose(); - - // Call again. - session = manager.CreateSession(); - session.Dispose(); - Assert.Equal(1, callCount); - } - - [Fact] - public void DesignerSerializationManager_CreateSessionDispose_InvokeWithSessionDisposed_CallsHandler() - { - DesignerSerializationManager manager = new(); - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(manager, sender); - Assert.Same(EventArgs.Empty, e); - callCount++; - }; - manager.SessionDisposed += handler; - - IDisposable session = manager.CreateSession(); - session.Dispose(); - Assert.Equal(1, callCount); - - // Call again. - session = manager.CreateSession(); - session.Dispose(); - Assert.Equal(2, callCount); - - // Remove handler. - manager.SessionDisposed -= handler; - session = manager.CreateSession(); - session.Dispose(); - Assert.Equal(2, callCount); - } - - [Fact] - public void DesignerSerializationManager_CreateSessionDispose_InvokeWithSerializationComplete_CallsHandler() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(manager, sender); - Assert.Same(EventArgs.Empty, e); - callCount++; - }; - IDisposable session = manager.CreateSession(); - iManager.SerializationComplete += handler; - session.Dispose(); - Assert.Equal(1, callCount); - - // Call again. - session = manager.CreateSession(); - session.Dispose(); - Assert.Equal(1, callCount); - - // Remove handler. - session = manager.CreateSession(); - iManager.SerializationComplete += handler; - iManager.SerializationComplete -= handler; - session.Dispose(); - Assert.Equal(1, callCount); - } - - [Fact] - public void DesignerSerializationManager_CreateSession_InvokeWithSession_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - manager.CreateSession(); - Assert.Throws(() => manager.CreateSession()); - } - - public static IEnumerable GetInstance_NoSuchInstance_TestData() - { - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(null); - - Component component = new(); - Container container = new(); - container.Add(component, "name"); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.Container) - .Returns(container); - Mock mockContainerServiceProvider = new(MockBehavior.Strict); - mockContainerServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - - yield return new object[] { mockServiceProvider.Object, true, string.Empty, null }; - yield return new object[] { mockServiceProvider.Object, false, string.Empty, null }; - yield return new object[] { mockServiceProvider.Object, true, "NoSuchName", null }; - yield return new object[] { mockServiceProvider.Object, false, "NoSuchName", null }; - - yield return new object[] { mockContainerServiceProvider.Object, true, string.Empty, null }; - yield return new object[] { mockContainerServiceProvider.Object, false, string.Empty, null }; - yield return new object[] { mockContainerServiceProvider.Object, true, "NoSuchName", null }; - yield return new object[] { mockContainerServiceProvider.Object, false, "NoSuchName", null }; - yield return new object[] { mockContainerServiceProvider.Object, true, "name", component }; - yield return new object[] { mockContainerServiceProvider.Object, false, "name", null }; - yield return new object[] { mockContainerServiceProvider.Object, true, "Name", component }; - yield return new object[] { mockContainerServiceProvider.Object, false, "Name", null }; - } - - [Theory] - [MemberData(nameof(GetInstance_NoSuchInstance_TestData))] - public void DesignerSerializationManager_GetInstance_NoNamedInstances_ReturnsNull(IServiceProvider provider, bool preserveNames, string name, object expected) - { - DesignerSerializationManager manager = new(provider) - { - PreserveNames = preserveNames - }; - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - Assert.Same(expected, iManager.GetInstance(name)); - - // Call again. - Assert.Same(expected, iManager.GetInstance(name)); - } - - [Theory] - [StringData] - public void DesignerSerializationManager_GetInstance_HasNameInstancesNameExists_ReturnsExpected(string name) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - - object instance = new(); - iManager.SetName(instance, name); - Assert.Same(instance, iManager.GetInstance(name)); - - // Call again. - Assert.Same(instance, iManager.GetInstance(name)); - } - - [Theory] - [InlineData("")] - [InlineData("Name")] - [InlineData("NoSuchName")] - public void DesignerSerializationManager_GetInstance_HasNameInstancesNoSuchName_ReturnsExpected(string name) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - - object instance = new(); - iManager.SetName(instance, "name"); - Assert.Null(iManager.GetInstance(name)); - - // Call again. - Assert.Null(iManager.GetInstance(name)); - } - - public static IEnumerable GetInstance_InvokeWithResolveName_TestData() - { - yield return new object[] { string.Empty, null }; - yield return new object[] { string.Empty, new object() }; - yield return new object[] { "NoSuchName", null }; - yield return new object[] { "NoSuchName", new object() }; - } - - [Theory] - [MemberData(nameof(GetInstance_InvokeWithResolveName_TestData))] - public void DesignerSerializationManager_GetInstance_InvokeWithResolveName_CallsHandler(string name, object value) - { - Component component = new(); - Container container = new(); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.Container) - .Returns(container); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - DesignerSerializationManager manager = new(mockServiceProvider.Object); - IDesignerSerializationManager iManager = manager; - int callCount = 0; - ResolveNameEventHandler handler = (sender, e) => - { - Assert.Same(manager, sender); - Assert.Same(name, e.Name); - e.Value = value; - callCount++; - }; - manager.CreateSession(); - iManager.ResolveName += handler; - - // With handler. - Assert.Same(value, iManager.GetInstance(name)); - Assert.Equal(1, callCount); - - // Call again. - Assert.Same(value, iManager.GetInstance(name)); - Assert.Equal(2, callCount); - - // Does not call if there is a container instance. - container.Add(component, "name"); - Assert.Same(component, iManager.GetInstance("name")); - Assert.Equal(2, callCount); - - // Does not call if there is a named instance. - container.Remove(component); - iManager.SetName(component, "name"); - Assert.Same(component, iManager.GetInstance("name")); - Assert.Equal(2, callCount); - - // Remove handler. - iManager.ResolveName -= handler; - Assert.Null(iManager.GetInstance(name)); - Assert.Equal(2, callCount); - } - - [Fact] - public void DesignerSerializationManager_GetInstance_NullName_ThrowsArgumentNullException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Throws("name", () => iManager.GetInstance(null)); - } - - [Theory] - [StringData] - public void DesignerSerializationManager_GetInstance_NoSession_ThrowsInvalidOperationException(string name) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Throws(() => iManager.GetInstance(name)); - } - - public static IEnumerable GetName_NoNamedInstance_TestData() - { - yield return new object[] { new object(), null }; - yield return new object[] { new Component(), null }; - - Mock mockNoSiteComponent = new(MockBehavior.Strict); - mockNoSiteComponent - .Setup(c => c.Site) - .Returns((ISite)null); - mockNoSiteComponent - .Setup(c => c.Dispose()); - yield return new object[] { mockNoSiteComponent.Object, null }; - - foreach (string name in new string[] { null, string.Empty, "name" }) - { - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.Name) - .Returns(name); - Mock mockSiteComponent = new(MockBehavior.Strict); - mockSiteComponent - .Setup(c => c.Site) - .Returns(mockSite.Object); - mockSiteComponent - .Setup(c => c.Dispose()); - yield return new object[] { mockSiteComponent.Object, name }; - - Mock mockNestedSite = new(MockBehavior.Strict); - mockNestedSite - .Setup(s => s.FullName) - .Returns(name); - Mock mockNestedSiteComponent = new(MockBehavior.Strict); - mockNestedSiteComponent - .Setup(c => c.Site) - .Returns(mockNestedSite.Object); - mockNestedSiteComponent - .Setup(c => c.Dispose()); - yield return new object[] { mockNestedSiteComponent.Object, name }; - } - } - - [Theory] - [MemberData(nameof(GetName_NoNamedInstance_TestData))] - public void DesignerSerializationManager_GetName_NoNamedInstance_ReturnsExpected(object instance, string expected) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - - Assert.Same(expected, iManager.GetName(instance)); - } - - [Theory] - [StringData] - public void DesignerSerializationManager_GetName_HasNamedInstance_ReturnsExpected(string name) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - - object instance = new(); - iManager.SetName(instance, name); - Assert.Same(name, iManager.GetName(instance)); - } - - [Theory] - [StringData] - public void DesignerSerializationManager_GetName_HasNamedComponent_ReturnsExpected(string name) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - - Mock mockInstance = new(MockBehavior.Strict); - mockInstance - .Setup(i => i.Site) - .Verifiable(); - iManager.SetName(mockInstance.Object, name); - Assert.Same(name, iManager.GetName(mockInstance.Object)); - mockInstance.Verify(i => i.Site, Times.Never()); - } - - [Fact] - public void DesignerSerializationManager_GetName_NullValue_ThrowsArgumentNullException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Throws("value", () => iManager.GetName(null)); - } - - [Fact] - public void DesignerSerializationManager_GetName_InvokeNoSession_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Throws(() => iManager.GetName("value")); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void DesignerSerializationManager_GetService_WithProvider_ReturnsExpected(Type serviceType) - { - object service = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(serviceType)) - .Returns(service) - .Verifiable(); - SubDesignerSerializationManager manager = new(mockServiceProvider.Object); - Assert.Same(service, manager.GetService(serviceType)); - mockServiceProvider.Verify(p => p.GetService(serviceType), Times.Once()); - - Assert.Same(service, ((IServiceProvider)manager).GetService(serviceType)); - mockServiceProvider.Verify(p => p.GetService(serviceType), Times.Exactly(2)); - } - - [Theory] - [MemberData(nameof(Ctor_IServiceProvider_TestData))] - public void DesignerSerializationManager_GetService_IContainer_ReturnsExpected(IServiceProvider provider, object expected) - { - SubDesignerSerializationManager manager = new(provider); - Assert.Same(expected, manager.GetService(typeof(IContainer))); - Assert.Same(expected, ((IServiceProvider)manager).GetService(typeof(IContainer))); - } - - [Theory] - [InlineData(null)] - [InlineData(typeof(int))] - [InlineData(typeof(IContainer))] - public void DesignerSerializationManager_GetService_NoProvider_ReturnsNull(Type serviceType) - { - SubDesignerSerializationManager manager = new(); - Assert.Null(manager.GetService(serviceType)); - Assert.Null(((IServiceProvider)manager).GetService(serviceType)); - } - - [Fact] - public void DesignerSerializationManager_IDesignerSerializationManagerGetService_Invoke_CallsProtectedGetService() - { - object service = new(); - Mock mockManager = new(MockBehavior.Strict); - mockManager - .Protected() - .Setup("GetService", typeof(int)) - .Returns(service) - .Verifiable(); - IDesignerSerializationManager iManager = mockManager.Object; - Assert.Same(service, iManager.GetService(typeof(int))); - mockManager.Protected().Verify("GetService", Times.Once(), typeof(int)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetService_WithProvider_ReturnsExpected(Type serviceType) - { - object service = new(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(serviceType)) - .Returns(service) - .Verifiable(); - IDesignerSerializationManager iManager = new DesignerSerializationManager(mockServiceProvider.Object); - Assert.Same(service, iManager.GetService(serviceType)); - mockServiceProvider.Verify(p => p.GetService(serviceType), Times.Once()); - - Assert.Same(service, ((IServiceProvider)iManager).GetService(serviceType)); - mockServiceProvider.Verify(p => p.GetService(serviceType), Times.Exactly(2)); - } - - [Theory] - [MemberData(nameof(Ctor_IServiceProvider_TestData))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetService_IContainer_ReturnsExpected(IServiceProvider provider, object expected) - { - IDesignerSerializationManager iManager = new DesignerSerializationManager(provider); - Assert.Same(expected, iManager.GetService(typeof(IContainer))); - Assert.Same(expected, ((IServiceProvider)iManager).GetService(typeof(IContainer))); - } - - [Theory] - [InlineData(null)] - [InlineData(typeof(int))] - [InlineData(typeof(IContainer))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetService_NoProvider_ReturnsNull(Type serviceType) - { - IDesignerSerializationManager iManager = new DesignerSerializationManager(); - Assert.Null(iManager.GetService(serviceType)); - Assert.Null(((IServiceProvider)iManager).GetService(serviceType)); - } - - public static IEnumerable GetRuntimeType_ValidProvider_TestData() - { - foreach (string typeName in new string[] { null, string.Empty, "typeName" }) - { - yield return new object[] { typeName, null }; - yield return new object[] { typeName, typeof(string) }; - } - } - - [Theory] - [MemberData(nameof(GetRuntimeType_ValidProvider_TestData))] - public void DesignerSerializationManager_GetRuntimeType_ValidProvider_ReturnsExpected(string typeName, Type resolvedType) - { - Mock mockTypeResolutionService = new(MockBehavior.Strict); - mockTypeResolutionService - .Setup(s => s.GetType(typeName)) - .Returns(resolvedType) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns((IDesignerHost)null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(mockTypeResolutionService.Object) - .Verifiable(); - DesignerSerializationManager manager = new(mockServiceProvider.Object); - Assert.Same(resolvedType, manager.GetRuntimeType(typeName)); - mockServiceProvider.Verify(p => p.GetService(typeof(ITypeResolutionService)), Times.Once()); - mockTypeResolutionService.Verify(s => s.GetType(typeName), Times.Once()); - - // Call again. - Assert.Same(resolvedType, manager.GetRuntimeType(typeName)); - mockServiceProvider.Verify(p => p.GetService(typeof(ITypeResolutionService)), Times.Once()); - mockTypeResolutionService.Verify(s => s.GetType(typeName), Times.Exactly(2)); - } - - public static IEnumerable GetRuntimeType_InvalidProvider_TestData() - { - Mock nullMockServiceProvider = new(MockBehavior.Strict); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns((IDesignerHost)null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns((ITypeResolutionService)null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns((TypeDescriptionProviderService)null); - yield return new object[] { nullMockServiceProvider.Object }; - - Mock invalidMockServiceProvider = new(MockBehavior.Strict); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(new object()); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(new object()); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(new object()); - yield return new object[] { invalidMockServiceProvider.Object }; - } - - [Theory] - [MemberData(nameof(GetRuntimeType_InvalidProvider_TestData))] - public void DesignerSerializationManager_GetRuntimeType_InvalidProvider_ReturnsExpected(IServiceProvider provider) - { - DesignerSerializationManager manager = new(provider); - Assert.Equal(typeof(int), manager.GetRuntimeType(typeof(int).FullName)); - } - - [Theory] - [InlineData("System.Int32", typeof(int))] - [InlineData("system.int32", null)] - [InlineData("NoSuchType", null)] - [InlineData("", null)] - public void DesignerSerializationManager_GetRuntimeType_NoProvider_ReturnsExpected(string typeName, Type expected) - { - DesignerSerializationManager manager = new(); - Assert.Same(expected, manager.GetRuntimeType(typeName)); - } - - [Fact] - public void DesignerSerializationManager_GetRuntimeType_NullTypeName_ThrowsArgumentNullException() - { - DesignerSerializationManager manager = new(); - Assert.Throws("typeName", () => manager.GetRuntimeType(null)); - } - - public static IEnumerable GetSerializer_TestData() - { - foreach (Type objectType in new Type[] { null, typeof(int) }) - { - yield return new object[] { objectType, typeof(int), null }; - yield return new object[] { objectType, typeof(IDesignerSerializationProvider), null }; - yield return new object[] { objectType, typeof(PublicDesignerSerializationProvider), null }; - yield return new object[] { objectType, typeof(PrivateDesignerSerializationProvider), null }; - yield return new object[] { objectType, typeof(ClassWithEmptyDefaultSerializationProvider), null }; - yield return new object[] { objectType, typeof(ClassWithNoSuchDefaultSerializationProvider), null }; - yield return new object[] { objectType, typeof(ClassWithInvalidDefaultSerializationProvider), null }; - yield return new object[] { objectType, typeof(ClassWithPublicDesignerSerializationProvider), PublicDesignerSerializationProvider.Serializer }; - yield return new object[] { objectType, typeof(ClassWithPrivateDesignerSerializationProvider), PrivateDesignerSerializationProvider.Serializer }; - yield return new object[] { objectType, typeof(ClassWithNullDesignerSerializationProvider), null }; - } - - yield return new object[] { typeof(ClassWithNullBaseDesignerSerializer), typeof(int), null }; - yield return new object[] { typeof(ClassWithEmptyBaseDesignerSerializer), typeof(int), null }; - yield return new object[] { typeof(ClassWithNoSuchBaseDesignerSerializer), typeof(int), null }; - yield return new object[] { typeof(ClassWithNullSubDesignerSerializer), typeof(int), null }; - yield return new object[] { typeof(ClassWithEmptySubDesignerSerializer), typeof(int), null }; - yield return new object[] { typeof(ClassWithNoSuchSubDesignerSerializer), typeof(int), null }; - yield return new object[] { typeof(ClassWithPublicDesignerSerializer), typeof(int), null }; - yield return new object[] { typeof(ClassWithPublicDesignerSerializer), typeof(object), null }; - yield return new object[] { typeof(ClassWithPublicDesignerSerializer), typeof(SubClass), null }; - } - - [Theory] - [MemberData(nameof(GetSerializer_TestData))] - public void DesignerSerializationManager_GetSerializer_CustomIDesignerSerializationProvider_ReturnsExpected(Type objectType, Type serializerType, object expected) - { - DesignerSerializationManager manager = new(); - Assert.Same(expected, manager.GetSerializer(objectType, serializerType)); - - // Call again. - Assert.Same(expected, manager.GetSerializer(objectType, serializerType)); - } - - [Theory] - [MemberData(nameof(GetSerializer_TestData))] - public void DesignerSerializationManager_GetSerializerWithSession_CustomIDesignerSerializationProvider_ReturnsExpected(Type objectType, Type serializerType, object expected) - { - DesignerSerializationManager manager = new(); - manager.CreateSession(); - - Assert.Same(expected, manager.GetSerializer(objectType, serializerType)); - - // Call again. - Assert.Same(expected, manager.GetSerializer(objectType, serializerType)); - } - - public static IEnumerable GetSerializer_CustomDesignerSerializer_TestData() - { - yield return new object[] { typeof(ClassWithPublicDesignerSerializer), typeof(PublicDesignerSerializationProvider) }; - yield return new object[] { typeof(ClassWithPrivateDesignerSerializer), typeof(PrivateDesignerSerializationProvider) }; - } - - [Theory] - [MemberData(nameof(GetSerializer_CustomDesignerSerializer_TestData))] - public void DesignerSerializationManager_GetSerializer_CustomDesignerSerializerNoSession_ReturnsExpected(Type objectType, Type expectedSerializerType) - { - DesignerSerializationManager manager = new(); - object serializer1 = manager.GetSerializer(objectType, typeof(BaseClass)); - Assert.IsType(expectedSerializerType, serializer1); - - // Call again. - object serializer2 = manager.GetSerializer(objectType, typeof(BaseClass)); - Assert.IsType(expectedSerializerType, serializer2); - Assert.NotSame(serializer1, serializer2); - - // Call different serializer type. - Assert.Null(manager.GetSerializer(objectType, expectedSerializerType)); - - // Call again. - Assert.Null(manager.GetSerializer(objectType, expectedSerializerType)); - - // Call invalid serializer type. - Assert.Null(manager.GetSerializer(objectType, typeof(object))); - - // Call again. - Assert.Null(manager.GetSerializer(objectType, typeof(object))); - - // Call unrelated serializer type. - Assert.Null(manager.GetSerializer(objectType, typeof(int))); - - // Call again. - Assert.Null(manager.GetSerializer(objectType, typeof(int))); - } - - [Theory] - [MemberData(nameof(GetSerializer_CustomDesignerSerializer_TestData))] - public void DesignerSerializationManager_GetSerializer_CustomDesignerSerializerWithSession_ReturnsExpected(Type objectType, Type expectedSerializerType) - { - DesignerSerializationManager manager = new(); - manager.CreateSession(); - object serializer1 = manager.GetSerializer(objectType, typeof(BaseClass)); - Assert.IsType(expectedSerializerType, serializer1); - - // Call again. - object serializer2 = manager.GetSerializer(objectType, typeof(BaseClass)); - Assert.IsType(expectedSerializerType, serializer2); - Assert.NotSame(serializer1, serializer2); - - // Call different serializer type. - object serializer3 = manager.GetSerializer(objectType, expectedSerializerType); - Assert.IsType(expectedSerializerType, serializer3); - Assert.NotSame(serializer1, serializer2); - - // Call again. - object serializer4 = manager.GetSerializer(objectType, expectedSerializerType); - Assert.IsType(expectedSerializerType, serializer4); - Assert.Same(serializer3, serializer4); - - // Call invalid serializer type. - object serializer5 = manager.GetSerializer(objectType, typeof(object)); - Assert.IsType(expectedSerializerType, serializer5); - Assert.Same(serializer4, serializer5); - - // Call again. - object serializer6 = manager.GetSerializer(objectType, typeof(object)); - Assert.IsType(expectedSerializerType, serializer6); - Assert.Same(serializer5, serializer6); - - // Call unrelated serializer type. - Assert.Null(manager.GetSerializer(objectType, typeof(int))); - - // Call again. - Assert.Null(manager.GetSerializer(objectType, typeof(int))); - } - - [Fact] - public void DesignerSerializationManager_GetSerializer_IDesignerSerializationProvider_ThrowsMissingMethodException() - { - DesignerSerializationManager manager = new(); - Assert.Throws(() => manager.GetSerializer(null, typeof(ClassWithInterfaceDefaultSerializationProvider))); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void DesignerSerializationManager_GetSerializer_NullSerializerType_ThrowsArgumentNullException(Type objectType) - { - DesignerSerializationManager manager = new(); - Assert.Throws("serializerType", () => manager.GetSerializer(objectType, null)); - } - - [Theory] - [MemberData(nameof(GetSerializer_TestData))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetSerializer_CustomIDesignerSerializationProvider_ReturnsExpected(Type objectType, Type serializerType, object expected) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Same(expected, iManager.GetSerializer(objectType, serializerType)); - - // Call again. - Assert.Same(expected, iManager.GetSerializer(objectType, serializerType)); - } - - [Theory] - [MemberData(nameof(GetSerializer_TestData))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetSerializerWithSession_CustomIDesignerSerializationProvider_ReturnsExpected(Type objectType, Type serializerType, object expected) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - - Assert.Same(expected, iManager.GetSerializer(objectType, serializerType)); - - // Call again. - Assert.Same(expected, iManager.GetSerializer(objectType, serializerType)); - } - - [Theory] - [MemberData(nameof(GetSerializer_CustomDesignerSerializer_TestData))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetSerializer_CustomDesignerSerializerNoSession_ReturnsExpected(Type objectType, Type expectedSerializerType) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - object serializer1 = iManager.GetSerializer(objectType, typeof(BaseClass)); - Assert.IsType(expectedSerializerType, serializer1); - - // Call again. - object serializer2 = iManager.GetSerializer(objectType, typeof(BaseClass)); - Assert.IsType(expectedSerializerType, serializer2); - Assert.NotSame(serializer1, serializer2); - - // Call different serializer type. - Assert.Null(iManager.GetSerializer(objectType, expectedSerializerType)); - - // Call again. - Assert.Null(iManager.GetSerializer(objectType, expectedSerializerType)); - - // Call invalid serializer type. - Assert.Null(iManager.GetSerializer(objectType, typeof(object))); - - // Call again. - Assert.Null(iManager.GetSerializer(objectType, typeof(object))); - - // Call unrelated serializer type. - Assert.Null(iManager.GetSerializer(objectType, typeof(int))); - - // Call again. - Assert.Null(iManager.GetSerializer(objectType, typeof(int))); - } - - [Theory] - [MemberData(nameof(GetSerializer_CustomDesignerSerializer_TestData))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetSerializer_CustomDesignerSerializerWithSession_ReturnsExpected(Type objectType, Type expectedSerializerType) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - object serializer1 = iManager.GetSerializer(objectType, typeof(BaseClass)); - Assert.IsType(expectedSerializerType, serializer1); - - // Call again. - object serializer2 = iManager.GetSerializer(objectType, typeof(BaseClass)); - Assert.IsType(expectedSerializerType, serializer2); - Assert.NotSame(serializer1, serializer2); - - // Call different serializer type. - object serializer3 = iManager.GetSerializer(objectType, expectedSerializerType); - Assert.IsType(expectedSerializerType, serializer3); - Assert.NotSame(serializer1, serializer2); - - // Call again. - object serializer4 = iManager.GetSerializer(objectType, expectedSerializerType); - Assert.IsType(expectedSerializerType, serializer4); - Assert.Same(serializer3, serializer4); - - // Call invalid serializer type. - object serializer5 = iManager.GetSerializer(objectType, typeof(object)); - Assert.IsType(expectedSerializerType, serializer5); - Assert.Same(serializer4, serializer5); - - // Call again. - object serializer6 = iManager.GetSerializer(objectType, typeof(object)); - Assert.IsType(expectedSerializerType, serializer6); - Assert.Same(serializer5, serializer6); - - // Call unrelated serializer type. - Assert.Null(iManager.GetSerializer(objectType, typeof(int))); - - // Call again. - Assert.Null(iManager.GetSerializer(objectType, typeof(int))); - - // Call unrelated object type - Assert.Null(iManager.GetSerializer(typeof(object), typeof(int))); - } - - [Fact] - public void DesignerSerializationManager_IDesignerSerializationManagerGetSerializer_IDesignerSerializationProvider_ThrowsMissingMethodException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Throws(() => iManager.GetSerializer(null, typeof(ClassWithInterfaceDefaultSerializationProvider))); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetTypeWithNullTheoryData))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetSerializer_NullSerializerType_ThrowsArgumentNullException(Type objectType) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Throws("serializerType", () => iManager.GetSerializer(objectType, null)); - } - - public static IEnumerable GetType_ValidProvider_TestData() - { - foreach (string typeName in new string[] { null, string.Empty, "typeName" }) - { - yield return new object[] { typeName, null, 0, true, null }; - yield return new object[] { typeName, null, 0, false, null }; - yield return new object[] { typeName, typeof(int), 1, true, typeof(int) }; - yield return new object[] { typeName, typeof(int), 1, false, null }; - } - } - - [Theory] - [MemberData(nameof(GetType_ValidProvider_TestData))] - public void DesignerSerializationManager_GetType_ValidProvider_ReturnsExpected(string typeName, Type resolvedType, int typeDescriptionProviderServiceCount, bool supportedType, Type expected) - { - Mock mockTypeResolutionService = new(MockBehavior.Strict); - mockTypeResolutionService - .Setup(s => s.GetType(typeName)) - .Returns(resolvedType) - .Verifiable(); - Mock mockTypeDescriptionProvider = new(MockBehavior.Strict); - mockTypeDescriptionProvider - .Setup(p => p.IsSupportedType(resolvedType)) - .Returns(supportedType) - .Verifiable(); - Mock mockTypeDescriptionProviderService = new(MockBehavior.Strict); - mockTypeDescriptionProviderService - .Setup(s => s.GetProvider(resolvedType)) - .Returns(mockTypeDescriptionProvider.Object) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns((IDesignerHost)null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(mockTypeResolutionService.Object) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(mockTypeDescriptionProviderService.Object) - .Verifiable(); - SubDesignerSerializationManager manager = new(mockServiceProvider.Object); - Assert.Same(expected, manager.GetType(typeName)); - mockServiceProvider.Verify(p => p.GetService(typeof(ITypeResolutionService)), Times.Once()); - mockTypeResolutionService.Verify(s => s.GetType(typeName), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Exactly(typeDescriptionProviderServiceCount)); - mockTypeDescriptionProviderService.Verify(s => s.GetProvider(resolvedType), Times.Exactly(typeDescriptionProviderServiceCount)); - mockTypeDescriptionProvider.Verify(s => s.IsSupportedType(resolvedType), Times.Exactly(typeDescriptionProviderServiceCount)); - - // Call again. - Assert.Same(expected, manager.GetType(typeName)); - mockServiceProvider.Verify(p => p.GetService(typeof(ITypeResolutionService)), Times.Once()); - mockTypeResolutionService.Verify(s => s.GetType(typeName), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Exactly(typeDescriptionProviderServiceCount * 2)); - mockTypeDescriptionProviderService.Verify(s => s.GetProvider(resolvedType), Times.Exactly(typeDescriptionProviderServiceCount * 2)); - mockTypeDescriptionProvider.Verify(s => s.IsSupportedType(resolvedType), Times.Exactly(typeDescriptionProviderServiceCount * 2)); - } - - public static IEnumerable GetType_InvalidProvider_TestData() - { - Mock nullMockServiceProvider = new(MockBehavior.Strict); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns((IDesignerHost)null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns((ITypeResolutionService)null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns((TypeDescriptionProviderService)null); - yield return new object[] { nullMockServiceProvider.Object }; - - Mock invalidMockServiceProvider = new(MockBehavior.Strict); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(new object()); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(new object()); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(new object()); - yield return new object[] { invalidMockServiceProvider.Object }; - - Mock invalidMockTypeDescriptionProviderService = new(MockBehavior.Strict); - invalidMockTypeDescriptionProviderService - .Setup(p => p.GetProvider(typeof(int))) - .Returns((TypeDescriptionProvider)null); - Mock invalidTypeDescriptionProviderServiceMockServiceProvider = new(MockBehavior.Strict); - invalidTypeDescriptionProviderServiceMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - invalidTypeDescriptionProviderServiceMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - invalidTypeDescriptionProviderServiceMockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(invalidMockTypeDescriptionProviderService.Object); - yield return new object[] { invalidTypeDescriptionProviderServiceMockServiceProvider.Object }; - } - - [Theory] - [MemberData(nameof(GetType_InvalidProvider_TestData))] - public void DesignerSerializationManager_GetType_InvalidProvider_ReturnsExpected(IServiceProvider provider) - { - SubDesignerSerializationManager manager = new(provider); - Assert.Equal(typeof(int), manager.GetType(typeof(int).FullName)); - } - - public static IEnumerable GetType_NoProvider_TestData() - { - yield return new object[] { "System.Int32", typeof(int) }; - yield return new object[] { "system.int32", null }; - yield return new object[] { "NoSuchType", null }; - yield return new object[] { string.Empty, null }; - yield return new object[] { ".System.Int32", null }; - yield return new object[] { "System.Int32.", null }; - yield return new object[] { "Name.System.Int32", null }; - yield return new object[] { "System.Int32.Name", null }; - yield return new object[] { ".", null }; - yield return new object[] { typeof(NestedClass).AssemblyQualifiedName, typeof(NestedClass) }; - } - - [Theory] - [MemberData(nameof(GetType_NoProvider_TestData))] - public void DesignerSerializationManager_GetType_NoProvider_ReturnsExpected(string typeName, Type expected) - { - SubDesignerSerializationManager manager = new(); - Assert.Same(expected, manager.GetType(typeName)); - } - - [Fact] - public void DesignerSerializationManager_GetType_NullTypeName_ThrowsArgumentNullException() - { - SubDesignerSerializationManager manager = new(); - Assert.Throws("typeName", () => manager.GetType(null)); - } - - [Theory] - [MemberData(nameof(GetType_ValidProvider_TestData))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetType_ValidProvider_ReturnsExpected(string typeName, Type resolvedType, int typeDescriptionProviderServiceCount, bool supportedType, Type expected) - { - Mock mockTypeResolutionService = new(MockBehavior.Strict); - mockTypeResolutionService - .Setup(s => s.GetType(typeName)) - .Returns(resolvedType) - .Verifiable(); - Mock mockTypeDescriptionProvider = new(MockBehavior.Strict); - mockTypeDescriptionProvider - .Setup(p => p.IsSupportedType(resolvedType)) - .Returns(supportedType) - .Verifiable(); - Mock mockTypeDescriptionProviderService = new(MockBehavior.Strict); - mockTypeDescriptionProviderService - .Setup(s => s.GetProvider(resolvedType)) - .Returns(mockTypeDescriptionProvider.Object) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns((IDesignerHost)null); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(mockTypeResolutionService.Object) - .Verifiable(); - mockServiceProvider - .Setup(p => p.GetService(typeof(TypeDescriptionProviderService))) - .Returns(mockTypeDescriptionProviderService.Object) - .Verifiable(); - DesignerSerializationManager manager = new(mockServiceProvider.Object); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - - Assert.Same(expected, iManager.GetType(typeName)); - mockServiceProvider.Verify(p => p.GetService(typeof(ITypeResolutionService)), Times.Once()); - mockTypeResolutionService.Verify(s => s.GetType(typeName), Times.Once()); - mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Exactly(typeDescriptionProviderServiceCount)); - mockTypeDescriptionProviderService.Verify(s => s.GetProvider(resolvedType), Times.Exactly(typeDescriptionProviderServiceCount)); - mockTypeDescriptionProvider.Verify(s => s.IsSupportedType(resolvedType), Times.Exactly(typeDescriptionProviderServiceCount)); - - // Call again. - Assert.Same(expected, iManager.GetType(typeName)); - mockServiceProvider.Verify(p => p.GetService(typeof(ITypeResolutionService)), Times.Once()); - mockTypeResolutionService.Verify(s => s.GetType(typeName), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(TypeDescriptionProviderService)), Times.Exactly(typeDescriptionProviderServiceCount * 2)); - mockTypeDescriptionProviderService.Verify(s => s.GetProvider(resolvedType), Times.Exactly(typeDescriptionProviderServiceCount * 2)); - mockTypeDescriptionProvider.Verify(s => s.IsSupportedType(resolvedType), Times.Exactly(typeDescriptionProviderServiceCount * 2)); - } - - [Theory] - [MemberData(nameof(GetType_InvalidProvider_TestData))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetType_InvalidProvider_ReturnsExpected(IServiceProvider provider) - { - DesignerSerializationManager manager = new(provider); - IDesignerSerializationManager iManager = manager; - using IDisposable session = manager.CreateSession(); - Assert.Equal(typeof(int), iManager.GetType(typeof(int).FullName)); - } - - [Theory] - [MemberData(nameof(GetType_NoProvider_TestData))] - public void DesignerSerializationManager_IDesignerSerializationManagerGetType_NoProvider_ReturnsExpected(string typeName, Type expected) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - using IDisposable session = manager.CreateSession(); - Assert.Same(expected, iManager.GetType(typeName)); - } - - [Theory] - [StringWithNullData] - public void DesignerSerializationManager_IDesignerSerializationManagerGetType_NoSession_ThrowsInvalidOperationException(string typeName) - { - IDesignerSerializationManager iManager = new DesignerSerializationManager(); - Assert.Throws(() => iManager.GetType(typeName)); - } - - [Fact] - public void DesignerSerializationManager_IDesignerSerializationManagerGetType_NullTypeName_ThrowsArgumentNullException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - using IDisposable session = manager.CreateSession(); - Assert.Throws("typeName", () => iManager.GetType(null)); - } - - public static IEnumerable ResolveNameEventArgs_TestData() - { - yield return new object[] { null }; - yield return new object[] { new ResolveNameEventArgs("name") }; - } - - [Theory] - [MemberData(nameof(ResolveNameEventArgs_TestData))] - public void DesignerSerializationManager_OnResolveName_InvokeWithResolveName_CallsHandler(ResolveNameEventArgs eventArgs) - { - SubDesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - int callCount = 0; - ResolveNameEventHandler handler = (sender, e) => - { - Assert.Same(manager, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - IDisposable session = manager.CreateSession(); - iManager.ResolveName += handler; - - // With handler. - manager.OnResolveName(eventArgs); - Assert.Equal(1, callCount); - session.Dispose(); - - // Call again. - session = manager.CreateSession(); - iManager.ResolveName += handler; - manager.OnResolveName(eventArgs); - Assert.Equal(2, callCount); - session.Dispose(); - - // Remove handler. - session = manager.CreateSession(); - iManager.ResolveName += handler; - iManager.ResolveName -= handler; - Assert.Equal(2, callCount); - session.Dispose(); - } - - [Theory] - [NewAndDefaultData] - public void DesignerSerializationManager_OnSessionCreated_InvokeWithSessionCreated_CallsHandler(EventArgs eventArgs) - { - SubDesignerSerializationManager manager = new(); - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(manager, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - manager.SessionCreated += handler; - - // With handler. - manager.OnSessionCreated(eventArgs); - Assert.Equal(1, callCount); - - // Call again. - manager.OnSessionCreated(eventArgs); - Assert.Equal(2, callCount); - - // Remove handler. - manager.SessionCreated -= handler; - Assert.Equal(2, callCount); - } - - [Fact] - public void DesignerSerializationManager_OnSessionDisposed_Invoke_ClearsErrors() - { - SubDesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - - IDisposable session1 = manager.CreateSession(); - IList errors1 = manager.Errors; - Assert.Empty(errors1); - Assert.Same(errors1, manager.Errors); - object errorInformation = new(); - iManager.ReportError(errorInformation); - Assert.Same(errorInformation, Assert.Single(errors1)); - - // Dispose, get another and ensure cleared. - manager.OnSessionDisposed(EventArgs.Empty); - IDisposable session2 = manager.CreateSession(); - IList errors2 = manager.Errors; - Assert.Empty(errors2); - Assert.Same(errors2, manager.Errors); - Assert.NotSame(errors1, errors2); - } - - [Fact] - public void DesignerSerializationManager_OnSessionDisposed_Invoke_ClearsContext() - { - SubDesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - - IDisposable session1 = manager.CreateSession(); - ContextStack stack1 = iManager.Context; - Assert.NotNull(stack1); - Assert.Same(stack1, iManager.Context); - - // Dispose, get another and ensure cleared. - manager.OnSessionDisposed(EventArgs.Empty); - IDisposable session2 = manager.CreateSession(); - ContextStack stack2 = iManager.Context; - Assert.NotNull(stack2); - Assert.Same(stack2, iManager.Context); - Assert.NotSame(stack1, stack2); - } - - [Fact] - public void DesignerSerializationManager_OnSessionDisposed_Invoke_ClearsSerializers() - { - SubDesignerSerializationManager manager = new(); - - IDisposable session1 = manager.CreateSession(); - object serializer1 = manager.GetSerializer(typeof(ClassWithPublicDesignerSerializer), typeof(BaseClass)); - Assert.IsType(serializer1); - Assert.Same(serializer1, manager.GetSerializer(typeof(ClassWithPublicDesignerSerializer), typeof(PublicDesignerSerializationProvider))); - - // Dispose and ensure cleared. - manager.OnSessionDisposed(EventArgs.Empty); - object serializer2 = manager.GetSerializer(typeof(ClassWithPublicDesignerSerializer), typeof(BaseClass)); - Assert.IsType(serializer2); - Assert.NotSame(serializer1, serializer2); - Assert.NotSame(serializer2, manager.GetSerializer(typeof(ClassWithPublicDesignerSerializer), typeof(BaseClass))); - } - - [Theory] - [NewAndDefaultData] - public void DesignerSerializationManager_OnSessionDisposed_InvokeWithSessionDisposed_CallsHandler(EventArgs eventArgs) - { - SubDesignerSerializationManager manager = new(); - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(manager, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - manager.SessionDisposed += handler; - - // With handler. - manager.OnSessionDisposed(eventArgs); - Assert.Equal(1, callCount); - - // Call again. - manager.OnSessionDisposed(eventArgs); - Assert.Equal(2, callCount); - - // Remove handler. - manager.SessionDisposed -= handler; - manager.OnSessionDisposed(eventArgs); - Assert.Equal(2, callCount); - } - - [Theory] - [NewAndDefaultData] - public void DesignerSerializationManager_OnSessionDisposed_InvokeWithSerializationComplete_CallsHandler(EventArgs eventArgs) - { - SubDesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - int callCount = 0; - EventHandler handler = (sender, e) => - { - Assert.Same(manager, sender); - Assert.Same(eventArgs, e); - callCount++; - }; - IDisposable session = manager.CreateSession(); - iManager.SerializationComplete += handler; - manager.OnSessionDisposed(eventArgs); - Assert.Equal(1, callCount); - session.Dispose(); - - // Call again. - session = manager.CreateSession(); - iManager.SerializationComplete += handler; - manager.OnSessionDisposed(eventArgs); - Assert.Equal(2, callCount); - - // Remove handler. - session = manager.CreateSession(); - iManager.SerializationComplete += handler; - iManager.SerializationComplete -= handler; - manager.OnSessionDisposed(eventArgs); - Assert.Equal(2, callCount); - } - - [Fact] - public void DesignerSerializationManager_RemoveSerializationProvider_Invoke_GetSerializerReturnsNull() - { - object serializer = new(); - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Mock mockDesignerSerializationProvider = new(MockBehavior.Strict); - mockDesignerSerializationProvider - .Setup(p => p.GetSerializer(manager, null, typeof(int), mockDesignerSerializationProvider.Object.GetType())) - .Returns(serializer) - .Verifiable(); - iManager.AddSerializationProvider(mockDesignerSerializationProvider.Object); - Assert.Same(serializer, iManager.GetSerializer(typeof(int), mockDesignerSerializationProvider.Object.GetType())); - mockDesignerSerializationProvider.Verify(p => p.GetSerializer(manager, null, typeof(int), mockDesignerSerializationProvider.Object.GetType()), Times.Once()); - - iManager.RemoveSerializationProvider(mockDesignerSerializationProvider.Object); - Assert.Null(iManager.GetSerializer(typeof(int), mockDesignerSerializationProvider.Object.GetType())); - mockDesignerSerializationProvider.Verify(p => p.GetSerializer(manager, null, typeof(int), mockDesignerSerializationProvider.Object.GetType()), Times.Once()); - - // Remove again. - iManager.RemoveSerializationProvider(mockDesignerSerializationProvider.Object); - Assert.Null(iManager.GetSerializer(typeof(int), mockDesignerSerializationProvider.Object.GetType())); - mockDesignerSerializationProvider.Verify(p => p.GetSerializer(manager, null, typeof(int), mockDesignerSerializationProvider.Object.GetType()), Times.Once()); - } - - [Fact] - public void DesignerSerializationManager_RemoveSerializationProvider_NoSuchProviderNotEmpty_Nop() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Mock mockDesignerSerializationProvider1 = new(MockBehavior.Strict); - Mock mockDesignerSerializationProvider2 = new(MockBehavior.Strict); - iManager.AddSerializationProvider(mockDesignerSerializationProvider1.Object); - iManager.RemoveSerializationProvider(null); - iManager.RemoveSerializationProvider(mockDesignerSerializationProvider2.Object); - } - - [Fact] - public void DesignerSerializationManager_RemoveSerializationProvider_NoSuchProviderEmpty_Nop() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Mock mockDesignerSerializationProvider = new(MockBehavior.Strict); - iManager.RemoveSerializationProvider(null); - iManager.RemoveSerializationProvider(mockDesignerSerializationProvider.Object); - } - - [Fact] - public void DesignerSerializationManager_ReportError_NonNullErrorInformation_AddsToErrors() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - using (IDisposable session = manager.CreateSession()) - { - object errorInformation = new(); - iManager.ReportError(errorInformation); - Assert.Same(errorInformation, Assert.Single(manager.Errors)); - } - } - - [Fact] - public void DesignerSerializationManager_ReportError_NullErrorInformation_Nop() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - using IDisposable session = manager.CreateSession(); - iManager.ReportError(null); - Assert.Empty(manager.Errors); - } - - [Fact] - public void DesignerSerializationManager_ReportError_NoSession_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Throws(() => iManager.ReportError(null)); - } - - [Theory] - [StringData] - public void DesignerSerializationManager_SetName_Invoke_GetNameReturnsExpected(string name) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - - object instance1 = new(); - iManager.SetName(instance1, name); - Assert.Same(instance1, iManager.GetInstance(name)); - Assert.Same(name, iManager.GetName(instance1)); - - object instance2 = new(); - iManager.SetName(instance2, "OtherName"); - Assert.Same(instance2, iManager.GetInstance("OtherName")); - Assert.Equal("OtherName", iManager.GetName(instance2)); - } - - [Fact] - public void DesignerSerializationManager_SetName_NullInstance_ThrowsArgumentNullException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - Assert.Throws("instance", () => iManager.SetName(null, "name")); - } - - [Fact] - public void DesignerSerializationManager_SetName_NullName_ThrowsArgumentNullException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - Assert.Throws("name", () => iManager.SetName(new object(), null)); - } - - [Theory] - [StringData] - public void DesignerSerializationManager_SetName_OtherInstanceHasName_ThrowsArgumentException(string name) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - object instance = new(); - iManager.SetName(instance, name); - Assert.Throws("name", () => iManager.SetName(new object(), name)); - Assert.Equal(name, iManager.GetName(instance)); - } - - [Theory] - [StringData] - public void DesignerSerializationManager_SetName_SameInstanceHasName_ThrowsArgumentException(string name) - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - manager.CreateSession(); - object instance = new(); - iManager.SetName(instance, name); - Assert.Throws("name", () => iManager.SetName(instance, name)); - Assert.Throws("instance", () => iManager.SetName(instance, "OtherName")); - Assert.Equal(name, iManager.GetName(instance)); - } - - [Fact] - public void DesignerSerializationManager_SetName_InvokeNoSession_ThrowsInvalidOperationException() - { - DesignerSerializationManager manager = new(); - IDesignerSerializationManager iManager = manager; - Assert.Throws(() => iManager.SetName(null, null)); - } - - private class SubDesignerSerializationManager : DesignerSerializationManager - { - public SubDesignerSerializationManager() : base() - { - } - - public SubDesignerSerializationManager(IServiceProvider provider) : base(provider) - { - } - - public new object CreateInstance(Type type, ICollection arguments, string name, bool addToContainer) - { - return base.CreateInstance(type, arguments, name, addToContainer); - } - - public new object GetService(Type serviceType) => base.GetService(serviceType); - - public new Type GetType(string typeName) => base.GetType(typeName); - - public new void OnResolveName(ResolveNameEventArgs e) => base.OnResolveName(e); - - public new void OnSessionCreated(EventArgs e) => base.OnSessionCreated(e); - - public new void OnSessionDisposed(EventArgs e) => base.OnSessionDisposed(e); - } - - private class PropertyProvider - { - [Category("Category")] - [Description("Description")] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] - [DesignOnly(true)] - [DisplayName("DisplayName")] - [Localizable(true)] - [TypeConverter(typeof(Int64Converter))] - public int Value { get; set; } - } - - private class OtherPropertyProvider - { - public int OtherValue { get; set; } - } - - private class NestedClass - { - } - - [DesignerSerializerAttribute("System.Int32", (string)null)] - private class ClassWithNullBaseDesignerSerializer - { - } - - [DesignerSerializerAttribute("System.Int32", "")] - private class ClassWithEmptyBaseDesignerSerializer - { - } - - [DesignerSerializerAttribute("System.Int32", "NoSuchType")] - private class ClassWithNoSuchBaseDesignerSerializer - { - } - - [DesignerSerializerAttribute((string)null, typeof(int))] - private class ClassWithNullSubDesignerSerializer - { - } - - [DesignerSerializerAttribute("", typeof(int))] - private class ClassWithEmptySubDesignerSerializer - { - } - - [DesignerSerializerAttribute("NoSuchType", typeof(int))] - private class ClassWithNoSuchSubDesignerSerializer - { - } - - private class BaseClass - { - } - - private class SubClass : BaseClass - { - } - - [DesignerSerializerAttribute(typeof(PublicDesignerSerializationProvider), typeof(BaseClass))] - private class ClassWithPublicDesignerSerializer - { - } - - [DesignerSerializerAttribute(typeof(PrivateDesignerSerializationProvider), typeof(BaseClass))] - private class ClassWithPrivateDesignerSerializer - { - } - - [DefaultSerializationProvider("")] - private class ClassWithEmptyDefaultSerializationProvider - { - } - - [DefaultSerializationProvider("NoSuchType")] - private class ClassWithNoSuchDefaultSerializationProvider - { - } - - [DefaultSerializationProvider(typeof(int))] - private class ClassWithInvalidDefaultSerializationProvider - { - } - - [DefaultSerializationProvider(typeof(IDesignerSerializationProvider))] - private class ClassWithInterfaceDefaultSerializationProvider - { - } - - [DefaultSerializationProvider(typeof(PublicDesignerSerializationProvider))] - private class ClassWithPublicDesignerSerializationProvider - { - } - - [DefaultSerializationProvider(typeof(PrivateDesignerSerializationProvider))] - private class ClassWithPrivateDesignerSerializationProvider - { - } - - [DefaultSerializationProvider(typeof(NullDesignerSerializationProvider))] - private class ClassWithNullDesignerSerializationProvider - { - } - - private class PublicDesignerSerializationProvider : IDesignerSerializationProvider - { - public static object Serializer { get; } = new object(); - - private PublicDesignerSerializationProvider() - { - } - - public object GetSerializer(IDesignerSerializationManager manager, object currentSerializer, Type objectType, Type serializerType) - { - return Serializer; - } - } - - private class PrivateDesignerSerializationProvider : IDesignerSerializationProvider - { - public static object Serializer { get; } = new object(); - - private PrivateDesignerSerializationProvider() - { - } - - public object GetSerializer(IDesignerSerializationManager manager, object currentSerializer, Type objectType, Type serializerType) - { - return Serializer; - } - } - - private class NullDesignerSerializationProvider : IDesignerSerializationProvider - { - public object GetSerializer(IDesignerSerializationManager manager, object currentSerializer, Type objectType, Type serializerType) - { - return null; - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/ExpressionContextTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/ExpressionContextTests.cs deleted file mode 100644 index 483b73a0fd1..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/ExpressionContextTests.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.CodeDom; - -namespace System.ComponentModel.Design.Serialization.Tests; - -public class ExpressionContextTests -{ - public static IEnumerable Ctor_CodeExpression_Type_Object_Object_TestData() - { - yield return new object[] { new CodeExpression(), typeof(int), new object(), new object() }; - yield return new object[] { new CodeExpression(), typeof(int), new object(), null }; - } - - [Theory] - [MemberData(nameof(Ctor_CodeExpression_Type_Object_Object_TestData))] - public void ExpressionContext_Ctor_CodeExpression_Type_Object_Object_TestData(CodeExpression expression, Type expressionType, object owner, object presetValue) - { - ExpressionContext context = new(expression, expressionType, owner, presetValue); - Assert.Same(expression, context.Expression); - Assert.Same(expressionType, context.ExpressionType); - Assert.Same(owner, context.Owner); - Assert.Same(presetValue, context.PresetValue); - } - - public static IEnumerable Ctor_CodeExpression_Type_Object_TestData() - { - yield return new object[] { new CodeExpression(), typeof(int), new object() }; - } - - [Theory] - [MemberData(nameof(Ctor_CodeExpression_Type_Object_TestData))] - public void ExpressionContext_Ctor_CodeExpression_Type_Object_TestData(CodeExpression expression, Type expressionType, object owner) - { - ExpressionContext context = new(expression, expressionType, owner); - Assert.Same(expression, context.Expression); - Assert.Same(expressionType, context.ExpressionType); - Assert.Same(owner, context.Owner); - Assert.Null(context.PresetValue); - } - - [Fact] - public void ExpressionContext_Ctor_NullExpression_ThrowsArgumentNullException() - { - Assert.Throws("expression", () => new ExpressionContext(null, typeof(int), new object(), new object())); - } - - [Fact] - public void RootContext_Ctor_NullExpressionType_ThrowsArgumentNullException() - { - Assert.Throws("expressionType", () => new ExpressionContext(new CodeExpression(), null, new object(), new object())); - } - - [Fact] - public void RootContext_Ctor_NullOwner_ThrowsArgumentNullException() - { - Assert.Throws("owner", () => new ExpressionContext(new CodeExpression(), typeof(int), null, new object())); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/RootContextTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/RootContextTests.cs deleted file mode 100644 index d5f8c6d6ba0..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/RootContextTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.CodeDom; - -namespace System.ComponentModel.Design.Serialization.Tests; - -public class RootContextTests -{ - [Fact] - public void RootContext_Ctor_CodeExpression_Object() - { - CodeExpression expression = new(); - object value = new(); - RootContext context = new(expression, value); - Assert.Same(expression, context.Expression); - Assert.Same(value, context.Value); - } - - [Fact] - public void RootContext_Ctor_NullExpression_ThrowsArgumentNullException() - { - Assert.Throws("expression", () => new RootContext(null, new object())); - } - - [Fact] - public void RootContext_Ctor_NullValue_ThrowsArgumentNullException() - { - CodeExpression expression = new(); - Assert.Throws("value", () => new RootContext(expression, null)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/SerializeAbsoluteContextTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/SerializeAbsoluteContextTests.cs deleted file mode 100644 index ac3906a8810..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/SerializeAbsoluteContextTests.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.ComponentModel.Design.Serialization.Tests; - -public class SerializeAbsoluteContextTests -{ - [Fact] - public void SerializeAbsoluteContext_Ctor_Default() - { - SerializeAbsoluteContext context = new(); - Assert.Null(context.Member); - } - - public static IEnumerable Ctor_MemberDescriptor_TestData() - { - yield return new object[] { null }; - - PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(RootContext)); - yield return new object[] { properties[nameof(RootContext.Expression)] }; - } - - [Theory] - [MemberData(nameof(Ctor_MemberDescriptor_TestData))] - public void SerializeAbsoluteContext_Ctor_MemberDescriptor(MemberDescriptor member) - { - SerializeAbsoluteContext context = new(member); - Assert.Same(member, context.Member); - } - - public static IEnumerable ShouldSerialize_TestData() - { - PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(RootContext)); - MemberDescriptor member1 = properties[nameof(RootContext.Expression)]; - MemberDescriptor member2 = properties[nameof(RootContext.Value)]; - - yield return new object[] { new SerializeAbsoluteContext(null), null, true }; - yield return new object[] { new SerializeAbsoluteContext(null), member1, true }; - - yield return new object[] { new SerializeAbsoluteContext(member1), null, false }; - yield return new object[] { new SerializeAbsoluteContext(member1), member1, true }; - yield return new object[] { new SerializeAbsoluteContext(member2), member2, true }; - } - - [Theory] - [MemberData(nameof(ShouldSerialize_TestData))] - public void SerializeAbsoluteContext_ShouldSerialize_Invoke_ReturnsExpected(SerializeAbsoluteContext context, MemberDescriptor member, bool expected) - { - Assert.Equal(expected, context.ShouldSerialize(member)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/StatementContextTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/StatementContextTests.cs deleted file mode 100644 index 1532efa41bd..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/Serialization/StatementContextTests.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.ComponentModel.Design.Serialization.Tests; - -public class StatementContextTests -{ - [Fact] - public void StatementContext_Ctor_Default() - { - StatementContext context = new(); - Assert.Empty(context.StatementCollection); - Assert.Same(context.StatementCollection, context.StatementCollection); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/SiteNestedContainerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/SiteNestedContainerTests.cs deleted file mode 100644 index 2933ad5579f..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/SiteNestedContainerTests.cs +++ /dev/null @@ -1,1138 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design.Serialization; -using Moq; - -namespace System.ComponentModel.Design.Tests; - -public class SiteNestedContainerTests -{ - public static IEnumerable CreateNestedContainer_TestData() - { - static ISite CreateSite(string name) - { - Mock mockSite = new(MockBehavior.Strict); - mockSite - .Setup(s => s.Name) - .Returns(name); - mockSite - .Setup(s => s.Container) - .Returns((IContainer)null); - mockSite - .Setup(s => s.GetService(typeof(ContainerFilterService))) - .Returns(null); - return mockSite.Object; - } - - foreach (ISite site in new ISite[] { null, CreateSite(null) }) - { - yield return new object[] { site, null, null, null }; - yield return new object[] { site, null, string.Empty, string.Empty }; - yield return new object[] { site, null, "componentName", "componentName" }; - yield return new object[] { site, string.Empty, null, null }; - yield return new object[] { site, string.Empty, string.Empty, string.Empty }; - yield return new object[] { site, string.Empty, "componentName", "componentName" }; - yield return new object[] { site, "containerName", null, null }; - yield return new object[] { site, "containerName", string.Empty, ".containerName." }; - yield return new object[] { site, "containerName", "componentName", ".containerName.componentName" }; - } - - yield return new object[] { CreateSite(string.Empty), null, null, null }; - yield return new object[] { CreateSite(string.Empty), null, string.Empty, "." }; - yield return new object[] { CreateSite(string.Empty), null, "componentName", ".componentName" }; - yield return new object[] { CreateSite(string.Empty), string.Empty, null, null }; - yield return new object[] { CreateSite(string.Empty), string.Empty, string.Empty, "." }; - yield return new object[] { CreateSite(string.Empty), string.Empty, "componentName", ".componentName" }; - yield return new object[] { CreateSite(string.Empty), "containerName", null, null }; - yield return new object[] { CreateSite(string.Empty), "containerName", string.Empty, ".containerName." }; - yield return new object[] { CreateSite(string.Empty), "containerName", "componentName", ".containerName.componentName" }; - - yield return new object[] { CreateSite("ownerName"), null, null, null }; - yield return new object[] { CreateSite("ownerName"), null, string.Empty, "ownerName." }; - yield return new object[] { CreateSite("ownerName"), null, "componentName", "ownerName.componentName" }; - yield return new object[] { CreateSite("ownerName"), string.Empty, null, null }; - yield return new object[] { CreateSite("ownerName"), string.Empty, string.Empty, "ownerName." }; - yield return new object[] { CreateSite("ownerName"), string.Empty, "componentName", "ownerName.componentName" }; - yield return new object[] { CreateSite("ownerName"), "containerName", null, null }; - yield return new object[] { CreateSite("ownerName"), "containerName", string.Empty, "ownerName.containerName." }; - yield return new object[] { CreateSite("ownerName"), "containerName", "componentName", "ownerName.containerName.componentName" }; - } - - [WinFormsTheory] - [MemberData(nameof(CreateNestedContainer_TestData))] - public void SiteNestedContainer_Add_Component_Success(ISite ownerSite, string containerName, string componentName, string expectedFullName) - { - using SubDesignSurface surface = new(); - using Component ownerComponent = new() - { - Site = ownerSite - }; - IDesignerLoaderHost2 host = surface.Host; - using INestedContainer container = surface.CreateNestedContainer(ownerComponent, containerName); - using RootDesignerComponent component1 = new(); - container.Add(component1, componentName); - Assert.Same(container, component1.Container); - INestedSite nestedSite = Assert.IsAssignableFrom(component1.Site); - Assert.Same(component1, nestedSite.Component); - Assert.Same(container, nestedSite.Container); - Assert.True(nestedSite.DesignMode); - Assert.Equal(expectedFullName, nestedSite.FullName); - Assert.Same(componentName, component1.Site.Name); - Assert.Same(component1, Assert.Single(container.Components)); - Assert.Empty(host.Container.Components); - Assert.Equal(componentName, host.RootComponentClassName); - - // Add another. - using RootDesignerComponent component2 = new(); - container.Add(component2, "otherComponent"); - Assert.Equal(new IComponent[] { component1, component2 }, container.Components.Cast()); - Assert.Empty(host.Container.Components); - - // Add again. - container.Add(component1, "newName"); - if (component1.Site is not null) - { - Assert.Equal(componentName, component1.Site.Name); - } - - Assert.Equal(new IComponent[] { component1, component2 }, container.Components.Cast()); - Assert.Empty(host.Container.Components); - } - - public static IEnumerable Add_InvalidNameCreationServiceParentProvider_TestData() - { - yield return new object[] { null }; - - Mock nullMockServiceProvider = new(MockBehavior.Strict); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(null); - yield return new object[] { nullMockServiceProvider.Object }; - - Mock invalidMockServiceProvider = new(MockBehavior.Strict); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(new object()); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(null); - yield return new object[] { invalidMockServiceProvider.Object }; - } - - public static IEnumerable Add_ComponentParentProvider_TestData() - { - foreach (object[] testData in Add_InvalidNameCreationServiceParentProvider_TestData()) - { - yield return new object[] { testData[0] }; - } - - foreach (string name in new string[] { null, string.Empty, "name" }) - { - Mock mockNameCreationService = new(MockBehavior.Strict); - mockNameCreationService - .Setup(s => s.CreateName(It.IsAny(), It.IsAny())) - .Returns(name); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(mockNameCreationService.Object); - yield return new object[] { mockServiceProvider.Object }; - } - } - - [WinFormsTheory] - [MemberData(nameof(Add_ComponentParentProvider_TestData))] - public void SiteNestedContainer_Add_ComponentWithRootDesigner_Success(IServiceProvider parentProvider) - { - using SubDesignSurface surface = new(parentProvider); - IDesignerLoaderHost2 host = surface.Host; - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - using RootDesignerComponent component1 = new(); - using RootDesignerComponent component2 = new(); - using DesignerComponent component3 = new(); - using Component component4 = new(); - - container.Add(component1); - Assert.Same(component1, Assert.Single(container.Components)); - Assert.Null(host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(container, component1.Container); - Assert.Same(component1, component1.Site.Component); - Assert.Same(container, component1.Site.Container); - Assert.True(component1.Site.DesignMode); - Assert.Null(component1.Site.Name); - - // Add different - root designer. - container.Add(component2); - Assert.Equal(new IComponent[] { component1, component2 }, container.Components.Cast()); - Assert.Null(host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(container, component2.Container); - Assert.Same(component2, component2.Site.Component); - Assert.Same(container, component2.Site.Container); - Assert.True(component2.Site.DesignMode); - Assert.Null(component2.Site.Name); - - // Add different - non root designer. - container.Add(component3); - Assert.Equal(new IComponent[] { component1, component2, component3 }, container.Components.Cast()); - Assert.Null(host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(container, component3.Container); - Assert.Same(component3, component3.Site.Component); - Assert.Same(container, component3.Site.Container); - Assert.True(component3.Site.DesignMode); - Assert.Null(component3.Site.Name); - - // Add different - non designer. - container.Add(component4); - Assert.Equal(new IComponent[] { component1, component2, component3, component4 }, container.Components.Cast()); - Assert.Null(host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(container, component4.Container); - Assert.Same(component4, component4.Site.Component); - Assert.Same(container, component4.Site.Container); - Assert.True(component4.Site.DesignMode); - Assert.Null(component4.Site.Name); - } - - [WinFormsTheory] - [MemberData(nameof(Add_InvalidNameCreationServiceParentProvider_TestData))] - public void SiteNestedContainer_Add_ComponentStringWithRootDesigner_Success(IServiceProvider parentProvider) - { - using SubDesignSurface surface = new(parentProvider); - IDesignerLoaderHost2 host = surface.Host; - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - using RootDesignerComponent component1 = new(); - using RootDesignerComponent component2 = new(); - using DesignerComponent component3 = new(); - using Component component4 = new(); - - container.Add(component1, "name1"); - Assert.Same(component1, Assert.Single(container.Components)); - Assert.Equal("name1", host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(container, component1.Container); - Assert.Same(component1, component1.Site.Component); - Assert.Same(container, component1.Site.Container); - Assert.True(component1.Site.DesignMode); - Assert.Equal("name1", component1.Site.Name); - - // Add different - root designer. - container.Add(component2, "name2"); - Assert.Equal(new IComponent[] { component1, component2 }, container.Components.Cast()); - Assert.Same(container, component2.Container); - Assert.Equal("name1", host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(component2, component2.Site.Component); - Assert.Same(container, component2.Site.Container); - Assert.True(component2.Site.DesignMode); - Assert.Equal("name2", component2.Site.Name); - - // Add different - non root designer. - container.Add(component3, string.Empty); - Assert.Equal(new IComponent[] { component1, component2, component3 }, container.Components.Cast()); - Assert.Same(container, component3.Container); - Assert.Equal("name1", host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(component3, component3.Site.Component); - Assert.Same(container, component3.Site.Container); - Assert.True(component3.Site.DesignMode); - Assert.Empty(component3.Site.Name); - - // Add different - non designer. - container.Add(component4, null); - Assert.Equal(new IComponent[] { component1, component2, component3, component4 }, container.Components.Cast()); - Assert.Same(container, component4.Container); - Assert.Equal("name1", host.RootComponentClassName); - Assert.Same(component1, host.RootComponent); - Assert.Same(component4, component4.Site.Component); - Assert.Same(container, component4.Site.Container); - Assert.True(component4.Site.DesignMode); - Assert.Null(component4.Site.Name); - } - - public static IEnumerable Add_IExtenderProviderServiceWithoutDefault_TestData() - { - yield return new object[] { new RootDesignerComponent(), 0 }; - yield return new object[] { new RootExtenderProviderDesignerComponent(), 1 }; - - RootExtenderProviderDesignerComponent readOnlyComponent = new(); - TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly)); - yield return new object[] { readOnlyComponent, 0 }; - - RootExtenderProviderDesignerComponent inheritedComponent = new(); - TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited)); - yield return new object[] { inheritedComponent, 1 }; - - RootExtenderProviderDesignerComponent notInheritedComponent = new(); - TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited)); - yield return new object[] { notInheritedComponent, 1 }; - } - - [WinFormsTheory] - [MemberData(nameof(Add_IExtenderProviderServiceWithoutDefault_TestData))] - public void SiteNestedContainer_Add_IExtenderProviderServiceWithoutDefault_Success(Component component, int expectedCallCount) - { - Mock mockExtenderProviderService = new(MockBehavior.Strict); - mockExtenderProviderService - .Setup(s => s.AddExtenderProvider(component as IExtenderProvider)) - .Verifiable(); - mockExtenderProviderService - .Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider)); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderListService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(mockExtenderProviderService.Object) - .Verifiable(); - - using SubDesignSurface surface = new(mockServiceProvider.Object); - surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService)); - IDesignerLoaderHost2 host = surface.Host; - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - - container.Add(component); - Assert.Same(component, Assert.Single(container.Components)); - Assert.Null(component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedCallCount)); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedCallCount)); - - // Add again. - container.Add(component); - Assert.Same(component, Assert.Single(container.Components)); - Assert.Null(component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedCallCount * 2 + 1)); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedCallCount * 2)); - - // Add again with name. - container.Add(component, "name"); - Assert.Same(component, Assert.Single(container.Components)); - Assert.Null(component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedCallCount * 3 + 1)); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedCallCount * 3)); - } - - public static IEnumerable Add_IExtenderProviderServiceWithDefault_TestData() - { - yield return new object[] { new RootDesignerComponent(), false }; - yield return new object[] { new RootExtenderProviderDesignerComponent(), true }; - - RootExtenderProviderDesignerComponent readOnlyComponent = new(); - TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly)); - yield return new object[] { readOnlyComponent, false }; - - RootExtenderProviderDesignerComponent inheritedComponent = new(); - TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited)); - yield return new object[] { inheritedComponent, true }; - - RootExtenderProviderDesignerComponent notInheritedComponent = new(); - TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited)); - yield return new object[] { notInheritedComponent, true }; - } - - [WinFormsTheory] - [MemberData(nameof(Add_IExtenderProviderServiceWithDefault_TestData))] - public void SiteNestedContainer_Add_IExtenderProviderServiceWithDefault_DoesNotCallGetService(Component component, bool throws) - { - Mock mockExtenderProviderService = new(MockBehavior.Strict); - mockExtenderProviderService - .Setup(s => s.AddExtenderProvider(component as IExtenderProvider)) - .Verifiable(); - mockExtenderProviderService - .Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider)); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(DesignerCommandSet))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IInheritanceService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(mockExtenderProviderService.Object) - .Verifiable(); - - using DesignSurface surface = new(mockServiceProvider.Object); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - - container.Add(component); - Assert.Same(component, Assert.Single(container.Components)); - Assert.Null(component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never()); - - // Add again. - if (throws) - { - Assert.Throws("provider", () => container.Add(component)); - Assert.Empty(container.Components); - Assert.Null(component.Site); - } - else - { - container.Add(component); - Assert.Same(component, Assert.Single(container.Components)); - Assert.Null(component.Site.Name); - } - - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never()); - - // Add again with name. - container.Add(component, "name"); - Assert.Same(component, Assert.Single(container.Components)); - if (throws) - { - Assert.Equal("name", component.Site.Name); - } - else - { - Assert.Null(component.Site.Name); - } - - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never()); - } - - public static IEnumerable InvalidIExtenderProviderService_TestData() - { - yield return new object[] { null }; - - Mock nullMockServiceProvider = new(MockBehavior.Strict); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - nullMockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(null) - .Verifiable(); - yield return new object[] { nullMockServiceProvider }; - - Mock invalidMockServiceProvider = new(MockBehavior.Strict); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - invalidMockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(new object()) - .Verifiable(); - yield return new object[] { invalidMockServiceProvider }; - } - - [WinFormsTheory] - [MemberData(nameof(InvalidIExtenderProviderService_TestData))] - public void SiteNestedContainer_Add_InvalidIExtenderProviderServiceWithoutDefault_CallsParentGetService(Mock mockParentProvider) - { - using SubDesignSurface surface = new(mockParentProvider?.Object); - surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService)); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - using RootExtenderProviderDesignerComponent component = new(); - - container.Add(component); - Assert.Same(component, Assert.Single(container.Components)); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Once()); - } - - [WinFormsTheory] - [MemberData(nameof(InvalidIExtenderProviderService_TestData))] - public void SiteNestedContainer_Add_InvalidIExtenderProviderServiceWithDefault_DoesNotCallParentGetService(Mock mockParentProvider) - { - using SubDesignSurface surface = new(mockParentProvider?.Object); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - using RootExtenderProviderDesignerComponent component = new(); - - container.Add(component); - Assert.Same(component, Assert.Single(container.Components)); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - } - - [WinFormsFact] - public void SiteNestedContainer_Add_IComponentWithComponentAddingAndAdded_CallsHandler() - { - using SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - - using RootDesignerComponent component = new(); - int componentAddingCallCount = 0; - ComponentEventHandler componentAddingHandler = (sender, e) => - { - Assert.Same(container, sender); - Assert.Same(component, e.Component); - componentAddingCallCount++; - }; - changeService.ComponentAdding += componentAddingHandler; - int componentAddedCallCount = 0; - ComponentEventHandler componentAddedHandler = (sender, e) => - { - Assert.Same(container, sender); - Assert.Same(component, e.Component); - Assert.True(componentAddedCallCount < componentAddingCallCount); - componentAddedCallCount++; - }; - changeService.ComponentAdded += componentAddedHandler; - - // With handler. - container.Add(component); - Assert.Same(container, component.Container); - Assert.Equal(1, componentAddingCallCount); - Assert.Equal(1, componentAddedCallCount); - - // Add again. - container.Add(component); - Assert.Same(container, component.Container); - Assert.Equal(2, componentAddingCallCount); - Assert.Equal(2, componentAddedCallCount); - - // Remove handler. - changeService.ComponentAdding -= componentAddingHandler; - changeService.ComponentAdded -= componentAddedHandler; - container.Add(component); - Assert.Same(container, component.Container); - Assert.Equal(2, componentAddingCallCount); - Assert.Equal(2, componentAddedCallCount); - } - - public static IEnumerable Add_NoRootDesigner_TestData() - { - yield return new object[] { new Component() }; - yield return new object[] { new DesignerComponent() }; - } - - [WinFormsTheory] - [MemberData(nameof(Add_NoRootDesigner_TestData))] - public void SiteNestedContainer_Add_NoRootDesigner_ThrowsException(IComponent component) - { - using DesignSurface surface = new(); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - - Assert.Throws(() => container.Add(component)); - Assert.Throws(() => container.Add(component, "name")); - Assert.Empty(container.Components); - } - - [WinFormsFact] - public void SiteNestedContainer_Add_CyclicRootDesigner_ThrowsException() - { - using SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - using RootDesignerComponent component = new(); - container.Add(component, component.GetType().FullName); - Assert.Equal(component.GetType().FullName, host.RootComponentClassName); - Assert.Throws(() => container.Add(component)); - Assert.Throws(() => container.Add(new RootDesignerComponent(), host.RootComponentClassName)); - } - - [WinFormsFact] - public void SiteNestedContainer_Add_NonInitializingRootDesigner_ThrowsInvalidOperationException() - { - using DesignSurface surface = new(); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - using NonInitializingDesignerComponent component = new(); - Assert.Throws(() => container.Add(component)); - Assert.Throws(() => container.Add(component, "name")); - } - - [WinFormsFact] - public void SiteNestedContainer_Add_ThrowingInitializingRootDesigner_RethrowsException() - { - using DesignSurface surface = new(); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - using ThrowingInitializingDesignerComponent component = new(); - Assert.Throws(() => container.Add(component)); - Assert.Null(component.Container); - Assert.Null(component.Site); - - Assert.Throws(() => container.Add(component, "name")); - Assert.Null(component.Container); - Assert.Null(component.Site); - } - - [WinFormsFact] - public void SiteNestedContainer_Add_CheckoutExceptionThrowingInitializingRootDesigner_RethrowsException() - { - using DesignSurface surface = new(); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - using CheckoutExceptionThrowingInitializingDesignerComponent component = new(); - // CheckoutException does not bubble up in xunit. - bool threwCheckoutException = false; - try - { - container.Add(component); - } - catch (CheckoutException) - { - threwCheckoutException = true; - } - - Assert.True(threwCheckoutException); - Assert.Same(container, component.Container); - Assert.Null(component.Site.Name); - - container.Add(component, "name"); - Assert.Same(container, component.Container); - Assert.Null(component.Site.Name); - } - - [Fact(Skip = "Unstable test. See https://github.com/dotnet/winforms/issues/1151")] - public void SiteNestedContainer_Add_Unloading_Nop() - { - using SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - surface.BeginLoad(typeof(RootDesignerComponent)); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - - DisposingDesignerComponent component = new(); - container.Add(component); - int callCount = 0; - DisposingDesigner.Disposed += (sender, e) => - { - callCount++; - }; - surface.Dispose(); - Assert.Equal(0, callCount); - } - - [WinFormsFact] - public void SiteNestedContainer_Remove_Invoke_Success() - { - using SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - - using RootDesignerComponent rootComponent = new(); - using DesignerComponent component = new(); - container.Add(rootComponent); - container.Add(component); - container.Remove(rootComponent); - Assert.Same(component, Assert.Single(container.Components)); - Assert.Null(host.RootComponent); - Assert.Null(host.RootComponentClassName); - Assert.Null(rootComponent.Container); - Assert.Null(rootComponent.Site); - Assert.Same(container, component.Container); - Assert.NotNull(component.Site); - - // Remove again. - container.Remove(rootComponent); - Assert.Same(component, Assert.Single(container.Components)); - Assert.Null(host.RootComponent); - Assert.Null(host.RootComponentClassName); - Assert.Null(rootComponent.Container); - Assert.Null(rootComponent.Site); - Assert.Same(container, component.Container); - Assert.NotNull(component.Site); - - // Remove other. - container.Remove(component); - Assert.Empty(container.Components); - Assert.Null(host.RootComponent); - Assert.Null(host.RootComponentClassName); - Assert.Null(rootComponent.Container); - Assert.Null(rootComponent.Site); - Assert.Null(component.Container); - Assert.Null(component.Site); - } - - public static IEnumerable Remove_IExtenderProviderServiceWithoutDefault_TestData() - { - yield return new object[] { new RootDesignerComponent(), 0, 0 }; - yield return new object[] { new RootExtenderProviderDesignerComponent(), 1, 1 }; - - RootExtenderProviderDesignerComponent readOnlyComponent = new(); - TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly)); - yield return new object[] { readOnlyComponent, 0, 1 }; - - RootExtenderProviderDesignerComponent inheritedComponent = new(); - TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited)); - yield return new object[] { inheritedComponent, 1, 1 }; - - RootExtenderProviderDesignerComponent notInheritedComponent = new(); - TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited)); - yield return new object[] { notInheritedComponent, 1, 1 }; - } - - [WinFormsTheory] - [MemberData(nameof(Remove_IExtenderProviderServiceWithoutDefault_TestData))] - public void SiteNestedContainer_Remove_IExtenderProviderServiceWithoutDefault_Success(Component component, int expectedAddCallCount, int expectedRemoveCallCount) - { - Mock mockExtenderProviderService = new(MockBehavior.Strict); - mockExtenderProviderService - .Setup(s => s.AddExtenderProvider(component as IExtenderProvider)); - mockExtenderProviderService - .Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider)) - .Verifiable(); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(mockExtenderProviderService.Object) - .Verifiable(); - - using SubDesignSurface surface = new(mockServiceProvider.Object); - surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService)); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - - container.Add(component); - Assert.Same(component, Assert.Single(container.Components)); - Assert.Same(container, component.Container); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedAddCallCount)); - - // Remove. - container.Remove(component); - Assert.Empty(container.Components); - Assert.Null(component.Container); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedAddCallCount + expectedRemoveCallCount)); - mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedRemoveCallCount)); - - // Remove again. - container.Remove(component); - Assert.Empty(container.Components); - Assert.Null(component.Container); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(expectedAddCallCount + expectedRemoveCallCount)); - mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Exactly(expectedRemoveCallCount)); - } - - public static IEnumerable Remove_IExtenderProviderServiceWithDefault_TestData() - { - yield return new object[] { new RootDesignerComponent() }; - yield return new object[] { new RootExtenderProviderDesignerComponent() }; - - RootExtenderProviderDesignerComponent readOnlyComponent = new(); - TypeDescriptor.AddAttributes(readOnlyComponent, new InheritanceAttribute(InheritanceLevel.InheritedReadOnly)); - yield return new object[] { readOnlyComponent }; - - RootExtenderProviderDesignerComponent inheritedComponent = new(); - TypeDescriptor.AddAttributes(inheritedComponent, new InheritanceAttribute(InheritanceLevel.Inherited)); - yield return new object[] { inheritedComponent }; - - RootExtenderProviderDesignerComponent notInheritedComponent = new(); - TypeDescriptor.AddAttributes(notInheritedComponent, new InheritanceAttribute(InheritanceLevel.NotInherited)); - yield return new object[] { notInheritedComponent }; - } - - [WinFormsTheory] - [MemberData(nameof(Remove_IExtenderProviderServiceWithDefault_TestData))] - public void SiteNestedContainer_Remove_IExtenderProviderServiceWithDefault_Success(Component component) - { - Mock mockExtenderProviderService = new(MockBehavior.Strict); - mockExtenderProviderService - .Setup(s => s.AddExtenderProvider(component as IExtenderProvider)) - .Verifiable(); - mockExtenderProviderService - .Setup(s => s.RemoveExtenderProvider(component as IExtenderProvider)); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(ITypeResolutionService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(INameCreationService))) - .Returns(null); - mockServiceProvider - .Setup(p => p.GetService(typeof(IExtenderProviderService))) - .Returns(mockExtenderProviderService.Object) - .Verifiable(); - - using DesignSurface surface = new(mockServiceProvider.Object); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - - container.Add(component); - Assert.Same(component, Assert.Single(container.Components)); - Assert.Null(component.Site.Name); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.AddExtenderProvider(component as IExtenderProvider), Times.Never()); - - // Remove. - container.Remove(component); - Assert.Empty(container.Components); - Assert.Null(component.Container); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Never()); - - // Remove again. - container.Remove(component); - Assert.Empty(container.Components); - Assert.Null(component.Container); - mockServiceProvider.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - mockExtenderProviderService.Verify(s => s.RemoveExtenderProvider(component as IExtenderProvider), Times.Never()); - } - - [WinFormsTheory] - [MemberData(nameof(InvalidIExtenderProviderService_TestData))] - public void SiteNestedContainer_Remove_InvalidIExtenderProviderServiceWithoutDefault_CallsParentGetService(Mock mockParentProvider) - { - using SubDesignSurface surface = new(mockParentProvider?.Object); - surface.ServiceContainer.RemoveService(typeof(IExtenderProviderService)); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - using RootExtenderProviderDesignerComponent component = new(); - - container.Add(component); - Assert.Same(component, Assert.Single(container.Components)); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Once()); - - container.Remove(component); - Assert.Empty(container.Components); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Exactly(2)); - } - - [WinFormsTheory] - [MemberData(nameof(InvalidIExtenderProviderService_TestData))] - public void SiteNestedContainer_Remove_InvalidIExtenderProviderServiceWithDefault_DoesNotCallParentGetService(Mock mockParentProvider) - { - using DesignSurface surface = new(mockParentProvider?.Object); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - using RootExtenderProviderDesignerComponent component = new(); - - container.Add(component); - Assert.Same(component, Assert.Single(container.Components)); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - - container.Remove(component); - Assert.Empty(container.Components); - mockParentProvider?.Verify(p => p.GetService(typeof(IExtenderProviderService)), Times.Never()); - } - - [WinFormsFact] - public void SiteNestedContainer_Remove_ComponentNotInContainerNonEmpty_Nop() - { - using DesignSurface surface = new(); - using Component component1 = new(); - using INestedContainer container1 = surface.CreateNestedContainer(component1, "containerName"); - using Component component2 = new(); - using INestedContainer container2 = surface.CreateNestedContainer(component2, "containerName"); - - using RootDesignerComponent otherComponent = new(); - using RootDesignerComponent component = new(); - container1.Add(otherComponent); - container2.Add(component); - container2.Remove(otherComponent); - container2.Remove(new Component()); - Assert.Same(otherComponent, Assert.Single(container1.Components)); - Assert.Same(component, Assert.Single(container2.Components)); - } - - [WinFormsFact] - public void SiteNestedContainer_Remove_ComponentNotInContainerEmpty_Nop() - { - using DesignSurface surface = new(); - using Component component1 = new(); - using INestedContainer container1 = surface.CreateNestedContainer(component1, "containerName"); - using Component component2 = new(); - using INestedContainer container2 = surface.CreateNestedContainer(component2, "containerName"); - - using RootDesignerComponent otherComponent = new(); - container1.Add(otherComponent); - container2.Remove(otherComponent); - container2.Remove(new Component()); - Assert.Same(otherComponent, Assert.Single(container1.Components)); - Assert.Empty(container2.Components); - } - - [WinFormsFact] - public void SiteNestedContainer_Remove_InvokeWithComponentRemoved_CallsHandler() - { - using SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - - using RootDesignerComponent component1 = new(); - using DesignerComponent component2 = new(); - int componentRemovingCallCount = 0; - ComponentEventHandler componentRemovingHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(component1, e.Component); - Assert.NotNull(e.Component.Site); - componentRemovingCallCount++; - }; - changeService.ComponentRemoving += componentRemovingHandler; - - int componentRemovedCallCount = 0; - ComponentEventHandler componentRemovedHandler = (sender, e) => - { - Assert.Same(host, sender); - Assert.Same(component1, e.Component); - Assert.NotNull(e.Component.Site); - Assert.True(componentRemovedCallCount < componentRemovingCallCount); - componentRemovedCallCount++; - }; - changeService.ComponentRemoved += componentRemovedHandler; - - container.Add(component1); - container.Add(component2); - - // With handler. - container.Remove(component1); - Assert.Null(component1.Container); - Assert.Null(component1.Site); - Assert.Same(container, component2.Container); - Assert.NotNull(component2.Site); - Assert.Same(component2, Assert.Single(container.Components)); - Assert.Equal(1, componentRemovingCallCount); - Assert.Equal(1, componentRemovedCallCount); - - // Remove again. - container.Remove(component1); - Assert.Null(component1.Container); - Assert.Null(component1.Site); - Assert.Same(container, component2.Container); - Assert.NotNull(component2.Site); - Assert.Same(component2, Assert.Single(container.Components)); - Assert.Equal(1, componentRemovingCallCount); - Assert.Equal(1, componentRemovedCallCount); - - // Remove handler. - changeService.ComponentRemoving -= componentRemovingHandler; - changeService.ComponentRemoved -= componentRemovedHandler; - container.Remove(component2); - Assert.Null(component1.Container); - Assert.Null(component1.Site); - Assert.Null(component2.Container); - Assert.Null(component2.Site); - Assert.Empty(host.Container.Components); - Assert.Equal(1, componentRemovingCallCount); - Assert.Equal(1, componentRemovedCallCount); - } - - [WinFormsFact] - public void SiteNestedContainer_Remove_SetSiteToNullInComponentRemoving_Success() - { - using SubDesignSurface surface = new(); - IDesignerLoaderHost2 host = surface.Host; - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - IComponentChangeService changeService = Assert.IsAssignableFrom(host); - - using RootDesignerComponent component = new(); - int componentRemovingCallCount = 0; - ComponentEventHandler componentRemovingHandler = (sender, e) => - { - component.Site = null; - componentRemovingCallCount++; - }; - changeService.ComponentRemoving += componentRemovingHandler; - - container.Add(component); - container.Remove(component); - Assert.Null(component.Container); - Assert.Null(component.Site); - } - - [WinFormsFact] - public void SiteNestedContainer_Remove_SiteHasDictionary_DoesNotClearDictionary() - { - using SubDesignSurface surface = new(); - using Component owningComponent = new(); - using INestedContainer container = surface.CreateNestedContainer(owningComponent, "containerName"); - - using RootDesignerComponent component = new(); - container.Add(component); - IDictionaryService service = Assert.IsAssignableFrom(component.Site); - service.SetValue("key", "value"); - Assert.Equal("value", service.GetValue("key")); - - container.Remove(component); - Assert.Equal("value", service.GetValue("key")); - } - - private class SubDesignSurface : DesignSurface - { - public SubDesignSurface() : base() - { - } - - public SubDesignSurface(IServiceProvider parentProvider) : base(parentProvider) - { - } - - public new ServiceContainer ServiceContainer => base.ServiceContainer; - - public IDesignerLoaderHost2 Host => Assert.IsAssignableFrom(ComponentContainer); - } - - private abstract class CustomDesigner : IDesigner - { - protected IComponent _initializedComponent; - - public IComponent Component => _initializedComponent; - - public DesignerVerbCollection Verbs { get; } - - public void DoDefaultAction() - { - } - - public void Dispose() => Dispose(true); - - protected virtual void Dispose(bool disposing) - { - } - - public abstract void Initialize(IComponent component); - } - - private class Designer : CustomDesigner - { - public override void Initialize(IComponent component) => _initializedComponent = component; - } - - [Designer(typeof(Designer))] - private class DesignerComponent : Component - { - } - - private class RootDesigner : Designer, IRootDesigner - { - public ViewTechnology[] SupportedTechnologies { get; } - - public object GetView(ViewTechnology technology) => throw new NotImplementedException(); - } - - [Designer(typeof(RootDesigner), typeof(IRootDesigner))] - private class RootDesignerComponent : Component - { - } - - [Designer(typeof(RootDesigner), typeof(IRootDesigner))] - private class RootExtenderProviderDesignerComponent : Component, IExtenderProvider - { - public bool CanExtend(object extendee) => false; - } - - private class NonInitializingDesigner : RootDesigner - { - public override void Initialize(IComponent component) - { - } - } - - [Designer(typeof(NonInitializingDesigner), typeof(IRootDesigner))] - private class NonInitializingDesignerComponent : Component - { - } - - private class ThrowingInitializingDesigner : RootDesigner - { - public override void Initialize(IComponent component) - { - throw new DivideByZeroException(); - } - } - - [Designer(typeof(ThrowingInitializingDesigner), typeof(IRootDesigner))] - private class ThrowingInitializingDesignerComponent : Component - { - } - - private class CheckoutExceptionThrowingInitializingDesigner : RootDesigner - { - public override void Initialize(IComponent component) - { - throw CheckoutException.Canceled; - } - } - - [Designer(typeof(CheckoutExceptionThrowingInitializingDesigner), typeof(IRootDesigner))] - private class CheckoutExceptionThrowingInitializingDesignerComponent : Component - { - } - - private class DisposingDesigner : Designer - { - public static EventHandler Disposed; - - protected override void Dispose(bool disposing) - { - Disposed?.Invoke(this, EventArgs.Empty); - } - } - - [Designer(typeof(DisposingDesigner))] - private class DisposingDesignerComponent : Component - { - } - - [Designer(typeof(RootDesigner), typeof(IRootDesigner))] - private class CustomTypeDescriptionProviderComponent : Component - { - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/UndoUnitTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/UndoUnitTests.cs deleted file mode 100644 index 265167f5e66..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/UndoUnitTests.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design.Serialization; -using Moq; - -namespace System.ComponentModel.Design.Tests; - -public class UndoUnitTests : UndoEngine -{ - public UndoUnitTests() : base(GetServiceProvider()) - { - } - - private static IServiceProvider GetServiceProvider() - { - Mock mockServiceProvider = new(); - Mock mockDesignerHost = new(); - Mock mockComponentChangeService = new(); - mockServiceProvider - .Setup(p => p.GetService(typeof(IDesignerHost))) - .Returns(mockDesignerHost.Object); - mockServiceProvider - .Setup(p => p.GetService(typeof(IComponentChangeService))) - .Returns(mockComponentChangeService.Object); - mockServiceProvider - .Setup(p => p.GetService(typeof(ComponentSerializationService))) - .Returns(new CodeDomComponentSerializationService()); - return mockServiceProvider.Object; - } - - [Theory] - [NormalizedStringData] - public void UndoUnit_Ctor_UndoEngine_String(string name, string expectedName) - { - SubUndoUnit unit = new(this, name); - Assert.Same(this, unit.UndoEngine); - Assert.Equal(expectedName, unit.Name); - Assert.True(unit.IsEmpty); - } - - [Fact] - public void UndoUnit_NullEngine_ThrowsArgumentNullException() - { - Assert.Throws("engine", () => new UndoUnit(null, "name")); - } - - protected override void AddUndoUnit(UndoUnit unit) - { - } - - protected class SubUndoUnit : UndoUnit - { - public SubUndoUnit(UndoEngine engine, string name) : base(engine, name) - { - } - - public new UndoEngine UndoEngine => base.UndoEngine; - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/BitmapEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/BitmapEditorTests.cs deleted file mode 100644 index dd819a953fe..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/BitmapEditorTests.cs +++ /dev/null @@ -1,127 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing.Imaging; -using System.Windows.Forms.TestUtilities; - -namespace System.Drawing.Design.Tests; - -public class BitmapEditorTests -{ - [Fact] - public void BitmapEditor_Ctor_Default() - { - BitmapEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - [Fact] - public void BitmapEditor_BitmapExtensions_Get_ReturnsExpected() - { - SubBitmapEditor editor = new(); - List extensions = SubBitmapEditor.BitmapExtensions; - Assert.Equal(new string[] { "bmp", "gif", "jpg", "jpeg", "png", "ico" }, extensions); - Assert.Same(extensions, SubBitmapEditor.BitmapExtensions); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void BitmapEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - BitmapEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.Modal, editor.GetEditStyle(context)); - } - - [Fact] - public void BitmapEditor_GetExtensions_InvokeDefault_ReturnsExpected() - { - SubBitmapEditor editor = new(); - string[] extensions = editor.GetExtensions(); - Assert.Equal(new string[] { "bmp", "gif", "jpg", "jpeg", "png", "ico" }, extensions); - Assert.NotSame(extensions, editor.GetExtensions()); - } - - [Fact] - public void BitmapEditor_GetExtensions_InvokeCustomExtenders_ReturnsExpected() - { - CustomGetImageExtendersEditor editor = new(); - string[] extensions = editor.GetExtensions(); - Assert.Equal(new string[] { "bmp", "gif", "jpg", "jpeg", "png", "ico" }, extensions); - Assert.NotSame(extensions, editor.GetExtensions()); - } - - [Fact] - public void BitmapEditor_GetFileDialogDescription_Invoke_ReturnsExpected() - { - SubBitmapEditor editor = new(); - Assert.Equal("Bitmap files", editor.GetFileDialogDescription()); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void BitmapEditor_GetPaintValueSupported_Invoke_ReturnsTrue(ITypeDescriptorContext context) - { - BitmapEditor editor = new(); - Assert.True(editor.GetPaintValueSupported(context)); - } - - [Fact] - public void BitmapEditor_LoadFromStream_BitmapStream_ReturnsExpected() - { - SubBitmapEditor editor = new(); - using (MemoryStream stream = new MemoryStream()) - using (Bitmap image = new(10, 10)) - { - image.Save(stream, ImageFormat.Bmp); - stream.Position = 0; - Bitmap result = Assert.IsType(editor.LoadFromStream(stream)); - Assert.Equal(new Size(10, 10), result.Size); - - using MemoryStream resultStream = new(); - result.Save(resultStream, ImageFormat.Bmp); - Assert.Equal(stream.Length, resultStream.Length); - } - } - - [Fact] - public void BitmapEditor_LoadFromStream_MetafileStream_ReturnsExpected() - { - SubBitmapEditor editor = new(); - using (Stream stream = File.OpenRead("Resources/telescope_01.wmf")) - { - Bitmap result = Assert.IsType(editor.LoadFromStream(stream)); - Assert.Equal(new Size(490, 654), result.Size); - } - } - - [Fact] - public void BitmapEditor_LoadFromStream_NullStream_ThrowsArgumentNullException() - { - SubBitmapEditor editor = new(); - Assert.Throws("stream", () => editor.LoadFromStream(null)); - } - - private class SubBitmapEditor : BitmapEditor - { - public static new List BitmapExtensions = BitmapEditor.BitmapExtensions; - - public new string[] GetExtensions() => base.GetExtensions(); - - public new string GetFileDialogDescription() => base.GetFileDialogDescription(); - - public new Image LoadFromStream(Stream stream) => base.LoadFromStream(stream); - } - - private class CustomGetImageExtendersEditor : BitmapEditor - { - public new string[] GetExtensions() => base.GetExtensions(); - - protected override Type[] GetImageExtenders() => new Type[] { typeof(CustomGetExtensionsEditor) }; - } - - private class CustomGetExtensionsEditor : ImageEditor - { - protected override string[] GetExtensions() => new string[] { "CustomGetExtensionsEditor" }; - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ColorEditorTests.CustomColorDialogTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ColorEditorTests.CustomColorDialogTests.cs deleted file mode 100644 index e69749a9026..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ColorEditorTests.CustomColorDialogTests.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Drawing.Design.Tests; - -public partial class ColorEditor_CustomColorDialogTests -{ - [WinFormsFact] - public void CustomColorDialog_Ctor_Default() - { - Type? typeCustomColorDialog = typeof(ColorEditor).Assembly.GetTypes().SingleOrDefault(t => t.Name == "CustomColorDialog"); - Assert.NotNull(typeCustomColorDialog); - - using ColorDialog dialog = (ColorDialog)Activator.CreateInstance(typeCustomColorDialog!)!; - Assert.NotNull(dialog); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ColorEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ColorEditorTests.cs deleted file mode 100644 index 71463510fb4..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ColorEditorTests.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Windows.Forms.Design; -using Moq; -using System.Windows.Forms.TestUtilities; - -namespace System.Drawing.Design.Tests; - -public partial class ColorEditorTests -{ - [Fact] - public void ColorEditor_Ctor_Default() - { - ColorEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - public static IEnumerable EditValue_TestData() - { - yield return new object[] { null }; - yield return new object[] { "value" }; - yield return new object[] { Color.Empty }; - yield return new object[] { Color.Red }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(EditValue_TestData))] - public void ColorEditor_EditValue_ValidProvider_ReturnsValue(object value) - { - ColorEditor editor = new(); - Mock mockEditorService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object) - .Verifiable(); - mockEditorService - .Setup(e => e.DropDownControl(It.IsAny())) - .Verifiable(); - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Once()); - mockEditorService.Verify(e => e.DropDownControl(It.IsAny()), Times.Once()); - - // Edit again. - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void ColorEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - ColorEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void ColorEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - ColorEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.DropDown, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void ColorEditor_GetPaintValueSupported_Invoke_ReturnsTrue(ITypeDescriptorContext context) - { - ColorEditor editor = new(); - Assert.True(editor.GetPaintValueSupported(context)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/CursorEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/CursorEditorTests.cs deleted file mode 100644 index 58a0dc5889e..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/CursorEditorTests.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Windows.Forms.Design; -using Moq; -using System.Windows.Forms.TestUtilities; - -namespace System.Drawing.Design.Tests; - -public class CursorEditorTests -{ - [Fact] - public void CursorEditor_Ctor_Default() - { - CursorEditor editor = new(); - Assert.True(editor.IsDropDownResizable); - } - - public static IEnumerable EditValue_TestData() - { - yield return new object[] { null }; - yield return new object[] { "value" }; - yield return new object[] { Cursors.Default }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(EditValue_TestData))] - public void CursorEditor_EditValue_ValidProvider_ReturnsValue(object value) - { - CursorEditor editor = new(); - Mock mockEditorService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object) - .Verifiable(); - mockEditorService - .Setup(e => e.DropDownControl(It.IsAny())) - .Verifiable(); - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Once()); - mockEditorService.Verify(e => e.DropDownControl(It.IsAny()), Times.Once()); - - // Edit again. - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void CursorEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - CursorEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void CursorEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - CursorEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.DropDown, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void CursorEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - CursorEditor editor = new(); - Assert.False(editor.GetPaintValueSupported(context)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/FontEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/FontEditorTests.cs deleted file mode 100644 index 91ff0614af6..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/FontEditorTests.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Windows.Forms.TestUtilities; - -namespace System.Drawing.Design.Tests; - -public class FontEditorTests -{ - [Fact] - public void FontEditor_Ctor_Default() - { - FontEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void FontEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - FontEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void FontEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - FontEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.Modal, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void FontEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - FontEditor editor = new(); - Assert.False(editor.GetPaintValueSupported(context)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/FontNameEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/FontNameEditorTests.cs deleted file mode 100644 index e1b0c39bc89..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/FontNameEditorTests.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Windows.Forms.Design; -using Moq; -using System.Windows.Forms.TestUtilities; - -namespace System.Drawing.Design.Tests; - -public class FontNameEditorTests -{ - private readonly ITypeDescriptorContext _typeDescriptorContext; - - public FontNameEditorTests() - { - _typeDescriptorContext = new Mock(MockBehavior.Strict).Object; - } - - [Fact] - public void FontNameEditor_Ctor_Default() - { - FontNameEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - public static IEnumerable EditValue_TestData() - { - yield return new object[] { null }; - yield return new object[] { "value" }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(EditValue_TestData))] - public void FontNameEditor_EditValue_ValidProvider_ReturnsValue(object value) - { - FontNameEditor editor = new(); - Mock mockEditorService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object) - .Verifiable(); - Assert.Same(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Never()); - - // Edit again. - Assert.Same(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Never()); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void FontNameEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - FontNameEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void FontNameEditor_GetEditStyle_Invoke_ReturnsNone(ITypeDescriptorContext context) - { - FontNameEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.None, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void FontNameEditor_GetPaintValueSupported_Invoke_ReturnsTrue(ITypeDescriptorContext context) - { - FontNameEditor editor = new(); - Assert.True(editor.GetPaintValueSupported(context)); - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("\t")] - public void FontNameEditor_PaintValue_ReturnsEarly_InvalidPaintValueEventArgsValue(string fontName) - { - PaintValueEventArgs e; - using (Bitmap bitmap = new(1, 1)) - { - using var g = Graphics.FromImage(bitmap); - e = new PaintValueEventArgs(_typeDescriptorContext, fontName, g, Rectangle.Empty); - } - - // assert by the virtue of calling the method - // if the implementation is incorrect, having disposed of the Graphics object - // we would received an AE attempting to call e.Graphics.FillRectangle() - FontNameEditor editor = new(); - editor.PaintValue(e); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ImageEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ImageEditorTests.cs deleted file mode 100644 index 8e751661d38..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ImageEditorTests.cs +++ /dev/null @@ -1,270 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing.Imaging; -using System.Windows.Forms.TestUtilities; - -namespace System.Drawing.Design.Tests; - -public class ImageEditorTests -{ - [Fact] - public void ImageEditor_Ctor_Default() - { - ImageEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - public static IEnumerable CreateExtensionsString_TestData() - { - yield return new object[] { null, ",", null }; - yield return new object[] { Array.Empty(), ",", null }; - yield return new object[] { new string[] { "a", "b", "c" }, ",", "*.a,*.b,*.c" }; - yield return new object[] { new string[] { "a", "b", "c" }, "", "*.a*.b*.c" }; - yield return new object[] { new string[] { "a", "b", "c" }, null, "*.a*.b*.c" }; - yield return new object[] { new string[] { null, null, null }, ",", "" }; - yield return new object[] { new string[] { string.Empty, string.Empty, string.Empty }, ",", "" }; - } - - [Theory] - [MemberData(nameof(CreateExtensionsString_TestData))] - public void ImageEditor_CreateExtensionsString_Invoke_ReturnsExpected(string[] extensions, string sep, string expected) - { - Assert.Equal(expected, SubImageEditor.CreateExtensionsString(extensions, sep)); - } - - [Fact] - public void ImageEditor_CreateFilterEntry_Invoke_CallsGetExtensionsOnce() - { - CustomGetImageExtendersEditor editor = new() - { - GetImageExtendersResult = new Type[] { typeof(PublicImageEditor), typeof(PrivateImageEditor) } - }; - Assert.Equal("CustomGetImageExtendersEditor(*.PublicImageEditor,*.PrivateImageEditor)|*.PublicImageEditor;*.PrivateImageEditor", SubImageEditor.CreateFilterEntry(editor)); - Assert.Equal(1, editor.GetImageExtendersCallCount); - } - - [Fact] - public void ImageEditor_CreateFilterEntry_NullE_ThrowsArgumentNullException() - { - Assert.Throws("e", () => SubImageEditor.CreateFilterEntry(null)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void ImageEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - ImageEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void ImageEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - ImageEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.Modal, editor.GetEditStyle(context)); - } - - [Fact] - public void ImageEditor_GetExtensions_InvokeDefault_ReturnsExpected() - { - SubImageEditor editor = new(); - string[] extensions = editor.GetExtensions(); - Assert.Equal(new string[] { "bmp", "gif", "jpg", "jpeg", "png", "ico", "emf", "wmf" }, extensions); - Assert.NotSame(extensions, editor.GetExtensions()); - } - - [Fact] - public void ImageEditor_GetExtensions_InvokeCustom_CallsGetImageExtendersOnce() - { - CustomGetImageExtendersEditor editor = new() - { - GetImageExtendersResult = new Type[] { typeof(PublicImageEditor), typeof(PrivateImageEditor), typeof(ImageEditor), typeof(NullExtensionsImageEditor) } - }; - Assert.Equal(new string[] { "PublicImageEditor", "PrivateImageEditor" }, editor.GetExtensions()); - Assert.Equal(1, editor.GetImageExtendersCallCount); - } - - [Fact] - public void ImageEditor_GetExtensions_InvokeInvalid_ReturnsExpected() - { - CustomGetImageExtendersEditor editor = new() - { - GetImageExtendersResult = new Type[] { typeof(object), null } - }; - Assert.Empty(editor.GetExtensions()); - Assert.Equal(1, editor.GetImageExtendersCallCount); - } - - [Fact] - public void ImageEditor_GetFileDialogDescription_Invoke_ReturnsExpected() - { - SubImageEditor editor = new(); - Assert.Equal("All image files", editor.GetFileDialogDescription()); - } - - [Fact] - public void ImageEditor_GetImageExtenders_Invoke_ReturnsExpected() - { - SubImageEditor editor = new(); - Type[] extenders = editor.GetImageExtenders(); - Assert.Equal(new Type[] { typeof(BitmapEditor), typeof(MetafileEditor) }, extenders); - Assert.Same(extenders, editor.GetImageExtenders()); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void ImageEditor_GetPaintValueSupported_Invoke_ReturnsTrue(ITypeDescriptorContext context) - { - ImageEditor editor = new(); - Assert.True(editor.GetPaintValueSupported(context)); - } - - [Fact] - public void ImageEditor_LoadFromStream_BitmapStream_ReturnsExpected() - { - SubImageEditor editor = new(); - using (MemoryStream stream = new MemoryStream()) - using (Bitmap image = new(10, 10)) - { - image.Save(stream, ImageFormat.Bmp); - stream.Position = 0; - Bitmap result = Assert.IsType(editor.LoadFromStream(stream)); - Assert.Equal(new Size(10, 10), result.Size); - - using MemoryStream resultStream = new(); - result.Save(resultStream, ImageFormat.Bmp); - Assert.Equal(stream.Length, resultStream.Length); - } - } - - [Fact] - public void ImageEditor_LoadFromStream_MetafileStream_ThrowsArgumentException() - { - SubImageEditor editor = new(); - using (Stream stream = File.OpenRead("Resources/telescope_01.wmf")) - { - Assert.Throws(() => editor.LoadFromStream(stream)); - } - } - - [Fact] - public void ImageEditor_LoadFromStream_NullStream_ThrowsArgumentNullException() - { - SubImageEditor editor = new(); - Assert.Throws("stream", () => editor.LoadFromStream(null)); - } - - [Fact] - public void ImageEditor_PaintValue_Invoke_Success() - { - ImageEditor editor = new(); - using (Bitmap image = new(10, 10)) - using (Bitmap otherImage = new(3, 2)) - using (Graphics graphics = Graphics.FromImage(image)) - { - otherImage.SetPixel(0, 0, Color.Red); - otherImage.SetPixel(1, 0, Color.Red); - otherImage.SetPixel(2, 0, Color.Red); - otherImage.SetPixel(0, 1, Color.Red); - otherImage.SetPixel(1, 1, Color.Red); - otherImage.SetPixel(2, 1, Color.Red); - - PaintValueEventArgs e = new(null, otherImage, graphics, new Rectangle(1, 2, 3, 4)); - editor.PaintValue(e); - } - } - - public static IEnumerable PaintValue_InvalidArgsValue_TestData() - { - yield return new object[] { null }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(PaintValue_InvalidArgsValue_TestData))] - public void ImageEditor_PaintValue_InvalidArgsValue_Nop(object value) - { - ImageEditor editor = new(); - using (Bitmap image = new(10, 10)) - using (Graphics graphics = Graphics.FromImage(image)) - { - PaintValueEventArgs e = new(null, value, graphics, new Rectangle(1, 2, 3, 4)); - editor.PaintValue(e); - } - } - - [Fact] - public void ImageEditor_PaintValue_NullE_Nop() - { - ImageEditor editor = new(); - editor.PaintValue(null); - } - - private class SubImageEditor : ImageEditor - { - public static new string CreateExtensionsString(string[] extensions, string sep) - { - return ImageEditor.CreateExtensionsString(extensions, sep); - } - - public static new string CreateFilterEntry(ImageEditor e) - { - return ImageEditor.CreateFilterEntry(e); - } - - public new string[] GetExtensions() => base.GetExtensions(); - - public new string GetFileDialogDescription() => base.GetFileDialogDescription(); - - public new Type[] GetImageExtenders() => base.GetImageExtenders(); - - public new Image LoadFromStream(Stream stream) => base.LoadFromStream(stream); - } - - private class CustomGetImageExtendersEditor : ImageEditor - { - public int GetImageExtendersCallCount { get; set; } - - public Type[] GetImageExtendersResult { get; set; } - - public new string[] GetExtensions() => base.GetExtensions(); - - protected override string GetFileDialogDescription() => "CustomGetImageExtendersEditor"; - - protected override Type[] GetImageExtenders() - { - GetImageExtendersCallCount++; - return GetImageExtendersResult; - } - } - - private class PublicImageEditor : ImageEditor - { - public PublicImageEditor() - { - } - - protected override string[] GetExtensions() => new string[] { "PublicImageEditor" }; - } - - private class PrivateImageEditor : ImageEditor - { - private PrivateImageEditor() - { - } - - protected override string[] GetExtensions() => new string[] { "PrivateImageEditor" }; - } - - private class NullExtensionsImageEditor : ImageEditor - { - public NullExtensionsImageEditor() - { - } - - protected override string[] GetExtensions() => null; - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/MetafileEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/MetafileEditorTests.cs deleted file mode 100644 index 3b27a0d62f2..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/MetafileEditorTests.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing.Imaging; -using System.Runtime.InteropServices; -using System.Windows.Forms.TestUtilities; - -namespace System.Drawing.Design.Tests; - -public class MetafileEditorTests -{ - [Fact] - public void MetafileEditor_Ctor_Default() - { - MetafileEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void MetafileEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - MetafileEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.Modal, editor.GetEditStyle(context)); - } - - [Fact] - public void MetafileEditor_GetExtensions_InvokeDefault_ReturnsExpected() - { - SubMetafileEditor editor = new(); - string[] extensions = editor.GetExtensions(); - Assert.Equal(new string[] { "emf", "wmf" }, extensions); - Assert.NotSame(extensions, editor.GetExtensions()); - } - - [Fact] - public void MetafileEditor_GetFileDialogDescription_Invoke_ReturnsExpected() - { - SubMetafileEditor editor = new(); - Assert.Equal("Metafiles", editor.GetFileDialogDescription()); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void MetafileEditor_GetPaintValueSupported_Invoke_ReturnsTrue(ITypeDescriptorContext context) - { - MetafileEditor editor = new(); - Assert.True(editor.GetPaintValueSupported(context)); - } - - [Fact] - public void MetafileEditor_LoadFromStream_BitmapStream_ThrowsExternalException() - { - SubMetafileEditor editor = new(); - using (MemoryStream stream = new MemoryStream()) - using (Bitmap image = new(10, 10)) - { - image.Save(stream, ImageFormat.Bmp); - stream.Position = 0; - Assert.Throws(() => editor.LoadFromStream(stream)); - } - } - - [Fact] - public void MetafileEditor_LoadFromStream_MetafileStream_ReturnsExpected() - { - SubMetafileEditor editor = new(); - using (Stream stream = File.OpenRead("Resources/telescope_01.wmf")) - { - Metafile result = Assert.IsType(editor.LoadFromStream(stream)); - Assert.Equal(new Size(3096, 4127), result.Size); - } - } - - [Fact] - public void MetafileEditor_LoadFromStream_NullStream_ThrowsArgumentNullException() - { - SubMetafileEditor editor = new(); - Assert.Throws("stream", () => editor.LoadFromStream(null)); - } - - private class SubMetafileEditor : MetafileEditor - { - public new string[] GetExtensions() => base.GetExtensions(); - - public new string GetFileDialogDescription() => base.GetFileDialogDescription(); - - public new Image LoadFromStream(Stream stream) => base.LoadFromStream(stream); - } - - private class CustomGetImageExtendersEditor : MetafileEditor - { - public new string[] GetExtensions() => base.GetExtensions(); - - protected override Type[] GetImageExtenders() => new Type[] { typeof(CustomGetExtensionsEditor) }; - } - - private class CustomGetExtensionsEditor : ImageEditor - { - protected override string[] GetExtensions() => new string[] { "CustomGetExtensionsEditor" }; - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxComponentsCreatedEventArgsTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxComponentsCreatedEventArgsTests.cs deleted file mode 100644 index 4d88a90973a..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxComponentsCreatedEventArgsTests.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; - -namespace System.Drawing.Design.Tests; - -public class ToolboxComponentsCreatedEventArgsTests -{ - public static IEnumerable Ctor_IComponentArray_TestData() - { - yield return new object[] { null }; - yield return new object[] { Array.Empty() }; - yield return new object[] { new IComponent[] { null } }; - } - - [Theory] - [MemberData(nameof(Ctor_IComponentArray_TestData))] - public void Ctor_IComponentArray(IComponent[] components) - { - ToolboxComponentsCreatedEventArgs e = new(components); - if (components is null) - { - Assert.Null(e.Components); - } - else - { - Assert.Equal(components, e.Components); - Assert.NotSame(components, e.Components); - Assert.Equal(e.Components, e.Components); - Assert.NotSame(e.Components, e.Components); - } - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxComponentsCreatingEventArgsTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxComponentsCreatingEventArgsTests.cs deleted file mode 100644 index c58789f3fb6..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxComponentsCreatingEventArgsTests.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design; -using Moq; - -namespace System.Drawing.Design.Tests; - -public class ToolboxComponentsCreatingEventArgsTests -{ - public static IEnumerable Ctor_IDesignerHost_TestData() - { - yield return new object[] { null }; - yield return new object[] { new Mock(MockBehavior.Strict).Object }; - } - - [Theory] - [MemberData(nameof(Ctor_IDesignerHost_TestData))] - public void Ctor_IDesignerHost(IDesignerHost host) - { - ToolboxComponentsCreatingEventArgs e = new(host); - Assert.Equal(host, e.DesignerHost); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxItemCollectionTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxItemCollectionTests.cs deleted file mode 100644 index c55d2da638d..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxItemCollectionTests.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Design.Tests; - -public class ToolboxItemCollectionTests -{ - [Fact] - public void ToolboxItemCollection_Ctor_ToolboxItemArray() - { - ToolboxItem item = new(); - ToolboxItemCollection collection = new(new ToolboxItem[] { item }); - Assert.Same(item, Assert.Single(collection)); - Assert.Same(item, collection[0]); - Assert.True(collection.Contains(item)); - Assert.Equal(0, collection.IndexOf(item)); - } - - [Fact] - public void ToolboxItemCollection_Ctor_NullToolboxItemArray_ThrowsArgumentNullException() - { - Assert.Throws("c", () => new ToolboxItemCollection((ToolboxItem[])null)); - } - - [Fact] - public void ToolboxItemCollection_Ctor_ToolboxItemCollection() - { - ToolboxItem item = new(); - ToolboxItemCollection value = new(new ToolboxItem[] { item }); - ToolboxItemCollection collection = new(value); - Assert.Same(item, Assert.Single(collection)); - Assert.Same(item, collection[0]); - Assert.True(collection.Contains(item)); - Assert.Equal(0, collection.IndexOf(item)); - } - - [Fact] - public void ToolboxItemCollection_Ctor_NullToolboxItemCollection_ThrowsArgumentNullException() - { - Assert.Throws("c", () => new ToolboxItemCollection((ToolboxItemCollection)null)); - } - - [Fact] - public void ToolboxItemCollection_Contains_NoSuchValue_ReturnsFalse() - { - ToolboxItem item = new(); - ToolboxItemCollection collection = new(new ToolboxItem[] { item }); - Assert.False(collection.Contains(new ToolboxItem { DisplayName = "Other" })); - Assert.False(collection.Contains(null)); - } - - [Fact] - public void ToolboxItemCollection_IndexOf_NoSuchValue_ReturnsNegativeOne() - { - ToolboxItem item = new(); - ToolboxItemCollection collection = new(new ToolboxItem[] { item }); - Assert.Equal(-1, collection.IndexOf(new ToolboxItem { DisplayName = "Other" })); - Assert.Equal(-1, collection.IndexOf(null)); - } - - [Fact] - public void ToolboxItemCollection_CopyTo_Invoke_Success() - { - ToolboxItem item = new(); - ToolboxItemCollection collection = new(new ToolboxItem[] { item }); - - var array = new ToolboxItem[3]; - collection.CopyTo(array, 1); - Assert.Equal(new ToolboxItem[] { null, item, null }, array); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxItemTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxItemTests.cs deleted file mode 100644 index 6a1464424c9..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Drawing/Design/ToolboxItemTests.cs +++ /dev/null @@ -1,1788 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design; -using System.Reflection; -using System.Runtime.Loader; -using Moq; - -namespace System.Drawing.Design.Tests; - -public class ToolboxItemTests -{ - [Fact] - public void ToolboxItem_Ctor_Default() - { - ToolboxItem item = new(); - Assert.Null(item.AssemblyName); - Assert.Null(item.Bitmap); - Assert.Null(item.Company); - Assert.Equal(".NET Component", item.ComponentType); - Assert.Null(item.DependentAssemblies); - Assert.Null(item.Description); - Assert.Empty(item.DisplayName); - Assert.Empty(item.Filter); - Assert.Same(item.Filter, item.Filter); - Assert.False(item.IsTransient); - Assert.False(item.Locked); - Assert.Null(item.OriginalBitmap); - Assert.Empty(item.Properties); - Assert.Same(item.Properties, item.Properties); - Assert.False(item.Properties.IsFixedSize); - Assert.False(item.Properties.IsReadOnly); - Assert.Empty(item.TypeName); - Assert.Empty(item.Version); - } - - public static IEnumerable AssemblyName_Set_TestData() - { - yield return new object[] { null }; - yield return new object[] { new AssemblyName() }; - yield return new object[] { new AssemblyName(typeof(int).Assembly.FullName) }; - } - - [Theory] - [MemberData(nameof(AssemblyName_Set_TestData))] - public void ToolboxItem_AssemblyName_Set_GetReturnsExpected(AssemblyName value) - { - ToolboxItem item = new() - { - AssemblyName = value - }; - if (value is null) - { - Assert.Null(item.AssemblyName); - Assert.Null(item.Properties["AssemblyName"]); - Assert.Empty(item.Version); - } - else - { - Assert.Equal(value.FullName, item.AssemblyName.FullName); - Assert.NotSame(value, item.AssemblyName); - Assert.NotSame(item.AssemblyName, item.AssemblyName); - Assert.Equal(value.FullName, ((AssemblyName)item.Properties["AssemblyName"]).FullName); - Assert.NotSame(value, item.Properties["AssemblyName"]); - Assert.NotSame(item.Properties["AssemblyName"], item.Properties["AssemblyName"]); - Assert.Equal(value.Version?.ToString() ?? string.Empty, item.Version); - } - - // Set same. - item.AssemblyName = value; - if (value is null) - { - Assert.Null(item.AssemblyName); - Assert.Null(item.Properties["AssemblyName"]); - Assert.Empty(item.Version); - } - else - { - Assert.Equal(value.FullName, item.AssemblyName.FullName); - Assert.NotSame(value, item.AssemblyName); - Assert.NotSame(item.AssemblyName, item.AssemblyName); - Assert.Equal(value.FullName, ((AssemblyName)item.Properties["AssemblyName"]).FullName); - Assert.NotSame(value, item.Properties["AssemblyName"]); - Assert.NotSame(item.Properties["AssemblyName"], item.Properties["AssemblyName"]); - Assert.Equal(value.Version?.ToString() ?? string.Empty, item.Version); - } - } - - [Fact] - public void ToolboxItem_AssemblyName_SetWithInvalidPropertyType_ThrowsArgumentException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("AssemblyName", new object())); - } - - public static IEnumerable Bitmap_Set_TestData() - { - yield return new object[] { null }; - yield return new object[] { new Bitmap(10, 10) }; - } - - [Theory] - [MemberData(nameof(Bitmap_Set_TestData))] - public void ToolboxItem_Bitmap_Set_GetReturnsExpected(Bitmap value) - { - ToolboxItem item = new() - { - Bitmap = value - }; - Assert.Same(value, item.Bitmap); - Assert.Same(value, item.Properties["Bitmap"]); - - // Set same. - item.Bitmap = value; - Assert.Same(value, item.Bitmap); - Assert.Same(value, item.Properties["Bitmap"]); - } - - [Fact] - public void ToolboxItem_Bitmap_SetWithInvalidPropertyType_ThrowsArgumentException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("Bitmap", new object())); - } - - [Theory] - [NormalizedStringData] - public void ToolboxItem_Company_Set_GetReturnsExpected(string value, string expected) - { - ToolboxItem item = new() - { - Company = value - }; - Assert.Equal(expected, item.Company); - Assert.Equal(expected, item.Properties["Company"]); - - // Set same. - item.Company = value; - Assert.Equal(expected, item.Company); - Assert.Equal(expected, item.Properties["Company"]); - } - - [Fact] - public void ToolboxItem_Company_SetWithInvalidPropertyType_ThrowsArgumentException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("Company", new object())); - } - - public static IEnumerable DependentAssemblies_Set_TestData() - { - yield return new object[] { null }; - yield return new object[] { Array.Empty() }; - yield return new object[] { new AssemblyName[] { null } }; - yield return new object[] { new AssemblyName[] { new AssemblyName() } }; - } - - [Theory] - [MemberData(nameof(DependentAssemblies_Set_TestData))] - public void ToolboxItem_DependentAssemblies_Set_GetReturnsExpected(AssemblyName[] value) - { - ToolboxItem item = new() - { - DependentAssemblies = value - }; - if (value is null) - { - Assert.Null(item.DependentAssemblies); - Assert.Null(item.Properties["DependentAssemblies"]); - } - else - { - Assert.Equal(value, item.DependentAssemblies); - Assert.NotSame(value, item.DependentAssemblies); - Assert.Equal(value, item.Properties["DependentAssemblies"]); - Assert.NotSame(value, item.Properties["DependentAssemblies"]); - } - - // Set same. - item.DependentAssemblies = value; - if (value is null) - { - Assert.Null(item.DependentAssemblies); - Assert.Null(item.Properties["DependentAssemblies"]); - } - else - { - Assert.Equal(value, item.DependentAssemblies); - Assert.NotSame(value, item.DependentAssemblies); - Assert.Equal(value, item.Properties["DependentAssemblies"]); - Assert.NotSame(value, item.Properties["DependentAssemblies"]); - } - } - - [Fact] - public void ToolboxItem_DependentAssemblies_SetWithInvalidPropertyType_GetThrowsArgumentException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("DependentAssemblies", new object())); - } - - [Theory] - [NormalizedStringData] - public void ToolboxItem_Description_Set_GetReturnsExpected(string value, string expected) - { - ToolboxItem item = new() - { - Description = value - }; - Assert.Equal(expected, item.Description); - Assert.Equal(expected, item.Properties["Description"]); - - // Set same. - item.Description = value; - Assert.Equal(expected, item.Description); - Assert.Equal(expected, item.Properties["Description"]); - } - - [Fact] - public void ToolboxItem_Description_SetWithInvalidPropertyType_ThrowsArgumentException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("Description", new object())); - } - - [Theory] - [NormalizedStringData] - public void ToolboxItem_DisplayName_Set_GetReturnsExpected(string value, string expected) - { - ToolboxItem item = new() - { - DisplayName = value - }; - Assert.Equal(expected, item.DisplayName); - Assert.Equal(expected, item.Properties["DisplayName"]); - - // Set same. - item.DisplayName = value; - Assert.Equal(expected, item.DisplayName); - Assert.Equal(expected, item.Properties["DisplayName"]); - } - - [Fact] - public void ToolboxItem_DisplayName_SetWithInvalidPropertyType_ThrowsArgumentException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("DisplayName", new object())); - } - - public static IEnumerable Filter_Set_TestData() - { - yield return new object[] { null, Array.Empty() }; - yield return new object[] { Array.Empty(), Array.Empty() }; - yield return new object[] { new object[] { null }, Array.Empty() }; - yield return new object[] { new object[] { new object(), new ToolboxItemFilterAttribute("filterString") }, new object[] { new ToolboxItemFilterAttribute("filterString") } }; - } - - [Theory] - [MemberData(nameof(Filter_Set_TestData))] - public void ToolboxItem_Filter_Set_GetReturnsExpected(ICollection value, ICollection expected) - { - ToolboxItem item = new() - { - Filter = value - }; - Assert.Equal(expected, item.Filter); - Assert.Equal(expected, item.Properties["Filter"]); - - // Set same. - item.Filter = value; - Assert.Equal(expected, item.Filter); - Assert.Equal(expected, item.Properties["Filter"]); - } - - [Fact] - public void ToolboxItem_Filter_SetWithInvalidPropertyType_GetThrowsArgumentException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("Filter", new object())); - } - - [Theory] - [BoolData] - public void ToolboxItem_IsTransient_Set_GetReturnsExpected(bool value) - { - ToolboxItem item = new() - { - IsTransient = value - }; - Assert.Equal(value, item.IsTransient); - Assert.Equal(value, item.Properties["IsTransient"]); - - // Set same. - item.IsTransient = value; - Assert.Equal(value, item.IsTransient); - Assert.Equal(value, item.Properties["IsTransient"]); - } - - [Fact] - public void ToolboxItem_IsTransient_SetWithNullPropertyType_GetThrowsArgumentNullException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("IsTransient", null)); - } - - [Fact] - public void ToolboxItem_IsTransient_SetWithInvalidPropertyType_GetThrowsArgumentException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("IsTransient", new object())); - } - - [Theory] - [MemberData(nameof(Bitmap_Set_TestData))] - public void ToolboxItem_OriginalBitmap_Set_GetReturnsExpected(Bitmap value) - { - ToolboxItem item = new() - { - OriginalBitmap = value - }; - Assert.Same(value, item.OriginalBitmap); - Assert.Same(value, item.Properties["OriginalBitmap"]); - - // Set same. - item.OriginalBitmap = value; - Assert.Same(value, item.OriginalBitmap); - Assert.Same(value, item.Properties["OriginalBitmap"]); - } - - [Fact] - public void ToolboxItem_OriginalBitmap_SetWithInvalidPropertyType_ThrowsArgumentException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("OriginalBitmap", new object())); - } - - [Theory] - [NormalizedStringData] - public void ToolboxItem_TypeName_Set_GetReturnsExpected(string value, string expected) - { - ToolboxItem item = new() - { - TypeName = value - }; - Assert.Equal(expected, item.TypeName); - Assert.Equal(expected, item.Properties["TypeName"]); - - // Set same. - item.TypeName = value; - Assert.Equal(expected, item.TypeName); - Assert.Equal(expected, item.Properties["TypeName"]); - } - - [Fact] - public void ToolboxItem_TypeName_SetWithInvalidPropertyType_ThrowsArgumentException() - { - ToolboxItem item = new(); - Assert.Throws("value", () => item.Properties.Add("TypeName", new object())); - } - - [Fact] - public void ToolboxItem_CreateComponents_InvokeWithoutHost_ReturnsExpected() - { - ToolboxItem item = new() - { - AssemblyName = typeof(Component).Assembly.GetName(true), - TypeName = "System.ComponentModel.Component" - }; - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Null(e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.IsType(Assert.Single(e.Components)); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - // With handler. - Assert.IsType(Assert.Single(item.CreateComponents())); - Assert.Equal(1, creatingCallCount); - Assert.Equal(1, createdCallCount); - - Assert.IsType(Assert.Single(item.CreateComponents(null))); - Assert.Equal(2, creatingCallCount); - Assert.Equal(2, createdCallCount); - - // Remove handler. - item.ComponentsCreating -= creatingHandler; - item.ComponentsCreated -= createdHandler; - - Assert.IsType(Assert.Single(item.CreateComponents(null))); - Assert.Equal(2, creatingCallCount); - Assert.Equal(2, createdCallCount); - } - - public static IEnumerable CreateComponents_InvokeWithHostWithNonIComponentInitializerDesigner_TestData() - { - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner.Setup(d => d.Dispose()); - - yield return new object[] { new Component(), null }; - yield return new object[] { new Component(), mockDesigner.Object }; - - yield return new object[] { null, null }; - yield return new object[] { null, mockDesigner.Object }; - } - - [Theory] - [MemberData(nameof(CreateComponents_InvokeWithHostWithNonIComponentInitializerDesigner_TestData))] - public void ToolboxItem_CreateComponents_InvokeWithHostWithNonIComponentInitializerDesigner_ReturnsExpected(Component component, IDesigner designer) - { - ToolboxItem item = new() - { - TypeName = "typeName" - }; - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(new CustomTypeResolutionService()); - mockDesignerHost - .Setup(h => h.CreateComponent(typeof(bool))) - .Returns(component); - mockDesignerHost - .Setup(h => h.GetDesigner(component)) - .Returns(designer); - - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(mockDesignerHost.Object, e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(component, Assert.Single(e.Components)); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - // With handler. - Assert.Same(component, Assert.Single(item.CreateComponents(mockDesignerHost.Object))); - Assert.Equal(1, creatingCallCount); - Assert.Equal(1, createdCallCount); - - Assert.Same(component, Assert.Single(item.CreateComponents(mockDesignerHost.Object, null))); - Assert.Equal(2, creatingCallCount); - Assert.Equal(2, createdCallCount); - - Assert.Same(component, Assert.Single(item.CreateComponents(mockDesignerHost.Object, new Hashtable()))); - Assert.Equal(3, creatingCallCount); - Assert.Equal(3, createdCallCount); - - // Remove handler. - item.ComponentsCreating -= creatingHandler; - item.ComponentsCreated -= createdHandler; - - Assert.Same(component, Assert.Single(item.CreateComponents(mockDesignerHost.Object))); - Assert.Equal(3, creatingCallCount); - Assert.Equal(3, createdCallCount); - } - - [Fact] - public void ToolboxItem_CreateComponents_InvokeWithHostWithIComponentInitializerDesigner_ReturnsExpected() - { - using Component component = new(); - ToolboxItem item = new() - { - TypeName = "typeName" - }; - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner.Setup(d => d.Dispose()); - Mock mockComponentInitializer = mockDesigner.As(); - mockComponentInitializer - .Setup(i => i.InitializeNewComponent(null)); - mockComponentInitializer - .Setup(i => i.InitializeNewComponent(new Hashtable())); - - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(new CustomTypeResolutionService()); - mockDesignerHost - .Setup(h => h.CreateComponent(typeof(bool))) - .Returns(component); - mockDesignerHost - .Setup(h => h.GetDesigner(component)) - .Returns(mockDesigner.Object); - - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(mockDesignerHost.Object, e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(component, Assert.Single(e.Components)); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - // With handler. - Assert.Same(component, Assert.Single(item.CreateComponents(mockDesignerHost.Object))); - Assert.Equal(1, creatingCallCount); - Assert.Equal(1, createdCallCount); - - Assert.Same(component, Assert.Single(item.CreateComponents(mockDesignerHost.Object, null))); - Assert.Equal(2, creatingCallCount); - Assert.Equal(2, createdCallCount); - - Assert.Same(component, Assert.Single(item.CreateComponents(mockDesignerHost.Object, new Hashtable()))); - Assert.Equal(3, creatingCallCount); - Assert.Equal(3, createdCallCount); - - // Remove handler. - item.ComponentsCreating -= creatingHandler; - item.ComponentsCreated -= createdHandler; - - Assert.Same(component, Assert.Single(item.CreateComponents(mockDesignerHost.Object))); - Assert.Equal(3, creatingCallCount); - Assert.Equal(3, createdCallCount); - } - - [Fact] - public void ToolboxItem_CreateComponents_InvokeWithHostWithThrowingIComponentInitializerDesigner_ReturnsExpected() - { - using Component component = new(); - ToolboxItem item = new() - { - TypeName = "typeName" - }; - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner.Setup(d => d.Dispose()); - Mock mockComponentInitializer = mockDesigner.As(); - mockComponentInitializer - .Setup(i => i.InitializeNewComponent(null)) - .Throws(new Exception()); - mockComponentInitializer - .Setup(i => i.InitializeNewComponent(new Hashtable())) - .Throws(new Exception()); - - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(new CustomTypeResolutionService()); - mockDesignerHost - .Setup(h => h.CreateComponent(typeof(bool))) - .Returns(component); - mockDesignerHost - .Setup(h => h.GetDesigner(component)) - .Returns(mockDesigner.Object); - mockDesignerHost - .Setup(h => h.DestroyComponent(component)); - - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(mockDesignerHost.Object, e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(component, Assert.Single(e.Components)); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - // With handler. - Assert.Throws(() => item.CreateComponents(mockDesignerHost.Object)); - Assert.Equal(1, creatingCallCount); - Assert.Equal(0, createdCallCount); - - Assert.Throws(() => item.CreateComponents(mockDesignerHost.Object, null)); - Assert.Equal(2, creatingCallCount); - Assert.Equal(0, createdCallCount); - - Assert.Throws(() => item.CreateComponents(mockDesignerHost.Object, new Hashtable())); - Assert.Equal(3, creatingCallCount); - Assert.Equal(0, createdCallCount); - - // Remove handler. - item.ComponentsCreating -= creatingHandler; - item.ComponentsCreated -= createdHandler; - - Assert.Throws(() => item.CreateComponents(mockDesignerHost.Object)); - Assert.Equal(3, creatingCallCount); - Assert.Equal(0, createdCallCount); - } - - [Fact] - public void ToolboxItem_CreateComponents_InvokeWithNullComponentsCoreWithHost_ReturnsExpected() - { - NullComponentsToolboxItem item = new() - { - TypeName = "typeName" - }; - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(new CustomTypeResolutionService()); - mockDesignerHost - .Setup(h => h.CreateComponent(typeof(bool))) - .Returns(new Component()); - - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(mockDesignerHost.Object, e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Null(e.Components); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - // With handler. - Assert.Null(item.CreateComponents(mockDesignerHost.Object)); - Assert.Equal(1, creatingCallCount); - Assert.Equal(0, createdCallCount); - - Assert.Null(item.CreateComponents(mockDesignerHost.Object, null)); - Assert.Equal(2, creatingCallCount); - Assert.Equal(0, createdCallCount); - - Assert.Null(item.CreateComponents(mockDesignerHost.Object, new Hashtable())); - Assert.Equal(3, creatingCallCount); - Assert.Equal(0, createdCallCount); - - // Remove handler. - item.ComponentsCreating -= creatingHandler; - item.ComponentsCreated -= createdHandler; - - Assert.Null(item.CreateComponents(mockDesignerHost.Object)); - Assert.Equal(3, creatingCallCount); - Assert.Equal(0, createdCallCount); - } - - [Theory] - [InlineData("")] - [InlineData("NoSuchType")] - [InlineData("System.Int32")] - public void ToolboxItem_CreateComponents_InvokeInvalidType_ReturnsEmpty(string typeName) - { - ToolboxItem item = new() - { - TypeName = typeName - }; - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Null(e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Null(e.Components); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - Assert.Empty(item.CreateComponents()); - Assert.Equal(1, creatingCallCount); - Assert.Equal(0, createdCallCount); - } - - [Fact] - public void ToolboxItem_CreateComponentsCore_InvokeWithoutHost_ReturnsExpected() - { - SubToolboxItem item = new() - { - AssemblyName = typeof(Component).Assembly.GetName(true), - TypeName = "System.ComponentModel.Component" - }; - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Null(e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.IsType(Assert.Single(e.Components)); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - // With handler. - Assert.IsType(Assert.Single(item.CreateComponentsCore(null))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - - // Remove handler. - item.ComponentsCreating -= creatingHandler; - item.ComponentsCreated -= createdHandler; - - Assert.IsType(Assert.Single(item.CreateComponentsCore(null))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - } - - [Theory] - [MemberData(nameof(CreateComponents_InvokeWithHostWithNonIComponentInitializerDesigner_TestData))] - public void ToolboxItem_CreateComponentsCore_InvokeWithHostWithNonIComponentInitializerDesigner_ReturnsExpected(Component component, IDesigner designer) - { - SubToolboxItem item = new() - { - TypeName = "typeName" - }; - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(new CustomTypeResolutionService()); - mockDesignerHost - .Setup(h => h.CreateComponent(typeof(bool))) - .Returns(component); - mockDesignerHost - .Setup(h => h.GetDesigner(component)) - .Returns(designer); - - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(mockDesignerHost.Object, e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(component, Assert.Single(e.Components)); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - // With handler. - Assert.Same(component, Assert.Single(item.CreateComponentsCore(mockDesignerHost.Object))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - - Assert.Same(component, Assert.Single(item.CreateComponentsCore(mockDesignerHost.Object, null))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - - Assert.Same(component, Assert.Single(item.CreateComponentsCore(mockDesignerHost.Object, new Hashtable()))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - - // Remove handler. - item.ComponentsCreating -= creatingHandler; - item.ComponentsCreated -= createdHandler; - - Assert.Same(component, Assert.Single(item.CreateComponents(mockDesignerHost.Object))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - } - - [Fact] - public void ToolboxItem_CreateComponentsCore_InvokeWithHostWithIComponentInitializerDesigner_ReturnsExpected() - { - using Component component = new(); - SubToolboxItem item = new() - { - TypeName = "typeName" - }; - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner.Setup(d => d.Dispose()); - Mock mockComponentInitializer = mockDesigner.As(); - mockComponentInitializer - .Setup(i => i.InitializeNewComponent(null)); - mockComponentInitializer - .Setup(i => i.InitializeNewComponent(new Hashtable())); - - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(new CustomTypeResolutionService()); - mockDesignerHost - .Setup(h => h.CreateComponent(typeof(bool))) - .Returns(component); - mockDesignerHost - .Setup(h => h.GetDesigner(component)) - .Returns(mockDesigner.Object); - - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(mockDesignerHost.Object, e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(component, Assert.Single(e.Components)); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - // With handler. - Assert.Same(component, Assert.Single(item.CreateComponentsCore(mockDesignerHost.Object))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - - Assert.Same(component, Assert.Single(item.CreateComponentsCore(mockDesignerHost.Object, null))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - - Assert.Same(component, Assert.Single(item.CreateComponentsCore(mockDesignerHost.Object, new Hashtable()))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - - // Remove handler. - item.ComponentsCreating -= creatingHandler; - item.ComponentsCreated -= createdHandler; - - Assert.Same(component, Assert.Single(item.CreateComponents(mockDesignerHost.Object))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - } - - [Fact] - public void ToolboxItem_CreateComponentsCore_InvokeWithHostWithThrowingIComponentInitializerDesigner_ReturnsExpected() - { - using Component component = new(); - SubToolboxItem item = new() - { - TypeName = "typeName" - }; - Mock mockDesigner = new(MockBehavior.Strict); - mockDesigner.Setup(d => d.Dispose()); - Mock mockComponentInitializer = mockDesigner.As(); - mockComponentInitializer - .Setup(i => i.InitializeNewComponent(null)) - .Throws(new Exception()); - mockComponentInitializer - .Setup(i => i.InitializeNewComponent(new Hashtable())) - .Throws(new Exception()); - - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(new CustomTypeResolutionService()); - mockDesignerHost - .Setup(h => h.CreateComponent(typeof(bool))) - .Returns(component); - mockDesignerHost - .Setup(h => h.GetDesigner(component)) - .Returns(mockDesigner.Object); - mockDesignerHost - .Setup(h => h.DestroyComponent(component)); - - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(mockDesignerHost.Object, e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Same(component, Assert.Single(e.Components)); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - // With handler. - Assert.Same(component, Assert.Single(item.CreateComponentsCore(mockDesignerHost.Object))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - - Assert.Throws(() => item.CreateComponentsCore(mockDesignerHost.Object, null)); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - - Assert.Throws(() => item.CreateComponentsCore(mockDesignerHost.Object, new Hashtable())); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - - // Remove handler. - item.ComponentsCreating -= creatingHandler; - item.ComponentsCreated -= createdHandler; - - Assert.Same(component, Assert.Single(item.CreateComponentsCore(mockDesignerHost.Object))); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - } - - [Theory] - [InlineData("")] - [InlineData("NoSuchType")] - [InlineData("System.Int32")] - public void ToolboxItem_CreateComponentsCore_InvokeInvalidType_ReturnsEmpty(string typeName) - { - SubToolboxItem item = new() - { - TypeName = typeName - }; - int creatingCallCount = 0; - int createdCallCount = 0; - ToolboxComponentsCreatingEventHandler creatingHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Null(e.DesignerHost); - creatingCallCount++; - }; - ToolboxComponentsCreatedEventHandler createdHandler = (sender, e) => - { - Assert.Same(item, sender); - Assert.Null(e.Components); - createdCallCount++; - }; - item.ComponentsCreating += creatingHandler; - item.ComponentsCreated += createdHandler; - - Assert.Empty(item.CreateComponentsCore(null)); - Assert.Equal(0, creatingCallCount); - Assert.Equal(0, createdCallCount); - } - - [Fact] - public void ToolboxItem_CheckUnlocked_NotLocked_Nop() - { - SubToolboxItem item = new(); - item.CheckUnlocked(); - item.CheckUnlocked(); - } - - [Fact] - public void ToolboxItem_CheckUnlocked_Locked_ThrowsInvalidOperationException() - { - SubToolboxItem item = new(); - item.Lock(); - Assert.Throws(() => item.CheckUnlocked()); - } - - public static IEnumerable Equals_TestData() - { - ToolboxItem item = new(); - yield return new object[] { item, item, true }; - yield return new object[] { item, new ToolboxItem(), true }; - yield return new object[] { item, new SubToolboxItem(), false }; - - yield return new object[] - { - item, - new ToolboxItem - { - Company = "Company", - DependentAssemblies = new AssemblyName[] { null }, - Description = "Description", - Filter = new ToolboxItemFilterAttribute[] { new ToolboxItemFilterAttribute("Filter") }, - IsTransient = true - }, - true - }; - - yield return new object[] - { - new ToolboxItem { TypeName = "TypeName" }, - new ToolboxItem { TypeName = "TypeName" }, - true - }; - yield return new object[] - { - new ToolboxItem { TypeName = "TypeName" }, - new ToolboxItem { TypeName = "typename" }, - false - }; - yield return new object[] - { - new ToolboxItem { TypeName = "TypeName" }, - new ToolboxItem(), - false - }; - yield return new object[] - { - new ToolboxItem(), - new ToolboxItem { TypeName = "TypeName" }, - false - }; - yield return new object[] - { - new NoValidationToolboxItem { TypeName = null }, - new NoValidationToolboxItem { TypeName = null }, - true - }; - yield return new object[] - { - new NoValidationToolboxItem { TypeName = null }, - new NoValidationToolboxItem { TypeName = "TypeName" }, - false - }; - yield return new object[] - { - new NoValidationToolboxItem { TypeName = "TypeName" }, - new NoValidationToolboxItem { TypeName = null }, - false - }; - - yield return new object[] - { - new ToolboxItem { DisplayName = "DisplayName" }, - new ToolboxItem { DisplayName = "DisplayName" }, - true - }; - yield return new object[] - { - new ToolboxItem { DisplayName = "DisplayName" }, - new ToolboxItem { DisplayName = "displayname" }, - false - }; - yield return new object[] - { - new ToolboxItem { DisplayName = "DisplayName" }, - new ToolboxItem(), - false - }; - yield return new object[] - { - new ToolboxItem(), - new ToolboxItem { DisplayName = "DisplayName" }, - false - }; - yield return new object[] - { - new NoValidationToolboxItem { DisplayName = null }, - new NoValidationToolboxItem { DisplayName = null }, - true - }; - yield return new object[] - { - new NoValidationToolboxItem { DisplayName = null }, - new NoValidationToolboxItem { DisplayName = "TypeName" }, - false - }; - yield return new object[] - { - new NoValidationToolboxItem { DisplayName = "TypeName" }, - new NoValidationToolboxItem { DisplayName = null }, - false - }; - - yield return new object[] - { - new ToolboxItem { AssemblyName = new AssemblyName("Name") }, - new ToolboxItem { AssemblyName = new AssemblyName("Name") }, - true - }; - yield return new object[] - { - new ToolboxItem { AssemblyName = new AssemblyName("Name") }, - new ToolboxItem { AssemblyName = new AssemblyName("name") }, - false - }; - yield return new object[] - { - new ToolboxItem(), - new ToolboxItem { AssemblyName = new AssemblyName("Name") }, - false - }; - yield return new object[] - { - new ToolboxItem { AssemblyName = new AssemblyName("Name") }, - new ToolboxItem(), - false - }; - - yield return new object[] { new ToolboxItem(), new object(), false }; - yield return new object[] { new ToolboxItem(), null, false }; - } - - [Theory] - [MemberData(nameof(Equals_TestData))] - public void ToolboxItem_Equals_Invoke_ReturnsExpected(ToolboxItem item, object other, bool expected) - { - Assert.Equal(expected, item.Equals(other)); - } - - public static IEnumerable FilterPropertyValue_TestData() - { - object o = new(); - yield return new object[] { "AssemblyName", null, null, true }; - yield return new object[] { "AssemblyName", new AssemblyName("Name"), new AssemblyName("Name"), false }; - yield return new object[] { "AssemblyName", o, o, true }; - yield return new object[] { "assemblyName", new AssemblyName("Name"), new AssemblyName("Name"), true }; - - yield return new object[] { "DisplayName", null, string.Empty, false }; - yield return new object[] { "DisplayName", "value", "value", true }; - yield return new object[] { "DisplayName", o, o, true }; - yield return new object[] { "displayname", null, null, true }; - - yield return new object[] { "TypeName", null, string.Empty, false }; - yield return new object[] { "TypeName", "value", "value", true }; - yield return new object[] { "TypeName", o, o, true }; - yield return new object[] { "typename", null, null, true }; - - yield return new object[] { "Filter", null, Array.Empty(), false }; - yield return new object[] { "Filter", Array.Empty(), Array.Empty(), true }; - yield return new object[] { "Filter", o, o, true }; - yield return new object[] { "filter", null, null, true }; - - yield return new object[] { "IsTransient", null, false, false }; - yield return new object[] { "IsTransient", true, true, true }; - yield return new object[] { "IsTransient", o, o, true }; - yield return new object[] { "istransient", null, null, true }; - - yield return new object[] { "NoSuchProperty", null, null, true }; - yield return new object[] { "NoSuchProperty", "value", "value", true }; - yield return new object[] { "NoSuchProperty", o, o, true }; - } - - [Theory] - [MemberData(nameof(FilterPropertyValue_TestData))] - public void ToolboxItem_FilterPropertyValue_Invoke_ReturnsExpected(string propertyName, object value, object expected, bool same) - { - SubToolboxItem item = new(); - object actual = item.FilterPropertyValue(propertyName, value); - if (expected is AssemblyName expectedName) - { - Assert.Equal(expectedName.FullName, Assert.IsType(actual).FullName); - } - else - { - Assert.Equal(expected, actual); - } - - Assert.Equal(same, object.ReferenceEquals(value, actual)); - } - - public static IEnumerable GetHashCode_TestData() - { - yield return new object[] { new ToolboxItem() }; - yield return new object[] { new ToolboxItem { TypeName = "TypeName", DisplayName = "DisplayName" } }; - yield return new object[] { new NoValidationToolboxItem { TypeName = null, DisplayName = null } }; - } - - [Theory] - [MemberData(nameof(GetHashCode_TestData))] - public void ToolboxItem_GetHashCode_Invoke_ReturnsExpected(ToolboxItem item) - { - Assert.Equal(item.GetHashCode(), item.GetHashCode()); - } - - public static IEnumerable GetType_TestData() - { - Mock nullServiceDesignerHost = new(MockBehavior.Strict); - nullServiceDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(null); - foreach (object host in new object[] { null, nullServiceDesignerHost.Object }) - { - yield return new object[] { null, null, "System.Int32", false, typeof(int) }; - yield return new object[] { null, new AssemblyName("NoSuchAssembly"), "System.Int32", false, typeof(int) }; - yield return new object[] { null, new AssemblyName(typeof(int).Assembly.FullName), "System.Int32", false, typeof(int) }; - yield return new object[] { null, new AssemblyName(typeof(ToolboxItem).Assembly.FullName), "System.Int32", false, typeof(int) }; - yield return new object[] { null, new AssemblyName(typeof(int).Assembly.FullName), "System.Drawing.Design.Tests.ToolboxItemTests", false, null }; - yield return new object[] { null, new AssemblyName(typeof(ToolboxItemTests).Assembly.FullName), "System.Drawing.Design.Tests.ToolboxItemTests", false, typeof(ToolboxItemTests) }; - yield return new object[] { null, new AssemblyName(typeof(ToolboxItemTests).Assembly.FullName), "System.Drawing.Design.Tests.toolboxitemtests", false, null }; - yield return new object[] { null, new AssemblyName(typeof(ToolboxItemTests).Assembly.FullName), "NoSuchType", false, null }; - yield return new object[] { null, null, string.Empty, false, null }; - -#pragma warning disable SYSLIB0044 // Type or member is obsolete - AssemblyName validNameWithCodeBase = new(typeof(int).Assembly.FullName) - { - CodeBase = "System.Windows.Forms.Design.Tests.dll" - }; - yield return new object[] { null, validNameWithCodeBase, "System.Drawing.Design.Tests.ToolboxItemTests", false, null }; - - AssemblyName invalidNameWithCodeBase = new("NoSuchAssembly") - { - CodeBase = "System.Windows.Forms.Design.Tests.dll" - }; - yield return new object[] { null, invalidNameWithCodeBase, "System.Drawing.Design.Tests.ToolboxItemTests", false, typeof(ToolboxItemTests) }; - - AssemblyName invalidNameWithInvalidCodeBase = new("NoSuchAssembly") - { - CodeBase = "AlsoNoSuchAssembly" - }; - yield return new object[] { null, invalidNameWithInvalidCodeBase, "System.Drawing.Design.Tests.ToolboxItemTests", false, null }; - - AssemblyLoadContext.Default.Resolving += (context, name) => - { - if (name.Name == "ThrowBadImageFormatException") - { - throw new BadImageFormatException(); - } - else if (name.Name == "ThrowIOException") - { - throw new IOException(); - } - - return null; - }; - yield return new object[] { null, new AssemblyName("ThrowBadImageFormatException"), "System.Int32", false, typeof(int) }; - yield return new object[] { null, new AssemblyName("ThrowIOException"), "System.Int32", false, typeof(int) }; - - AssemblyName badImageFormatExceptionCodeBase = new("NoSuchAssembly") - { - CodeBase = "ThrowBadImageFormatException" - }; - yield return new object[] { null, badImageFormatExceptionCodeBase, "System.Int32", false, typeof(int) }; - - AssemblyName ioFormatExceptionCodeBase = new("NoSuchAssembly") - { - CodeBase = "ThrowIOException" - }; -#pragma warning restore SYSLIB0044 // Type or member is obsolete - yield return new object[] { null, ioFormatExceptionCodeBase, "System.Int32", false, typeof(int) }; - } - - Mock invalidServiceDesignerHost = new(MockBehavior.Strict); - invalidServiceDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(new object()); - yield return new object[] { invalidServiceDesignerHost.Object, new AssemblyName(typeof(int).Assembly.FullName), "System.Int32", false, typeof(int) }; - - foreach (bool reference in new bool[] { true, false }) - { - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(new CustomTypeResolutionService()); - yield return new object[] { mockDesignerHost.Object, null, "typeName", reference, typeof(bool) }; - yield return new object[] { mockDesignerHost.Object, null, string.Empty, false, null }; - yield return new object[] { mockDesignerHost.Object, new AssemblyName(), "typeName", reference, typeof(bool) }; - yield return new object[] { mockDesignerHost.Object, new AssemblyName(typeof(int).Assembly.FullName), "System.Int32", reference, typeof(int) }; - yield return new object[] { mockDesignerHost.Object, new AssemblyName(typeof(int).Assembly.FullName), "System.Drawing.Design.Tests.ToolboxItemTests", reference, typeof(ToolboxItemTests) }; - yield return new object[] { mockDesignerHost.Object, new AssemblyName(typeof(int).Assembly.FullName), "System.Drawing.Design.Tests.toolboxitemtests", reference, null }; - yield return new object[] { mockDesignerHost.Object, new AssemblyName(typeof(int).Assembly.FullName), "NoSuchType", reference, null }; - } - } - - [Theory] - [MemberData(nameof(GetType_TestData))] - public void ToolboxItem_GetType_InvokeWithoutTypeNameAssemblyName_ReturnsExpected(IDesignerHost host, AssemblyName assemblyName, string typeName, bool reference, Type expected) - { - if (reference) - { - return; - } - - ToolboxItem item = new() - { - AssemblyName = assemblyName, - TypeName = typeName - }; - Assert.Equal(expected, item.GetType(host)); - } - - [Theory] - [MemberData(nameof(GetType_TestData))] - public void ToolboxItem_GetType_InvokeWithTypeNameAssemblyName_ReturnsExpected(IDesignerHost host, AssemblyName assemblyName, string typeName, bool reference, Type expected) - { - SubToolboxItem item = new(); - Assert.Equal(expected, item.GetType(host, assemblyName, typeName, reference)); - } - - [Fact] - public void ToolboxItem_GetType_NullTypeName_ThrowsArgumentNullException() - { - SubToolboxItem item = new(); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(null); - Assert.Throws("typeName", () => item.GetType(mockDesignerHost.Object, null, null, false)); - Assert.Throws("typeName", () => item.GetType(null, null, null, false)); - } - - [Fact] - public void ToolboxItem_GetType_EmptyAssemblyName_ThrowsArgumentException() - { - SubToolboxItem item = new(); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.GetService(typeof(ITypeResolutionService))) - .Returns(null); - Assert.Throws(() => item.GetType(mockDesignerHost.Object, new AssemblyName(), "typeName", false)); - Assert.Throws(() => item.GetType(null, new AssemblyName(), "typeName", false)); - } - - public static IEnumerable Initialize_TypeWithAttributes_TestData() - { - yield return new object[] { typeof(ClassWithValidAttributes), new Size(16, 16) }; - yield return new object[] { typeof(ClassWithStretchedWidthImage), new Size(24, 16) }; - yield return new object[] { typeof(ClassWithStretchedHeightImage), new Size(16, 24) }; - yield return new object[] { typeof(ClassWithInvalidImage), new Size(16, 16) }; - } - - [Theory] - [MemberData(nameof(Initialize_TypeWithAttributes_TestData))] - public void ToolboxItem_Initialize_TypeWithAttributes_Success(Type type, Size expectedOriginalBitmapSize) - { - using Bitmap bitmap = new(10, 10); - using Bitmap originalBitmap = new(10, 10); - - var filter = new ToolboxItemFilterAttribute[] { new ToolboxItemFilterAttribute("Filter") }; - ToolboxItem item = new() - { - AssemblyName = new AssemblyName("AssemblyName"), - Bitmap = bitmap, - Company = "Company", - Description = "Description", - DependentAssemblies = new AssemblyName[2], - DisplayName = "DisplayName", - Filter = filter, - OriginalBitmap = originalBitmap - }; - item.Initialize(type); - if (expectedOriginalBitmapSize == new Size(10, 10)) - { - Assert.NotEqual(bitmap, item.Bitmap); - Assert.Same(item.Bitmap, item.Bitmap); - } - else - { - Assert.Equal(new Size(16, 16), item.Bitmap.Size); - } - - Assert.Equal("Microsoft Corporation", item.Company); - Assert.Equal("Description", item.Description); - Assert.Equal(type.Assembly.FullName, item.AssemblyName.FullName); - Assert.Equal(new string[] { type.Assembly.FullName }, item.DependentAssemblies.Select(a => a.FullName)); - Assert.Equal(type.Name, item.DisplayName); - Assert.Equal(new string[] { type.Name, "Filter", "System.Drawing.Design.Tests.ToolboxItemTests+" + type.Name }, item.Filter.Cast().Select(a => a.FilterString).OrderBy(f => f)); - Assert.Equal(expectedOriginalBitmapSize, item.OriginalBitmap.Size); - - Assert.Equal("Microsoft Corporation", item.Company); - Assert.Equal("Description", item.Description); - Assert.Equal(type.Assembly.FullName, item.AssemblyName.FullName); - Assert.Equal(new string[] { type.Assembly.FullName }, item.DependentAssemblies.Select(a => a.FullName)); - Assert.Equal(type.Name, item.DisplayName); - Assert.Equal(new string[] { type.Name, "Filter", "System.Drawing.Design.Tests.ToolboxItemTests+" + type.Name }, item.Filter.Cast().Select(a => a.FilterString).OrderBy(f => f)); - Assert.Equal(expectedOriginalBitmapSize, item.OriginalBitmap.Size); - } - - [Fact] - public void ToolboxItem_Initialize_ObjectType_Success() - { - using (Bitmap bitmap = new(10, 10)) - using (Bitmap originalBitmap = new(10, 10)) - { - var filter = new ToolboxItemFilterAttribute[] { new ToolboxItemFilterAttribute("Filter") }; - ToolboxItem item = new() - { - AssemblyName = new AssemblyName("AssemblyName"), - Bitmap = bitmap, - Company = "Company", - Description = "Description", - DependentAssemblies = new AssemblyName[2], - DisplayName = "DisplayName", - Filter = filter, - OriginalBitmap = originalBitmap - }; - item.Initialize(typeof(object)); - Assert.NotEqual(bitmap, item.Bitmap); - Assert.Same(item.Bitmap, item.Bitmap); - Assert.Equal("Microsoft Corporation", item.Company); - Assert.Empty(item.Description); - Assert.Equal(typeof(object).Assembly.FullName, item.AssemblyName.FullName); - Assert.Equal(new string[] { typeof(object).Assembly.FullName }, item.DependentAssemblies.Select(a => a.FullName)); - Assert.Equal("Object", item.DisplayName); - Assert.Equal(new string[] { "System.Object" }, item.Filter.Cast().Select(a => a.FilterString)); - Assert.Same(item.OriginalBitmap, item.OriginalBitmap); - } - } - - [Fact] - public void ToolboxItem_Initialize_NullType_Nop() - { - using (Bitmap bitmap = new(10, 10)) - using (Bitmap originalBitmap = new(10, 10)) - { - var filter = new ToolboxItemFilterAttribute[] { new ToolboxItemFilterAttribute("Filter") }; - ToolboxItem item = new() - { - AssemblyName = new AssemblyName("AssemblyName"), - Bitmap = bitmap, - Company = "Company", - Description = "Description", - DependentAssemblies = new AssemblyName[2], - DisplayName = "DisplayName", - Filter = filter, - OriginalBitmap = originalBitmap - }; - item.Initialize(null); - Assert.Equal("AssemblyName", item.AssemblyName.FullName); - Assert.Same(bitmap, item.Bitmap); - Assert.Equal("Company", item.Company); - Assert.Equal("Description", item.Description); - Assert.Equal(new AssemblyName[2], item.DependentAssemblies); - Assert.Equal("DisplayName", item.DisplayName); - Assert.Equal(filter, item.Filter); - Assert.Same(originalBitmap, item.OriginalBitmap); - } - } - - [Theory] - [InlineData(null)] - [InlineData(typeof(int))] - public void ToolboxItem_Initialize_Locked_ThrowsInvalidOperationException(Type type) - { - ToolboxItem item = new(); - item.Lock(); - Assert.Throws(() => item.Initialize(type)); - } - - [Fact] - public void ToolboxItem_Lock_Invoke_Success() - { - ToolboxItem item = new(); - item.Lock(); - Assert.True(item.Locked); - Assert.True(item.Properties.IsFixedSize); - Assert.True(item.Properties.IsReadOnly); - - // Lock again. - item.Lock(); - Assert.True(item.Locked); - Assert.True(item.Properties.IsFixedSize); - Assert.True(item.Properties.IsReadOnly); - } - - [Fact] - public void ToolboxItem_OnComponentsCreated_Invoke_Success() - { - SubToolboxItem item = new(); - - // No handler. - item.OnComponentsCreated(null); - - // Handler. - int callCount = 0; - ToolboxComponentsCreatedEventHandler handler = (sender, e) => - { - Assert.Equal(item, sender); - Assert.Null(e); - callCount++; - }; - - item.ComponentsCreated += handler; - item.OnComponentsCreated(null); - Assert.Equal(1, callCount); - - // Should not call if the handler is removed. - item.ComponentsCreated -= handler; - item.OnComponentsCreated(null); - Assert.Equal(1, callCount); - } - - [Fact] - public void ToolboxItem_OnComponentsCreating_Invoke_Success() - { - SubToolboxItem item = new(); - - // No handler. - item.OnComponentsCreating(null); - - // Handler. - int callCount = 0; - ToolboxComponentsCreatingEventHandler handler = (sender, e) => - { - Assert.Equal(item, sender); - Assert.Null(e); - callCount++; - }; - - item.ComponentsCreating += handler; - item.OnComponentsCreating(null); - Assert.Equal(1, callCount); - - // Should not call if the handler is removed. - item.ComponentsCreating -= handler; - item.OnComponentsCreating(null); - Assert.Equal(1, callCount); - } - - public static IEnumerable ToString_TestData() - { - yield return new object[] { new ToolboxItem(), string.Empty }; - yield return new object[] { new ToolboxItem { DisplayName = "DisplayName" }, "DisplayName" }; - yield return new object[] { new NoValidationToolboxItem { DisplayName = null }, string.Empty }; - } - - [Theory] - [MemberData(nameof(ToString_TestData))] - public void ToolboxItem_ToString_Invoke_ReturnsExpected(ToolboxItem item, string expected) - { - Assert.Equal(expected, item.ToString()); - } - - public static IEnumerable ValidatePropertyValue_TestData() - { - AssemblyName name = new(); - yield return new object[] { "AssemblyName", null, null }; - yield return new object[] { "AssemblyName", name, name }; - - Bitmap bitmap = new(10, 10); - yield return new object[] { "Bitmap", null, null }; - yield return new object[] { "Bitmap", bitmap, bitmap }; - - Bitmap originalBitmap = new(10, 10); - yield return new object[] { "OriginalBitmap", null, null }; - yield return new object[] { "OriginalBitmap", originalBitmap, originalBitmap }; - - yield return new object[] { "Company", null, string.Empty }; - yield return new object[] { "Company", "value", "value" }; - - yield return new object[] { "Description", null, string.Empty }; - yield return new object[] { "Description", "value", "value" }; - - yield return new object[] { "DisplayName", null, string.Empty }; - yield return new object[] { "DisplayName", "value", "value" }; - - yield return new object[] { "TypeName", null, string.Empty }; - yield return new object[] { "TypeName", "value", "value" }; - - ToolboxItemFilterAttribute filter = new("filter"); - yield return new object[] { "Filter", null, Array.Empty() }; - yield return new object[] { "Filter", Array.Empty(), Array.Empty() }; - yield return new object[] { "Filter", new object[] { null, "value", filter, filter }, new ToolboxItemFilterAttribute[] { filter, filter } }; - - yield return new object[] { "NoSuchProperty", null, null }; - yield return new object[] { "NoSuchProperty", 1, 1 }; - - yield return new object[] { "istransient", null, null }; - yield return new object[] { "istransient", 1, 1 }; - } - - [Theory] - [MemberData(nameof(ValidatePropertyValue_TestData))] - public void ToolboxItem_ValidatePropertyValue_ValueAllowed_ReturnsExpected(string propertyName, object value, object expected) - { - SubToolboxItem item = new(); - Assert.Equal(expected, item.ValidatePropertyValue(propertyName, value)); - } - - [Theory] - [InlineData("IsTransient")] - public void ToolboxItem_ValidatePropertyValue_NullValueDisallowed_ThrowsArgumentNullException(string propertyName) - { - SubToolboxItem item = new(); - Assert.Throws("value", () => item.ValidatePropertyValue(propertyName, null)); - } - - [Theory] - [InlineData("AssemblyName")] - [InlineData("Bitmap")] - [InlineData("OriginalBitmap")] - [InlineData("Company")] - [InlineData("Description")] - [InlineData("DisplayName")] - [InlineData("TypeName")] - [InlineData("Filter")] - [InlineData("DependentAssemblies")] - public void ToolboxItem_ValidatePropertyValue_InvalidValue_ThrowsArgumentException(string propertyName) - { - SubToolboxItem item = new(); - Assert.Throws("value", () => item.ValidatePropertyValue(propertyName, new object())); - } - - [Theory] - [InlineData(null, null)] - [InlineData("propertyName", typeof(int))] - public void ToolboxItem_ValidatePropertyType_NullDisallowed_ThrowsArgumentNullException(string propertyName, Type expectedType) - { - SubToolboxItem item = new(); - Assert.Throws("value", () => item.ValidatePropertyType(propertyName, null, expectedType, allowNull: false)); - } - - [Theory] - [InlineData(null, null)] - [InlineData("propertyName", typeof(int))] - public void ToolboxItem_ValidatePropertyType_NullAllowed_Nop(string propertyName, Type expectedType) - { - SubToolboxItem item = new(); - item.ValidatePropertyType(propertyName, null, expectedType, allowNull: true); - } - - [Theory] - [InlineData(null, false)] - [InlineData("propertyName", true)] - public void ToolboxItem_ValidatePropertyType_ValidType_Nop(string propertyName, bool allowNull) - { - SubToolboxItem item = new(); - item.ValidatePropertyType(propertyName, 1, typeof(int), allowNull); - } - - [Theory] - [InlineData(null, false)] - [InlineData("propertyName", true)] - public void ToolboxItem_ValidatePropertyType_InvalidType_ThrowsArgumentException(string propertyName, bool allowNull) - { - SubToolboxItem item = new(); - Assert.Throws("value", () => item.ValidatePropertyType(propertyName, new object(), typeof(int), allowNull)); - } - - private class SubToolboxItem : ToolboxItem - { - public new void CheckUnlocked() => base.CheckUnlocked(); - - public new IComponent[] CreateComponentsCore(IDesignerHost host) - { - return base.CreateComponentsCore(host); - } - - public new IComponent[] CreateComponentsCore(IDesignerHost host, IDictionary defaultValues) - { - return base.CreateComponentsCore(host, defaultValues); - } - - public new object FilterPropertyValue(string propertyName, object value) - { - return base.FilterPropertyValue(propertyName, value); - } - - public new Type GetType(IDesignerHost host, AssemblyName assemblyName, string typeName, bool reference) - { - return base.GetType(host, assemblyName, typeName, reference); - } - - public new void OnComponentsCreated(ToolboxComponentsCreatedEventArgs args) - { - base.OnComponentsCreated(args); - } - - public new void OnComponentsCreating(ToolboxComponentsCreatingEventArgs args) - { - base.OnComponentsCreating(args); - } - - public new object ValidatePropertyValue(string propertyName, object value) - { - return base.ValidatePropertyValue(propertyName, value); - } - - public new void ValidatePropertyType(string propertyName, object value, Type expectedType, bool allowNull) - { - base.ValidatePropertyType(propertyName, value, expectedType, allowNull); - } - } - - private class CustomTypeResolutionService : ITypeResolutionService - { - public Assembly GetAssemblyResult { get; set; } - - public Assembly GetAssembly(AssemblyName name) => GetAssemblyResult; - - public Assembly GetAssembly(AssemblyName name, bool throwOnError) - { - throw new NotImplementedException(); - } - - public string GetPathOfAssembly(AssemblyName name) - { - throw new NotImplementedException(); - } - - public Type GetType(string name) - { - if (name == "typeName") - { - return typeof(bool); - } - - return Type.GetType(name); - } - - public Type GetType(string name, bool throwOnError) - { - throw new NotImplementedException(); - } - - public Type GetType(string name, bool throwOnError, bool ignoreCase) - { - throw new NotImplementedException(); - } - - public List ReferenceAssemblies { get; } = new List(); - - public void ReferenceAssembly(AssemblyName name) - { - ReferenceAssemblies.Add(name); - } - } - - private class NoValidationToolboxItem : ToolboxItem - { - protected override object FilterPropertyValue(string propertyName, object value) - { - // Don't normalize. - return value; - } - - protected override object ValidatePropertyValue(string propertyName, object value) - { - // Don't normalize. - return value; - } - } - - private class NullComponentsToolboxItem : ToolboxItem - { - protected override IComponent[] CreateComponentsCore(IDesignerHost host) - { - return null; - } - } - - [Description("Description")] - [ToolboxBitmap(typeof(ToolboxItemTests), "16x16.bmp")] - [ToolboxItemFilter("System.Drawing.Design.Tests.ToolboxItemTests+ClassWithValidAttributes")] - [ToolboxItemFilter("ClassWithValidAttributes")] - [ToolboxItemFilter("Filter")] - private class ClassWithValidAttributes - { - } - - [Description("Description")] - [ToolboxBitmap(typeof(ToolboxItemTests), "24x16.bmp")] - [ToolboxItemFilter("System.Drawing.Design.Tests.ToolboxItemTests+ClassWithStretchedWidthImage")] - [ToolboxItemFilter("ClassWithStretchedWidthImage")] - [ToolboxItemFilter("Filter")] - private class ClassWithStretchedWidthImage - { - } - - [Description("Description")] - [ToolboxBitmap(typeof(ToolboxItemTests), "16x24.bmp")] - [ToolboxItemFilter("System.Drawing.Design.Tests.ToolboxItemTests+ClassWithStretchedHeightImage")] - [ToolboxItemFilter("ClassWithStretchedHeightImage")] - [ToolboxItemFilter("Filter")] - private class ClassWithStretchedHeightImage - { - } - - [Description("Description")] - [ToolboxBitmap("NoSuchImage")] - [ToolboxItemFilter("System.Drawing.Design.Tests.ToolboxItemTests+ClassWithInvalidImage")] - [ToolboxItemFilter("ClassWithInvalidImage")] - [ToolboxItemFilter("Filter")] - private class ClassWithInvalidImage - { - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Resources/Tools/CodeDomCompileHelper.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Resources/Tools/CodeDomCompileHelper.cs deleted file mode 100644 index 9e2cbc50096..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Resources/Tools/CodeDomCompileHelper.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.CodeDom.Compiler; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CSharp; -using System.CodeDom; -using System.Runtime.Loader; -using System.Reflection; -using System.Drawing; - -namespace System.Resources.Tools.Tests; - -internal static class CodeDomCompileHelper -{ - private static readonly CodeDomProvider s_cSharpProvider = new CSharpCodeProvider(); - - private static MetadataReference[] References { get; } = CreateReferences(); - - private static MetadataReference[] CreateReferences() - { - string corelibPath = typeof(object).Assembly.Location; - return new[] - { - MetadataReference.CreateFromFile(corelibPath), - MetadataReference.CreateFromFile(Path.Join(Path.GetDirectoryName(corelibPath), "System.Runtime.dll")), - MetadataReference.CreateFromFile(typeof(Bitmap).Assembly.Location), - }; - } - - private static Stream CreateAssemblyImage(string source, string assemblyName, string resourceName, Stream resource) - { - CSharpCompilation compilation = CSharpCompilation.Create( - assemblyName, - new[] { CSharpSyntaxTree.ParseText(source) }, - References, - new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - - ResourceDescription[] description = resource is null - ? null - : new ResourceDescription[] { new(resourceName, () => resource, isPublic: true) }; - - MemoryStream stream = new(); - var result = compilation.Emit(stream, manifestResources: description); - if (result.Success) - { - stream.Position = 0; - return stream; - } - else - { - throw new InvalidOperationException(string.Join('\n', result.Diagnostics.Select(d => d.GetMessage()))); - } - } - - internal static Type CompileClass( - CodeCompileUnit compileUnit, - string baseName, - string nameSpace = null, - Stream resource = null) - { - AssemblyLoadContext context = new(name: null, isCollectible: true); - string fullName = nameSpace is null ? baseName : $"{nameSpace}.{baseName}"; - - using StringWriter writer = new(); - s_cSharpProvider.GenerateCodeFromCompileUnit(compileUnit, writer, new()); - Assembly assembly = context.LoadFromStream(CreateAssemblyImage( - writer.ToString(), - fullName, - $"{fullName}.resources", - resource)); - Type type = assembly.GetType(fullName, throwOnError: true); - - // Once all references are collected, the assembly will unload. - context.Unload(); - return type; - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Resources/Tools/StronglyTypedResourceBuilderTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Resources/Tools/StronglyTypedResourceBuilderTests.cs deleted file mode 100644 index 431e4f4a964..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Resources/Tools/StronglyTypedResourceBuilderTests.cs +++ /dev/null @@ -1,715 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.CodeDom; -using System.CodeDom.Compiler; -using System.Collections; -using System.ComponentModel; -using System.Drawing; -using System.Reflection; -using System.Text; -using System.Windows.Forms.TestUtilities; -using AxWMPLib; -using Microsoft.CSharp; - -namespace System.Resources.Tools.Tests; - -public partial class StronglyTypedResourceBuilderTests -{ - // https://docs.microsoft.com/dotnet/core/extensions/work-with-resx-files-programmatically - - private static readonly CodeDomProvider s_cSharpProvider = new CSharpCodeProvider(); - private const string TypeAssembly = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; - private const string TxtFileEncoding = "Windows-1252"; - - [Fact] - public void StronglyTypedResourceBuilder_Create_NullBaseName_ThrowsArgumentNull() - { - Hashtable resources = new(); - Assert.Throws( - "baseName", - () => StronglyTypedResourceBuilder.Create( - resources, - baseName: null, - string.Empty, - s_cSharpProvider, - internalClass: false, - out _)); - - Assert.Throws( - "baseName", - () => StronglyTypedResourceBuilder.Create( - resources, - baseName: null, - string.Empty, - string.Empty, - s_cSharpProvider, - internalClass: false, - out _)); - - using var temp = TempFile.Create(ResxHelper.CreateResx()); - Assert.Throws( - "baseName", - () => StronglyTypedResourceBuilder.Create( - temp.Path, - baseName: null, - string.Empty, - s_cSharpProvider, - internalClass: false, - out _)); - - Assert.Throws( - "baseName", - () => StronglyTypedResourceBuilder.Create( - temp.Path, - baseName: null, - string.Empty, - string.Empty, - s_cSharpProvider, - internalClass: false, - out _)); - } - - [Fact] - public void StronglyTypedResourceBuilder_Create_NullCodeProvider_ThrowsArgumentNull() - { - Hashtable resources = new(); - Assert.Throws( - "codeProvider", - () => StronglyTypedResourceBuilder.Create( - resources, - string.Empty, - string.Empty, - codeProvider: null, - internalClass: false, - out _)); - - Assert.Throws( - "codeProvider", - () => StronglyTypedResourceBuilder.Create( - resources, - string.Empty, - string.Empty, - string.Empty, - codeProvider: null, - internalClass: false, - out _)); - - using var temp = TempFile.Create(ResxHelper.CreateResx()); - Assert.Throws( - "codeProvider", - () => StronglyTypedResourceBuilder.Create( - temp.Path, - string.Empty, - string.Empty, - codeProvider: null, - internalClass: false, - out _)); - - Assert.Throws( - "codeProvider", - () => StronglyTypedResourceBuilder.Create( - temp.Path, - string.Empty, - string.Empty, - string.Empty, - codeProvider: null, - internalClass: false, - out _)); - } - - [Fact] - public void StronglyTypedResourceBuilder_Create_NullResourceList_ThrowsArgumentNull() - { - Hashtable resources = new(); - Assert.Throws( - "resourceList", - () => StronglyTypedResourceBuilder.Create( - resourceList: null, - string.Empty, - string.Empty, - s_cSharpProvider, - internalClass: false, - out _)); - - Assert.Throws( - "resourceList", - () => StronglyTypedResourceBuilder.Create( - resourceList: null, - string.Empty, - string.Empty, - string.Empty, - s_cSharpProvider, - internalClass: false, - out _)); - } - - [Fact] - public void StronglyTypedResourceBuilder_Create_NullResxFile_ThrowsArgumentNull() - { - Assert.Throws( - "resxFile", - () => StronglyTypedResourceBuilder.Create( - resxFile: null, - string.Empty, - string.Empty, - s_cSharpProvider, - internalClass: false, - out _)); - - Assert.Throws( - "resxFile", - () => StronglyTypedResourceBuilder.Create( - resxFile: null, - string.Empty, - string.Empty, - string.Empty, - s_cSharpProvider, - internalClass: false, - out _)); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_MismatchedResxDataNode_Throws() - { - Hashtable values = new() - { - { "TestName", new ResXDataNode("WrongName", "TestValue") } - }; - - Assert.Throws(() => StronglyTypedResourceBuilder.Create( - resourceList: values, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _)); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_EmptyResx() - { - using var temp = TempFile.Create(ResxHelper.CreateResx()); - var compileUnit = StronglyTypedResourceBuilder.Create( - resxFile: temp.Path, - baseName: "Resources", - generatedCodeNamespace: null, - s_cSharpProvider, - internalClass: false, - out _); - - Type type = CodeDomCompileHelper.CompileClass(compileUnit, "Resources"); - Assert.NotNull(type); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_StringResource_FromFile() - { - const string data = """ - - TestValue - - """; - - using var temp = TempFile.Create(ResxHelper.CreateResx(data)); - var compileUnit = StronglyTypedResourceBuilder.Create( - resxFile: temp.Path, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using MemoryStream resourceStream = new(); - using ResourceWriter resourceWriter = new(resourceStream); - resourceWriter.AddResource("TestName", "TestValue"); - resourceWriter.Generate(); - resourceStream.Position = 0; - - Type type = CodeDomCompileHelper.CompileClass(compileUnit, "Resources", "Namespace", resourceStream); - Assert.NotNull(type); - var nameProperty = type.GetProperty("TestName"); - Assert.NotNull(nameProperty); - Assert.Equal("TestValue", (string)nameProperty.GetValue(obj: null)); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_StringResource_FromResxWriterFile() - { - using var temp = TempFile.Create(); - using (ResXResourceWriter writer = new(temp.Path)) - { - writer.AddResource("TestName", "TestValue"); - writer.Generate(); - } - - var compileUnit = StronglyTypedResourceBuilder.Create( - resxFile: temp.Path, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using MemoryStream resourceStream = new(); - using ResourceWriter resourceWriter = new(resourceStream); - resourceWriter.AddResource("TestName", "TestValue"); - resourceWriter.Generate(); - resourceStream.Position = 0; - - Type type = CodeDomCompileHelper.CompileClass(compileUnit, "Resources", "Namespace", resourceStream); - Assert.NotNull(type); - var nameProperty = type.GetProperty("TestName"); - Assert.NotNull(nameProperty); - Assert.Equal("TestValue", (string)nameProperty.GetValue(obj: null)); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_StringResource_FromResxDataNode() - { - Hashtable values = new() - { - { "TestName", new ResXDataNode("TestName", "TestValue") } - }; - - var compileUnit = StronglyTypedResourceBuilder.Create( - resourceList: values, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using MemoryStream resourceStream = new(); - using ResourceWriter resourceWriter = new(resourceStream); - resourceWriter.AddResource("TestName", "TestValue"); - resourceWriter.Generate(); - resourceStream.Position = 0; - - Type type = CodeDomCompileHelper.CompileClass(compileUnit, "Resources", "Namespace", resourceStream); - Assert.NotNull(type); - var nameProperty = type.GetProperty("TestName"); - Assert.NotNull(nameProperty); - Assert.Equal("TestValue", (string)nameProperty.GetValue(obj: null)); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_BitmapResource_FromFile() - { - const string data = $""" - - Resources\Image1.png;System.Byte[], {TypeAssembly} - - """; - - using var temp = TempFile.Create(ResxHelper.CreateResx(data)); - - var compileUnit = StronglyTypedResourceBuilder.Create( - resxFile: temp.Path, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using ResXResourceReader reader = new(temp.Path); - var imagePropertyInfo = CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "Image1"); - using Bitmap expected = (Bitmap)Image.FromFile(@"Resources\Image1.png"); - ValidateResultBitmap(imagePropertyInfo, expected, TypeDescriptor.GetConverter(typeof(Bitmap))); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_BitmapResource_FromMemory() - { - using Bitmap bitmap = new(10, 10); - bitmap.SetPixel(0, 0, Color.Red); - var converter = TypeDescriptor.GetConverter(bitmap); - - ResXDataNode node = new("Image1", converter.ConvertTo(bitmap, typeof(byte[]))); - using var temp = TempFile.Create(); - using (ResXResourceWriter resxWriter = new(temp.Path)) - { - resxWriter.AddResource(node); - resxWriter.Generate(); - } - - var compileUnit = StronglyTypedResourceBuilder.Create( - resxFile: temp.Path, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using ResXResourceReader reader = new(temp.Path); - var imagePropertyInfo = CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "Image1"); - ValidateResultBitmap(imagePropertyInfo, bitmap, converter); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_BitmapResource_FromFileRef() - { - ResXFileRef fileRef = new(@"Resources\Image1.png", $"System.Byte[], {TypeAssembly}"); - Hashtable values = new() - { - { "Image1", new ResXDataNode("Image1", fileRef) } - }; - - var compileUnit = StronglyTypedResourceBuilder.Create( - resourceList: values, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using MemoryStream resxStream = new(); - using ResXResourceWriter resxWriter = new(resxStream); - resxWriter.AddResource(new ResXDataNode("Image1", fileRef)); - resxWriter.Generate(); - resxStream.Position = 0; - using ResXResourceReader reader = new(resxStream); - var imagePropertyInfo = CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "Image1"); - using Bitmap expected = (Bitmap)Image.FromFile(@"Resources\Image1.png"); - ValidateResultBitmap(imagePropertyInfo, expected, TypeDescriptor.GetConverter(typeof(Bitmap))); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_IconResource_FromFile() - { - const string data = $""" - - Resources\Icon1.ico;System.Byte[], {TypeAssembly} - - """; - - using var temp = TempFile.Create(ResxHelper.CreateResx(data)); - - var compileUnit = StronglyTypedResourceBuilder.Create( - resxFile: temp.Path, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using ResXResourceReader reader = new(temp.Path); - var iconPropertyInfo = CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "Icon1"); - using Icon expected = new(@"Resources\Icon1.ico"); - ValidateResultIcon(iconPropertyInfo, expected, TypeDescriptor.GetConverter(typeof(Icon))); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_IconResource_FromMemory() - { - using Icon icon = new(SystemIcons.Exclamation, 16, 16); - var converter = TypeDescriptor.GetConverter(icon); - - ResXDataNode node = new("Icon1", converter.ConvertTo(icon, typeof(byte[]))); - using var temp = TempFile.Create(); - using (ResXResourceWriter resxWriter = new(temp.Path)) - { - resxWriter.AddResource(node); - resxWriter.Generate(); - } - - var compileUnit = StronglyTypedResourceBuilder.Create( - resxFile: temp.Path, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using ResXResourceReader reader = new(temp.Path); - var iconPropertyInfo = CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "Icon1"); - ValidateResultIcon(iconPropertyInfo, icon, converter); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_IconResource_FromFileRef() - { - ResXFileRef fileRef = new(@"Resources\Icon1.ico", $"System.Byte[], {TypeAssembly}"); - Hashtable values = new() - { - { "Icon1", new ResXDataNode("Icon1", fileRef) } - }; - - var compileUnit = StronglyTypedResourceBuilder.Create( - resourceList: values, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using MemoryStream resxStream = new(); - using ResXResourceWriter resxWriter = new(resxStream); - resxWriter.AddResource(new ResXDataNode("Icon1", fileRef)); - resxWriter.Generate(); - resxStream.Position = 0; - using ResXResourceReader reader = new(resxStream); - var iconPropertyInfo = CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "Icon1"); - using Icon expected = new(@"Resources\Icon1.ico"); - ValidateResultIcon(iconPropertyInfo, expected, TypeDescriptor.GetConverter(typeof(Icon))); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_TxtFileResource_FromFile() - { - const string data = $""" - - Resources\TextFile1.txt;System.String, {TypeAssembly};{TxtFileEncoding} - - """; - - using var temp = TempFile.Create(ResxHelper.CreateResx(data)); - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - - var compileUnit = StronglyTypedResourceBuilder.Create( - resxFile: temp.Path, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using ResXResourceReader reader = new(temp.Path); - ValidateResultTxtFileContent(CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "TextFile1")); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_TxtFileResource_FromFileRef() - { - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - ResXFileRef fileRef = new( - @"Resources\TextFile1.txt", - $"System.String, {TypeAssembly}", - Encoding.GetEncoding(TxtFileEncoding)); - Hashtable values = new() - { - { "TextFile1", new ResXDataNode("TextFile1", fileRef) } - }; - - var compileUnit = StronglyTypedResourceBuilder.Create( - resourceList: values, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using MemoryStream resxStream = new(); - using ResXResourceWriter resxWriter = new(resxStream); - resxWriter.AddResource(new ResXDataNode("TextFile1", fileRef)); - resxWriter.Generate(); - resxStream.Position = 0; - using ResXResourceReader reader = new(resxStream); - ValidateResultTxtFileContent(CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "TextFile1")); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_AudioResource_FromFile() - { - const string data = $""" - - Resources\Audio1.wav;System.IO.MemoryStream, {TypeAssembly} - - """; - - using var temp = TempFile.Create(ResxHelper.CreateResx(data)); - - var compileUnit = StronglyTypedResourceBuilder.Create( - resxFile: temp.Path, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using ResXResourceReader reader = new(temp.Path); - ValidateResultAudio(CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "Audio1")); - } - - [Fact] - public static void StronglyTypedResourceBuilder_Create_AudioResource_FromFileRef() - { - ResXFileRef fileRef = new(@"Resources\Audio1.wav", $"System.IO.MemoryStream, {TypeAssembly}"); - Hashtable values = new() - { - { "Audio1", new ResXDataNode("Audio1", fileRef) } - }; - - var compileUnit = StronglyTypedResourceBuilder.Create( - resourceList: values, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using MemoryStream resxStream = new(); - using ResXResourceWriter resxWriter = new(resxStream); - resxWriter.AddResource(new ResXDataNode("Audio1", fileRef)); - resxWriter.Generate(); - resxStream.Position = 0; - using ResXResourceReader reader = new(resxStream); - ValidateResultAudio(CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "Audio1")); - } - - [Fact] - public static void StronglyTypedResourceBuilder_VerifyResourceName_ValidName() - { - string key = "MyResource"; - string result = StronglyTypedResourceBuilder.VerifyResourceName(key, s_cSharpProvider); - Assert.Equal(key, result); - } - - [Fact] - public static void StronglyTypedResourceBuilder_VerifyResourceName_InvalidName() - { - string key = "Invalid Resource?"; - string result = StronglyTypedResourceBuilder.VerifyResourceName(key, s_cSharpProvider); - Assert.Equal("Invalid_Resource_", result); - } - - [Fact] - public static void StronglyTypedResourceBuilder_VerifyResourceName_NameWithSpaces() - { - string key = "Resource Name"; - string result = StronglyTypedResourceBuilder.VerifyResourceName(key, s_cSharpProvider); - Assert.Equal("Resource_Name", result); - } - - [Fact] - public static void StronglyTypedResourceBuilder_VerifyResourceName_NameStartWithNumber() - { - string key = "1.name"; - string result = StronglyTypedResourceBuilder.VerifyResourceName(key, s_cSharpProvider); - Assert.Equal("_1_name", result); - } - - [Theory] - [MemberData(nameof(ResourceName_TestData))] - public static void StronglyTypedResourceBuilder_VerifyResourceName_NameWithSpecialCharacters(string resourceName, string expectedResult) - { - string result = StronglyTypedResourceBuilder.VerifyResourceName(resourceName, s_cSharpProvider); - Assert.Equal(expectedResult, result); - } - - [WinFormsFact] - public static void StronglyTypedResourceBuilder_Create_AxHost_FromMemory_SerializeWith_StateConverter() - { - // AxHost.StateConverter is not properly registered as a converter for AxHost.State. - // Temporarily register StateConverter as State's converter and test serialization. - TypeConverter converter = TypeDescriptor.GetConverter(typeof(AxHost.State)); - Assert.Equal(typeof(TypeConverter), converter.GetType()); - using var scope = CustomConverter.RegisterConverter(typeof(AxHost.State), new AxHost.StateConverter()); - converter = TypeDescriptor.GetConverter(typeof(AxHost.State)); - Assert.Equal(typeof(AxHost.StateConverter), converter.GetType()); - - using Form form = new(); - using AxWindowsMediaPlayer mediaPlayer = new(); - ((ISupportInitialize)mediaPlayer).BeginInit(); - form.Controls.Add(mediaPlayer); - ((ISupportInitialize)mediaPlayer).EndInit(); - - string expectedUrl = $"{Path.GetTempPath()}testurl1"; - mediaPlayer.URL = expectedUrl; - - ResXDataNode node = new("MediaPlayer1", converter.ConvertTo(mediaPlayer.OcxState, typeof(byte[]))); - using var temp = TempFile.Create(); - using (ResXResourceWriter resxWriter = new(temp.Path)) - { - resxWriter.AddResource(node); - resxWriter.Generate(); - } - - var compileUnit = StronglyTypedResourceBuilder.Create( - resxFile: temp.Path, - baseName: "Resources", - generatedCodeNamespace: "Namespace", - s_cSharpProvider, - internalClass: false, - out _); - - using ResXResourceReader reader = new(temp.Path); - var mediaPlayerPropertyInfo = CompileAndGetPropertyInfo(reader.GetEnumerator(), compileUnit, "MediaPlayer1"); - byte[] resourceByte = Assert.IsType(mediaPlayerPropertyInfo.GetValue(obj: null)); - AxHost.State state = Assert.IsType(converter.ConvertFrom(resourceByte)); - - string changedUrl = $"{Path.GetTempPath()}testurl2"; - mediaPlayer.URL = changedUrl; - Assert.Equal(changedUrl, mediaPlayer.URL); - - mediaPlayer.OcxState = state; - Assert.Equal(expectedUrl, mediaPlayer.URL); - } - - // Utilizes ResourceWriter to save the resources and gets the specified - // PropertyInfo. - private static PropertyInfo CompileAndGetPropertyInfo( - IDictionaryEnumerator resources, - CodeCompileUnit compileUnit, - string propertyName) - { - using MemoryStream resourceStream = new(); - using ResourceWriter resourceWriter = new(resourceStream); - while (resources.MoveNext()) - { - resourceWriter.AddResource((string)resources.Key, resources.Value); - } - - resourceWriter.Generate(); - resourceStream.Position = 0; - - Type type = CodeDomCompileHelper.CompileClass(compileUnit, "Resources", "Namespace", resourceStream); - Assert.NotNull(type); - var propertyInfo = type.GetProperty(propertyName); - Assert.NotNull(propertyInfo); - return propertyInfo; - } - - private static void ValidateResultBitmap(PropertyInfo imagePropertyInfo, Bitmap expected, TypeConverter converter) - { - byte[] resourceBytes = Assert.IsType(imagePropertyInfo.GetValue(obj: null)); - using Bitmap resourceBitmap = Assert.IsType(converter.ConvertFrom(resourceBytes)); - Assert.Equal(expected.Size, resourceBitmap.Size); - Assert.Equal(expected.GetPixel(0, 0), resourceBitmap.GetPixel(0, 0)); - } - - private static void ValidateResultIcon(PropertyInfo iconPropertyInfo, Icon expected, TypeConverter converter) - { - byte[] resourceByte = Assert.IsType(iconPropertyInfo.GetValue(obj: null)); - using Icon resourceIcon = Assert.IsType(converter.ConvertFrom(resourceByte)); - Assert.Equal(expected.Size, resourceIcon.Size); - } - - private static void ValidateResultTxtFileContent(PropertyInfo txtFilePropertyInfo) - { - string resourceTxtFileContents = Assert.IsType(txtFilePropertyInfo.GetValue(obj: null)); - Assert.Equal("hello test\r\n!", resourceTxtFileContents); - } - - private static void ValidateResultAudio(PropertyInfo audioPropertyInfo) - { - using UnmanagedMemoryStream resourceAudio = - Assert.IsType(audioPropertyInfo.GetValue(obj: null)); - var contents = new byte[resourceAudio.Length]; - int pos = (int)(resourceAudio.Position = 0); - while (pos < resourceAudio.Length) - { - pos += resourceAudio.Read(contents, pos, (int)(resourceAudio.Length - pos)); - } - - Assert.Equal("HELLO", Encoding.UTF8.GetString(contents)); - } - - public static IEnumerable ResourceName_TestData() - { - yield return new object[] { "Image#Jpeg", "Image_Jpeg" }; - yield return new object[] { "Generate &method", "Generate__method" }; - yield return new object[] { "'%s' in this scope", "__s__in_this_scope" }; - yield return new object[] { "{ ... }", "_______" }; - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/AnchorEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/AnchorEditorTests.cs deleted file mode 100644 index 9939f1057c6..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/AnchorEditorTests.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing.Design; -using Moq; -using System.Windows.Forms.TestUtilities; -using System.Reflection; - -namespace System.Windows.Forms.Design.Tests; - -public class AnchorEditorTests -{ - [Fact] - public void AnchorEditor_Ctor_Default() - { - AnchorEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - public static IEnumerable EditValue_TestData() - { - yield return new object[] { null }; - yield return new object[] { "value" }; - yield return new object[] { AnchorStyles.Top }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(EditValue_TestData))] - public void AnchorEditor_EditValue_ValidProvider_ReturnsValue(object value) - { - AnchorEditor editor = new(); - Mock mockEditorService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object) - .Verifiable(); - mockEditorService - .Setup(e => e.DropDownControl(It.IsAny())) - .Verifiable(); - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Once()); - mockEditorService.Verify(e => e.DropDownControl(It.IsAny()), Times.Once()); - - // Edit again. - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void AnchorEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - AnchorEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void AnchorEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - AnchorEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.DropDown, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void AnchorEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - AnchorEditor editor = new(); - Assert.False(editor.GetPaintValueSupported(context)); - } - - [Theory] - [InlineData("left")] - [InlineData("right")] - [InlineData("top")] - [InlineData("bottom")] - public void AnchorEditor_AnchorUI_ControlType_IsCheckButton(string fieldName) - { - AnchorEditor editor = new(); - Type type = editor.GetType() - .GetNestedType("AnchorUI", BindingFlags.NonPublic | BindingFlags.Instance); - var anchorUI = (Control)Activator.CreateInstance(type, new object[] { editor }); - var item = (Control)anchorUI.GetType() - .GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(anchorUI); - - object actual = item.AccessibilityObject.TestAccessor().Dynamic - .GetPropertyValue(Interop.UiaCore.UIA.ControlTypePropertyId); - - Assert.Equal(Interop.UiaCore.UIA.CheckBoxControlTypeId, actual); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/Behavior/BehaviorDragDropEventArgsTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/Behavior/BehaviorDragDropEventArgsTests.cs deleted file mode 100644 index 7f0732ab4ac..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/Behavior/BehaviorDragDropEventArgsTests.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; - -namespace System.Windows.Forms.Design.Behavior.Tests; - -public class BehaviorDragDropEventArgsTests -{ - public static IEnumerable Ctor_ICollection_TestData() - { - yield return new object[] { null }; - yield return new object[] { Array.Empty() }; - yield return new object[] { new object[] { null } }; - } - - [Theory] - [MemberData(nameof(Ctor_ICollection_TestData))] - public void Ctor_ICollection(ICollection components) - { - BehaviorDragDropEventArgs e = new(components); - Assert.Same(components, e.DragComponents); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/Behavior/SnapLineTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/Behavior/SnapLineTests.cs deleted file mode 100644 index ba8e02577fa..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/Behavior/SnapLineTests.cs +++ /dev/null @@ -1,239 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Design.Behavior.Tests; - -public class SnapLineTests -{ - private static string[] s_Margins = new[] { SnapLine.MarginLeft, SnapLine.MarginTop, SnapLine.MarginRight, SnapLine.MarginBottom }; - private static string[] s_Paddings = new[] { SnapLine.PaddingLeft, SnapLine.PaddingTop, SnapLine.PaddingRight, SnapLine.PaddingBottom }; - - private const int DefaultOffset = 123; - private const string DefaultFilter = "filter"; - private const SnapLinePriority DefaultPriority = SnapLinePriority.Medium; - - [Fact] - public void SnapLine_Ctor_type_offset() - { - SnapLine snapLine = new(SnapLineType.Baseline, DefaultOffset); - - Assert.Equal(SnapLineType.Baseline, snapLine.SnapLineType); - Assert.Equal(DefaultOffset, snapLine.Offset); - Assert.Null(snapLine.Filter); - Assert.Equal(SnapLinePriority.Low, snapLine.Priority); - } - - [Fact] - public void SnapLine_Ctor_type_offset_filter() - { - SnapLine snapLine = new(SnapLineType.Baseline, DefaultOffset, DefaultFilter); - - Assert.Equal(SnapLineType.Baseline, snapLine.SnapLineType); - Assert.Equal(DefaultOffset, snapLine.Offset); - Assert.Equal(DefaultFilter, snapLine.Filter); - Assert.Equal(SnapLinePriority.Low, snapLine.Priority); - } - - [Fact] - public void SnapLine_Ctor_type_offset_priority() - { - SnapLine snapLine = new(SnapLineType.Baseline, DefaultOffset, DefaultPriority); - - Assert.Equal(SnapLineType.Baseline, snapLine.SnapLineType); - Assert.Equal(DefaultOffset, snapLine.Offset); - Assert.Null(snapLine.Filter); - Assert.Equal(DefaultPriority, snapLine.Priority); - } - - [Fact] - public void SnapLine_Ctor_type_offset_filter_priority() - { - SnapLine snapLine = new(SnapLineType.Baseline, DefaultOffset, DefaultFilter, DefaultPriority); - - Assert.Equal(SnapLineType.Baseline, snapLine.SnapLineType); - Assert.Equal(DefaultOffset, snapLine.Offset); - Assert.Equal(DefaultFilter, snapLine.Filter); - Assert.Equal(DefaultPriority, snapLine.Priority); - } - - [Theory] - [InlineData(SnapLineType.Top, true)] - [InlineData(SnapLineType.Bottom, true)] - [InlineData(SnapLineType.Horizontal, true)] - [InlineData(SnapLineType.Baseline, true)] - [InlineData(SnapLineType.Left, false)] - [InlineData(SnapLineType.Right, false)] - [InlineData(SnapLineType.Vertical, false)] - public void SnapLine_IsHorizontal(SnapLineType type, bool expected) - { - SnapLine snapLine = new(type, DefaultOffset, DefaultFilter, DefaultPriority); - - Assert.Equal(expected, snapLine.IsHorizontal); - } - - [Theory] - [InlineData(SnapLineType.Top, false)] - [InlineData(SnapLineType.Bottom, false)] - [InlineData(SnapLineType.Horizontal, false)] - [InlineData(SnapLineType.Baseline, false)] - [InlineData(SnapLineType.Left, true)] - [InlineData(SnapLineType.Right, true)] - [InlineData(SnapLineType.Vertical, true)] - public void SnapLine_IsVertical(SnapLineType type, bool expected) - { - SnapLine snapLine = new(type, DefaultOffset, DefaultFilter, DefaultPriority); - - Assert.Equal(expected, snapLine.IsVertical); - } - - public static IEnumerable SnapLineType_Set_TestData() - { - foreach (var type in Enum.GetValues(typeof(SnapLineType))) - { - yield return new[] { type }; - } - } - - [Theory] - [MemberData(nameof(SnapLineType_Set_TestData))] - public void SnapLine_ensure_IsHorizontal_IsVertical_do_not_overlap(SnapLineType type) - { - SnapLine snapLine = new(type, DefaultOffset, DefaultFilter, DefaultPriority); - - Assert.NotEqual(snapLine.IsHorizontal, snapLine.IsVertical); - } - - [Theory] - [InlineData(DefaultOffset, 10, DefaultOffset + 10)] - [InlineData(DefaultOffset, -10, DefaultOffset - 10)] - [InlineData(DefaultOffset, int.MaxValue, /* overflown */-2147483526)] - [InlineData(-DefaultOffset, int.MinValue, /* overflown */2147483525)] - public void SnapLine_AdjustOffset(int offset, int adjustment, int expected) - { - SnapLine snapLine = new(SnapLineType.Baseline, offset, DefaultFilter, DefaultPriority); - - snapLine.AdjustOffset(adjustment); - Assert.Equal(expected, snapLine.Offset); - } - - [Fact] - public void SnapLine_ShouldSnap_should_return_false_if_types_differ() - { - SnapLine snapLine1 = new(SnapLineType.Top, DefaultOffset, DefaultFilter, DefaultPriority); - SnapLine snapLine2 = new(SnapLineType.Baseline, DefaultOffset, DefaultFilter, DefaultPriority); - - Assert.False(SnapLine.ShouldSnap(snapLine1, snapLine2)); - } - - [Fact] - public void SnapLine_ShouldSnap_should_return_true_if_types_equal_and_both_filters_null() - { - SnapLine snapLine1 = new(SnapLineType.Top, DefaultOffset, null, DefaultPriority); - SnapLine snapLine2 = new(SnapLineType.Top, DefaultOffset, null, SnapLinePriority.Low); - - Assert.True(SnapLine.ShouldSnap(snapLine1, snapLine2)); - } - - [Fact] - public void SnapLine_ShouldSnap_should_return_false_if_types_equal_and_one_of_filters_not_null() - { - SnapLine snapLine1 = new(SnapLineType.Top, DefaultOffset, null, DefaultPriority); - SnapLine snapLine2 = new(SnapLineType.Top, DefaultOffset, DefaultFilter, SnapLinePriority.Low); - - Assert.False(SnapLine.ShouldSnap(snapLine1, snapLine2)); - } - - public static IEnumerable SnapLineFilter_Margin_TestData() - { - return EnumerateFilterMarginPaths(SnapLine.MarginRight, SnapLine.MarginLeft, SnapLine.PaddingRight) - .Union(EnumerateFilterMarginPaths(SnapLine.MarginLeft, SnapLine.MarginRight, SnapLine.PaddingLeft)) - .Union(EnumerateFilterMarginPaths(SnapLine.MarginTop, SnapLine.MarginBottom, SnapLine.PaddingTop)) - .Union(EnumerateFilterMarginPaths(SnapLine.MarginBottom, SnapLine.MarginTop, SnapLine.PaddingBottom)); - - static IEnumerable EnumerateFilterMarginPaths(string snapLine1Filter, string snapLine2MarginFilter, string snapLine2PaddingFilter) - { - // happy paths - yield return new object[] { snapLine1Filter, snapLine2MarginFilter, true }; - yield return new object[] { snapLine1Filter, snapLine2PaddingFilter, true }; - - // unhappy paths - foreach (var margin in s_Margins.Except(new[] { snapLine2MarginFilter })) - { - yield return new object[] { snapLine1Filter, margin, false }; - } - - foreach (var margin in s_Paddings.Except(new[] { snapLine2PaddingFilter })) - { - yield return new object[] { snapLine1Filter, margin, false }; - } - } - } - - [Theory] - [MemberData(nameof(SnapLineFilter_Margin_TestData))] - public void SnapLine_ShouldSnap_should_return_expected_if_types_equal_and_filter_contains_margin(string snapLine1Filter, string snapLine2Filter, bool expected) - { - SnapLine snapLine1 = new(SnapLineType.Top, DefaultOffset, snapLine1Filter, DefaultPriority); - SnapLine snapLine2 = new(SnapLineType.Top, DefaultOffset, snapLine2Filter, SnapLinePriority.Low); - - Assert.Equal(expected, SnapLine.ShouldSnap(snapLine1, snapLine2)); - } - - public static IEnumerable SnapLineFilter_Padding_TestData() - { - return EnumerateFilterPaddingPaths(SnapLine.PaddingLeft, SnapLine.MarginLeft) - .Union(EnumerateFilterPaddingPaths(SnapLine.PaddingRight, SnapLine.MarginRight)) - .Union(EnumerateFilterPaddingPaths(SnapLine.PaddingTop, SnapLine.MarginTop)) - .Union(EnumerateFilterPaddingPaths(SnapLine.PaddingBottom, SnapLine.MarginBottom)); - - static IEnumerable EnumerateFilterPaddingPaths(string snapLine1Filter, string snapLine2Filter) - { - // happy paths - yield return new object[] { snapLine1Filter, snapLine2Filter, true }; - - // unhappy paths - foreach (var margin in s_Margins.Except(new[] { snapLine2Filter })) - { - yield return new object[] { snapLine1Filter, margin, false }; - } - } - } - - [Theory] - [MemberData(nameof(SnapLineFilter_Padding_TestData))] - public void SnapLine_ShouldSnap_should_return_expected_if_types_equal_and_filter_contains_padding(string snapLine1Filter, string snapLine2Filter, bool expected) - { - SnapLine snapLine1 = new(SnapLineType.Top, DefaultOffset, snapLine1Filter, DefaultPriority); - SnapLine snapLine2 = new(SnapLineType.Top, DefaultOffset, snapLine2Filter, SnapLinePriority.Low); - - Assert.Equal(expected, SnapLine.ShouldSnap(snapLine1, snapLine2)); - } - - [Fact] - public void SnapLine_ShouldSnap_should_return_true_if_types_equal_and_filters_match() - { - SnapLine snapLine1 = new(SnapLineType.Top, DefaultOffset, "custom filter", DefaultPriority); - SnapLine snapLine2 = new(SnapLineType.Top, DefaultOffset, "custom filter", SnapLinePriority.Low); - - Assert.True(SnapLine.ShouldSnap(snapLine1, snapLine2)); - } - - [Fact] - public void SnapLine_ShouldSnap_should_return_false_if_types_equal_and_filters_not_match() - { - SnapLine snapLine1 = new(SnapLineType.Top, DefaultOffset, "custom filter", DefaultPriority); - SnapLine snapLine2 = new(SnapLineType.Top, DefaultOffset, "another filter", SnapLinePriority.Low); - - Assert.False(SnapLine.ShouldSnap(snapLine1, snapLine2)); - } - - [Theory] - [InlineData(null, "SnapLine: {type = Baseline, offset = 123, priority = Medium, filter = }")] - [InlineData(DefaultFilter, "SnapLine: {type = Baseline, offset = 123, priority = Medium, filter = filter}")] - public void SnapLine_ToString(string filter, string expected) - { - SnapLine snapLine = new(SnapLineType.Baseline, DefaultOffset, filter, DefaultPriority); - - Assert.Equal(expected, snapLine.ToString()); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/BorderSidesEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/BorderSidesEditorTests.cs deleted file mode 100644 index 42579768c40..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/BorderSidesEditorTests.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing.Design; -using Moq; -using System.Windows.Forms.TestUtilities; - -namespace System.Windows.Forms.Design.Tests; - -public class BorderSidesEditorTests -{ - [Fact] - public void BorderSidesEditor_Ctor_Default() - { - BorderSidesEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - public static IEnumerable EditValue_TestData() - { - yield return new object[] { null }; - yield return new object[] { "value" }; - yield return new object[] { ToolStripStatusLabelBorderSides.Top }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(EditValue_TestData))] - public void BorderSidesEditor_EditValue_ValidProvider_ReturnsValue(object value) - { - BorderSidesEditor editor = new(); - Mock mockEditorService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object) - .Verifiable(); - mockEditorService - .Setup(e => e.DropDownControl(It.IsAny())) - .Verifiable(); - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Once()); - mockEditorService.Verify(e => e.DropDownControl(It.IsAny()), Times.Once()); - - // Edit again. - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void BorderSidesEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - BorderSidesEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void BorderSidesEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - BorderSidesEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.DropDown, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void BorderSidesEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - BorderSidesEditor editor = new(); - Assert.False(editor.GetPaintValueSupported(context)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ColumnHeaderCollectionEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ColumnHeaderCollectionEditorTests.cs deleted file mode 100644 index a84da13d0ab..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ColumnHeaderCollectionEditorTests.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Design.Tests; - -public class ColumnHeaderCollectionEditorTests -{ - [Fact] - public void ColumnHeaderCollectionEditor_Ctor_Default() - { - ColumnHeaderCollectionEditor editor = new(typeof(string)); - Assert.False(editor.IsDropDownResizable); - } - - [Fact] - public void ColumnHeaderCollectionEditor_EditValue_ReturnsValue() - { - ColumnHeaderCollectionEditor editor = new(typeof(string)); - string[] value = new string[] { "asdf", "qwer", "zxcv" }; - - Assert.Same(value, editor.EditValue(null, value)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ContentAlignmentEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ContentAlignmentEditorTests.cs deleted file mode 100644 index 0010ebdc11f..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ContentAlignmentEditorTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Design; -using System.Reflection; - -namespace System.Windows.Forms.Design.Tests; - -public class ContentAlignmentEditorTests -{ - [Theory] - [InlineData("_topLeft")] - [InlineData("_topCenter")] - [InlineData("_topRight")] - [InlineData("_middleLeft")] - [InlineData("_middleCenter")] - [InlineData("_middleRight")] - [InlineData("_bottomLeft")] - [InlineData("_bottomCenter")] - [InlineData("_bottomRight")] - public void ContentAlignmentEditor_ContentAlignmentEditor_ContentUI_IsRadioButton(string fieldName) - { - ContentAlignmentEditor editor = new(); - Type type = editor.GetType() - .GetNestedType("ContentUI", BindingFlags.NonPublic | BindingFlags.Instance); - var contentUI = (Control)Activator.CreateInstance(type); - var item = (Control)contentUI.GetType() - .GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(contentUI); - - object actual = item.AccessibilityObject.TestAccessor().Dynamic - .GetPropertyValue(Interop.UiaCore.UIA.ControlTypePropertyId); - - Assert.Equal(Interop.UiaCore.UIA.RadioButtonControlTypeId, actual); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DataGridViewCellStyleEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DataGridViewCellStyleEditorTests.cs deleted file mode 100644 index bab5774d6ad..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DataGridViewCellStyleEditorTests.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Design; - -namespace System.Windows.Forms.Design.Tests; - -public class DataGridViewCellStyleEditorTests -{ - [Fact] - public void DataGridViewCellStyleEditor_Ctor_Default() - { - DataGridViewCellStyleEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - [Fact] - public void DataGridViewCellStyleEditor_GetEditStyle_ReturnsModal() - { - DataGridViewCellStyleEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.Modal, editor.GetEditStyle(null)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DataMemberFieldConverterTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DataMemberFieldConverterTests.cs deleted file mode 100644 index 67797a29721..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DataMemberFieldConverterTests.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace System.Windows.Forms.Design.Tests; - -public class DataMemberFieldConverterTests -{ - private static DataMemberFieldConverter s_converter = new(); - private static ITypeDescriptorContext s_context = new MyTypeDescriptorContext(); - - [Fact] - public static void CanConvertFrom() - { - Assert.True(s_converter.CanConvertFrom(s_context, typeof(string))); - Assert.True(s_converter.CanConvertFrom(s_context, typeof(InstanceDescriptor))); - } - - [Theory] - [InlineData("", "")] - [InlineData(null, null)] - [InlineData("(None)", "")] - public static void ConvertFrom(object actual, object expected) - { - Assert.Equal(expected, s_converter.ConvertFrom(s_context, CultureInfo.CurrentCulture, actual)); - } - - [Theory] - [InlineData("", typeof(string), "(none)")] - [InlineData(null, typeof(string), "(none)")] - [InlineData("FirstName", typeof(string), "FirstName")] - public static void ConvertTo(object actual, Type expectedType, object expected) - { - Assert.Equal(expected, s_converter.ConvertTo(s_context, CultureInfo.CurrentCulture, actual, expectedType)); - } - - [Theory] - [InlineData("", typeof(int))] - [InlineData("FirstName", typeof(int))] - public static void ConvertTo_ThrowsNotSupportedException(object actual, Type expectedType) - { - Assert.Throws( - () => s_converter.ConvertTo(s_context, CultureInfo.CurrentCulture, actual, expectedType)); - } -} - -[Serializable] -public class MyTypeDescriptorContext : ITypeDescriptorContext -{ - public IContainer Container => null; - public object Instance { get { return null; } } - public PropertyDescriptor PropertyDescriptor { get { return null; } } - public bool OnComponentChanging() { return true; } - public void OnComponentChanged() { } - public object GetService(Type serviceType) { return null; } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DesignerOptionsTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DesignerOptionsTests.cs deleted file mode 100644 index 78abd8cce0f..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DesignerOptionsTests.cs +++ /dev/null @@ -1,182 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; - -namespace System.Windows.Forms.Design.Tests; - -public class DesignerOptionsTests -{ - [Fact] - public void DesignerOptions_Ctor_Default() - { - DesignerOptions options = new(); - Assert.True(options.EnableInSituEditing); - Assert.Equal(new Size(8, 8), options.GridSize); - Assert.True(options.ObjectBoundSmartTagAutoShow); - Assert.True(options.ShowGrid); - Assert.True(options.SnapToGrid); - Assert.False(options.UseOptimizedCodeGeneration); - Assert.False(options.UseSmartTags); - Assert.False(options.UseSnapLines); - } - - [Theory] - [BoolData] - public void DesignerOptions_EnableInSituEditing_Set_GetReturnsExpected(bool value) - { - DesignerOptions options = new() - { - EnableInSituEditing = value - }; - Assert.Equal(value, options.EnableInSituEditing); - - // Set same. - options.EnableInSituEditing = value; - Assert.Equal(value, options.EnableInSituEditing); - - // Set different. - options.EnableInSituEditing = !value; - Assert.Equal(!value, options.EnableInSituEditing); - } - - public static IEnumerable GridSize_Set_TestData() - { - yield return new object[] { new Size(0, 0), new Size(2, 2) }; - yield return new object[] { new Size(0, 2), new Size(2, 2) }; - yield return new object[] { new Size(2, 0), new Size(2, 2) }; - yield return new object[] { new Size(2, 2), new Size(2, 2) }; - yield return new object[] { new Size(200, 200), new Size(200, 200) }; - yield return new object[] { new Size(201, 200), new Size(200, 200) }; - yield return new object[] { new Size(200, 201), new Size(200, 200) }; - } - - [Theory] - [MemberData(nameof(GridSize_Set_TestData))] - public void DesignerOptions_GridSize_Set_GetReturnsExpected(Size value, Size expected) - { - DesignerOptions options = new() - { - GridSize = value - }; - Assert.Equal(expected, options.GridSize); - - // Set same. - options.GridSize = value; - Assert.Equal(expected, options.GridSize); - } - - [Theory] - [BoolData] - public void DesignerOptions_ObjectBoundSmartTagAutoShow_Set_GetReturnsExpected(bool value) - { - DesignerOptions options = new() - { - ObjectBoundSmartTagAutoShow = value - }; - Assert.Equal(value, options.ObjectBoundSmartTagAutoShow); - - // Set same. - options.ObjectBoundSmartTagAutoShow = value; - Assert.Equal(value, options.ObjectBoundSmartTagAutoShow); - - // Set different. - options.ObjectBoundSmartTagAutoShow = !value; - Assert.Equal(!value, options.ObjectBoundSmartTagAutoShow); - } - - [Theory] - [BoolData] - public void DesignerOptions_ShowGrid_Set_GetReturnsExpected(bool value) - { - DesignerOptions options = new() - { - ShowGrid = value - }; - Assert.Equal(value, options.ShowGrid); - - // Set same. - options.ShowGrid = value; - Assert.Equal(value, options.ShowGrid); - - // Set different. - options.ShowGrid = !value; - Assert.Equal(!value, options.ShowGrid); - } - - [Theory] - [BoolData] - public void DesignerOptions_SnapToGrid_Set_GetReturnsExpected(bool value) - { - DesignerOptions options = new() - { - SnapToGrid = value - }; - Assert.Equal(value, options.SnapToGrid); - - // Set same. - options.SnapToGrid = value; - Assert.Equal(value, options.SnapToGrid); - - // Set different. - options.SnapToGrid = !value; - Assert.Equal(!value, options.SnapToGrid); - } - - [Theory] - [BoolData] - public void DesignerOptions_UseOptimizedCodeGeneration_Set_GetReturnsExpected(bool value) - { - DesignerOptions options = new() - { - UseOptimizedCodeGeneration = value - }; - Assert.Equal(value, options.UseOptimizedCodeGeneration); - - // Set same. - options.UseOptimizedCodeGeneration = value; - Assert.Equal(value, options.UseOptimizedCodeGeneration); - - // Set different. - options.UseOptimizedCodeGeneration = !value; - Assert.Equal(!value, options.UseOptimizedCodeGeneration); - } - - [Theory] - [BoolData] - public void DesignerOptions_UseSmartTags_Set_GetReturnsExpected(bool value) - { - DesignerOptions options = new() - { - UseSmartTags = value - }; - Assert.Equal(value, options.UseSmartTags); - - // Set same. - options.UseSmartTags = value; - Assert.Equal(value, options.UseSmartTags); - - // Set different. - options.UseSmartTags = !value; - Assert.Equal(!value, options.UseSmartTags); - } - - [Theory] - [BoolData] - public void DesignerOptions_UseSnapLines_Set_GetReturnsExpected(bool value) - { - DesignerOptions options = new() - { - UseSnapLines = value - }; - Assert.Equal(value, options.UseSnapLines); - - // Set same. - options.UseSnapLines = value; - Assert.Equal(value, options.UseSnapLines); - - // Set different. - options.UseSnapLines = !value; - Assert.Equal(!value, options.UseSnapLines); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DockEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DockEditorTests.cs deleted file mode 100644 index 36a2c08d584..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/DockEditorTests.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing.Design; -using Moq; -using System.Windows.Forms.TestUtilities; - -namespace System.Windows.Forms.Design.Tests; - -public class DockEditorTests -{ - [Fact] - public void DockEditor_Ctor_Default() - { - DockEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - public static IEnumerable EditValue_TestData() - { - yield return new object[] { null }; - yield return new object[] { "value" }; - yield return new object[] { DockStyle.Top }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(EditValue_TestData))] - public void DockEditor_EditValue_ValidProvider_ReturnsValue(object value) - { - DockEditor editor = new(); - Mock mockEditorService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object) - .Verifiable(); - mockEditorService - .Setup(e => e.DropDownControl(It.IsAny())) - .Verifiable(); - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Once()); - mockEditorService.Verify(e => e.DropDownControl(It.IsAny()), Times.Once()); - - // Edit again. - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void DockEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - DockEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void DockEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - DockEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.DropDown, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void DockEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - DockEditor editor = new(); - Assert.False(editor.GetPaintValueSupported(context)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/EmbeddedResourceTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/EmbeddedResourceTests.cs deleted file mode 100644 index a918d6a4339..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/EmbeddedResourceTests.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Reflection; - -namespace System.Windows.Forms.Design.Tests; - -public class EmbeddedResourceTests -{ - // Get System.Windows.Forms.Design assembly to verify that it contains all the icons that the code uses. - private readonly Assembly assembly = Assembly.GetAssembly(typeof(AnchorEditor)); - - private static string s_expectedIconNames = """ - System.ComponentModel.Design.Arrow - System.ComponentModel.Design.ComponentEditorPage - System.ComponentModel.Design.DateTimeFormat - System.ComponentModel.Design.DefaultComponent - System.ComponentModel.Design.NumericFormat - System.ComponentModel.Design.OrderImages - System.ComponentModel.Design.SortDown - System.ComponentModel.Design.SortUp - System.ComponentModel.Design.UncheckedBox - System.Windows.Forms.Design.256_1 - System.Windows.Forms.Design.256_2 - System.Windows.Forms.Design.AddNewDataSource - System.Windows.Forms.Design.Behavior.bottomclose - System.Windows.Forms.Design.Behavior.bottomopen - System.Windows.Forms.Design.Behavior.Close_left - System.Windows.Forms.Design.Behavior.DesignerShortcutBox - System.Windows.Forms.Design.Behavior.leftClose - System.Windows.Forms.Design.Behavior.leftOpen - System.Windows.Forms.Design.Behavior.MoverGlyph - System.Windows.Forms.Design.Behavior.Open_left - System.Windows.Forms.Design.Behavior.rightclose - System.Windows.Forms.Design.Behavior.rightopen - System.Windows.Forms.Design.Behavior.topclose - System.Windows.Forms.Design.Behavior.topopen - System.Windows.Forms.Design.BindingFormattingDialog.Arrow - System.Windows.Forms.Design.BindingFormattingDialog.Bound - System.Windows.Forms.Design.BindingFormattingDialog.Unbound - System.Windows.Forms.Design.BoundProperty - System.Windows.Forms.Design.ChildFolder - System.Windows.Forms.Design.classic - System.Windows.Forms.Design.colorful1 - System.Windows.Forms.Design.DataGridViewColumnsDialog.delete - System.Windows.Forms.Design.DataGridViewColumnsDialog.moveDown - System.Windows.Forms.Design.DataGridViewColumnsDialog.moveUp - System.Windows.Forms.Design.DataGridViewColumnsDialog.selectedColumns - System.Windows.Forms.Design.DataPickerImages - System.Windows.Forms.Design.default - System.Windows.Forms.Design.Delete - System.Windows.Forms.Design.DummyNodeImage - System.Windows.Forms.Design.Folder - System.Windows.Forms.Design.ImageEditor - System.Windows.Forms.Design.InheritedGlyph - System.Windows.Forms.Design.InsertableObject - System.Windows.Forms.Design.Professional1 - System.Windows.Forms.Design.Professional2 - System.Windows.Forms.Design.ToolStripTemplateNode - System.Windows.Forms.Design.UserControlToolboxItem - """; - - public static TheoryData ExpectedIconNames() - => s_expectedIconNames.Split(Environment.NewLine).ToTheoryData(); - - [Theory] - [MemberData(nameof(ExpectedIconNames))] - public void EmbeddedResource_ResourcesExist_Icon(string resourceName) - { - using Stream stream = assembly.GetManifestResourceStream(resourceName); - Assert.NotNull(stream); - - using Icon icon = new(stream); - Assert.NotNull(icon); - } - - private const string expectedResourceNames = """ - System.ComponentModel.Design.BinaryEditor.resources - System.ComponentModel.Design.CollectionEditor.resources - System.SR.resources - System.Windows.Forms.Design.BorderSidesEditor.resources - System.Windows.Forms.Design.colordlg.data - System.Windows.Forms.Design.FormatControl.resources - System.Windows.Forms.Design.LinkAreaEditor.resources - System.Windows.Forms.Design.MaskDesignerDialog.resources - System.Windows.Forms.Design.ShortcutKeysEditor.resources - System.Windows.Forms.Design.StringCollectionEditor.resources - """; - - [Fact] - public void EmbeddedResource_VerifyList() - { - string[] actual = assembly.GetManifestResourceNames(); - Array.Sort(actual, StringComparer.Ordinal); - - string[] expected = $"{s_expectedIconNames}{Environment.NewLine}{expectedResourceNames}".Split(Environment.NewLine); - Array.Sort(expected, StringComparer.Ordinal); - - AssertExtensions.Equal(expected, actual); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/EventHandlerServiceTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/EventHandlerServiceTests.cs deleted file mode 100644 index 6531eb20d8b..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/EventHandlerServiceTests.cs +++ /dev/null @@ -1,181 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Design.Tests; - -public class EventHandlerServiceTests -{ - [Fact] - public void ctor_should_set_FocusWindow() - { - EventHandlerService service = new(null); - Assert.Null(service.FocusWindow); - - using Control focusWnd = new(); - service = new EventHandlerService(focusWnd); - Assert.Same(focusWnd, service.FocusWindow); - } - - [Fact] - public void GetHandler_should_throw_if_handlerType_null() - { - EventHandlerService service = new(null); - - Assert.Throws(() => service.GetHandler(null)); - } - - [Fact] - public void GetHandler_should_return_null_if_no_handlers() - { - EventHandlerService service = new(null); - - Assert.Null(service.GetHandler(typeof(object))); - } - - [Fact] - public void GetHandler_should_return_last_inserted_handler_of_type() - { - EventHandlerService service = new(null); - service.PushHandler(new A()); - - object second = new A(); - service.PushHandler(second); - - Assert.Same(second, service.GetHandler(typeof(A))); - } - - [Fact] - public void GetHandler_should_not_remove_from_handlers() - { - EventHandlerService service = new(null); - A a = new A(); - service.PushHandler(a); - - var foundHandler = service.GetHandler(typeof(A)); - Assert.Same(a, foundHandler); - foundHandler = service.GetHandler(typeof(A)); - Assert.Same(a, foundHandler); - } - - [Fact] - public void GetHandler_should_return_derived_handler_if_found() - { - EventHandlerService service = new(null); - A a = new A(); - service.PushHandler(a); - B b = new B(); - service.PushHandler(b); - - var foundHandler = service.GetHandler(typeof(A)); - - Assert.Same(b, foundHandler); - } - - [Fact] - public void GetHandler_should_return_null_if_handler_type_not_found() - { - EventHandlerService service = new(null); - service.PushHandler("Handler"); - - // PopHandler asserts when an item isn't found - using (new NoAssertContext()) - { - Assert.Null(service.GetHandler(typeof(int))); - } - } - - [Fact] - public void PopHandler_should_throw_if_handler_null() - { - EventHandlerService service = new(null); - - Assert.Throws(() => service.PopHandler(null)); - } - - [Fact] - public void PopHandler_should_not_throw_if_stack_empty() - { - EventHandlerService service = new(null); - - service.PopHandler(typeof(ComboBox)); - } - - [Fact] - public void PopHandler_should_not_pop_if_handler_not_found_on_stack() - { - EventHandlerService service = new(null); - A a = new A(); - service.PushHandler(a); - - // PopHandler asserts when an item isn't found - using (new NoAssertContext()) - { - service.PopHandler(new B()); - } - - Assert.Same(a, service.GetHandler(typeof(A))); - } - - [Fact] - public void PopHandler_should_pop_if_handler_found_on_stack() - { - EventHandlerService service = new(null); - A a = new A(); - service.PushHandler(a); - service.PopHandler(a); - Assert.Null(service.GetHandler(typeof(A))); - } - - [Fact] - public void PopHandler_should_raise_changedEvent_if_handler_found_on_stack() - { - EventHandlerService service = new(null); - - A a = new A(); - service.PushHandler(a); - - int callCount = 0; - service.EventHandlerChanged += (s, e) => { callCount++; }; - - service.PopHandler(a); - - Assert.Equal(1, callCount); - } - - [Fact] - public void PushHandler_should_throw_if_handler_null() - { - EventHandlerService service = new(null); - - Assert.Throws(() => service.PushHandler(null)); - } - - [Fact] - public void PushHandler_should_set_handlerHead_to_new_handler() - { - EventHandlerService service = new(null); - - A a1 = new A(); - service.PushHandler(a1); - A a2 = new A(); - service.PushHandler(a2); - - Assert.Same(a2, service.GetHandler(typeof(A))); - } - - [Fact] - public void PushHandler_should_raise_changedEvent_for_new_handler() - { - EventHandlerService service = new(null); - A a = new(); - int callCount = 0; - service.EventHandlerChanged += (s, e) => { callCount++; }; - - service.PushHandler(a); - - Assert.Equal(1, callCount); - } - - private class A { } - private class B : A { } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/FileNameEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/FileNameEditorTests.cs deleted file mode 100644 index d57065cc32e..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/FileNameEditorTests.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing.Design; -using System.Windows.Forms.TestUtilities; - -namespace System.Windows.Forms.Design.Tests; - -public class FileNameEditorTests -{ - [Fact] - public void FileNameEditor_Ctor_Default() - { - FileNameEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void FileNameEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - FileNameEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void FileNameEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - FileNameEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.Modal, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void FileNameEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - FileNameEditor editor = new(); - Assert.False(editor.GetPaintValueSupported(context)); - } - - [Fact] - public void FileNameEditor_InitializeDialog_Invoke_Success() - { - SubFileNameEditor editor = new(); - using (OpenFileDialog openFileDialog = new()) - { - editor.InitializeDialog(openFileDialog); - Assert.Equal("All Files(*.*)|*.*", openFileDialog.Filter); - Assert.Equal("Open File", openFileDialog.Title); - } - } - - [Fact] - public void FileNameEditor_InitializeDialog_NullOpenFileDialog_ThrowsArgumentNullException() - { - SubFileNameEditor editor = new(); - Assert.Throws("openFileDialog", () => editor.InitializeDialog(null)); - } - - private class SubFileNameEditor : FileNameEditor - { - public new void InitializeDialog(OpenFileDialog openFileDialog) => base.InitializeDialog(openFileDialog); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/FolderNameEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/FolderNameEditorTests.cs deleted file mode 100644 index d53cef3a678..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/FolderNameEditorTests.cs +++ /dev/null @@ -1,106 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing.Design; -using System.Windows.Forms.TestUtilities; - -namespace System.Windows.Forms.Design.Tests; - -public class FolderNameEditorTests -{ - [Fact] - public void FolderNameEditor_Ctor_Default() - { - FileNameEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void FolderNameEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - FolderNameEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.Modal, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void FolderNameEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - FolderNameEditor editor = new(); - Assert.False(editor.GetPaintValueSupported(context)); - } - - [Fact] - public void FolderNameEditor_InitializeDialog_Invoke_Nop() - { - SubFolderNameEditor editor = new(); - editor.InitializeDialog(); - } - - public class FolderBrowserTests : FolderNameEditor - { - [Fact] - public void FolderBrowser_Ctor_Default() - { - FolderBrowser browser = new(); - Assert.Empty(browser.DirectoryPath); - Assert.Empty(browser.Description); - Assert.Equal(FolderBrowserStyles.RestrictToFilesystem, browser.Style); - Assert.Equal(FolderBrowserFolder.Desktop, browser.StartLocation); - } - - [Theory] - [NormalizedStringData] - public void FolderBrowser_Description_Set_GetReturnsExpected(string value, string expected) - { - FolderBrowser browser = new() - { - Description = value - }; - Assert.Equal(expected, browser.Description); - - // Set same. - browser.Description = value; - Assert.Equal(expected, browser.Description); - } - - [Theory] - [EnumData] - [InvalidEnumData] - protected void FolderBrowser_StartLocation_Set_GetReturnsExpected(FolderBrowserFolder value) - { - FolderBrowser browser = new() - { - StartLocation = value - }; - Assert.Equal(value, browser.StartLocation); - - // Set same. - browser.StartLocation = value; - Assert.Equal(value, browser.StartLocation); - } - - [Theory] - [EnumData] - [InvalidEnumData] - protected void FolderBrowser_Style_Set_GetReturnsExpected(FolderBrowserStyles value) - { - FolderBrowser browser = new() - { - Style = value - }; - Assert.Equal(value, browser.Style); - - // Set same. - browser.Style = value; - Assert.Equal(value, browser.Style); - } - } - - private class SubFolderNameEditor : FolderNameEditor - { - public void InitializeDialog() => base.InitializeDialog(null); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ImageListImageEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ImageListImageEditorTests.cs deleted file mode 100644 index 991eb3c6a6d..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ImageListImageEditorTests.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Drawing.Imaging; - -namespace System.Windows.Forms.Design.Tests; - -public class ImageListImageEditorTests -{ - [Fact] - public void ImageListImageEditor_LoadImageFromStream_BitmapStream_ReturnsExpected() - { - ImageListImageEditor editor = new(); - var editor_LoadImageFromStream = editor.TestAccessor().CreateDelegate>("LoadImageFromStream"); - - using MemoryStream stream = new(); - using Bitmap image = new(10, 10); - image.Save(stream, ImageFormat.Bmp); - stream.Position = 0; - - var result = Assert.IsType(editor_LoadImageFromStream(stream, false)); - var resultImage = Assert.IsType(result.Image); - Assert.Equal(new Size(10, 10), result.Size); - Assert.Equal(new Size(10, 10), resultImage.Size); - - using MemoryStream resultStream = new(); - result.Image.Save(resultStream, ImageFormat.Bmp); - Assert.Equal(stream.Length, resultStream.Length); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/MenuCommandsTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/MenuCommandsTests.cs deleted file mode 100644 index 2866b979514..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/MenuCommandsTests.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design; - -namespace System.Windows.Forms.Design.Tests; - -public class MenuCommandsTests -{ - [Fact] - public void MenuCommands_Ctor_Default() - { - // Make sure it doesn't throw. - new MenuCommands(); - } - - public static IEnumerable Commands_TestData() - { - yield return new object[] { MenuCommands.ComponentTrayMenu, new CommandID(new Guid("74d21312-2aee-11d1-8bfb-00a0c90f26f7"), 1286) }; - yield return new object[] { MenuCommands.ContainerMenu, new CommandID(new Guid("74d21312-2aee-11d1-8bfb-00a0c90f26f7"), 1281) }; - yield return new object[] { MenuCommands.DesignerProperties, new CommandID(new Guid("74d21313-2aee-11d1-8bfb-00a0c90f26f7"), 4097) }; - yield return new object[] { MenuCommands.EditLabel, new CommandID(new Guid("5efc7975-14bc-11cf-9b2b-00aa00573819"), 338) }; - yield return new object[] { MenuCommands.KeyCancel, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 103) }; - yield return new object[] { MenuCommands.KeyDefaultAction, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 3) }; - yield return new object[] { MenuCommands.KeyEnd, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 17) }; - yield return new object[] { MenuCommands.KeyHome, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 15) }; - yield return new object[] { MenuCommands.KeyInvokeSmartTag, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 147) }; - yield return new object[] { MenuCommands.KeyMoveDown, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 13) }; - yield return new object[] { MenuCommands.KeyMoveLeft, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 7) }; - yield return new object[] { MenuCommands.KeyMoveRight, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 9) }; - yield return new object[] { MenuCommands.KeyMoveUp, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 11) }; - yield return new object[] { MenuCommands.KeyNudgeDown, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 1225) }; - yield return new object[] { MenuCommands.KeyNudgeHeightDecrease, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 1229) }; - yield return new object[] { MenuCommands.KeyNudgeHeightIncrease, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 1228) }; - yield return new object[] { MenuCommands.KeyNudgeLeft, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 1224) }; - yield return new object[] { MenuCommands.KeyNudgeRight, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 1226) }; - yield return new object[] { MenuCommands.KeyNudgeUp, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 1227) }; - yield return new object[] { MenuCommands.KeyNudgeWidthDecrease, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 1230) }; - yield return new object[] { MenuCommands.KeyNudgeWidthDecrease, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 1230) }; - yield return new object[] { MenuCommands.KeyNudgeHeightIncrease, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 1228) }; - yield return new object[] { MenuCommands.KeyReverseCancel, new CommandID(new Guid("74d21313-2aee-11d1-8bfb-00a0c90f26f7"), 16385) }; - yield return new object[] { MenuCommands.KeySelectNext, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 4) }; - yield return new object[] { MenuCommands.KeySelectPrevious, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 5) }; - yield return new object[] { MenuCommands.KeyShiftEnd, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 18) }; - yield return new object[] { MenuCommands.KeyShiftHome, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 16) }; - yield return new object[] { MenuCommands.KeySizeHeightDecrease, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 14) }; - yield return new object[] { MenuCommands.KeySizeHeightIncrease, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 12) }; - yield return new object[] { MenuCommands.KeySizeWidthDecrease, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 8) }; - yield return new object[] { MenuCommands.KeySizeWidthIncrease, new CommandID(new Guid("1496a755-94de-11d0-8c3f-00c04fc2aae2"), 10) }; - yield return new object[] { MenuCommands.KeyTabOrderSelect, new CommandID(new Guid("74d21313-2aee-11d1-8bfb-00a0c90f26f7"), 16405) }; - yield return new object[] { MenuCommands.SelectionMenu, new CommandID(new Guid("74d21312-2aee-11d1-8bfb-00a0c90f26f7"), 1280) }; - yield return new object[] { MenuCommands.SetStatusRectangle, new CommandID(new Guid("74d21313-2aee-11d1-8bfb-00a0c90f26f7"), 16388) }; - yield return new object[] { MenuCommands.SetStatusText, new CommandID(new Guid("74d21313-2aee-11d1-8bfb-00a0c90f26f7"), 16387) }; - yield return new object[] { MenuCommands.TraySelectionMenu, new CommandID(new Guid("74d21312-2aee-11d1-8bfb-00a0c90f26f7"), 1283) }; - } - - [Theory] - [MemberData(nameof(Commands_TestData))] - public void MenuCommands_Commands_Get_ReturnsExpected(CommandID command, CommandID expected) - { - Assert.Equal(expected, command); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ShortcutKeysEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ShortcutKeysEditorTests.cs deleted file mode 100644 index c88e7c454e2..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/ShortcutKeysEditorTests.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing.Design; -using Moq; -using System.Windows.Forms.TestUtilities; - -namespace System.Windows.Forms.Design.Tests; - -public class ShortcutKeysEditorTests -{ - [Fact] - public void ShortcutKeysEditor_Ctor_Default() - { - ShortcutKeysEditor editor = new(); - Assert.False(editor.IsDropDownResizable); - } - - public static IEnumerable EditValue_TestData() - { - yield return new object[] { null }; - yield return new object[] { "value" }; - yield return new object[] { Shortcut.CtrlA }; - yield return new object[] { new object() }; - } - - [Theory] - [MemberData(nameof(EditValue_TestData))] - public void ShortcutKeysEditor_EditValue_ValidProvider_ReturnsValue(object value) - { - ShortcutKeysEditor editor = new(); - Mock mockEditorService = new(MockBehavior.Strict); - Mock mockServiceProvider = new(MockBehavior.Strict); - mockServiceProvider - .Setup(p => p.GetService(typeof(IWindowsFormsEditorService))) - .Returns(mockEditorService.Object) - .Verifiable(); - mockEditorService - .Setup(e => e.DropDownControl(It.IsAny())) - .Verifiable(); - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Once()); - mockEditorService.Verify(e => e.DropDownControl(It.IsAny()), Times.Once()); - - // Edit again. - Assert.Equal(value, editor.EditValue(null, mockServiceProvider.Object, value)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - mockServiceProvider.Verify(p => p.GetService(typeof(IWindowsFormsEditorService)), Times.Exactly(2)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetEditValueInvalidProviderTestData))] - public void ShortcutKeysEditor_EditValue_InvalidProvider_ReturnsValue(IServiceProvider provider, object value) - { - ShortcutKeysEditor editor = new(); - Assert.Same(value, editor.EditValue(null, provider, value)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void ShortcutKeysEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context) - { - ShortcutKeysEditor editor = new(); - Assert.Equal(UITypeEditorEditStyle.DropDown, editor.GetEditStyle(context)); - } - - [Theory] - [CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))] - public void ShortcutKeysEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context) - { - ShortcutKeysEditor editor = new(); - Assert.False(editor.GetPaintValueSupported(context)); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/WindowsFormsDesignerOptionServiceTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/WindowsFormsDesignerOptionServiceTests.cs deleted file mode 100644 index 036585aa9cf..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/WindowsFormsDesignerOptionServiceTests.cs +++ /dev/null @@ -1,125 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.ComponentModel.Design; -using System.Drawing; - -namespace System.Windows.Forms.Design.Tests; - -public class WindowsFormsDesignerOptionServiceTests -{ - [Fact] - public void WindowsFormsDesignerOptionService_Ctor_Default() - { - WindowsFormsDesignerOptionService service = new(); - DesignerOptions options = service.CompatibilityOptions; - Assert.True(options.EnableInSituEditing); - Assert.Equal(new Size(8, 8), options.GridSize); - Assert.True(options.ObjectBoundSmartTagAutoShow); - Assert.True(options.ShowGrid); - Assert.True(options.SnapToGrid); - Assert.False(options.UseSmartTags); - Assert.False(options.UseSnapLines); - Assert.False(options.UseOptimizedCodeGeneration); - Assert.Same(options, service.CompatibilityOptions); - } - - [Fact] - public void WindowsFormsDesignerOptionService_Options_Get_ReturnsExpected() - { - WindowsFormsDesignerOptionService service = new(); - Assert.Empty(service.Options.Name); - DesignerOptionService.DesignerOptionCollection childCollection = Assert.IsType(Assert.Single(service.Options)); - Assert.Equal("DesignerOptions", childCollection.Name); - Assert.Same(service.Options, childCollection.Parent); - Assert.Equal(new string[] { "EnableInSituEditing", "GridSize", "ObjectBoundSmartTagAutoShow", "ShowGrid", "SnapToGrid", "UseOptimizedCodeGeneration", "UseSmartTags", "UseSnapLines" }, childCollection.Properties.Sort().Cast().Select(p => p.Name)); - Assert.Empty(childCollection); - } - - [Fact] - public void WindowsFormsDesignerOptionService_Options_GetNullDesignerOptions_ReturnsExpected() - { - NullCompatibilityOptions service = new(); - Assert.Empty(service.Options.Name); - Assert.Empty(service.Options); - } - - [Fact] - public void WindowsFormsDesignerOptionService_PopulateOptionCollection_ValidOptionsFromSameClass_Success() - { - SubWindowsFormsDesignerOptionService service = new(); - service.PopulateOptionCollectionEntry(service.Options); - Assert.Equal(1, service.PopulateOptionCollectionCallCount); - - // Should not retrieve again when accessing Options. - DesignerOptionService.DesignerOptionCollection childCollection = Assert.IsType(Assert.Single(service.Options)); - Assert.Equal(1, service.PopulateOptionCollectionCallCount); - Assert.Equal("DesignerOptions", childCollection.Name); - Assert.Same(service.Options, childCollection.Parent); - Assert.Equal(new string[] { "EnableInSituEditing", "GridSize", "ObjectBoundSmartTagAutoShow", "ShowGrid", "SnapToGrid", "UseOptimizedCodeGeneration", "UseSmartTags", "UseSnapLines" }, childCollection.Properties.Sort().Cast().Select(p => p.Name)); - Assert.Empty(childCollection); - } - - [Fact] - public void WindowsFormsDesignerOptionService_PopulateOptionCollection_ValidOptionsFromOtherClass_Success() - { - SubWindowsFormsDesignerOptionService service = new(); - SubWindowsFormsDesignerOptionService otherService = new(); - service.PopulateOptionCollectionEntry(otherService.Options); - Assert.Equal(1, service.PopulateOptionCollectionCallCount); - - // Should retrieve again when accessing Options. - DesignerOptionService.DesignerOptionCollection childCollection = Assert.IsType(Assert.Single(service.Options)); - Assert.Equal(2, service.PopulateOptionCollectionCallCount); - Assert.Equal("DesignerOptions", childCollection.Name); - Assert.Same(service.Options, childCollection.Parent); - Assert.Equal(new string[] { "EnableInSituEditing", "GridSize", "ObjectBoundSmartTagAutoShow", "ShowGrid", "SnapToGrid", "UseOptimizedCodeGeneration", "UseSmartTags", "UseSnapLines" }, childCollection.Properties.Sort().Cast().Select(p => p.Name)); - Assert.Empty(childCollection); - - DesignerOptionService.DesignerOptionCollection otherChildCollection = Assert.IsType(Assert.Single(service.Options)); - Assert.Equal(0, otherService.PopulateOptionCollectionCallCount); - Assert.Equal("DesignerOptions", otherChildCollection.Name); - Assert.Same(service.Options, otherChildCollection.Parent); - Assert.Equal(new string[] { "EnableInSituEditing", "GridSize", "ObjectBoundSmartTagAutoShow", "ShowGrid", "SnapToGrid", "UseOptimizedCodeGeneration", "UseSmartTags", "UseSnapLines" }, childCollection.Properties.Sort().Cast().Select(p => p.Name)); - Assert.Empty(otherChildCollection); - } - - [Fact] - public void WindowsFormsDesignerOptionService_PopulateOptionCollection_NullOptions_Success() - { - SubWindowsFormsDesignerOptionService service = new(); - service.PopulateOptionCollectionEntry(null); - Assert.Equal(1, service.PopulateOptionCollectionCallCount); - - // Should retrieve again when accessing Options. - DesignerOptionService.DesignerOptionCollection childCollection = Assert.IsType(Assert.Single(service.Options)); - Assert.Equal(2, service.PopulateOptionCollectionCallCount); - Assert.Equal("DesignerOptions", childCollection.Name); - Assert.Same(service.Options, childCollection.Parent); - Assert.Equal(new string[] { "EnableInSituEditing", "GridSize", "ObjectBoundSmartTagAutoShow", "ShowGrid", "SnapToGrid", "UseOptimizedCodeGeneration", "UseSmartTags", "UseSnapLines" }, childCollection.Properties.Sort().Cast().Select(p => p.Name)); - Assert.Empty(childCollection); - Assert.Equal(3, service.PopulateOptionCollectionCallCount); - } - - private class SubWindowsFormsDesignerOptionService : WindowsFormsDesignerOptionService - { - public int PopulateOptionCollectionCallCount { get; set; } - - public void PopulateOptionCollectionEntry(DesignerOptionCollection options) - { - PopulateOptionCollection(options); - } - - protected override void PopulateOptionCollection(DesignerOptionCollection options) - { - PopulateOptionCollectionCallCount++; - base.PopulateOptionCollection(options); - } - } - - private class NullCompatibilityOptions : WindowsFormsDesignerOptionService - { - public override DesignerOptions CompatibilityOptions => null; - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/SystemDesignMetadataReader.cs b/src/System.Windows.Forms.Design/tests/UnitTests/SystemDesignMetadataReader.cs deleted file mode 100644 index 3af622fcc0e..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/SystemDesignMetadataReader.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design; -using System.Reflection; -using System.Reflection.Metadata; -using System.Reflection.PortableExecutable; - -namespace System.Windows.Forms.Design.Editors.Tests; - -internal sealed class SystemDesignMetadataReader -{ - public IReadOnlyList GetExportedTypeNames() - { - // Force load System.Design into the appdomain - DesignSurface designSurface = new(); - IDesigner designer = designSurface.CreateDesigner(new Control(), true); - Assert.NotNull(designer); - - Assembly systemDesign = AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "System.Design"); - - using FileStream fs = new(systemDesign.Location, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - using PEReader peReader = new(fs); - - MetadataReader metadataReader = peReader.GetMetadataReader(); - List typeNames = new(); - - foreach (ExportedTypeHandle typeHandle in metadataReader.ExportedTypes) - { - ExportedType type = metadataReader.GetExportedType(typeHandle); - - string ns = metadataReader.GetString(type.Namespace); - string name = metadataReader.GetString(type.Name); - - typeNames.Add($"{ns}.{name}"); - } - - return typeNames; - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/TestControlDesigner.cs b/src/System.Windows.Forms.Design/tests/UnitTests/TestControlDesigner.cs deleted file mode 100644 index 1f8e465d66d..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/TestControlDesigner.cs +++ /dev/null @@ -1,91 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing; -using System.Windows.Forms.Design.Behavior; - -namespace System.Windows.Forms.Design.Tests; - -internal class TestControlDesigner : ControlDesigner -{ - internal AccessibleObject GetAccessibleObjectField() - { - return accessibilityObj; - } - - internal BehaviorService GetBehaviorServiceProperty() - { - return BehaviorService; - } - - internal bool GetEnableDragRectProperty() - { - return EnableDragRect; - } - - internal IComponent GetParentComponentProperty() - { - return ParentComponent; - } - - internal InheritanceAttribute GetInheritanceAttributeProperty() - { - return InheritanceAttribute; - } - - internal void BaseWndProcMethod(ref Message m) - { - BaseWndProc(ref m); - } - - internal void DefWndProcMethod(ref Message m) - { - DefWndProc(ref m); - } - - internal void DisplayErrorMethod(Exception e) - { - DisplayError(e); - } - - internal void DisposeMethod(bool disposing) - { - Dispose(disposing); - } - - internal bool EnableDesignModeMethod(Control child, string name) - { - return EnableDesignMode(child, name); - } - - internal void EnableDragDropMethod(bool value) - { - EnableDragDrop(value); - } - - internal ControlBodyGlyph GetControlGlyphMethod(GlyphSelectionType selectionType) - { - return GetControlGlyph(selectionType); - } - - internal bool GetHitTestMethod(Point point) - { - return GetHitTest(point); - } - - internal void HookChildControlsMethod(Control firstChild) - { - HookChildControls(firstChild); - } - - internal void OnContextMenuMethod(int x, int y) - { - OnContextMenu(x, y); - } - - internal void OnCreateHandleMethod() - { - OnCreateHandle(); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripDesignerTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripDesignerTests.cs deleted file mode 100644 index fcd98f0bd20..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripDesignerTests.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design; -using System.Windows.Forms.Design.Behavior; -using System.Windows.Forms.Design.Tests.Mocks; -using Moq; - -namespace System.Windows.Forms.Design.Tests; - -public class ToolStripDesignerTests -{ - [WinFormsFact] - public void ToolStripDesigner_AssociatedComponentsTest() - { - using ToolStripDesigner toolStripDesigner = new(); - using ToolStrip toolStrip = new(); - - Mock mockIComponentChangeService = new(MockBehavior.Strict); - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(toolStrip); - mockDesignerHost - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(mockIComponentChangeService.Object); - mockDesignerHost.Setup(s => s.AddService(typeof(ToolStripKeyboardHandlingService), It.IsAny())); - mockDesignerHost.Setup(s => s.AddService(typeof(ISupportInSituService), It.IsAny())); - - var mockSite = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object); - mockSite.Setup(s => s.GetService(typeof(BehaviorService))).Returns(null); - mockSite.Setup(s => s.GetService(typeof(ToolStripAdornerWindowService))).Returns(null); - toolStrip.Site = mockSite.Object; - - toolStripDesigner.Initialize(toolStrip); - - Assert.Empty(toolStripDesigner.AssociatedComponents); - - toolStrip.Items.Add("123"); - toolStrip.Items.Add("abc"); - - Assert.Equal(2, toolStripDesigner.AssociatedComponents.Count); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripDropDownDesignerTest.cs b/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripDropDownDesignerTest.cs deleted file mode 100644 index 3c838cde0f1..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripDropDownDesignerTest.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel.Design; -using System.ComponentModel; -using Moq; -using System.Windows.Forms.Design.Tests.Mocks; - -namespace System.Windows.Forms.Design.Tests; - -public class ToolStripDropDownDesignerTest -{ - [WinFormsFact] - public void ToolStripDropDownDesignerTest_AssociatedComponentsTest() - { - ToolStripDropDownDesigner toolStripDropDownDesigner = new(); - ToolStripDropDown toolStripDropDown = new(); - - Mock mockDesignerHost = new(MockBehavior.Strict); - mockDesignerHost - .Setup(h => h.RootComponent) - .Returns(toolStripDropDown); - mockDesignerHost - .Setup(h => h.Loading) - .Returns(true); - Mock mockComponentChangeService = new(MockBehavior.Strict); - mockDesignerHost - .Setup(s => s.GetService(typeof(IComponentChangeService))) - .Returns(mockComponentChangeService.Object); - mockDesignerHost.Setup(s => s.AddService(It.IsAny(), It.IsAny())); - - Mock mockSite = MockSite.CreateMockSiteWithDesignerHost(mockDesignerHost.Object); - toolStripDropDown.Site = mockSite.Object; - - toolStripDropDownDesigner.Initialize(toolStripDropDown); - - Assert.Empty(toolStripDropDownDesigner.AssociatedComponents); - - toolStripDropDown.Items.Add("123"); - toolStripDropDown.Items.Add("456"); - - Assert.Equal(2, toolStripDropDownDesigner.AssociatedComponents.Count); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripDropDownItemDesignerTest.cs b/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripDropDownItemDesignerTest.cs deleted file mode 100644 index be8816ac49a..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripDropDownItemDesignerTest.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace System.Windows.Forms.Design.Tests; - -public class ToolStripDropDownItemDesignerTest -{ - [WinFormsFact] - public void ToolStripDropDownItemDesignerTest_AssociatedComponentsTest() - { - ToolStripDropDownItemDesigner toolStripDropDownItemDesigner = new(); - ToolStripMenuItem toolStripDropDown = new(); - - toolStripDropDownItemDesigner.Initialize(toolStripDropDown); - - Assert.Empty(toolStripDropDownItemDesigner.AssociatedComponents); - - toolStripDropDown.DropDownItems.Add("123"); - - Assert.Equal(1, toolStripDropDownItemDesigner.AssociatedComponents.Count); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripMenuItemDesignerTest.cs b/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripMenuItemDesignerTest.cs deleted file mode 100644 index f561584c81c..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/ToolStripMenuItemDesignerTest.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Design.Tests; - -public class ToolStripMenuItemDesignerTest -{ - [WinFormsFact] - public void ToolStripMenuItemDesignerTest_AssociatedComponentsTest() - { - ToolStripMenuItemDesigner toolStripMenuItemDesigner = new(); - ToolStripMenuItem toolStripDropDown = new(); - toolStripMenuItemDesigner.Initialize(toolStripDropDown); - - Assert.Empty(toolStripMenuItemDesigner.AssociatedComponents); - - toolStripDropDown.DropDownItems.Add("123"); - - Assert.Equal(1, toolStripMenuItemDesigner.AssociatedComponents.Count); - } -} diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/runtimeconfig.template.json b/src/System.Windows.Forms.Design/tests/UnitTests/runtimeconfig.template.json deleted file mode 100644 index e460762026c..00000000000 --- a/src/System.Windows.Forms.Design/tests/UnitTests/runtimeconfig.template.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "configProperties": { - "TestSwitch.LocalAppContext.DisableCaching": "true", - "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": "false" - } -} \ No newline at end of file diff --git a/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.CCM.cs b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.CCM.cs new file mode 100644 index 00000000000..bdfa45508ab --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.CCM.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class ComCtl32 + { + public enum CCM : uint + { + FIRST = 0x2000, + SETBKCOLOR = FIRST + 1, + SETCOLORSCHEME = FIRST + 2, + GETCOLORSCHEME = FIRST + 3, + GETDROPTARGET = FIRST + 4, + SETUNICODEFORMAT = FIRST + 5, + GETUNICODEFORMAT = FIRST + 6, + SETVERSION = FIRST + 0x7, + GETVERSION = FIRST + 0x8, + SETNOTIFYWINDOW = FIRST + 0x9, + SETWINDOWTHEME = FIRST + 0xB, + DPISCALE = FIRST + 0xC, + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.ICC.cs b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.ICC.cs new file mode 100644 index 00000000000..64517dcfb08 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.ICC.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class ComCtl32 + { + public enum ICC : uint + { + LISTVIEW_CLASSES = 0x00000001, + TREEVIEW_CLASSES = 0x00000002, + BAR_CLASSES = 0x00000004, + TAB_CLASSES = 0x00000008, + UPDOWN_CLASS = 0x00000010, + PROGRESS_CLASS = 0x00000020, + HOTKEY_CLASS = 0x00000040, + ANIMATE_CLASS = 0x00000080, + WIN95_CLASSES = 0x000000FF, + DATE_CLASSES = 0x00000100, + USEREX_CLASSES = 0x00000200, + COOL_CLASSES = 0x00000400, + INTERNET_CLASSES = 0x00000800, + PAGESCROLLER_CLASS = 0x00001000, + NATIVEFNTCTL_CLASS = 0x00002000, + STANDARD_CLASSES = 0x00004000, + LINK_CLASS = 0x00008000, + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.InitCommonControlsEx.cs b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.InitCommonControlsEx.cs new file mode 100644 index 00000000000..298badf4c2e --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.InitCommonControlsEx.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal partial class Interop +{ + internal partial class ComCtl32 + { + [DllImport(Libraries.Comctl32, ExactSpelling = true, EntryPoint = "InitCommonControlsEx")] + private static extern BOOL InitCommonControlsExInternal(ref INITCOMMONCONTROLSEX picce); + + public static BOOL InitCommonControlsEx(ref INITCOMMONCONTROLSEX picce) + { + picce.dwSize = (uint)Marshal.SizeOf(); + return InitCommonControlsExInternal(ref picce); + } + + public struct INITCOMMONCONTROLSEX + { + public uint dwSize; + public ICC dwICC; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTDT.cs b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTDT.cs new file mode 100644 index 00000000000..5f52debc926 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTDT.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class ComCtl32 + { + public enum TTDT : uint + { + AUTOMATIC = 0, + RESHOW = 1, + AUTOPOP = 2, + INITIAL = 3, + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTF.cs b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTF.cs new file mode 100644 index 00000000000..5127c7d63ef --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTF.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class ComCtl32 + { + [Flags] + public enum TTF + { + IDISHWND = 0x0001, + CENTERTIP = 0x0002, + RTLREADING = 0x0004, + SUBCLASS = 0x0010, + TRACK = 0x0020, + ABSOLUTE = 0x0080, + TRANSPARENT = 0x0100, + PARSELINKS = 0x1000, + DI_SETITEM = 0x8000 + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTM.cs b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTM.cs new file mode 100644 index 00000000000..ea0c1250f2a --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTM.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using static Interop.User32; + +internal static partial class Interop +{ + internal static partial class ComCtl32 + { + public enum TTM : uint + { + ACTIVATE = WM.USER + 1, + SETDELAYTIME = WM.USER + 3, + RELAYEVENT = WM.USER + 7, + GETTOOLCOUNT = WM.USER + 13, + WINDOWFROMPOINT = WM.USER + 16, + TRACKACTIVATE = WM.USER + 17, + TRACKPOSITION = WM.USER + 18, + SETTIPBKCOLOR = WM.USER + 19, + SETTIPTEXTCOLOR = WM.USER + 20, + GETDELAYTIME = WM.USER + 21, + GETTIPBKCOLOR = WM.USER + 22, + GETTIPTEXTCOLOR = WM.USER + 23, + SETMAXTIPWIDTH = WM.USER + 24, + GETMAXTIPWIDTH = WM.USER + 25, + SETMARGIN = WM.USER + 26, + GETMARGIN = WM.USER + 27, + POP = WM.USER + 28, + UPDATE = WM.USER + 29, + GETBUBBLESIZE = WM.USER + 30, + ADJUSTRECT = WM.USER + 31, + SETTITLEW = WM.USER + 33, + POPUP = WM.USER + 34, + GETTITLE = WM.USER + 35, + ADDTOOLW = WM.USER + 50, + DELTOOLW = WM.USER + 51, + NEWTOOLRECTW = WM.USER + 52, + GETTOOLINFOW = WM.USER + 53, + SETTOOLINFOW = WM.USER + 54, + HITTESTW = WM.USER + 55, + GETTEXTW = WM.USER + 56, + UPDATETIPTEXTW = WM.USER + 57, + ENUMTOOLSW = WM.USER + 58, + GETCURRENTTOOLW = WM.USER + 59, + GETWINDOWTHEME = CCM.SETWINDOWTHEME, + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTS.cs b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTS.cs new file mode 100644 index 00000000000..e313a5a49ac --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.TTS.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class ComCtl32 + { + [Flags] + public enum TTS : int + { + ALWAYSTIP = 0x01, + NOPREFIX = 0x02, + NOANIMATE = 0x10, + NOFADE = 0x20, + BALLOON = 0x40, + CLOSE = 0x80, + USEVISUALSTYLE = 0x100 + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.WindowClasses.cs b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.WindowClasses.cs new file mode 100644 index 00000000000..ee4306885b5 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/ComCtl32/Interop.WindowClasses.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class ComCtl32 + { + public static class WindowClasses + { + public const string MSFTEDIT_CLASS = "RICHEDIT50W"; + public const string TOOLTIPS_CLASS = "tooltips_class32"; + public const string WC_BUTTON = "Button"; + public const string WC_COMBOBOX = "ComboBox"; + public const string WC_DATETIMEPICK = "SysDateTimePick32"; + public const string WC_EDIT = "Edit"; + public const string WC_LISTBOX = "ListBox"; + public const string WC_LISTVIEW = "SysListView32"; + public const string WC_MONTHCAL = "SysMonthCal32"; + public const string WC_PROGRESS = "msctls_progress32"; + public const string WC_SCROLLBAR = "ScrollBar"; + public const string WC_STATIC = "Static"; + public const string WC_STATUSBAR = "msctls_statusbar32"; + public const string WC_TABCONTROL = "SysTabControl32"; + public const string WC_TOOLBAR = "ToolbarWindow32"; + public const string WC_TREEVIEW = "SysTreeView32"; + public const string WC_TRACKBAR = "msctls_trackbar32"; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.CreateBrushIndirect.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.CreateBrushIndirect.cs new file mode 100644 index 00000000000..fa2f11e82aa --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.CreateBrushIndirect.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + [DllImport(Libraries.Gdi32, ExactSpelling = true, SetLastError = true)] + public static extern HBRUSH CreateBrushIndirect(ref LOGBRUSH lb); + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.DeleteObject.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.DeleteObject.cs new file mode 100644 index 00000000000..ff09b1a20e9 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.DeleteObject.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + [DllImport(Libraries.Gdi32, ExactSpelling = true)] + public static extern BOOL DeleteObject(IntPtr hObject); + + public static BOOL DeleteObject(HGDIOBJ hObject) => DeleteObject(hObject.Handle); + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.GetObjectType.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.GetObjectType.cs new file mode 100644 index 00000000000..5f4c3f47d5c --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.GetObjectType.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + // This does set last error but *only* in one error case that doesn't add any real value. + [DllImport(Libraries.Gdi32, ExactSpelling = true)] + public static extern OBJ GetObjectType(HGDIOBJ h); + + public static OBJ GetObjectType(HandleRef h) + { + OBJ result = GetObjectType((HGDIOBJ)h.Handle); + GC.KeepAlive(h.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.GetRegionData.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.GetRegionData.cs new file mode 100644 index 00000000000..01333c75c5c --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.GetRegionData.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + [DllImport(Libraries.Gdi32, ExactSpelling = true)] + public static extern uint GetRegionData(IntPtr hRgn, uint nCount, IntPtr lpRgnData); + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HBRUSH.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HBRUSH.cs new file mode 100644 index 00000000000..4b0624c5237 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HBRUSH.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + public readonly struct HBRUSH + { + public IntPtr Handle { get; } + + public HBRUSH(IntPtr handle) => Handle = handle; + + public bool IsNull => Handle == IntPtr.Zero; + + public static explicit operator IntPtr(HBRUSH hbrush) => hbrush.Handle; + public static explicit operator HBRUSH(IntPtr hbrush) => new HBRUSH(hbrush); + public static implicit operator HGDIOBJ(HBRUSH hbrush) => new HGDIOBJ(hbrush.Handle); + public static explicit operator HBRUSH(HGDIOBJ hbrush) => new HBRUSH(hbrush.Handle); + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HDC.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HDC.cs new file mode 100644 index 00000000000..22e63ead72b --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HDC.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + [SuppressMessage("Usage", "CA1066:Type {0} should implement IEquatable because it overrides Equals", Justification = "Reason for suppressing")] + internal static partial class Gdi32 + { + public readonly struct HDC + { + public IntPtr Handle { get; } + + public HDC(IntPtr handle) => Handle = handle; + + public bool IsNull => Handle == IntPtr.Zero; + + public static explicit operator IntPtr(HDC hdc) => hdc.Handle; + public static explicit operator HDC(IntPtr hdc) => new HDC(hdc); + public static implicit operator HGDIOBJ(HDC hdc) => new HGDIOBJ(hdc.Handle); + + public static bool operator ==(HDC value1, HDC value2) => value1.Handle == value2.Handle; + public static bool operator !=(HDC value1, HDC value2) => value1.Handle != value2.Handle; + public override bool Equals(object? obj) => obj is HDC hdc && hdc.Handle == Handle; + public override int GetHashCode() => Handle.GetHashCode(); + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HGDIOBJ.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HGDIOBJ.cs new file mode 100644 index 00000000000..645a6a3acc5 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HGDIOBJ.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + [SuppressMessage("Usage", "CA1066:Type {0} should implement IEquatable because it overrides Equals", Justification = "Reason for suppressing")] + internal static partial class Gdi32 + { + public struct HGDIOBJ + { + public IntPtr Handle { get; } + + public HGDIOBJ(IntPtr handle) => Handle = handle; + + public bool IsNull => Handle == IntPtr.Zero; + + public static explicit operator IntPtr(HGDIOBJ hgdiobj) => hgdiobj.Handle; + public static explicit operator HGDIOBJ(IntPtr hgdiobj) => new HGDIOBJ(hgdiobj); + + public static bool operator ==(HGDIOBJ value1, HGDIOBJ value2) => value1.Handle == value2.Handle; + public static bool operator !=(HGDIOBJ value1, HGDIOBJ value2) => value1.Handle != value2.Handle; + public override bool Equals(object? obj) => obj is HGDIOBJ hgdiobj && hgdiobj.Handle == Handle; + public override int GetHashCode() => Handle.GetHashCode(); + + public OBJ ObjectType => GetObjectType(this); + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HRGN.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HRGN.cs new file mode 100644 index 00000000000..b72fac07fed --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.HRGN.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Buffers; + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + public readonly struct HRGN + { + public IntPtr Handle { get; } + + public HRGN(IntPtr handle) => Handle = handle; + + public bool IsNull => Handle == IntPtr.Zero; + + public static implicit operator HGDIOBJ(HRGN hrgn) => new HGDIOBJ(hrgn.Handle); + public static explicit operator IntPtr(HRGN hrgn) => hrgn.Handle; + public static explicit operator HRGN(IntPtr hrgn) => new HRGN(hrgn); + + public unsafe RECT[] GetRegionRects() + { + uint regionDataSize = GetRegionData(Handle, 0, IntPtr.Zero); + if (regionDataSize == 0) + { + return Array.Empty(); + } + + byte[] buffer = ArrayPool.Shared.Rent((int)regionDataSize); + + fixed (byte* b = buffer) + { + if (GetRegionData(Handle, regionDataSize, (IntPtr)b) != regionDataSize) + { + return Array.Empty(); + } + + RECT[] result = RGNDATAHEADER.GetRegionRects((RGNDATAHEADER*)b); + ArrayPool.Shared.Return(buffer); + return result; + } + } + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.OBJ.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.OBJ.cs new file mode 100644 index 00000000000..9f74d55061f --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.OBJ.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + public enum OBJ : int + { + PEN = 1, + BRUSH = 2, + DC = 3, + METADC = 4, + PAL = 5, + FONT = 6, + BITMAP = 7, + REGION = 8, + METAFILE = 9, + MEMDC = 10, + EXTPEN = 11, + ENHMETADC = 12, + ENHMETAFILE = 13, + COLORSPACE = 14 + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.PatBlt.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.PatBlt.cs new file mode 100644 index 00000000000..51114a6d6c6 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.PatBlt.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + [DllImport(Libraries.Gdi32, ExactSpelling = true)] + public static extern BOOL PatBlt(HDC hdc, int x, int y, int w, int h, ROP rop); + + public static BOOL PatBlt(HandleRef hdc, int x, int y, int w, int h, ROP rop) + { + BOOL result = PatBlt((HDC)hdc.Handle, x, y, w, h, rop); + GC.KeepAlive(hdc.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.ROP.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.ROP.cs new file mode 100644 index 00000000000..43f0ff48eae --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.ROP.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + public enum ROP : uint + { + SRCCOPY = 0x00CC0020, // dest = source + SRCPAINT = 0x00EE0086, // dest = source OR dest + SRCAND = 0x008800C6, // dest = source AND dest + SRCINVERT = 0x00660046, // dest = source XOR dest + SRCERASE = 0x00440328, // dest = source AND (NOT dest) + NOTSRCCOPY = 0x00330008, // dest = (NOT source) + NOTSRCERASE = 0x001100A6, // dest = (NOT src) AND (NOT dest) + MERGECOPY = 0x00C000CA, // dest = (source AND pattern) + MERGEPAINT = 0x00BB0226, // dest = (NOT source) OR dest + PATCOPY = 0x00F00021, // dest = pattern + PATPAINT = 0x00FB0A09, // dest = DPSnoo + PATINVERT = 0x005A0049, // dest = pattern XOR dest + DSTINVERT = 0x00550009, // dest = (NOT dest) + BLACKNESS = 0x00000042, // dest = BLACK + WHITENESS = 0x00FF0062 // dest = WHITE + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.RealizePalette.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.RealizePalette.cs new file mode 100644 index 00000000000..85303aa96b1 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.RealizePalette.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + [DllImport(Libraries.Gdi32, ExactSpelling = true)] + public static extern uint RealizePalette(IntPtr hdc); + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.SelectObject.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.SelectObject.cs new file mode 100644 index 00000000000..efe2d753dde --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.SelectObject.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + [DllImport(Libraries.Gdi32, SetLastError = true, ExactSpelling = true)] + public static extern HGDIOBJ SelectObject(HDC hdc, HGDIOBJ h); + + public static HGDIOBJ SelectObject(IHandle hdc, HGDIOBJ h) + { + HGDIOBJ lastObject = SelectObject((HDC)hdc.Handle, h); + GC.KeepAlive(hdc); + return lastObject; + } + + public static HGDIOBJ SelectObject(HandleRef hdc, HGDIOBJ h) + { + HGDIOBJ lastObject = SelectObject((HDC)hdc.Handle, h); + GC.KeepAlive(hdc.Wrapper); + return lastObject; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.SelectPalette.cs b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.SelectPalette.cs new file mode 100644 index 00000000000..baab8127c44 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Gdi32/Interop.SelectPalette.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Gdi32 + { + [DllImport(Libraries.Gdi32, ExactSpelling = true, SetLastError = true)] + public static extern IntPtr SelectPalette(IntPtr hdc, IntPtr hPal, BOOL bForceBkgd); + + public static IntPtr SelectPalette(HandleRef hdc, HandleRef hPal, BOOL bForceBkgd) + { + IntPtr result = SelectPalette(hdc.Handle, hPal.Handle, bForceBkgd); + GC.KeepAlive(hdc.Wrapper); + GC.KeepAlive(hPal.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/IHandle.cs b/src/System.Windows.Forms.Primitives/src/Interop/IHandle.cs index aea69585820..af96942d1aa 100644 --- a/src/System.Windows.Forms.Primitives/src/Interop/IHandle.cs +++ b/src/System.Windows.Forms.Primitives/src/Interop/IHandle.cs @@ -44,3 +44,8 @@ internal interface IHandle where THandle : unmanaged /// object? Wrapper => this; } + +//internal interface IHandle +//{ +// public IntPtr Handle { get; } +//} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Interop.WindowMessages.cs b/src/System.Windows.Forms.Primitives/src/Interop/Interop.WindowMessages.cs new file mode 100644 index 00000000000..f9334539dbb --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Interop.WindowMessages.cs @@ -0,0 +1,252 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + public static class WindowMessages + { + public const int WM_NULL = 0x0000; + public const int WM_CREATE = 0x0001; + public const int WM_DELETEITEM = 0x002D; + public const int WM_DESTROY = 0x0002; + public const int WM_MOVE = 0x0003; + public const int WM_SIZE = 0x0005; + public const int WM_ACTIVATE = 0x0006; + public const int WM_SETFOCUS = 0x0007; + public const int WM_KILLFOCUS = 0x0008; + public const int WM_ENABLE = 0x000A; + public const int WM_SETREDRAW = 0x000B; + public const int WM_SETTEXT = 0x000C; + public const int WM_GETTEXT = 0x000D; + public const int WM_GETTEXTLENGTH = 0x000E; + public const int WM_PAINT = 0x000F; + public const int WM_CLOSE = 0x0010; + public const int WM_QUERYENDSESSION = 0x0011; + public const int WM_QUIT = 0x0012; + public const int WM_QUERYOPEN = 0x0013; + public const int WM_ERASEBKGND = 0x0014; + public const int WM_SYSCOLORCHANGE = 0x0015; + public const int WM_ENDSESSION = 0x0016; + public const int WM_SHOWWINDOW = 0x0018; + public const int WM_WININICHANGE = 0x001A; + public const int WM_SETTINGCHANGE = 0x001A; + public const int WM_DEVMODECHANGE = 0x001B; + public const int WM_ACTIVATEAPP = 0x001C; + public const int WM_FONTCHANGE = 0x001D; + public const int WM_TIMECHANGE = 0x001E; + public const int WM_CANCELMODE = 0x001F; + public const int WM_SETCURSOR = 0x0020; + public const int WM_MOUSEACTIVATE = 0x0021; + public const int WM_CHILDACTIVATE = 0x0022; + public const int WM_QUEUESYNC = 0x0023; + public const int WM_GETMINMAXINFO = 0x0024; + public const int WM_PAINTICON = 0x0026; + public const int WM_ICONERASEBKGND = 0x0027; + public const int WM_NEXTDLGCTL = 0x0028; + public const int WM_SPOOLERSTATUS = 0x002A; + public const int WM_DRAWITEM = 0x002B; + public const int WM_MEASUREITEM = 0x002C; + public const int WM_VKEYTOITEM = 0x002E; + public const int WM_CHARTOITEM = 0x002F; + public const int WM_SETFONT = 0x0030; + public const int WM_GETFONT = 0x0031; + public const int WM_SETHOTKEY = 0x0032; + public const int WM_GETHOTKEY = 0x0033; + public const int WM_QUERYDRAGICON = 0x0037; + public const int WM_COMPAREITEM = 0x0039; + public const int WM_GETOBJECT = 0x003D; + public const int WM_COMPACTING = 0x0041; + public const int WM_COMMNOTIFY = 0x0044; + public const int WM_WINDOWPOSCHANGING = 0x0046; + public const int WM_WINDOWPOSCHANGED = 0x0047; + public const int WM_POWER = 0x0048; + public const int WM_COPYDATA = 0x004A; + public const int WM_CANCELJOURNAL = 0x004B; + public const int WM_NOTIFY = 0x004E; + public const int WM_INPUTLANGCHANGEREQUEST = 0x0050; + public const int WM_INPUTLANGCHANGE = 0x0051; + public const int WM_TCARD = 0x0052; + public const int WM_HELP = 0x0053; + public const int WM_USERCHANGED = 0x0054; + public const int WM_NOTIFYFORMAT = 0x0055; + public const int WM_CONTEXTMENU = 0x007B; + public const int WM_STYLECHANGING = 0x007C; + public const int WM_STYLECHANGED = 0x007D; + public const int WM_DISPLAYCHANGE = 0x007E; + public const int WM_GETICON = 0x007F; + public const int WM_SETICON = 0x0080; + public const int WM_NCCREATE = 0x0081; + public const int WM_NCDESTROY = 0x0082; + public const int WM_NCCALCSIZE = 0x0083; + public const int WM_NCHITTEST = 0x0084; + public const int WM_NCPAINT = 0x0085; + public const int WM_NCACTIVATE = 0x0086; + public const int WM_GETDLGCODE = 0x0087; + public const int WM_NCMOUSEMOVE = 0x00A0; + public const int WM_NCMOUSELEAVE = 0x02A2; + public const int WM_NCLBUTTONDOWN = 0x00A1; + public const int WM_NCLBUTTONUP = 0x00A2; + public const int WM_NCLBUTTONDBLCLK = 0x00A3; + public const int WM_NCRBUTTONDOWN = 0x00A4; + public const int WM_NCRBUTTONUP = 0x00A5; + public const int WM_NCRBUTTONDBLCLK = 0x00A6; + public const int WM_NCMBUTTONDOWN = 0x00A7; + public const int WM_NCMBUTTONUP = 0x00A8; + public const int WM_NCMBUTTONDBLCLK = 0x00A9; + public const int WM_NCXBUTTONDOWN = 0x00AB; + public const int WM_NCXBUTTONUP = 0x00AC; + public const int WM_NCXBUTTONDBLCLK = 0x00AD; + public const int WM_KEYFIRST = 0x0100; + public const int WM_KEYDOWN = 0x0100; + public const int WM_KEYUP = 0x0101; + public const int WM_CHAR = 0x0102; + public const int WM_DEADCHAR = 0x0103; + public const int WM_CTLCOLOR = 0x0019; + public const int WM_SYSKEYDOWN = 0x0104; + public const int WM_SYSKEYUP = 0x0105; + public const int WM_SYSCHAR = 0x0106; + public const int WM_SYSDEADCHAR = 0x0107; + public const int WM_KEYLAST = 0x0108; + public const int WM_IME_STARTCOMPOSITION = 0x010D; + public const int WM_IME_ENDCOMPOSITION = 0x010E; + public const int WM_IME_COMPOSITION = 0x010F; + public const int WM_IME_KEYLAST = 0x010F; + public const int WM_INITDIALOG = 0x0110; + public const int WM_COMMAND = 0x0111; + public const int WM_SYSCOMMAND = 0x0112; + public const int WM_TIMER = 0x0113; + public const int WM_HSCROLL = 0x0114; + public const int WM_VSCROLL = 0x0115; + public const int WM_INITMENU = 0x0116; + public const int WM_INITMENUPOPUP = 0x0117; + public const int WM_MENUSELECT = 0x011F; + public const int WM_MENUCHAR = 0x0120; + public const int WM_ENTERIDLE = 0x0121; + public const int WM_UNINITMENUPOPUP = 0x0125; + public const int WM_CHANGEUISTATE = 0x0127; + public const int WM_UPDATEUISTATE = 0x0128; + public const int WM_QUERYUISTATE = 0x0129; + public const int WM_CTLCOLORMSGBOX = 0x0132; + public const int WM_CTLCOLOREDIT = 0x0133; + public const int WM_CTLCOLORLISTBOX = 0x0134; + public const int WM_CTLCOLORBTN = 0x0135; + public const int WM_CTLCOLORDLG = 0x0136; + public const int WM_CTLCOLORSCROLLBAR = 0x0137; + public const int WM_CTLCOLORSTATIC = 0x0138; + public const int WM_MOUSEFIRST = 0x0200; + public const int WM_MOUSEMOVE = 0x0200; + public const int WM_LBUTTONDOWN = 0x0201; + public const int WM_LBUTTONUP = 0x0202; + public const int WM_LBUTTONDBLCLK = 0x0203; + public const int WM_RBUTTONDOWN = 0x0204; + public const int WM_RBUTTONUP = 0x0205; + public const int WM_RBUTTONDBLCLK = 0x0206; + public const int WM_MBUTTONDOWN = 0x0207; + public const int WM_MBUTTONUP = 0x0208; + public const int WM_MBUTTONDBLCLK = 0x0209; + public const int WM_NCMOUSEHOVER = 0x02A0; + public const int WM_XBUTTONDOWN = 0x020B; + public const int WM_XBUTTONUP = 0x020C; + public const int WM_XBUTTONDBLCLK = 0x020D; + public const int WM_MOUSEWHEEL = 0x020A; + public const int WM_MOUSELAST = 0x020A; + public const int WM_PARENTNOTIFY = 0x0210; + public const int WM_ENTERMENULOOP = 0x0211; + public const int WM_EXITMENULOOP = 0x0212; + public const int WM_NEXTMENU = 0x0213; + public const int WM_SIZING = 0x0214; + public const int WM_CAPTURECHANGED = 0x0215; + public const int WM_MOVING = 0x0216; + public const int WM_POWERBROADCAST = 0x0218; + public const int WM_DEVICECHANGE = 0x0219; + public const int WM_IME_SETCONTEXT = 0x0281; + public const int WM_IME_NOTIFY = 0x0282; + public const int WM_IME_CONTROL = 0x0283; + public const int WM_IME_COMPOSITIONFULL = 0x0284; + public const int WM_IME_SELECT = 0x0285; + public const int WM_IME_CHAR = 0x0286; + public const int WM_IME_KEYDOWN = 0x0290; + public const int WM_IME_KEYUP = 0x0291; + public const int WM_MDICREATE = 0x0220; + public const int WM_MDIDESTROY = 0x0221; + public const int WM_MDIACTIVATE = 0x0222; + public const int WM_MDIRESTORE = 0x0223; + public const int WM_MDINEXT = 0x0224; + public const int WM_MDIMAXIMIZE = 0x0225; + public const int WM_MDITILE = 0x0226; + public const int WM_MDICASCADE = 0x0227; + public const int WM_MDIICONARRANGE = 0x0228; + public const int WM_MDIGETACTIVE = 0x0229; + public const int WM_MDISETMENU = 0x0230; + public const int WM_ENTERSIZEMOVE = 0x0231; + public const int WM_EXITSIZEMOVE = 0x0232; + public const int WM_DROPFILES = 0x0233; + public const int WM_MDIREFRESHMENU = 0x0234; + public const int WM_MOUSEHOVER = 0x02A1; + public const int WM_MOUSELEAVE = 0x02A3; + public const int WM_DPICHANGED = 0x02E0; + public const int WM_GETDPISCALEDSIZE = 0x02E1; + public const int WM_DPICHANGED_BEFOREPARENT = 0x02E2; + public const int WM_DPICHANGED_AFTERPARENT = 0x02E3; + public const int WM_CUT = 0x0300; + public const int WM_COPY = 0x0301; + public const int WM_PASTE = 0x0302; + public const int WM_CLEAR = 0x0303; + public const int WM_UNDO = 0x0304; + public const int WM_RENDERFORMAT = 0x0305; + public const int WM_RENDERALLFORMATS = 0x0306; + public const int WM_DESTROYCLIPBOARD = 0x0307; + public const int WM_DRAWCLIPBOARD = 0x0308; + public const int WM_PAINTCLIPBOARD = 0x0309; + public const int WM_VSCROLLCLIPBOARD = 0x030A; + public const int WM_SIZECLIPBOARD = 0x030B; + public const int WM_ASKCBFORMATNAME = 0x030C; + public const int WM_CHANGECBCHAIN = 0x030D; + public const int WM_HSCROLLCLIPBOARD = 0x030E; + public const int WM_QUERYNEWPALETTE = 0x030F; + public const int WM_PALETTEISCHANGING = 0x0310; + public const int WM_PALETTECHANGED = 0x0311; + public const int WM_HOTKEY = 0x0312; + public const int WM_PRINT = 0x0317; + public const int WM_PRINTCLIENT = 0x0318; + public const int WM_THEMECHANGED = 0x031A; + public const int WM_HANDHELDFIRST = 0x0358; + public const int WM_HANDHELDLAST = 0x035F; + public const int WM_AFXFIRST = 0x0360; + public const int WM_AFXLAST = 0x037F; + public const int WM_PENWINFIRST = 0x0380; + public const int WM_PENWINLAST = 0x038F; + public const int WM_APP = unchecked((int)0x8000); + public const int WM_USER = 0x0400; + public const int WM_REFLECT = WM_USER + 0x1C00; + + public const uint TTM_ACTIVATE = WM_USER + 1; + public const uint TTM_SETDELAYTIME = WM_USER + 3; + public const uint TTM_RELAYEVENT = WM_USER + 7; + public const uint TTM_WINDOWFROMPOINT = WM_USER + 16; + public const uint TTM_TRACKACTIVATE = WM_USER + 17; + public const uint TTM_TRACKPOSITION = WM_USER + 18; + public const uint TTM_SETTIPBKCOLOR = WM_USER + 19; + public const uint TTM_SETTIPTEXTCOLOR = WM_USER + 20; + public const uint TTM_GETDELAYTIME = WM_USER + 21; + public const uint TTM_GETTIPBKCOLOR = WM_USER + 22; + public const uint TTM_GETTIPTEXTCOLOR = WM_USER + 23; + public const uint TTM_SETMAXTIPWIDTH = WM_USER + 24; + public const uint TTM_POP = WM_USER + 28; + public const uint TTM_UPDATE = WM_USER + 29; + public const uint TTM_GETBUBBLESIZE = WM_USER + 30; + public const uint TTM_ADJUSTRECT = WM_USER + 31; + public const uint TTM_SETTITLEW = WM_USER + 33; + public const uint TTM_ADDTOOLW = WM_USER + 50; + public const uint TTM_DELTOOLW = WM_USER + 51; + public const uint TTM_NEWTOOLRECTW = WM_USER + 52; + public const uint TTM_GETTOOLINFOW = WM_USER + 53; + public const uint TTM_SETTOOLINFOW = WM_USER + 54; + public const uint TTM_HITTESTW = WM_USER + 55; + public const uint TTM_GETTEXTW = WM_USER + 56; + public const uint TTM_UPDATETIPTEXTW = WM_USER + 57; + public const uint TTM_ENUMTOOLSW = WM_USER + 58; + public const uint TTM_GETCURRENTTOOLW = WM_USER + 59; + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/Ole32/Interop.DispatchID.cs b/src/System.Windows.Forms.Primitives/src/Interop/Ole32/Interop.DispatchID.cs new file mode 100644 index 00000000000..17c0c500e94 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/Ole32/Interop.DispatchID.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class Ole32 + { + public enum DispatchID : int + { + VALUE = unchecked((int)0x0), + UNKNOWN = unchecked((int)0xFFFFFFFF), + MEMBERID_NIL = UNKNOWN, + PROPERTYPUT = unchecked((int)0xFFFFFFFD), + AUTOSIZE = unchecked((int)0xFFFFFE0C), + BACKCOLOR = unchecked((int)0xFFFFFE0B), + BACKSTYLE = unchecked((int)0xFFFFFE0A), + BORDERCOLOR = unchecked((int)0xFFFFFE09), + BORDERSTYLE = unchecked((int)0xFFFFFE08), + BORDERWIDTH = unchecked((int)0xFFFFFE07), + DRAWMODE = unchecked((int)0xFFFFFE05), + DRAWSTYLE = unchecked((int)0xFFFFFE04), + DRAWWIDTH = unchecked((int)0xFFFFFE03), + FILLCOLOR = unchecked((int)0xFFFFFE02), + FILLSTYLE = unchecked((int)0xFFFFFE01), + FONT = unchecked((int)0xFFFFFE00), + FORECOLOR = unchecked((int)0xFFFFFDFF), + ENABLED = unchecked((int)0xFFFFFDFE), + HWND = unchecked((int)0xFFFFFDFD), + TABSTOP = unchecked((int)0xFFFFFDFC), + TEXT = unchecked((int)0xFFFFFDFB), + CAPTION = unchecked((int)0xFFFFFDFA), + BORDERVISIBLE = unchecked((int)0xFFFFFDF9), + APPEARANCE = unchecked((int)0xFFFFFDF8), + MOUSEPOINTER = unchecked((int)0xFFFFFDF7), + MOUSEICON = unchecked((int)0xFFFFFDF6), + PICTURE = unchecked((int)0xFFFFFDF5), + VALID = unchecked((int)0xFFFFFDF4), + READYSTATE = unchecked((int)0xFFFFFDF3), + REFRESH = unchecked((int)0xFFFFFDDA), + DOCLICK = unchecked((int)0xFFFFFDD9), + ABOUTBOX = unchecked((int)0xFFFFFDD8), + CLICK = unchecked((int)0xFFFFFDA8), + DBLCLICK = unchecked((int)0xFFFFFDA7), + KEYDOWN = unchecked((int)0xFFFFFDA6), + KEYPRESS = unchecked((int)0xFFFFFDA5), + KEYUP = unchecked((int)0xFFFFFDA4), + MOUSEDOWN = unchecked((int)0xFFFFFDA3), + MOUSEMOVE = unchecked((int)0xFFFFFDA2), + MOUSEUP = unchecked((int)0xFFFFFDA1), + ERROREVENT = unchecked((int)0xFFFFFDA0), + RIGHTTOLEFT = unchecked((int)0xFFFFFD9D), + READYSTATECHANGE = unchecked((int)0xFFFFFD9F), + AMBIENT_BACKCOLOR = unchecked((int)0xFFFFFD43), + AMBIENT_DISPLAYNAME = unchecked((int)0xFFFFFD42), + AMBIENT_FONT = unchecked((int)0xFFFFFD41), + AMBIENT_FORECOLOR = unchecked((int)0xFFFFFD40), + AMBIENT_LOCALEID = unchecked((int)0xFFFFFD3F), + AMBIENT_MESSAGEREFLECT = unchecked((int)0xFFFFFD3E), + AMBIENT_SCALEUNITS = unchecked((int)0xFFFFFD3D), + AMBIENT_TEXTALIGN = unchecked((int)0xFFFFFD3C), + AMBIENT_USERMODE = unchecked((int)0xFFFFFD3B), + AMBIENT_UIDEAD = unchecked((int)0xFFFFFD3A), + AMBIENT_SHOWGRABHANDLES = unchecked((int)0xFFFFFD39), + AMBIENT_SHOWHATCHING = unchecked((int)0xFFFFFD38), + AMBIENT_DISPLAYASDEFAULT = unchecked((int)0xFFFFFD37), + AMBIENT_SUPPORTSMNEMONICS = unchecked((int)0xFFFFFD36), + AMBIENT_AUTOCLIP = unchecked((int)0xFFFFFD35), + AMBIENT_APPEARANCE = unchecked((int)0xFFFFFD34), + AMBIENT_PALETTE = unchecked((int)0xFFFFFD2A), + AMBIENT_TRANSFERPRIORITY = unchecked((int)0xFFFFFD28), + AMBIENT_RIGHTTOLEFT = unchecked((int)0xFFFFFD24), + Name = unchecked((int)0xFFFFFCE0), + Delete = unchecked((int)0xFFFFFCDF), + Object = unchecked((int)0xFFFFFCDE), + Parent = unchecked((int)0xFFFFFCDD), + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.CreateMenu.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.CreateMenu.cs new file mode 100644 index 00000000000..a852bee1e20 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.CreateMenu.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern IntPtr CreateMenu(); + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.CreatePopupMenu.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.CreatePopupMenu.cs new file mode 100644 index 00000000000..0073e0ccc36 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.CreatePopupMenu.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern IntPtr CreatePopupMenu(); + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.DCX.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.DCX.cs new file mode 100644 index 00000000000..a2da4cae69f --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.DCX.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class User32 + { + [Flags] + public enum DCX : uint + { + WINDOW = 0x00000001, + CACHE = 0x00000002, + NORESETATTRS = 0x00000004, + CLIPCHILDREN = 0x00000008, + CLIPSIBLINGS = 0x00000010, + PARENTCLIP = 0x00000020, + EXCLUDERGN = 0x00000040, + INTERSECTRGN = 0x00000080, + EXCLUDEUPDATE = 0x00000100, + INTERSECTUPDATE = 0x00000200, + LOCKWINDOWUPDATE = 0x00000400, + USESTYLE = 0x00010000, + VALIDATE = 0x00200000, + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.DRAWITEMSTRUCT.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.DRAWITEMSTRUCT.cs new file mode 100644 index 00000000000..d0e59d5c1bd --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.DRAWITEMSTRUCT.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +internal static partial class Interop +{ + internal static partial class User32 + { + public struct DRAWITEMSTRUCT + { + public ODT CtlType; + public uint CtlID; + public uint itemID; + public ODA itemAction; + public ODS itemState; + public IntPtr hwndItem; + public IntPtr hDC; + public RECT rcItem; + public IntPtr itemData; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.DestroyMenu.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.DestroyMenu.cs new file mode 100644 index 00000000000..8641e30cea9 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.DestroyMenu.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern BOOL DestroyMenu(IntPtr hMenu); + + public static BOOL DestroyMenu(HandleRef hMenu) + { + BOOL result = DestroyMenu(hMenu.Handle); + GC.KeepAlive(hMenu.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetDCEx.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetDCEx.cs new file mode 100644 index 00000000000..13139da3317 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetDCEx.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern Gdi32.HDC GetDCEx(HWND hWnd, IntPtr hrgnClip, DCX flags); + + public static Gdi32.HDC GetDCEx(IHandle hWnd, IntPtr hrgnClip, DCX flags) + { + Gdi32.HDC result = GetDCEx(hWnd.Handle, hrgnClip, flags); + GC.KeepAlive(hWnd); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetMenu.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetMenu.cs new file mode 100644 index 00000000000..8135d735542 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetMenu.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern IntPtr GetMenu(IntPtr hWnd); + + public static IntPtr GetMenu(IHandle hWnd) + { + IntPtr result = GetMenu((IntPtr)hWnd.Handle); + GC.KeepAlive(hWnd); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetMenuItemCount.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetMenuItemCount.cs new file mode 100644 index 00000000000..f9a8ef01e54 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetMenuItemCount.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern int GetMenuItemCount(IntPtr hMenu); + + public static int GetMenuItemCount(HandleRef hMenu) + { + int result = GetMenuItemCount(hMenu.Handle); + GC.KeepAlive(hMenu.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetMenuItemID.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetMenuItemID.cs new file mode 100644 index 00000000000..46a65d700b4 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetMenuItemID.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern int GetMenuItemID(IntPtr hMenu, int nPos); + + public static int GetMenuItemID(HandleRef hMenu, int nPos) + { + int result = GetMenuItemID(hMenu.Handle, nPos); + GC.KeepAlive(hMenu.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetSubMenu.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetSubMenu.cs new file mode 100644 index 00000000000..43be071c4d0 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.GetSubMenu.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern IntPtr GetSubMenu(IntPtr hMenu, int nPos); + + public static IntPtr GetSubMenu(HandleRef hMenu, int nPos) + { + IntPtr result = GetSubMenu(hMenu.Handle, nPos); + GC.KeepAlive(hMenu.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.MEASUREITEMSTRUCT.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.MEASUREITEMSTRUCT.cs new file mode 100644 index 00000000000..bd91a20092e --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.MEASUREITEMSTRUCT.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + public struct MEASUREITEMSTRUCT + { + public ODT CtlType; + public uint CtlID; + public uint itemID; + public uint itemWidth; + public uint itemHeight; + public IntPtr itemData; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.MF.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.MF.cs new file mode 100644 index 00000000000..d35bd253fb0 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.MF.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +internal static partial class Interop +{ + internal static partial class User32 + { + [Flags] + public enum MF : uint + { + INSERT = 0x00000000, + CHANGE = 0x00000080, + APPEND = 0x00000100, + DELETE = 0x00000200, + REMOVE = 0x00001000, + BYCOMMAND = 0x00000000, + BYPOSITION = 0x00000400, + SEPARATOR = 0x00000800, + ENABLED = 0x00000000, + GRAYED = 0x00000001, + DISABLED = 0x00000002, + UNCHECKED = 0x00000000, + CHECKED = 0x00000008, + USECHECKBITMAPS = 0x00000200, + STRING = 0x00000000, + BITMAP = 0x00000004, + OWNERDRAW = 0x00000100, + POPUP = 0x00000010, + MENUBARBREAK = 0x00000020, + MENUBREAK = 0x00000040, + UNHILITE = 0x00000000, + HILITE = 0x00000080, + DEFAULT = 0x00001000, + SYSMENU = 0x00002000, + HELP = 0x00004000, + RIGHTJUSTIFY = 0x00004000, + MOUSESELECT = 0x00008000, + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ODA.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ODA.cs new file mode 100644 index 00000000000..6b6583f93fb --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ODA.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [Flags] + public enum ODA : uint + { + DRAWENTIRE = 0x1, + SELECT = 0x2, + FOCUS = 0x4, + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ODT.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ODT.cs new file mode 100644 index 00000000000..dbf5d8036cb --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ODT.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + public enum ODT : uint + { + MENU = 1, + LISTBOX = 2, + COMBOBOX = 3, + BUTTON = 4, + STATIC = 5, + HEADER = 100, + TAB = 101, + LISTVIEW = 102 + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ReleaseDC.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ReleaseDC.cs new file mode 100644 index 00000000000..79b7bfb09c9 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ReleaseDC.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern int ReleaseDC(IntPtr hWnd, Gdi32.HDC hDC); + + public static int ReleaseDC(HandleRef hWnd, Gdi32.HDC hDC) + { + int result = ReleaseDC(hWnd.Handle, hDC); + GC.KeepAlive(hWnd.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.RemoveMenuItem.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.RemoveMenuItem.cs new file mode 100644 index 00000000000..9b1e4d73fc1 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.RemoveMenuItem.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern BOOL RemoveMenu(IntPtr hMenu, uint uPosition, MF uFlags); + + public static BOOL RemoveMenu(HandleRef hMenu, uint uPosition, MF uFlags) + { + BOOL result = RemoveMenu(hMenu.Handle, uPosition, uFlags); + GC.KeepAlive(hMenu.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SWP.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SWP.cs new file mode 100644 index 00000000000..63c4fc1208e --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SWP.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class User32 + { + [Flags] + public enum SWP : uint + { + NOSIZE = 0x0001, + NOMOVE = 0x0002, + NOZORDER = 0x0004, + NOREDRAW = 0x0008, + NOACTIVATE = 0x0010, + FRAMECHANGED = 0x0020, + SHOWWINDOW = 0x0040, + HIDEWINDOW = 0x0080, + NOCOPYBITS = 0x0100, + NOOWNERZORDER = 0x0200, + NOSENDCHANGING = 0x0400, + DEFERERASE = 0x2000, + ASYNCWINDOWPOS = 0x4000, + DRAWFRAME = FRAMECHANGED, + NOREPOSITION = NOOWNERZORDER + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ScrollSW.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ScrollSW.cs new file mode 100644 index 00000000000..ec7facffc87 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ScrollSW.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class User32 + { + [Flags] + public enum ScrollSW : uint + { + SCROLLCHILDREN = 0x0001, + INVALIDATE = 0x0002, + ERASE = 0x0004, + SMOOTHSCROLL = 0x0010, + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ScrollWindow.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ScrollWindow.cs new file mode 100644 index 00000000000..5b6fa0b420a --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ScrollWindow.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + private static extern BOOL ScrollWindow(HWND hWnd, int nXAmount, int nYAmount, ref RECT rectScrollRegion, ref RECT rectClip); + + public static BOOL ScrollWindow(IHandle hWnd, int nXAmount, int nYAmount, ref RECT rectScrollRegion, ref RECT rectClip) + { + BOOL result = ScrollWindow(hWnd.Handle, nXAmount, nYAmount, ref rectScrollRegion, ref rectClip); + GC.KeepAlive(hWnd); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ScrollWindowEx.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ScrollWindowEx.cs new file mode 100644 index 00000000000..c01cca0546a --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.ScrollWindowEx.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public unsafe static extern int ScrollWindowEx( + IntPtr hWnd, + int dx, + int dy, + RECT* prcScroll, + RECT* prcClip, + IntPtr hrgnUpdate, + RECT* prcUpdate, + ScrollSW flags); + + public unsafe static int ScrollWindowEx( + IHandle hWnd, + int dx, + int dy, + RECT* prcScroll, + RECT* prcClip, + IntPtr hrgnUpdate, + RECT* prcUpdate, + ScrollSW flags) + { + int result = ScrollWindowEx(hWnd.Handle, dx, dy, prcScroll, prcClip, hrgnUpdate, prcUpdate, flags); + GC.KeepAlive(hWnd); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SendMessageW.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SendMessageW.cs new file mode 100644 index 00000000000..0b4e69ea028 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SendMessageW.cs @@ -0,0 +1,114 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern IntPtr SendMessageW( + IntPtr hWnd, + WM Msg, + IntPtr wParam = default, + IntPtr lParam = default); + + public static IntPtr SendMessageW( + HandleRef hWnd, + WM Msg, + IntPtr wParam = default, + IntPtr lParam = default) + { + IntPtr result = SendMessageW(hWnd.Handle, Msg, wParam, lParam); + GC.KeepAlive(hWnd.Wrapper); + return result; + } + + public static IntPtr SendMessageW( + IHandle hWnd, + WM Msg, + IntPtr wParam = default, + IntPtr lParam = default) + { + IntPtr result = SendMessageW((IntPtr)hWnd.Handle, Msg, wParam, lParam); + GC.KeepAlive(hWnd); + return result; + } + + public unsafe static IntPtr SendMessageW( + IntPtr hWnd, + WM Msg, + IntPtr wParam, + string lParam) + { + fixed (char* c = lParam) + { + return SendMessageW(hWnd, Msg, wParam, (IntPtr)(void*)c); + } + } + + public unsafe static IntPtr SendMessageW( + HandleRef hWnd, + WM Msg, + IntPtr wParam, + string lParam) + { + fixed (char* c = lParam) + { + return SendMessageW(hWnd, Msg, wParam, (IntPtr)(void*)c); + } + } + + public unsafe static IntPtr SendMessageW( + IHandle hWnd, + WM Msg, + IntPtr wParam, + string lParam) + { + fixed (char* c = lParam) + { + return SendMessageW(hWnd, Msg, wParam, (IntPtr)(void*)c); + } + } + + public unsafe static IntPtr SendMessageW( + IntPtr hWnd, + WM Msg, + IntPtr wParam, + ref T lParam) where T : unmanaged + { + fixed (void* l = &lParam) + { + return SendMessageW(hWnd, Msg, wParam, (IntPtr)l); + } + } + + public unsafe static IntPtr SendMessageW( + IHandle hWnd, + WM Msg, + IntPtr wParam, + ref T lParam) where T : unmanaged + { + fixed (void* l = &lParam) + { + return SendMessageW(hWnd, Msg, wParam, (IntPtr)l); + } + } + + public unsafe static IntPtr SendMessageW( + IHandle hWnd, + WM Msg, + ref TWParam wParam, + ref TLParam lParam) + where TWParam : unmanaged + where TLParam : unmanaged + { + fixed (void* w = &wParam, l = &lParam) + { + return SendMessageW(hWnd, Msg, (IntPtr)w, (IntPtr)l); + } + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SetMenu.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SetMenu.cs new file mode 100644 index 00000000000..8db6f6421e8 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SetMenu.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public extern static BOOL SetMenu(IntPtr hWnd, IntPtr hMenu); + + public static BOOL SetMenu(IHandle hWnd, IntPtr hMenu) + { + BOOL result = SetMenu((IntPtr)hWnd.Handle, hMenu); + GC.KeepAlive(hWnd); + return result; + } + + public static BOOL SetMenu(IHandle hWnd, HandleRef hMenu) + { + BOOL result = SetMenu((IntPtr)hWnd.Handle, hMenu.Handle); + GC.KeepAlive(hWnd); + GC.KeepAlive(hMenu.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SetMenuDefaultItem.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SetMenuDefaultItem.cs new file mode 100644 index 00000000000..9825fed11e2 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SetMenuDefaultItem.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern BOOL SetMenuDefaultItem(IntPtr hwnd, int uItem, BOOL fByPos); + + public static BOOL SetMenuDefaultItem(HandleRef hwnd, int uItem, BOOL fByPos) + { + BOOL result = SetMenuDefaultItem(hwnd.Handle, uItem, fByPos); + GC.KeepAlive(hwnd.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SetWindowPos.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SetWindowPos.cs new file mode 100644 index 00000000000..3105988f420 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SetWindowPos.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class User32 + { + public static IntPtr HWND_TOP = (IntPtr)0; + public static IntPtr HWND_BOTTOM = (IntPtr)1; + public static IntPtr HWND_TOPMOST = (IntPtr)(-1); + public static IntPtr HWND_NOTOPMOST = (IntPtr)(-2); + public static IntPtr HWND_MESSAGE = (IntPtr)(-3); + + [DllImport(Libraries.User32, ExactSpelling = true)] + public static extern BOOL SetWindowPos( + IntPtr hWnd, + IntPtr hWndInsertAfter, + int x = 0, + int y = 0, + int cx = 0, + int cy = 0, + SWP flags = (SWP)0); + + public static BOOL SetWindowPos( + HandleRef hWnd, + IntPtr hWndInsertAfter, + int x = 0, + int y = 0, + int cx = 0, + int cy = 0, + SWP flags = (SWP)0) + { + BOOL result = SetWindowPos(hWnd.Handle, hWndInsertAfter, x, y, cx, cy, flags); + GC.KeepAlive(hWnd.Wrapper); + return result; + } + + public static BOOL SetWindowPos( + HandleRef hWnd, + HandleRef hWndInsertAfter, + int x = 0, + int y = 0, + int cx = 0, + int cy = 0, + SWP flags = (SWP)0) + { + BOOL result = SetWindowPos(hWnd.Handle, hWndInsertAfter.Handle, x, y, cx, cy, flags); + GC.KeepAlive(hWnd.Wrapper); + GC.KeepAlive(hWndInsertAfter.Wrapper); + return result; + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.WM.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.WM.cs new file mode 100644 index 00000000000..ef5220101fe --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.WM.cs @@ -0,0 +1,289 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +internal static partial class Interop +{ + internal static partial class User32 + { + public enum WM : uint + { + NULL = 0x0000, + CREATE = 0x0001, + DESTROY = 0x0002, + MOVE = 0x0003, + SIZE = 0x0005, + ACTIVATE = 0x0006, + SETFOCUS = 0x0007, + KILLFOCUS = 0x0008, + ENABLE = 0x000A, + SETREDRAW = 0x000B, + SETTEXT = 0x000C, + GETTEXT = 0x000D, + GETTEXTLENGTH = 0x000E, + PAINT = 0x000F, + CLOSE = 0x0010, + QUERYENDSESSION = 0x0011, + QUERYOPEN = 0x0013, + ENDSESSION = 0x0016, + QUIT = 0x0012, + ERASEBKGND = 0x0014, + SYSCOLORCHANGE = 0x0015, + SHOWWINDOW = 0x0018, + CTLCOLOR = 0x0019, + SETTINGCHANGE = 0x001A, + WININICHANGE = 0x001A, + DEVMODECHANGE = 0x001B, + ACTIVATEAPP = 0x001C, + FONTCHANGE = 0x001D, + TIMECHANGE = 0x001E, + CANCELMODE = 0x001F, + SETCURSOR = 0x0020, + MOUSEACTIVATE = 0x0021, + CHILDACTIVATE = 0x0022, + QUEUESYNC = 0x0023, + GETMINMAXINFO = 0x0024, + PAINTICON = 0x0026, + ICONERASEBKGND = 0x0027, + NEXTDLGCTL = 0x0028, + SPOOLERSTATUS = 0x002A, + DRAWITEM = 0x002B, + MEASUREITEM = 0x002C, + DELETEITEM = 0x002D, + VKEYTOITEM = 0x002E, + CHARTOITEM = 0x002F, + SETFONT = 0x0030, + GETFONT = 0x0031, + SETHOTKEY = 0x0032, + GETHOTKEY = 0x0033, + QUERYDRAGICON = 0x0037, + COMPAREITEM = 0x0039, + GETOBJECT = 0x003D, + COMPACTING = 0x0041, + COMMNOTIFY = 0x0044, + WINDOWPOSCHANGING = 0x0046, + WINDOWPOSCHANGED = 0x0047, + POWER = 0x0048, + COPYDATA = 0x004A, + CANCELJOURNAL = 0x004B, + NOTIFY = 0x004E, + INPUTLANGCHANGEREQUEST = 0x0050, + INPUTLANGCHANGE = 0x0051, + TCARD = 0x0052, + HELP = 0x0053, + USERCHANGED = 0x0054, + NOTIFYFORMAT = 0x0055, + CONTEXTMENU = 0x007B, + STYLECHANGING = 0x007C, + STYLECHANGED = 0x007D, + DISPLAYCHANGE = 0x007E, + GETICON = 0x007F, + SETICON = 0x0080, + NCCREATE = 0x0081, + NCDESTROY = 0x0082, + NCCALCSIZE = 0x0083, + NCHITTEST = 0x0084, + NCPAINT = 0x0085, + NCACTIVATE = 0x0086, + GETDLGCODE = 0x0087, + SYNCPAINT = 0x0088, + NCMOUSEMOVE = 0x00A0, + NCLBUTTONDOWN = 0x00A1, + NCLBUTTONUP = 0x00A2, + NCLBUTTONDBLCLK = 0x00A3, + NCRBUTTONDOWN = 0x00A4, + NCRBUTTONUP = 0x00A5, + NCRBUTTONDBLCLK = 0x00A6, + NCMBUTTONDOWN = 0x00A7, + NCMBUTTONUP = 0x00A8, + NCMBUTTONDBLCLK = 0x00A9, + NCXBUTTONDOWN = 0x00AB, + NCXBUTTONUP = 0x00AC, + NCXBUTTONDBLCLK = 0x00AD, + INPUT_DEVICE_CHANGE = 0x00FE, + INPUT = 0x00FF, + KEYFIRST = 0x0100, + KEYDOWN = 0x0100, + KEYUP = 0x0101, + CHAR = 0x0102, + DEADCHAR = 0x0103, + SYSKEYDOWN = 0x0104, + SYSKEYUP = 0x0105, + SYSCHAR = 0x0106, + SYSDEADCHAR = 0x0107, + UNICHAR = 0x0109, + KEYLAST = 0x0109, + IME_STARTCOMPOSITION = 0x010D, + IME_ENDCOMPOSITION = 0x010E, + IME_COMPOSITION = 0x010F, + IME_KEYLAST = 0x010F, + INITDIALOG = 0x0110, + COMMAND = 0x0111, + SYSCOMMAND = 0x0112, + TIMER = 0x0113, + HSCROLL = 0x0114, + VSCROLL = 0x0115, + INITMENU = 0x0116, + INITMENUPOPUP = 0x0117, + GESTURE = 0x0119, + GESTURENOTIFY = 0x011A, + MENUSELECT = 0x011F, + MENUCHAR = 0x0120, + ENTERIDLE = 0x0121, + MENURBUTTONUP = 0x0122, + MENUDRAG = 0x0123, + MENUGETOBJECT = 0x0124, + UNINITMENUPOPUP = 0x0125, + MENUCOMMAND = 0x0126, + CHANGEUISTATE = 0x0127, + UPDATEUISTATE = 0x0128, + QUERYUISTATE = 0x0129, + CTLCOLORMSGBOX = 0x0132, + CTLCOLOREDIT = 0x0133, + CTLCOLORLISTBOX = 0x0134, + CTLCOLORBTN = 0x0135, + CTLCOLORDLG = 0x0136, + CTLCOLORSCROLLBAR = 0x0137, + CTLCOLORSTATIC = 0x0138, + MOUSEFIRST = 0x0200, + MOUSEMOVE = 0x0200, + LBUTTONDOWN = 0x0201, + LBUTTONUP = 0x0202, + LBUTTONDBLCLK = 0x0203, + RBUTTONDOWN = 0x0204, + RBUTTONUP = 0x0205, + RBUTTONDBLCLK = 0x0206, + MBUTTONDOWN = 0x0207, + MBUTTONUP = 0x0208, + MBUTTONDBLCLK = 0x0209, + MOUSEWHEEL = 0x020A, + XBUTTONDOWN = 0x020B, + XBUTTONUP = 0x020C, + XBUTTONDBLCLK = 0x020D, + MOUSEHWHEEL = 0x020E, + MOUSELAST = 0x020E, + PARENTNOTIFY = 0x0210, + ENTERMENULOOP = 0x0211, + EXITMENULOOP = 0x0212, + NEXTMENU = 0x0213, + SIZING = 0x0214, + CAPTURECHANGED = 0x0215, + MOVING = 0x0216, + POWERBROADCAST = 0x0218, + DEVICECHANGE = 0x0219, + MDICREATE = 0x0220, + MDIDESTROY = 0x0221, + MDIACTIVATE = 0x0222, + MDIRESTORE = 0x0223, + MDINEXT = 0x0224, + MDIMAXIMIZE = 0x0225, + MDITILE = 0x0226, + MDICASCADE = 0x0227, + MDIICONARRANGE = 0x0228, + MDIGETACTIVE = 0x0229, + MDISETMENU = 0x0230, + ENTERSIZEMOVE = 0x0231, + EXITSIZEMOVE = 0x0232, + DROPFILES = 0x0233, + MDIREFRESHMENU = 0x0234, + POINTERDEVICECHANGE = 0x0238, + POINTERDEVICEINRANGE = 0x0239, + POINTERDEVICEOUTOFRANGE = 0x023A, + TOUCH = 0x0240, + NCPOINTERUPDATE = 0x0241, + NCPOINTERDOWN = 0x0242, + NCPOINTERUP = 0x0243, + POINTERUPDATE = 0x0245, + POINTERDOWN = 0x0246, + POINTERUP = 0x0247, + POINTERENTER = 0x0249, + POINTERLEAVE = 0x024A, + POINTERACTIVATE = 0x024B, + POINTERCAPTURECHANGED = 0x024C, + TOUCHHITTESTING = 0x024D, + POINTERWHEEL = 0x024E, + POINTERHWHEEL = 0x024F, + POINTERROUTEDTO = 0x0251, + POINTERROUTEDAWAY = 0x0252, + POINTERROUTEDRELEASED = 0x0253, + IME_SETCONTEXT = 0x0281, + IME_NOTIFY = 0x0282, + IME_CONTROL = 0x0283, + IME_COMPOSITIONFULL = 0x0284, + IME_SELECT = 0x0285, + IME_CHAR = 0x0286, + IME_REQUEST = 0x0288, + IME_KEYDOWN = 0x0290, + IME_KEYUP = 0x0291, + MOUSEHOVER = 0x02A1, + MOUSELEAVE = 0x02A3, + NCMOUSEHOVER = 0x02A0, + NCMOUSELEAVE = 0x02A2, + WTSSESSION_CHANGE = 0x02B1, + DPICHANGED = 0x02E0, + DPICHANGED_BEFOREPARENT = 0x02E2, + DPICHANGED_AFTERPARENT = 0x02E3, + GETDPISCALEDSIZE = 0x02E4, + CUT = 0x0300, + COPY = 0x0301, + PASTE = 0x0302, + CLEAR = 0x0303, + UNDO = 0x0304, + RENDERFORMAT = 0x0305, + RENDERALLFORMATS = 0x0306, + DESTROYCLIPBOARD = 0x0307, + DRAWCLIPBOARD = 0x0308, + PAINTCLIPBOARD = 0x0309, + VSCROLLCLIPBOARD = 0x030A, + SIZECLIPBOARD = 0x030B, + ASKCBFORMATNAME = 0x030C, + CHANGECBCHAIN = 0x030D, + HSCROLLCLIPBOARD = 0x030E, + QUERYNEWPALETTE = 0x030F, + PALETTEISCHANGING = 0x0310, + PALETTECHANGED = 0x0311, + HOTKEY = 0x0312, + PRINT = 0x0317, + PRINTCLIENT = 0x0318, + APPCOMMAND = 0x0319, + THEMECHANGED = 0x031A, + CLIPBOARDUPDATE = 0x031D, + DWMCOMPOSITIONCHANGED = 0x031E, + DWMNCRENDERINGCHANGED = 0x031F, + DWMCOLORIZATIONCOLORCHANGED = 0x0320, + DWMWINDOWMAXIMIZEDCHANGE = 0x0321, + DWMSENDICONICTHUMBNAIL = 0x0323, + DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326, + GETTITLEBARINFOEX = 0x033F, + HANDHELDFIRST = 0x0358, + HANDHELDLAST = 0x035F, + AFXFIRST = 0x0360, + AFXLAST = 0x037F, + PENWINFIRST = 0x0380, + PENWINLAST = 0x038F, + USER = 0x0400, + CHOOSEFONT_GETLOGFONT = USER + 1, + APP = 0x8000, + REFLECT = USER + 0x1C00, + + // Messages that are a combination of REFLECT with other messages. + REFLECT_NOTIFY = REFLECT + NOTIFY, + REFLECT_NOTIFYFORMAT = REFLECT + NOTIFYFORMAT, + REFLECT_COMMAND = REFLECT + COMMAND, + REFLECT_CHARTOITEM = REFLECT + CHARTOITEM, + REFLECT_VKEYTOITEM = REFLECT + VKEYTOITEM, + REFLECT_DRAWITEM = REFLECT + DRAWITEM, + REFLECT_MEASUREITEM = REFLECT + MEASUREITEM, + REFLECT_HSCROLL = REFLECT + HSCROLL, + REFLECT_VSCROLL = REFLECT + VSCROLL, + REFLECT_CTLCOLOR = REFLECT + CTLCOLOR, + REFLECT_CTLCOLORBTN = REFLECT + CTLCOLORBTN, + REFLECT_CTLCOLORDLG = REFLECT + CTLCOLORDLG, + REFLECT_CTLCOLORMSGBOX = REFLECT + CTLCOLORMSGBOX, + REFLECT_CTLCOLORSCROLLBAR = REFLECT + CTLCOLORSCROLLBAR, + REFLECT_CTLCOLOREDIT = REFLECT + CTLCOLOREDIT, + REFLECT_CTLCOLORLISTBOX = REFLECT + CTLCOLORLISTBOX, + REFLECT_CTLCOLORSTATIC = REFLECT + CTLCOLORSTATIC + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/Interop/User32/ODS.cs b/src/System.Windows.Forms.Primitives/src/Interop/User32/ODS.cs new file mode 100644 index 00000000000..c6211f1d6f8 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/Interop/User32/ODS.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +internal static partial class Interop +{ + internal static partial class User32 + { + [Flags] + public enum ODS : uint + { + SELECTED = 0x0001, + GRAYED = 0x0002, + DISABLED = 0x0004, + CHECKED = 0x0008, + FOCUS = 0x0010, + DEFAULT = 0x0020, + HOTLIGHT = 0x0040, + INACTIVE = 0x0080, + NOACCEL = 0x0100, + NOFOCUSRECT = 0x0200, + COMBOBOXEDIT = 0x1000, + } + } +} diff --git a/src/System.Windows.Forms.Primitives/src/NativeMethods.txt b/src/System.Windows.Forms.Primitives/src/NativeMethods.txt index 78140b43356..e60c0cb3167 100644 --- a/src/System.Windows.Forms.Primitives/src/NativeMethods.txt +++ b/src/System.Windows.Forms.Primitives/src/NativeMethods.txt @@ -25,6 +25,7 @@ CBN_* CBS_* CCM_* CDM_GETSPEC +CCS_* CDRF_* CHILDID_SELF ChildWindowFromPointEx @@ -517,6 +518,7 @@ NMLVCUSTOMDRAW_ITEM_TYPE NMDATETIMECHANGE_FLAGS NMLVGETINFOTIP_FLAGS NMHDR +NMTBHOTITEM NMTVCUSTOMDRAW NONCLIENTMETRICSW NotifyWinEvent @@ -683,8 +685,11 @@ TASKDIALOG_ICON_ELEMENTS TASKDIALOG_MESSAGES TASKDIALOG_NOTIFICATIONS TB_* +TBN_* TBS_* TBM_* +TBSTATE_* +TBSTYLE_* TCITEMHEADERA_MASK TCM_* TCS_* @@ -698,6 +703,7 @@ TranslateMDISysAccel TranslateMessage TTDT_* TTM_* +TTN_* TTS_* TVGN_* TVITEM_MASK diff --git a/src/System.Windows.Forms.Primitives/src/System.Windows.Forms.Primitives.csproj b/src/System.Windows.Forms.Primitives/src/System.Windows.Forms.Primitives.csproj index f7c99ef9c2c..c9809ed6bfc 100644 --- a/src/System.Windows.Forms.Primitives/src/System.Windows.Forms.Primitives.csproj +++ b/src/System.Windows.Forms.Primitives/src/System.Windows.Forms.Primitives.csproj @@ -1,7 +1,8 @@ - + System.Windows.Forms.Primitives + 8.0.0.0 true true enable @@ -11,7 +12,8 @@ users won't be impacted. If some name becomes difficult to adapt to with the @ symbol we can cross that bridge when we hit it (if ever). --> - $(NoWarn);CS8981;CS3016 + + $(NoWarn);CS8981;CS3016;CA1052;SA1507;CA1805 @@ -34,14 +36,11 @@ - - - - - + + diff --git a/src/System.Windows.Forms.Primitives/src/System/ExternDll.cs b/src/System.Windows.Forms.Primitives/src/System/ExternDll.cs new file mode 100644 index 00000000000..cdeb8547274 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/System/ExternDll.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System +{ + internal static class ExternDll + { + public const string Activeds = "activeds.dll"; + public const string Comctl32 = "comctl32.dll"; + public const string Comdlg32 = "comdlg32.dll"; + public const string Gdi32 = "gdi32.dll"; + public const string Gdiplus = "gdiplus.dll"; + public const string Hhctrl = "hhctrl.ocx"; + public const string Imm32 = "imm32.dll"; + public const string Kernel32 = "kernel32.dll"; + public const string Loadperf = "Loadperf.dll"; + public const string Mscoree = "mscoree.dll"; + public const string Clr = "clr.dll"; + public const string Msi = "msi.dll"; + public const string Mqrt = "mqrt.dll"; + public const string Ntdll = "ntdll.dll"; + public const string Ole32 = "ole32.dll"; + public const string Oleacc = "oleacc.dll"; + public const string Oleaut32 = "oleaut32.dll"; + public const string Olepro32 = "olepro32.dll"; + public const string PerfCounter = "perfcounter.dll"; + public const string Psapi = "psapi.dll"; + public const string Shell32 = "shell32.dll"; + public const string User32 = "user32.dll"; + public const string Uxtheme = "uxtheme.dll"; + public const string WinMM = "winmm.dll"; + public const string Winspool = "winspool.drv"; + public const string Wtsapi32 = "wtsapi32.dll"; + public const string Version = "version.dll"; + public const string Vsassert = "vsassert.dll"; + public const string Fxassert = "Fxassert.dll"; + public const string Crypt32 = "crypt32.dll"; + public const string ShCore = "SHCore.dll"; + public const string Wldp = "wldp.dll"; + + // system.data specific + internal const string Odbc32 = "odbc32.dll"; + internal const string SNI = "System.Data.dll"; + + // system.data.oracleclient specific + internal const string OciDll = "oci.dll"; + internal const string OraMtsDll = "oramts.dll"; + } +} diff --git a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/ClientUtils.cs b/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/ClientUtils.cs index 2a342b6d8e6..43187b3e3a1 100644 --- a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/ClientUtils.cs +++ b/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/ClientUtils.cs @@ -7,6 +7,15 @@ namespace System.Windows.Forms; internal static class ClientUtils { + // Sequential version + // assumes sequential enum members 0,1,2,3,4 -etc. + // + public static bool IsEnumValid(Enum enumValue, int value, int minValue, int maxValue) + { + bool valid = (value >= minValue) && (value <= maxValue); + return valid; + } + private enum CharType { None, diff --git a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/NativeMethods.cs b/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/NativeMethods.cs index 22f134cb63e..29a0ae79401 100644 --- a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/NativeMethods.cs +++ b/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/NativeMethods.cs @@ -10,8 +10,654 @@ internal static class NativeMethods { public delegate IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); + public static HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero); + + public const int WHEEL_DELTA = 120; + + public const string WC_DATETIMEPICK = "SysDateTimePick32", + WC_LISTVIEW = "SysListView32", + WC_MONTHCAL = "SysMonthCal32", + WC_PROGRESS = "msctls_progress32", + WC_STATUSBAR = "msctls_statusbar32", + WC_TOOLBAR = "ToolbarWindow32", + WC_TRACKBAR = "msctls_trackbar32", + WC_TREEVIEW = "SysTreeView32", + WC_TABCONTROL = "SysTabControl32", + MSH_MOUSEWHEEL = "MSWHEEL_ROLLMSG", + MSH_SCROLL_LINES = "MSH_SCROLL_LINES_MSG"; + + public const int CF_TEXT = 1, + CF_BITMAP = 2, + CF_METAFILEPICT = 3, + CF_SYLK = 4, + CF_DIF = 5, + CF_TIFF = 6, + CF_OEMTEXT = 7, + CF_DIB = 8, + CF_PALETTE = 9, + CF_PENDATA = 10, + CF_RIFF = 11, + CF_WAVE = 12, + CF_UNICODETEXT = 13, + CF_ENHMETAFILE = 14, + CF_HDROP = 15, + CF_LOCALE = 16, + CLSCTX_INPROC_SERVER = 0x1, + CLSCTX_LOCAL_SERVER = 0x4, + CW_USEDEFAULT = (unchecked((int)0x80000000)), + CWP_SKIPINVISIBLE = 0x0001, + COLOR_WINDOW = 5, + CB_ERR = (-1), + CBN_SELCHANGE = 1, + CBN_DBLCLK = 2, + CBN_EDITCHANGE = 5, + CBN_EDITUPDATE = 6, + CBN_DROPDOWN = 7, + CBN_CLOSEUP = 8, + CBN_SELENDOK = 9, + CBS_SIMPLE = 0x0001, + CBS_DROPDOWN = 0x0002, + CBS_DROPDOWNLIST = 0x0003, + CBS_OWNERDRAWFIXED = 0x0010, + CBS_OWNERDRAWVARIABLE = 0x0020, + CBS_AUTOHSCROLL = 0x0040, + CBS_HASSTRINGS = 0x0200, + CBS_NOINTEGRALHEIGHT = 0x0400, + CB_GETEDITSEL = 0x0140, + CB_LIMITTEXT = 0x0141, + CB_SETEDITSEL = 0x0142, + CB_ADDSTRING = 0x0143, + CB_DELETESTRING = 0x0144, + CB_GETCURSEL = 0x0147, + CB_GETLBTEXT = 0x0148, + CB_GETLBTEXTLEN = 0x0149, + CB_INSERTSTRING = 0x014A, + CB_RESETCONTENT = 0x014B, + CB_FINDSTRING = 0x014C, + CB_SETCURSEL = 0x014E, + CB_SHOWDROPDOWN = 0x014F, + CB_GETITEMDATA = 0x0150, + CB_SETITEMHEIGHT = 0x0153, + CB_GETITEMHEIGHT = 0x0154, + CB_GETDROPPEDSTATE = 0x0157, + CB_GETTOPINDEX = 0x015b, + CB_SETTOPINDEX = 0x015c, + CB_FINDSTRINGEXACT = 0x0158, + CB_GETDROPPEDWIDTH = 0x015F, + CB_SETDROPPEDWIDTH = 0x0160, + CDRF_DODEFAULT = 0x00000000, + CDRF_NEWFONT = 0x00000002, + CDRF_SKIPDEFAULT = 0x00000004, + CDRF_NOTIFYPOSTPAINT = 0x00000010, + CDRF_NOTIFYITEMDRAW = 0x00000020, + CDRF_NOTIFYSUBITEMDRAW = CDRF_NOTIFYITEMDRAW, + CDDS_PREPAINT = 0x00000001, + CDDS_POSTPAINT = 0x00000002, + CDDS_ITEM = 0x00010000, + CDDS_SUBITEM = 0x00020000, + CDDS_ITEMPREPAINT = (0x00010000 | 0x00000001), + CDDS_ITEMPOSTPAINT = (0x00010000 | 0x00000002), + CDIS_SELECTED = 0x0001, + CDIS_GRAYED = 0x0002, + CDIS_DISABLED = 0x0004, + CDIS_CHECKED = 0x0008, + CDIS_FOCUS = 0x0010, + CDIS_DEFAULT = 0x0020, + CDIS_HOT = 0x0040, + CDIS_MARKED = 0x0080, + CDIS_INDETERMINATE = 0x0100, + CDIS_SHOWKEYBOARDCUES = 0x0200, + CLR_NONE = unchecked((int)0xFFFFFFFF), + CLR_DEFAULT = unchecked((int)0xFF000000), + CCM_SETVERSION = (0x2000 + 0x7), + CCM_GETVERSION = (0x2000 + 0x8), + CCS_NORESIZE = 0x00000004, + CCS_NOPARENTALIGN = 0x00000008, + CCS_NODIVIDER = 0x00000040, + CBEM_INSERTITEM = (0x0400 + 11), + CBEM_SETITEM = (0x0400 + 12), + CBEM_GETITEM = (0x0400 + 13), + CBEN_ENDEDIT = ((0 - 800) - 6), + CONNECT_E_NOCONNECTION = unchecked((int)0x80040200), + CONNECT_E_CANNOTCONNECT = unchecked((int)0x80040202), + CTRLINFO_EATS_RETURN = 1, + CTRLINFO_EATS_ESCAPE = 2; + + public const int SW_SCROLLCHILDREN = 0x0001, + SW_INVALIDATE = 0x0002, + SW_ERASE = 0x0004, + SW_SMOOTHSCROLL = 0x0010, + SC_SIZE = 0xF000, + SC_MINIMIZE = 0xF020, + SC_MAXIMIZE = 0xF030, + SC_CLOSE = 0xF060, + SC_KEYMENU = 0xF100, + SC_RESTORE = 0xF120, + SC_MOVE = 0xF010, + SC_CONTEXTHELP = 0xF180, + SS_LEFT = 0x00000000, + SS_CENTER = 0x00000001, + SS_RIGHT = 0x00000002, + SS_OWNERDRAW = 0x0000000D, + SS_NOPREFIX = 0x00000080, + SS_SUNKEN = 0x00001000, + SBS_HORZ = 0x0000, + SBS_VERT = 0x0001, + SIF_RANGE = 0x0001, + SIF_PAGE = 0x0002, + SIF_POS = 0x0004, + SIF_TRACKPOS = 0x0010, + SIF_ALL = (0x0001 | 0x0002 | 0x0004 | 0x0010), + SPI_GETFONTSMOOTHING = 0x004A, + SPI_GETDROPSHADOW = 0x1024, + SPI_GETFLATMENU = 0x1022, + SPI_GETFONTSMOOTHINGTYPE = 0x200A, + SPI_GETFONTSMOOTHINGCONTRAST = 0x200C, + SPI_ICONHORIZONTALSPACING = 0x000D, + SPI_ICONVERTICALSPACING = 0x0018, + // SPI_GETICONMETRICS = 0x002D, + SPI_GETICONTITLEWRAP = 0x0019, + SPI_GETKEYBOARDCUES = 0x100A, + SPI_GETKEYBOARDDELAY = 0x0016, + SPI_GETKEYBOARDPREF = 0x0044, + SPI_GETKEYBOARDSPEED = 0x000A, + SPI_GETMOUSEHOVERWIDTH = 0x0062, + SPI_GETMOUSEHOVERHEIGHT = 0x0064, + SPI_GETMOUSEHOVERTIME = 0x0066, + SPI_GETMOUSESPEED = 0x0070, + SPI_GETMENUDROPALIGNMENT = 0x001B, + SPI_GETMENUFADE = 0x1012, + SPI_GETMENUSHOWDELAY = 0x006A, + SPI_GETCOMBOBOXANIMATION = 0x1004, + SPI_GETGRADIENTCAPTIONS = 0x1008, + SPI_GETHOTTRACKING = 0x100E, + SPI_GETLISTBOXSMOOTHSCROLLING = 0x1006, + SPI_GETMENUANIMATION = 0x1002, + SPI_GETSELECTIONFADE = 0x1014, + SPI_GETTOOLTIPANIMATION = 0x1016, + SPI_GETUIEFFECTS = 0x103E, + SPI_GETACTIVEWINDOWTRACKING = 0x1000, + SPI_GETACTIVEWNDTRKTIMEOUT = 0x2002, + SPI_GETANIMATION = 0x0048, + SPI_GETBORDER = 0x0005, + SPI_GETCARETWIDTH = 0x2006, + SPI_GETDRAGFULLWINDOWS = 38, + SPI_GETNONCLIENTMETRICS = 41, + SPI_GETWORKAREA = 48, + SPI_GETHIGHCONTRAST = 66, + SPI_GETDEFAULTINPUTLANG = 89, + SPI_GETSNAPTODEFBUTTON = 95, + SPI_GETWHEELSCROLLLINES = 104, + SBARS_SIZEGRIP = 0x0100, + SB_SETTEXT = (0x0400 + 11), + SB_GETTEXT = (0x0400 + 13), + SB_GETTEXTLENGTH = (0x0400 + 12), + SB_SETPARTS = (0x0400 + 4), + SB_SIMPLE = (0x0400 + 9), + SB_GETRECT = (0x0400 + 10), + SB_SETICON = (0x0400 + 15), + SB_SETTIPTEXT = (0x0400 + 17), + SB_GETTIPTEXT = (0x0400 + 19), + SBT_OWNERDRAW = 0x1000, + SBT_NOBORDERS = 0x0100, + SBT_POPOUT = 0x0200, + SBT_RTLREADING = 0x0400, + SRCCOPY = 0x00CC0020; + + public static HandleRef HWND_TOPMOST = new HandleRef(null, new IntPtr(-1)); + + public const int MEMBERID_NIL = (-1), + ERROR_INSUFFICIENT_BUFFER = 122, //https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx + MA_ACTIVATE = 0x0001, + MA_ACTIVATEANDEAT = 0x0002, + MA_NOACTIVATE = 0x0003, + MA_NOACTIVATEANDEAT = 0x0004, + MM_TEXT = 1, + MM_ANISOTROPIC = 8, + MNC_EXECUTE = 2, + MNC_SELECT = 3, + MIIM_STATE = 0x00000001, + MIIM_ID = 0x00000002, + MIIM_SUBMENU = 0x00000004, + MIIM_TYPE = 0x00000010, + MIIM_DATA = 0x00000020, + MIIM_STRING = 0x00000040, + MIIM_BITMAP = 0x00000080, + MIIM_FTYPE = 0x00000100, + MB_OK = 0x00000000, + MFS_DISABLED = 0x00000003, + MFT_MENUBREAK = 0x00000040, + MFT_SEPARATOR = 0x00000800, + MFT_RIGHTORDER = 0x00002000, + MFT_RIGHTJUSTIFY = 0x00004000, + MDIS_ALLCHILDSTYLES = 0x0001, + MDITILE_VERTICAL = 0x0000, + MDITILE_HORIZONTAL = 0x0001, + MDITILE_SKIPDISABLED = 0x0002, + MCM_SETMAXSELCOUNT = (0x1000 + 4), + MCM_SETSELRANGE = (0x1000 + 6), + MCM_GETMONTHRANGE = (0x1000 + 7), + MCM_GETMINREQRECT = (0x1000 + 9), + MCM_SETCOLOR = (0x1000 + 10), + MCM_SETTODAY = (0x1000 + 12), + MCM_GETTODAY = (0x1000 + 13), + MCM_HITTEST = (0x1000 + 14), + MCM_SETFIRSTDAYOFWEEK = (0x1000 + 15), + MCM_SETRANGE = (0x1000 + 18), + MCM_SETMONTHDELTA = (0x1000 + 20), + MCM_GETMAXTODAYWIDTH = (0x1000 + 21), + MCHT_TITLE = 0x00010000, + MCHT_CALENDAR = 0x00020000, + MCHT_TODAYLINK = 0x00030000, + MCHT_TITLEBK = (0x00010000), + MCHT_TITLEMONTH = (0x00010000 | 0x0001), + MCHT_TITLEYEAR = (0x00010000 | 0x0002), + MCHT_TITLEBTNNEXT = (0x00010000 | 0x01000000 | 0x0003), + MCHT_TITLEBTNPREV = (0x00010000 | 0x02000000 | 0x0003), + MCHT_CALENDARBK = (0x00020000), + MCHT_CALENDARDATE = (0x00020000 | 0x0001), + MCHT_CALENDARDATENEXT = ((0x00020000 | 0x0001) | 0x01000000), + MCHT_CALENDARDATEPREV = ((0x00020000 | 0x0001) | 0x02000000), + MCHT_CALENDARDAY = (0x00020000 | 0x0002), + MCHT_CALENDARWEEKNUM = (0x00020000 | 0x0003), + MCSC_TEXT = 1, + MCSC_TITLEBK = 2, + MCSC_TITLETEXT = 3, + MCSC_MONTHBK = 4, + MCSC_TRAILINGTEXT = 5, + MCN_VIEWCHANGE = (0 - 750), // MCN_SELECT -4 - give state of calendar view + MCN_SELCHANGE = ((0 - 750) + 1), + MCN_GETDAYSTATE = ((0 - 750) + 3), + MCN_SELECT = ((0 - 750) + 4), + MCS_DAYSTATE = 0x0001, + MCS_MULTISELECT = 0x0002, + MCS_WEEKNUMBERS = 0x0004, + MCS_NOTODAYCIRCLE = 0x0008, + MCS_NOTODAY = 0x0010, + MSAA_MENU_SIG = (unchecked((int)0xAA0DF00D)); + public delegate int ListViewCompareCallback(IntPtr lParam1, IntPtr lParam2, IntPtr lParamSort); + public const int IME_CMODE_NATIVE = 0x0001, + IME_CMODE_KATAKANA = 0x0002, + IME_CMODE_FULLSHAPE = 0x0008, + INPLACE_E_NOTOOLSPACE = unchecked((int)0x800401A1), + ICON_SMALL = 0, + ICON_BIG = 1, + IMAGE_ICON = 1, + IMAGE_CURSOR = 2, + ICC_LISTVIEW_CLASSES = 0x00000001, + ICC_TREEVIEW_CLASSES = 0x00000002, + ICC_BAR_CLASSES = 0x00000004, + ICC_TAB_CLASSES = 0x00000008, + ICC_PROGRESS_CLASS = 0x00000020, + ICC_DATE_CLASSES = 0x00000100, + ILC_MASK = 0x0001, + ILC_COLOR = 0x0000, + ILC_COLOR4 = 0x0004, + ILC_COLOR8 = 0x0008, + ILC_COLOR16 = 0x0010, + ILC_COLOR24 = 0x0018, + ILC_COLOR32 = 0x0020, + ILC_MIRROR = 0x00002000, + ILD_NORMAL = 0x0000, + ILD_TRANSPARENT = 0x0001, + ILD_MASK = 0x0010, + ILD_ROP = 0x0040, + +// ImageList +// + ILP_NORMAL = 0, + ILP_DOWNLEVEL = 1, + ILS_NORMAL = 0x0, + ILS_GLOW = 0x1, + ILS_SHADOW = 0x2, + ILS_SATURATE = 0x4, + ILS_ALPHA = 0x8; + + [StructLayout(LayoutKind.Sequential)] + public class DRAWITEMSTRUCT + { + public int CtlType = 0; + public int CtlID = 0; + public int itemID = 0; + public int itemAction = 0; + public int itemState = 0; + public IntPtr hwndItem = IntPtr.Zero; + public IntPtr hDC = IntPtr.Zero; + public RECT rcItem; + public IntPtr itemData = IntPtr.Zero; + } + + public const int NIM_ADD = 0x00000000, + NIM_MODIFY = 0x00000001, + NIM_DELETE = 0x00000002, + NIF_MESSAGE = 0x00000001, + NIM_SETVERSION = 0x00000004, + NIF_ICON = 0x00000002, + NIF_INFO = 0x00000010, + NIF_TIP = 0x00000004, + NIIF_NONE = 0x00000000, + NIIF_INFO = 0x00000001, + NIIF_WARNING = 0x00000002, + NIIF_ERROR = 0x00000003, + NIN_BALLOONSHOW = (Interop.WindowMessages.WM_USER + 2), + NIN_BALLOONHIDE = (Interop.WindowMessages.WM_USER + 3), + NIN_BALLOONTIMEOUT = (Interop.WindowMessages.WM_USER + 4), + NIN_BALLOONUSERCLICK = (Interop.WindowMessages.WM_USER + 5), + NFR_ANSI = 1, + NFR_UNICODE = 2, + NM_CLICK = ((0 - 0) - 2), + NM_DBLCLK = ((0 - 0) - 3), + NM_RCLICK = ((0 - 0) - 5), + NM_RDBLCLK = ((0 - 0) - 6), + NM_CUSTOMDRAW = ((0 - 0) - 12), + NM_RELEASEDCAPTURE = ((0 - 0) - 16); + + public const int + HC_ACTION = 0, + HC_GETNEXT = 1, + HC_SKIP = 2, + HTTRANSPARENT = (-1), + HTNOWHERE = 0, + HTCLIENT = 1, + HTLEFT = 10, + HTBOTTOM = 15, + HTBOTTOMLEFT = 16, + HTBOTTOMRIGHT = 17, + HTBORDER = 18, + HELPINFO_WINDOW = 0x0001, + HCF_HIGHCONTRASTON = 0x00000001, + HDI_ORDER = 0x0080, + HDI_WIDTH = 0x0001, + HDM_GETITEMCOUNT = (0x1200 + 0), + HDM_INSERTITEMW = (0x1200 + 10), + HDM_GETITEMW = (0x1200 + 11), + HDM_LAYOUT = (0x1200 + 5), + HDM_SETITEMW = (0x1200 + 12), + HDN_ITEMCHANGING = ((0 - 300) - 20), + HDN_ITEMCHANGED = ((0 - 300) - 21), + HDN_ITEMCLICK = ((0 - 300) - 22), + HDN_ITEMDBLCLICK = ((0 - 300) - 23), + HDN_DIVIDERDBLCLICK = ((0 - 300) - 25), + HDN_BEGINTDRAG = ((0 - 300) - 10), + HDN_BEGINTRACK = ((0 - 300) - 26), + HDN_ENDDRAG = ((0 - 300) - 11), + HDN_ENDTRACK = ((0 - 300) - 27), + HDN_TRACK = ((0 - 300) - 28), + HDN_GETDISPINFO = ((0 - 300) - 29); + // HOVER_DEFAULT = Do not use this value ever! It crashes entire servers. + + public const string TOOLTIPS_CLASS = "tooltips_class32"; + + public const int stc4 = 0x0443, + STARTF_USESHOWWINDOW = 0x00000001, + SB_HORZ = 0, + SB_VERT = 1, + SB_CTL = 2, + SB_LINEUP = 0, + SB_LINELEFT = 0, + SB_LINEDOWN = 1, + SB_LINERIGHT = 1, + SB_PAGEUP = 2, + SB_PAGELEFT = 2, + SB_PAGEDOWN = 3, + SB_PAGERIGHT = 3, + SB_THUMBPOSITION = 4, + SB_THUMBTRACK = 5, + SB_LEFT = 6, + SB_RIGHT = 7, + SB_ENDSCROLL = 8, + SB_TOP = 6, + SB_BOTTOM = 7, + SIZE_RESTORED = 0, + SIZE_MAXIMIZED = 2, + ESB_ENABLE_BOTH = 0x0000, + ESB_DISABLE_BOTH = 0x0003, + SORT_DEFAULT = 0x0, + SUBLANG_DEFAULT = 0x01, + SW_HIDE = 0, + SW_NORMAL = 1, + SW_SHOWMINIMIZED = 2, + SW_SHOWMAXIMIZED = 3, + SW_MAXIMIZE = 3, + SW_SHOWNOACTIVATE = 4, + SW_SHOW = 5, + SW_MINIMIZE = 6, + SW_SHOWMINNOACTIVE = 7, + SW_SHOWNA = 8, + SW_RESTORE = 9, + SW_MAX = 10, + SWP_NOSIZE = 0x0001, + SWP_NOMOVE = 0x0002, + SWP_NOZORDER = 0x0004, + SWP_NOACTIVATE = 0x0010, + SWP_SHOWWINDOW = 0x0040, + SWP_HIDEWINDOW = 0x0080, + SWP_DRAWFRAME = 0x0020, + SWP_NOOWNERZORDER = 0x0200; + + + public const int TRANSPARENT = 1, + OPAQUE = 2, + TME_HOVER = 0x00000001, + TME_LEAVE = 0x00000002, + TPM_LEFTBUTTON = 0x0000, + TPM_RIGHTBUTTON = 0x0002, + TPM_LEFTALIGN = 0x0000, + TPM_RIGHTALIGN = 0x0008, + TPM_VERTICAL = 0x0040, + TV_FIRST = 0x1100, + TBSTATE_CHECKED = 0x01, + TBSTATE_ENABLED = 0x04, + TBSTATE_HIDDEN = 0x08, + TBSTATE_INDETERMINATE = 0x10, + TBSTYLE_BUTTON = 0x00, + TBSTYLE_SEP = 0x01, + TBSTYLE_CHECK = 0x02, + TBSTYLE_DROPDOWN = 0x08, + TBSTYLE_TOOLTIPS = 0x0100, + TBSTYLE_FLAT = 0x0800, + TBSTYLE_LIST = 0x1000, + TBSTYLE_EX_DRAWDDARROWS = 0x00000001, + TB_ENABLEBUTTON = (0x0400 + 1), + TB_ISBUTTONCHECKED = (0x0400 + 10), + TB_ISBUTTONINDETERMINATE = (0x0400 + 13), + TB_ADDBUTTONS = (0x0400 + 68), + TB_INSERTBUTTON = (0x0400 + 67), + TB_DELETEBUTTON = (0x0400 + 22), + TB_GETBUTTON = (0x0400 + 23), + TB_SAVERESTORE = (0x0400 + 76), + TB_ADDSTRING = (0x0400 + 77), + TB_BUTTONSTRUCTSIZE = (0x0400 + 30), + TB_SETBUTTONSIZE = (0x0400 + 31), + TB_AUTOSIZE = (0x0400 + 33), + TB_GETROWS = (0x0400 + 40), + TB_GETBUTTONTEXT = (0x0400 + 75), + TB_SETIMAGELIST = (0x0400 + 48), + TB_GETRECT = (0x0400 + 51), + TB_GETBUTTONSIZE = (0x0400 + 58), + TB_GETBUTTONINFO = (0x0400 + 63), + TB_SETBUTTONINFO = (0x0400 + 64), + TB_SETEXTENDEDSTYLE = (0x0400 + 84), + TB_MAPACCELERATOR = (0x0400 + 90), + TB_GETTOOLTIPS = (0x0400 + 35), + TB_SETTOOLTIPS = (0x0400 + 36), + TBIF_IMAGE = 0x00000001, + TBIF_TEXT = 0x00000002, + TBIF_STATE = 0x00000004, + TBIF_STYLE = 0x00000008, + TBIF_COMMAND = 0x00000020, + TBIF_SIZE = 0x00000040, + TBN_GETBUTTONINFO = ((0 - 700) - 20), + TBN_QUERYINSERT = ((0 - 700) - 6), + TBN_DROPDOWN = ((0 - 700) - 10), + TBN_HOTITEMCHANGE = ((0 - 700) - 13), + TBN_GETDISPINFO = ((0 - 700) - 17), + TBN_GETINFOTIP = ((0 - 700) - 19), + TTS_ALWAYSTIP = 0x01, + TTS_NOPREFIX = 0x02, + TTS_NOANIMATE = 0x10, + TTS_NOFADE = 0x20, + TTS_BALLOON = 0x40, + //TTI_NONE =0, + //TTI_INFO =1, + TTI_WARNING = 2, + //TTI_ERROR =3, + TTN_GETDISPINFO = ((0 - 520) - 10), + TTN_SHOW = ((0 - 520) - 1), + TTN_POP = ((0 - 520) - 2), + TTN_NEEDTEXT = ((0 - 520) - 10), + TBS_AUTOTICKS = 0x0001, + TBS_VERT = 0x0002, + TBS_TOP = 0x0004, + TBS_BOTTOM = 0x0000, + TBS_BOTH = 0x0008, + TBS_NOTICKS = 0x0010, + TBM_GETPOS = (0x0400), + TBM_SETTIC = (0x0400 + 4), + TBM_SETPOS = (0x0400 + 5), + TBM_SETRANGE = (0x0400 + 6), + TBM_SETRANGEMIN = (0x0400 + 7), + TBM_SETRANGEMAX = (0x0400 + 8), + TBM_SETTICFREQ = (0x0400 + 20), + TBM_SETPAGESIZE = (0x0400 + 21), + TBM_SETLINESIZE = (0x0400 + 23), + TB_LINEUP = 0, + TB_LINEDOWN = 1, + TB_PAGEUP = 2, + TB_PAGEDOWN = 3, + TB_THUMBPOSITION = 4, + TB_THUMBTRACK = 5, + TB_TOP = 6, + TB_BOTTOM = 7, + TB_ENDTRACK = 8, + TVS_HASBUTTONS = 0x0001, + TVS_HASLINES = 0x0002, + TVS_LINESATROOT = 0x0004, + TVS_EDITLABELS = 0x0008, + TVS_SHOWSELALWAYS = 0x0020, + TVS_RTLREADING = 0x0040, + TVS_CHECKBOXES = 0x0100, + TVS_TRACKSELECT = 0x0200, + TVS_FULLROWSELECT = 0x1000, + TVS_NONEVENHEIGHT = 0x4000, + TVS_INFOTIP = 0x0800, + TVS_NOTOOLTIPS = 0x0080, + TVIF_TEXT = 0x0001, + TVIF_IMAGE = 0x0002, + TVIF_PARAM = 0x0004, + TVIF_STATE = 0x0008, + TVIF_HANDLE = 0x0010, + TVIF_SELECTEDIMAGE = 0x0020, + TVIS_SELECTED = 0x0002, + TVIS_EXPANDED = 0x0020, + TVIS_EXPANDEDONCE = 0x0040, + TVIS_STATEIMAGEMASK = 0xF000, + TVI_ROOT = (unchecked((int)0xFFFF0000)), + TVI_FIRST = (unchecked((int)0xFFFF0001)), + TVM_INSERTITEM = (0x1100 + 50), + TVM_DELETEITEM = (0x1100 + 1), + TVM_EXPAND = (0x1100 + 2), + TVE_COLLAPSE = 0x0001, + TVE_EXPAND = 0x0002, + TVM_GETITEMRECT = (0x1100 + 4), + TVM_GETINDENT = (0x1100 + 6), + TVM_SETINDENT = (0x1100 + 7), + TVM_GETIMAGELIST = (0x1100 + 8), + TVM_SETIMAGELIST = (0x1100 + 9), + TVM_GETNEXTITEM = (0x1100 + 10), + TVGN_NEXT = 0x0001, + TVGN_PREVIOUS = 0x0002, + TVGN_FIRSTVISIBLE = 0x0005, + TVGN_NEXTVISIBLE = 0x0006, + TVGN_PREVIOUSVISIBLE = 0x0007, + TVGN_DROPHILITE = 0x0008, + TVGN_CARET = 0x0009, + TVM_SELECTITEM = (0x1100 + 11), + TVM_GETITEM = (0x1100 + 62), + TVM_SETITEM = (0x1100 + 63), + TVM_EDITLABEL = (0x1100 + 65), + TVM_GETEDITCONTROL = (0x1100 + 15), + TVM_GETVISIBLECOUNT = (0x1100 + 16), + TVM_HITTEST = (0x1100 + 17), + TVM_ENSUREVISIBLE = (0x1100 + 20), + TVM_ENDEDITLABELNOW = (0x1100 + 22), + TVM_GETISEARCHSTRING = (0x1100 + 64), + TVM_SETITEMHEIGHT = (0x1100 + 27), + TVM_GETITEMHEIGHT = (0x1100 + 28), + TVN_SELCHANGING = ((0 - 400) - 50), + TVN_GETINFOTIP = ((0 - 400) - 14), + TVN_SELCHANGED = ((0 - 400) - 51), + TVC_UNKNOWN = 0x0000, + TVC_BYMOUSE = 0x0001, + TVC_BYKEYBOARD = 0x0002, + TVN_GETDISPINFO = ((0 - 400) - 52), + TVN_SETDISPINFO = ((0 - 400) - 53), + TVN_ITEMEXPANDING = ((0 - 400) - 54), + TVN_ITEMEXPANDED = ((0 - 400) - 55), + TVN_BEGINDRAG = ((0 - 400) - 56), + TVN_BEGINRDRAG = ((0 - 400) - 57), + TVN_BEGINLABELEDIT = ((0 - 400) - 59), + TVN_ENDLABELEDIT = ((0 - 400) - 60), + TCS_BOTTOM = 0x0002, + TCS_RIGHT = 0x0002, + TCS_FLATBUTTONS = 0x0008, + TCS_HOTTRACK = 0x0040, + TCS_VERTICAL = 0x0080, + TCS_TABS = 0x0000, + TCS_BUTTONS = 0x0100, + TCS_MULTILINE = 0x0200, + TCS_RIGHTJUSTIFY = 0x0000, + TCS_FIXEDWIDTH = 0x0400, + TCS_RAGGEDRIGHT = 0x0800, + TCS_OWNERDRAWFIXED = 0x2000, + TCS_TOOLTIPS = 0x4000, + TCM_SETIMAGELIST = (0x1300 + 3), + TCIF_TEXT = 0x0001, + TCIF_IMAGE = 0x0002, + TCM_GETITEM = (0x1300 + 60), + TCM_SETITEM = (0x1300 + 61), + TCM_INSERTITEM = (0x1300 + 62), + TCM_DELETEITEM = (0x1300 + 8), + TCM_DELETEALLITEMS = (0x1300 + 9), + TCM_GETITEMRECT = (0x1300 + 10), + TCM_GETCURSEL = (0x1300 + 11), + TCM_SETCURSEL = (0x1300 + 12), + TCM_ADJUSTRECT = (0x1300 + 40), + TCM_SETITEMSIZE = (0x1300 + 41), + TCM_SETPADDING = (0x1300 + 43), + TCM_GETROWCOUNT = (0x1300 + 44), + TCM_GETTOOLTIPS = (0x1300 + 45), + TCM_SETTOOLTIPS = (0x1300 + 46), + TCN_SELCHANGE = ((0 - 550) - 1), + TCN_SELCHANGING = ((0 - 550) - 2), + TBSTYLE_WRAPPABLE = 0x0200, + TVM_SETBKCOLOR = (TV_FIRST + 29), + TVM_SETTEXTCOLOR = (TV_FIRST + 30), + TYMED_NULL = 0, + TVM_GETLINECOLOR = (TV_FIRST + 41), + TVM_SETLINECOLOR = (TV_FIRST + 40), + TVM_SETTOOLTIPS = (TV_FIRST + 24), + TVSIL_STATE = 2, + TVM_SORTCHILDRENCB = (TV_FIRST + 21), + TMPF_FIXED_PITCH = 0x01; + + [StructLayout(LayoutKind.Sequential)] + public struct NMHDR + { + public IntPtr hwndFrom; + public IntPtr idFrom; //This is declared as UINT_PTR in winuser.h + public int code; + } + + [StructLayout(LayoutKind.Sequential)] + public class INITCOMMONCONTROLSEX + { + public int dwSize = 8; //ndirect.DllLib.sizeOf(this); + public int dwICC; + } + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class PRINTDLGEX { @@ -50,6 +696,17 @@ public class PRINTDLGEX public Comdlg32.PD_RESULT dwResultAction; } + [StructLayout(LayoutKind.Sequential)] + public class TPMPARAMS + { + public int cbSize = Marshal.SizeOf(); + // rcExclude was a by-value RECT structure + public int rcExclude_left; + public int rcExclude_top; + public int rcExclude_right; + public int rcExclude_bottom; + } + public static class ActiveX { public const int ALIGN_MIN = 0x0; @@ -59,5 +716,292 @@ public static class ActiveX public const int ALIGN_LEFT = 0x3; public const int ALIGN_RIGHT = 0x4; public const int ALIGN_MAX = 0x4; + + public const int OCM__BASE = 0x2000; + public const int DISPID_VALUE = unchecked((int)0x0); + public const int DISPID_UNKNOWN = unchecked((int)0xFFFFFFFF); + public const int DISPID_AUTOSIZE = unchecked((int)0xFFFFFE0C); + public const int DISPID_BACKCOLOR = unchecked((int)0xFFFFFE0B); + public const int DISPID_BACKSTYLE = unchecked((int)0xFFFFFE0A); + public const int DISPID_BORDERCOLOR = unchecked((int)0xFFFFFE09); + public const int DISPID_BORDERSTYLE = unchecked((int)0xFFFFFE08); + public const int DISPID_BORDERWIDTH = unchecked((int)0xFFFFFE07); + public const int DISPID_DRAWMODE = unchecked((int)0xFFFFFE05); + public const int DISPID_DRAWSTYLE = unchecked((int)0xFFFFFE04); + public const int DISPID_DRAWWIDTH = unchecked((int)0xFFFFFE03); + public const int DISPID_FILLCOLOR = unchecked((int)0xFFFFFE02); + public const int DISPID_FILLSTYLE = unchecked((int)0xFFFFFE01); + public const int DISPID_FONT = unchecked((int)0xFFFFFE00); + public const int DISPID_FORECOLOR = unchecked((int)0xFFFFFDFF); + public const int DISPID_ENABLED = unchecked((int)0xFFFFFDFE); + public const int DISPID_HWND = unchecked((int)0xFFFFFDFD); + public const int DISPID_TABSTOP = unchecked((int)0xFFFFFDFC); + public const int DISPID_TEXT = unchecked((int)0xFFFFFDFB); + public const int DISPID_CAPTION = unchecked((int)0xFFFFFDFA); + public const int DISPID_BORDERVISIBLE = unchecked((int)0xFFFFFDF9); + public const int DISPID_APPEARANCE = unchecked((int)0xFFFFFDF8); + public const int DISPID_MOUSEPOINTER = unchecked((int)0xFFFFFDF7); + public const int DISPID_MOUSEICON = unchecked((int)0xFFFFFDF6); + public const int DISPID_PICTURE = unchecked((int)0xFFFFFDF5); + public const int DISPID_VALID = unchecked((int)0xFFFFFDF4); + public const int DISPID_READYSTATE = unchecked((int)0xFFFFFDF3); + public const int DISPID_REFRESH = unchecked((int)0xFFFFFDDA); + public const int DISPID_DOCLICK = unchecked((int)0xFFFFFDD9); + public const int DISPID_ABOUTBOX = unchecked((int)0xFFFFFDD8); + public const int DISPID_CLICK = unchecked((int)0xFFFFFDA8); + public const int DISPID_DBLCLICK = unchecked((int)0xFFFFFDA7); + public const int DISPID_KEYDOWN = unchecked((int)0xFFFFFDA6); + public const int DISPID_KEYPRESS = unchecked((int)0xFFFFFDA5); + public const int DISPID_KEYUP = unchecked((int)0xFFFFFDA4); + public const int DISPID_MOUSEDOWN = unchecked((int)0xFFFFFDA3); + public const int DISPID_MOUSEMOVE = unchecked((int)0xFFFFFDA2); + public const int DISPID_MOUSEUP = unchecked((int)0xFFFFFDA1); + public const int DISPID_ERROREVENT = unchecked((int)0xFFFFFDA0); + public const int DISPID_RIGHTTOLEFT = unchecked((int)0xFFFFFD9D); + public const int DISPID_READYSTATECHANGE = unchecked((int)0xFFFFFD9F); + public const int DISPID_AMBIENT_BACKCOLOR = unchecked((int)0xFFFFFD43); + public const int DISPID_AMBIENT_DISPLAYNAME = unchecked((int)0xFFFFFD42); + public const int DISPID_AMBIENT_FONT = unchecked((int)0xFFFFFD41); + public const int DISPID_AMBIENT_FORECOLOR = unchecked((int)0xFFFFFD40); + public const int DISPID_AMBIENT_LOCALEID = unchecked((int)0xFFFFFD3F); + public const int DISPID_AMBIENT_MESSAGEREFLECT = unchecked((int)0xFFFFFD3E); + public const int DISPID_AMBIENT_SCALEUNITS = unchecked((int)0xFFFFFD3D); + public const int DISPID_AMBIENT_TEXTALIGN = unchecked((int)0xFFFFFD3C); + public const int DISPID_AMBIENT_USERMODE = unchecked((int)0xFFFFFD3B); + public const int DISPID_AMBIENT_UIDEAD = unchecked((int)0xFFFFFD3A); + public const int DISPID_AMBIENT_SHOWGRABHANDLES = unchecked((int)0xFFFFFD39); + public const int DISPID_AMBIENT_SHOWHATCHING = unchecked((int)0xFFFFFD38); + public const int DISPID_AMBIENT_DISPLAYASDEFAULT = unchecked((int)0xFFFFFD37); + public const int DISPID_AMBIENT_SUPPORTSMNEMONICS = unchecked((int)0xFFFFFD36); + public const int DISPID_AMBIENT_AUTOCLIP = unchecked((int)0xFFFFFD35); + public const int DISPID_AMBIENT_APPEARANCE = unchecked((int)0xFFFFFD34); + public const int DISPID_AMBIENT_PALETTE = unchecked((int)0xFFFFFD2A); + public const int DISPID_AMBIENT_TRANSFERPRIORITY = unchecked((int)0xFFFFFD28); + public const int DISPID_AMBIENT_RIGHTTOLEFT = unchecked((int)0xFFFFFD24); + public const int DISPID_Name = unchecked((int)0xFFFFFCE0); + public const int DISPID_Delete = unchecked((int)0xFFFFFCDF); + public const int DISPID_Object = unchecked((int)0xFFFFFCDE); + public const int DISPID_Parent = unchecked((int)0xFFFFFCDD); + public const int DVASPECT_CONTENT = 0x1; + public const int DVASPECT_THUMBNAIL = 0x2; + public const int DVASPECT_ICON = 0x4; + public const int DVASPECT_DOCPRINT = 0x8; + public const int OLEMISC_RECOMPOSEONRESIZE = 0x1; + public const int OLEMISC_ONLYICONIC = 0x2; + public const int OLEMISC_INSERTNOTREPLACE = 0x4; + public const int OLEMISC_STATIC = 0x8; + public const int OLEMISC_CANTLINKINSIDE = 0x10; + public const int OLEMISC_CANLINKBYOLE1 = 0x20; + public const int OLEMISC_ISLINKOBJECT = 0x40; + public const int OLEMISC_INSIDEOUT = 0x80; + public const int OLEMISC_ACTIVATEWHENVISIBLE = 0x100; + public const int OLEMISC_RENDERINGISDEVICEINDEPENDENT = 0x200; + public const int OLEMISC_INVISIBLEATRUNTIME = 0x400; + public const int OLEMISC_ALWAYSRUN = 0x800; + public const int OLEMISC_ACTSLIKEBUTTON = 0x1000; + public const int OLEMISC_ACTSLIKELABEL = 0x2000; + public const int OLEMISC_NOUIACTIVATE = 0x4000; + public const int OLEMISC_ALIGNABLE = 0x8000; + public const int OLEMISC_SIMPLEFRAME = 0x10000; + public const int OLEMISC_SETCLIENTSITEFIRST = 0x20000; + public const int OLEMISC_IMEMODE = 0x40000; + public const int OLEMISC_IGNOREACTIVATEWHENVISIBLE = 0x80000; + public const int OLEMISC_WANTSTOMENUMERGE = 0x100000; + public const int OLEMISC_SUPPORTSMULTILEVELUNDO = 0x200000; + public const int QACONTAINER_SHOWHATCHING = 0x1; + public const int QACONTAINER_SHOWGRABHANDLES = 0x2; + public const int QACONTAINER_USERMODE = 0x4; + public const int QACONTAINER_DISPLAYASDEFAULT = 0x8; + public const int QACONTAINER_UIDEAD = 0x10; + public const int QACONTAINER_AUTOCLIP = 0x20; + public const int QACONTAINER_MESSAGEREFLECT = 0x40; + public const int QACONTAINER_SUPPORTSMNEMONICS = 0x80; + public const int XFORMCOORDS_POSITION = 0x1; + public const int XFORMCOORDS_SIZE = 0x2; + public const int XFORMCOORDS_HIMETRICTOCONTAINER = 0x4; + public const int XFORMCOORDS_CONTAINERTOHIMETRIC = 0x8; + public const int PROPCAT_Nil = unchecked((int)0xFFFFFFFF); + public const int PROPCAT_Misc = unchecked((int)0xFFFFFFFE); + public const int PROPCAT_Font = unchecked((int)0xFFFFFFFD); + public const int PROPCAT_Position = unchecked((int)0xFFFFFFFC); + public const int PROPCAT_Appearance = unchecked((int)0xFFFFFFFB); + public const int PROPCAT_Behavior = unchecked((int)0xFFFFFFFA); + public const int PROPCAT_Data = unchecked((int)0xFFFFFFF9); + public const int PROPCAT_List = unchecked((int)0xFFFFFFF8); + public const int PROPCAT_Text = unchecked((int)0xFFFFFFF7); + public const int PROPCAT_Scale = unchecked((int)0xFFFFFFF6); + public const int PROPCAT_DDE = unchecked((int)0xFFFFFFF5); + public const int GC_WCH_SIBLING = 0x1; + public const int GC_WCH_CONTAINER = 0x2; + public const int GC_WCH_CONTAINED = 0x3; + public const int GC_WCH_ALL = 0x4; + public const int GC_WCH_FREVERSEDIR = 0x8000000; + public const int GC_WCH_FONLYNEXT = 0x10000000; + public const int GC_WCH_FONLYPREV = 0x20000000; + public const int GC_WCH_FSELECTED = 0x40000000; + public const int OLECONTF_EMBEDDINGS = 0x1; + public const int OLECONTF_LINKS = 0x2; + public const int OLECONTF_OTHERS = 0x4; + public const int OLECONTF_ONLYUSER = 0x8; + public const int OLECONTF_ONLYIFRUNNING = 0x10; + + public const int OLEVERBATTRIB_NEVERDIRTIES = 0x1; + public const int OLEVERBATTRIB_ONCONTAINERMENU = 0x2; + + public static Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}"); + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct MSAAMENUINFO + { + public int dwMSAASignature; + public int cchWText; + public string pszWText; + + public MSAAMENUINFO(string text) + { + dwMSAASignature = unchecked((int)MSAA_MENU_SIG); + cchWText = text.Length; + pszWText = text; + } + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class MENUITEMINFO_T + { + public int cbSize = Marshal.SizeOf(); + public int fMask; + public int fType; + public int fState; + public int wID; + public IntPtr hSubMenu; + public IntPtr hbmpChecked; + public IntPtr hbmpUnchecked; + public IntPtr dwItemData; + public string? dwTypeData; + public int cch; + } + + [StructLayout(LayoutKind.Sequential)] + public struct NMTOOLBAR + { + public NMHDR hdr; + public int iItem; + public TBBUTTON tbButton; + public int cchText; + public IntPtr pszText; + } + + [StructLayout(LayoutKind.Sequential)] + public struct TBBUTTON + { + public int iBitmap; + public int idCommand; + public byte fsState; + public byte fsStyle; + public byte bReserved0; + public byte bReserved1; + public IntPtr dwData; + public IntPtr iString; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class TOOLTIPTEXT + { + public NMHDR hdr; + public string? lpszText; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] + public string? szText = null; + + public IntPtr hinst; + public int uFlags; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct TBBUTTONINFO + { + public int cbSize; + public int dwMask; + public int idCommand; + public int iImage; + public byte fsState; + public byte fsStyle; + public short cx; + public IntPtr lParam; + public IntPtr pszText; + public int cchTest; + } + + public static class Util + { + public static int MAKELONG(int low, int high) + { + return (high << 16) | (low & 0xffff); + } + + public static IntPtr MAKELPARAM(int low, int high) + { + return (IntPtr)((high << 16) | (low & 0xffff)); + } + + public static int HIWORD(int n) + { + return (n >> 16) & 0xffff; + } + + public static int HIWORD(IntPtr n) + { + return HIWORD(unchecked((int)(long)n)); + } + + public static int LOWORD(int n) + { + return n & 0xffff; + } + + public static int LOWORD(IntPtr n) + { + return LOWORD(unchecked((int)(long)n)); + } + + public static int SignedHIWORD(IntPtr n) + { + return SignedHIWORD(unchecked((int)(long)n)); + } + + public static int SignedLOWORD(IntPtr n) + { + return SignedLOWORD(unchecked((int)(long)n)); + } + + public static int SignedHIWORD(int n) + { + int i = (int)(short)((n >> 16) & 0xffff); + + return i; + } + + public static int SignedLOWORD(int n) + { + int i = (int)(short)(n & 0xFFFF); + + return i; + } + + private static int GetEmbeddedNullStringLengthAnsi(string s) + { + int n = s.IndexOf('\0'); + if (n > -1) + { + string left = s.Substring(0, n); + string right = s.Substring(n + 1); + return left.Length + GetEmbeddedNullStringLengthAnsi(right) + 1; + } + else + { + return s.Length; + } + } } } diff --git a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/SafeNativeMethods.cs b/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/SafeNativeMethods.cs new file mode 100644 index 00000000000..ff9510b73c9 --- /dev/null +++ b/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/SafeNativeMethods.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +namespace System.Windows.Forms +{ + internal class SafeNativeMethods + { + [DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)] + public static extern bool TrackPopupMenuEx(HandleRef hmenu, int fuFlags, int x, int y, HandleRef hwnd, NativeMethods.TPMPARAMS tpm); + + [DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)] + public static extern bool DrawMenuBar(HandleRef hWnd); + + [DllImport(ExternDll.User32, CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, int[] lParam); + + [DllImport(ExternDll.Comctl32)] + public static extern bool InitCommonControlsEx(NativeMethods.INITCOMMONCONTROLSEX icc); + + [DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)] + public static extern bool SetWindowPos( + HandleRef hWnd, + HandleRef hWndInsertAfter, + int x = 0, + int y = 0, + int cx = 0, + int cy = 0, + int flags = 0); + + [DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)] + public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, + int x, int y, int cx, int cy, int flags); + } +} diff --git a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/UnsafeNativeMethods.cs b/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/UnsafeNativeMethods.cs index 817d87aa966..67c6da2b6f7 100644 --- a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/UnsafeNativeMethods.cs +++ b/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/UnsafeNativeMethods.cs @@ -10,4 +10,36 @@ internal static class UnsafeNativeMethods { [DllImport(Libraries.Comdlg32, SetLastError = true, CharSet = CharSet.Auto)] public static extern HRESULT PrintDlgEx([In, Out] NativeMethods.PRINTDLGEX lppdex); + + [DllImport(ExternDll.User32, CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(HandleRef hWnd, int msg, IntPtr wParam, string lParam); + + + [DllImport(ExternDll.User32, CharSet = CharSet.Unicode)] + public extern static IntPtr SendMessage(HandleRef hWnd, int Msg, IntPtr wParam, ref RECT lParam); + + [DllImport(ExternDll.User32, CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(HandleRef hWnd, int msg, HandleRef wParam, int lParam); + + [DllImport(ExternDll.User32, CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(HandleRef hWnd, int msg, IntPtr wParam, IntPtr lParam); + + [DllImport(Libraries.User32, CharSet = CharSet.Auto)] + public static extern BOOL GetMenuItemInfo(IntPtr hMenu, int uItem, bool fByPosition, [In, Out] NativeMethods.MENUITEMINFO_T lpmii); + + [DllImport(ExternDll.User32, CharSet = CharSet.Auto)] + public extern static bool InsertMenuItem(HandleRef hMenu, int uItem, bool fByPosition, NativeMethods.MENUITEMINFO_T lpmii); + + [DllImport(ExternDll.User32, CharSet = CharSet.Auto)] + public extern static bool SetMenuItemInfo(HandleRef hMenu, int uItem, bool fByPosition, NativeMethods.MENUITEMINFO_T lpmii); + + [DllImport(ExternDll.User32, CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, int[] lParam); + + public static BOOL GetMenuItemInfo(HandleRef hMenu, int uItem, bool fByPosition, NativeMethods.MENUITEMINFO_T lpmii) + { + BOOL result = GetMenuItemInfo(hMenu.Handle, uItem, fByPosition, lpmii); + GC.KeepAlive(hMenu.Wrapper); + return result; + } } diff --git a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Message.cs b/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Message.cs index f0ded75b306..d5322ffdce6 100644 --- a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Message.cs +++ b/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Message.cs @@ -61,22 +61,26 @@ public IntPtr WParam set => WParamInternal = (nuint)value; } +/* #if DEBUG [Obsolete( $"Casting to/from IntPtr is unsafe, use {nameof(LParamInternal)}.", DiagnosticId = "WFDEV001")] #endif +*/ public IntPtr LParam { readonly get => LParamInternal; set => LParamInternal = value; } +/* #if DEBUG [Obsolete( $"Casting to/from IntPtr is unsafe, use {nameof(ResultInternal)}.", DiagnosticId = "WFDEV001")] #endif +*/ public IntPtr Result { readonly get => ResultInternal; diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/ComparisonHelpersTests.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/ComparisonHelpersTests.cs deleted file mode 100644 index 1e57bf6f9c1..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/ComparisonHelpersTests.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Tests; - -public class ComparisonHelpersTests -{ - [Theory] - [InlineData(0, 0, 0, true)] - [InlineData(1, -1, 2, true)] - [InlineData(1, -1, 1, false)] - [InlineData(-1, 1, 2, true)] - [InlineData(-1, 1, 1, false)] - [InlineData(-1, -1, 0, true)] - [InlineData(-1, -2, 1, true)] - [InlineData(-2, -1, 1, true)] - [InlineData(int.MinValue, int.MinValue, int.MaxValue, true)] - public void EqualsInteger(int x, int y, int tolerance, bool expected) - { - Assert.Equal(expected, ComparisonHelpers.EqualsInteger(x, y, tolerance)); - } - - [Theory] - [InlineData(0, 0, 0, true)] - [InlineData(1, -1, 2, true)] - [InlineData(-1, 1, 2, true)] - [InlineData(-1, -1, 0, true)] - [InlineData(-1, -2, 1, true)] - [InlineData(-2, -1, 1, true)] - [InlineData(1.00000f, 1.00001f, 0.00002f, true)] - [InlineData(1.00000f, 1.00001f, 0.000001f, false)] - [InlineData(int.MinValue, int.MinValue, int.MaxValue, true)] - public void EqualsFloat(float x, float y, float tolerance, bool expected) - { - Assert.Equal(expected, ComparisonHelpers.EqualsFloating(x, y, tolerance)); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/GlobalUsings.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/GlobalUsings.cs deleted file mode 100644 index 4fb1a00800f..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -global using Xunit; diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/Metafiles/Validators/RepeatValidatorTests.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/Metafiles/Validators/RepeatValidatorTests.cs deleted file mode 100644 index a673d16c54d..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/Metafiles/Validators/RepeatValidatorTests.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Moq; - -namespace System.Windows.Forms.Metafiles.Tests; - -public class RepeatValidatorTests -{ - [Fact] - public unsafe void RepeatValidator_Validate_complete_should_be_expected() - { - Mock emfValidator = new(); - RepeatValidator repeatValidator = new(emfValidator.Object, 2); - - EmfRecord emfRecord = new(); - - repeatValidator.Validate(ref emfRecord, state: null!, out bool complete); - Assert.False(complete); - - // call again - we'll be at zero now - repeatValidator.Validate(ref emfRecord, state: null!, out complete); - Assert.True(complete); - } - - [Theory] - [InlineData(0)] - [InlineData(-1)] - public unsafe void RepeatValidator_Validate_should_throw_IOE_if_count_not_positive(int count) - { - Mock emfValidator = new(); - RepeatValidator repeatValidator = new(emfValidator.Object, count); - - EmfRecord emfRecord = new(); - - Assert.Throws(() => repeatValidator.Validate(ref emfRecord, state: null!, out bool complete)); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/System.Windows.Forms.Primitives.TestUtilities.Tests.csproj b/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/System.Windows.Forms.Primitives.TestUtilities.Tests.csproj deleted file mode 100644 index a29b3da0eab..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities.Tests/System.Windows.Forms.Primitives.TestUtilities.Tests.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - System.Windows.Forms.Primitives.TestUtilities.Tests - true - $(NoWarn);618 - enable - System.Windows.Forms.Primitives.TestUtilities.Tests - - - - - - - - - - - - - diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/ArchitectureDetection.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/ArchitectureDetection.cs deleted file mode 100644 index 1f4610884bf..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/ArchitectureDetection.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System; - -public static class ArchitectureDetection -{ - public static bool Is32bit => IntPtr.Size == 4; - public static bool Is64bit => IntPtr.Size == 8; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/DeviceContextState.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/DeviceContextState.cs deleted file mode 100644 index dbc98ac401b..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/DeviceContextState.cs +++ /dev/null @@ -1,203 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; -using System.Numerics; -using System.Windows.Forms.Metafiles; - -namespace System; - -/// -/// Holder for tracking HDC state. -/// -internal unsafe class DeviceContextState -{ - // Not all state is handled yet. Backfilling in as we write specific tests. Of special note is that we don't - // have tracking for Save/RestoreDC yet. - - private readonly List _savedStates = new(); - private State _currentState; - - /// - /// Initialize the current state of . - /// - public DeviceContextState(HDC hdc) - { - MapMode = (HDC_MAP_MODE)PInvoke.GetMapMode(hdc); - BackColor = PInvoke.GetBkColor(hdc); - TextColor = PInvoke.GetTextColor(hdc); - Rop2Mode = (R2_MODE)PInvoke.GetROP2(hdc); - TextAlign = (TEXT_ALIGN_OPTIONS)PInvoke.GetTextAlign(hdc); - BackgroundMode = (BACKGROUND_MODE)PInvoke.GetBkMode(hdc); - - Matrix3x2 transform = default; - PInvoke.GetWorldTransform(hdc, (XFORM*)(void*)&transform); - Transform = transform; - - Point point = default; - PInvoke.GetBrushOrgEx(hdc, &point); - BrushOrigin = point; - - var hfont = PInvoke.GetCurrentObject(hdc, OBJ_TYPE.OBJ_FONT); - PInvoke.GetObject(hfont, out LOGFONTW logfont); - SelectedFont = logfont; - - var hpen = PInvoke.GetCurrentObject(hdc, OBJ_TYPE.OBJ_PEN); - PInvoke.GetObject(hpen, out LOGPEN logpen); - SelectedPen = logpen; - - var hbrush = PInvoke.GetCurrentObject(hdc, OBJ_TYPE.OBJ_BRUSH); - PInvoke.GetObject(hbrush, out LOGBRUSH logbrush); - SelectedBrush = logbrush; - } - - public HDC_MAP_MODE MapMode { get => _currentState.MapMode; set => _currentState.MapMode = value; } - public R2_MODE Rop2Mode { get => _currentState.Rop2Mode; set => _currentState.Rop2Mode = value; } - public COLORREF BackColor { get => _currentState.BackColor; set => _currentState.BackColor = value; } - public COLORREF TextColor { get => _currentState.TextColor; set => _currentState.TextColor = value; } - public Point BrushOrigin { get => _currentState.BrushOrigin; set => _currentState.BrushOrigin = value; } - public TEXT_ALIGN_OPTIONS TextAlign { get => _currentState.TextAlign; set => _currentState.TextAlign = value; } - public BACKGROUND_MODE BackgroundMode { get => _currentState.BackgroundMode; set => _currentState.BackgroundMode = value; } - public LOGFONTW SelectedFont { get => _currentState.SelectedFont; set => _currentState.SelectedFont = value; } - public LOGBRUSH SelectedBrush { get => _currentState.SelectedBrush; set => _currentState.SelectedBrush = value; } - public EXTLOGPEN32 SelectedPen { get => _currentState.SelectedPen; set => _currentState.SelectedPen = value; } - public Point LastBeginPathBrushOrigin { get => _currentState.LastBeginPathBrushOrigin; set => _currentState.LastBeginPathBrushOrigin = value; } - public bool InPath { get => _currentState.InPath; set => _currentState.InPath = value; } - public Matrix3x2 Transform { get => _currentState.Transform; set => _currentState.Transform = value; } - public RECT[] ClipRegion { get => _currentState.ClipRegion; set => _currentState.ClipRegion = value; } - - private struct State - { - public HDC_MAP_MODE MapMode { get; set; } - public R2_MODE Rop2Mode { get; set; } - public COLORREF BackColor { get; set; } - public COLORREF TextColor { get; set; } - public Point BrushOrigin { get; set; } - public TEXT_ALIGN_OPTIONS TextAlign { get; set; } - public BACKGROUND_MODE BackgroundMode { get; set; } - public LOGFONTW SelectedFont { get; set; } - public LOGBRUSH SelectedBrush { get; set; } - public EXTLOGPEN32 SelectedPen { get; set; } - public Point LastBeginPathBrushOrigin { get; set; } - public bool InPath { get; set; } - public Matrix3x2 Transform { get; set; } - public RECT[] ClipRegion { get; set; } - } - - /// - /// When using to parse a metafile, this is the list of known created objects. - /// - public List GdiObjects { get; } = new List(); - - /// - /// Adds the given object to . - /// - public void AddGdiObject(ref EmfRecord record, int index) - { - // Ensure we have capacity - if (GdiObjects.Capacity <= index) - { - GdiObjects.Capacity = index + 1; - } - - // Fill in any gaps if we have them - while (GdiObjects.Count <= index) - { - GdiObjects.Add(default); - } - - GdiObjects[index] = record; - } - - public void SaveDC() => _savedStates.Add(_currentState); - - public void RestoreDC(int state) - { - int index; - if (state > 0) - { - // Positive removes a specific state - index = state - 1; - } - else - { - // Negative is relative (-1 is last saved state) - index = _savedStates.Count + state; - } - - _currentState = _savedStates[index]; - _savedStates.RemoveRange(index, _savedStates.Count - index); - } - - /// - /// Applies the given selection record to the state. - /// - public void SelectGdiObject(EMRINDEXRECORD* selectionRecord) - { - // Not all records are handled yet. Backfilling in as we write specific tests. - - if (selectionRecord->IsStockObject) - { - HGDIOBJ hgdiobj = PInvoke.GetStockObject(selectionRecord->StockObject); - - switch (selectionRecord->StockObject) - { - case GET_STOCK_OBJECT_FLAGS.ANSI_FIXED_FONT: - case GET_STOCK_OBJECT_FLAGS.OEM_FIXED_FONT: - case GET_STOCK_OBJECT_FLAGS.ANSI_VAR_FONT: - case GET_STOCK_OBJECT_FLAGS.SYSTEM_FONT: - case GET_STOCK_OBJECT_FLAGS.DEVICE_DEFAULT_FONT: - case GET_STOCK_OBJECT_FLAGS.SYSTEM_FIXED_FONT: - case GET_STOCK_OBJECT_FLAGS.DEFAULT_GUI_FONT: - PInvoke.GetObject(hgdiobj, out LOGFONTW logfont); - SelectedFont = logfont; - break; - case GET_STOCK_OBJECT_FLAGS.WHITE_BRUSH: - case GET_STOCK_OBJECT_FLAGS.LTGRAY_BRUSH: - case GET_STOCK_OBJECT_FLAGS.GRAY_BRUSH: - case GET_STOCK_OBJECT_FLAGS.DKGRAY_BRUSH: - case GET_STOCK_OBJECT_FLAGS.BLACK_BRUSH: - case GET_STOCK_OBJECT_FLAGS.NULL_BRUSH: - case GET_STOCK_OBJECT_FLAGS.DC_BRUSH: - PInvoke.GetObject(hgdiobj, out LOGBRUSH logBrush); - SelectedBrush = logBrush; - break; - case GET_STOCK_OBJECT_FLAGS.WHITE_PEN: - case GET_STOCK_OBJECT_FLAGS.BLACK_PEN: - case GET_STOCK_OBJECT_FLAGS.NULL_PEN: - case GET_STOCK_OBJECT_FLAGS.DC_PEN: - PInvoke.GetObject(hgdiobj, out LOGPEN logPen); - SelectedPen = logPen; - break; - case GET_STOCK_OBJECT_FLAGS.DEFAULT_PALETTE: - break; - } - - return; - } - - // WARNING: You can not use fields that index out of the saved EmfRecord's contents here as the struct - // is just a copy of the original. Any pointers or offsets outside of the struct aren't valid. - - EmfRecord savedRecord = GdiObjects[(int)selectionRecord->index]; - switch (savedRecord.Type) - { - case ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTCREATEFONTINDIRECTW: - SelectedFont = savedRecord.ExtCreateFontIndirectWRecord->elfw.elfLogFont; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEPEN: - SelectedPen = savedRecord.CreatePenRecord->lopn; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTCREATEPEN: - SelectedPen = savedRecord.ExtCreatePenRecord->elp; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEBRUSHINDIRECT: - SelectedBrush = savedRecord.CreateBrushIndirectRecord->lb; - break; - } - } - - public Point TransformPoint(Point point) => Transform.TransformPoint(point); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/AssertExtensions.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/AssertExtensions.cs deleted file mode 100644 index 8b1526ba282..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/AssertExtensions.cs +++ /dev/null @@ -1,709 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Numerics; -using System.Runtime.InteropServices; -using System.Windows.Forms; -using Xunit.Sdk; -using static Interop; - -namespace System; - -public static class AssertExtensions -{ - private static bool IsNetFramework => RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework"); - - internal static void True(AccessibleObject accessibleObject, UiaCore.UIA propertyId) - { - Assert.True((bool)accessibleObject.GetPropertyValue(propertyId)); - } - - internal static void False(AccessibleObject accessibleObject, UiaCore.UIA propertyId) - { - Assert.False((bool)accessibleObject.GetPropertyValue(propertyId)); - } - - public static void Throws(Action action, string expectedMessage) - where T : Exception - { - Assert.Equal(expectedMessage, Assert.Throws(action).Message); - } - - public static void ThrowsContains(Action action, string expectedMessageContent) - where T : Exception - { - Assert.Contains(expectedMessageContent, Assert.Throws(action).Message); - } - - public static T Throws(string netCoreParamName, string netFxParamName, Action action) - where T : ArgumentException - { - T exception = Assert.Throws(action); - - if (netFxParamName is null && IsNetFramework) - { - // Param name varies between .NET Framework versions -- skip checking it - return exception; - } - - string expectedParamName = - IsNetFramework ? - netFxParamName : netCoreParamName; - - Assert.Equal(expectedParamName, exception.ParamName); - return exception; - } - - public static void Throws(string netCoreParamName, string netFxParamName, Func testCode) - where T : ArgumentException - { - T exception = Assert.Throws(testCode); - - if (netFxParamName is null && IsNetFramework) - { - // Param name varies between .NET Framework versions -- skip checking it - return; - } - - string expectedParamName = - IsNetFramework ? - netFxParamName : netCoreParamName; - - Assert.Equal(expectedParamName, exception.ParamName); - } - - public static T Throws(string expectedParamName, Action action) - where T : ArgumentException - { - T exception = Assert.Throws(action); - - Assert.Equal(expectedParamName, exception.ParamName); - - return exception; - } - - public static T Throws(Action action) - where T : Exception - { - T exception = Assert.Throws(action); - - return exception; - } - - public static TException Throws(Func func) - where TException : Exception - { - object result = null; - bool returned = false; - try - { - return - Assert.Throws(() => - { - result = func(); - returned = true; - }); - } - catch (Exception ex) when (returned) - { - string resultStr; - if (result is null) - { - resultStr = "(null)"; - } - else - { - resultStr = result.ToString(); - if (typeof(TResult) == typeof(string)) - { - resultStr = $"\"{resultStr}\""; - } - } - - throw new AggregateException($"Result: {resultStr}", ex); - } - } - - public static T Throws(string expectedParamName, Func testCode) - where T : ArgumentException - { - T exception = Assert.Throws(testCode); - - Assert.Equal(expectedParamName, exception.ParamName); - - return exception; - } - - public static async Task ThrowsAsync(string expectedParamName, Func testCode) - where T : ArgumentException - { - T exception = await Assert.ThrowsAsync(testCode); - - Assert.Equal(expectedParamName, exception.ParamName); - - return exception; - } - - public static void Throws(string expectedParamName, Action action) - where TNetCoreExceptionType : ArgumentException - where TNetFxExceptionType : Exception - { - if (IsNetFramework) - { - // Support cases where the .NET Core exception derives from ArgumentException - // but the .NET Framework exception is not. - if (typeof(ArgumentException).IsAssignableFrom(typeof(TNetFxExceptionType))) - { - Exception exception = Assert.Throws(typeof(TNetFxExceptionType), action); - Assert.Equal(expectedParamName, ((ArgumentException)exception).ParamName); - } - else - { - AssertExtensions.Throws(action); - } - } - else - { - AssertExtensions.Throws(expectedParamName, action); - } - } - - public static Exception Throws(Action action) - where TNetCoreExceptionType : Exception - where TNetFxExceptionType : Exception - { - return Throws(typeof(TNetCoreExceptionType), typeof(TNetFxExceptionType), action); - } - - public static Exception Throws(Type netCoreExceptionType, Type netFxExceptionType, Action action) - { - if (IsNetFramework) - { - return Assert.Throws(netFxExceptionType, action); - } - else - { - return Assert.Throws(netCoreExceptionType, action); - } - } - - public static void Throws(string netCoreParamName, string netFxParamName, Action action) - where TNetCoreExceptionType : ArgumentException - where TNetFxExceptionType : ArgumentException - { - if (IsNetFramework) - { - Throws(netFxParamName, action); - } - else - { - Throws(netCoreParamName, action); - } - } - - public static void ThrowsAny(Type firstExceptionType, Type secondExceptionType, Action action) - { - ThrowsAnyInternal(action, firstExceptionType, secondExceptionType); - } - - private static void ThrowsAnyInternal(Action action, params Type[] exceptionTypes) - { - try - { - action(); - } - catch (Exception e) - { - Type exceptionType = e.GetType(); - if (exceptionTypes.Any(t => t.Equals(exceptionType))) - return; - - throw new XunitException($"Expected one of: ({string.Join(", ", exceptionTypes)}) -> Actual: ({exceptionType}): {e}"); // Log message and callstack to help diagnosis - } - - throw new XunitException($"Expected one of: ({string.Join(", ", exceptionTypes)}) -> Actual: No exception thrown"); - } - - public static void ThrowsAny(Action action) - where TFirstExceptionType : Exception - where TSecondExceptionType : Exception - { - ThrowsAnyInternal(action, typeof(TFirstExceptionType), typeof(TSecondExceptionType)); - } - - public static void ThrowsAny(Action action) - where TFirstExceptionType : Exception - where TSecondExceptionType : Exception - where TThirdExceptionType : Exception - { - ThrowsAnyInternal(action, typeof(TFirstExceptionType), typeof(TSecondExceptionType), typeof(TThirdExceptionType)); - } - - public static void ThrowsIf(bool condition, Action action) - where T : Exception - { - if (condition) - { - Assert.Throws(action); - } - else - { - action(); - } - } - - public static void Canceled(CancellationToken cancellationToken, Action testCode) - { - OperationCanceledException oce = Assert.ThrowsAny(testCode); - if (cancellationToken.CanBeCanceled) - { - Assert.Equal(cancellationToken, oce.CancellationToken); - } - } - - public static Task CanceledAsync(CancellationToken cancellationToken, Task task) - { - Assert.NotNull(task); - return CanceledAsync(cancellationToken, () => task); - } - - public static async Task CanceledAsync(CancellationToken cancellationToken, Func testCode) - { - OperationCanceledException oce = await Assert.ThrowsAnyAsync(testCode); - if (cancellationToken.CanBeCanceled) - { - Assert.Equal(cancellationToken, oce.CancellationToken); - } - } - - private static string AddOptionalUserMessage(string message, string userMessage) - { - if (userMessage is null) - return message; - else - return $"{message} {userMessage}"; - } - - /// - /// Tests whether the specified string contains the specified substring - /// and throws an exception if the substring does not occur within the - /// test string or if either string or substring is null. - /// - /// - /// The string that is expected to contain . - /// - /// - /// The string expected to occur within . - /// - public static void Contains(string value, string substring) - { - Assert.NotNull(value); - Assert.NotNull(substring); - Assert.Contains(substring, value, StringComparison.Ordinal); - } - - /// - /// Validate that a given value is greater than another value. - /// - /// The value that should be greater than . - /// The value that should be greater than. - public static void GreaterThan(T actual, T greaterThan, string userMessage = null) where T : IComparable - { - if (actual is null) - throw new XunitException( - greaterThan is null - ? AddOptionalUserMessage($"Expected: to be greater than .", userMessage) - : AddOptionalUserMessage($"Expected: to be greater than {greaterThan}.", userMessage)); - - if (actual.CompareTo(greaterThan) <= 0) - throw new XunitException(AddOptionalUserMessage($"Expected: {actual} to be greater than {greaterThan}", userMessage)); - } - - /// - /// Validate that a given value is less than another value. - /// - /// The value that should be less than . - /// The value that should be less than. - public static void LessThan(T actual, T lessThan, string userMessage = null) where T : IComparable - { - if (actual is null) - { - if (lessThan is null) - { - throw new XunitException(AddOptionalUserMessage($"Expected: to be less than .", userMessage)); - } - else - { - // Null is always less than non-null - return; - } - } - - if (actual.CompareTo(lessThan) >= 0) - throw new XunitException(AddOptionalUserMessage($"Expected: {actual} to be less than {lessThan}", userMessage)); - } - - /// - /// Validate that a given value is less than or equal to another value. - /// - /// The value that should be less than or equal to - /// The value that should be less than or equal to. - public static void LessThanOrEqualTo(T actual, T lessThanOrEqualTo, string userMessage = null) where T : IComparable - { - // null, by definition is always less than or equal to - if (actual is null) - return; - - if (actual.CompareTo(lessThanOrEqualTo) > 0) - throw new XunitException(AddOptionalUserMessage($"Expected: {actual} to be less than or equal to {lessThanOrEqualTo}", userMessage)); - } - - /// - /// Validate that a given value is greater than or equal to another value. - /// - /// The value that should be greater than or equal to - /// The value that should be greater than or equal to. - public static void GreaterThanOrEqualTo(T actual, T greaterThanOrEqualTo, string userMessage = null) where T : IComparable - { - // null, by definition is always less than or equal to - if (actual is null) - { - if (greaterThanOrEqualTo is null) - { - // We're equal - return; - } - else - { - // Null is always less than non-null - throw new XunitException(AddOptionalUserMessage($"Expected: to be greater than or equal to .", userMessage)); - } - } - - if (actual.CompareTo(greaterThanOrEqualTo) < 0) - throw new XunitException(AddOptionalUserMessage($"Expected: {actual} to be greater than or equal to {greaterThanOrEqualTo}", userMessage)); - } - - // NOTE: Consider using SequenceEqual below instead, as it will give more useful information about what - // the actual differences are, especially for large arrays/spans. - /// - /// Validates that the actual array is equal to the expected array. XUnit only displays the first 5 values - /// of each collection if the test fails. This doesn't display at what point or how the equality assertion failed. - /// - /// The array that should be equal to. - /// - public static void Equal(T[] expected, T[] actual) where T : IEquatable - { - // Use the SequenceEqual to compare the arrays for better performance. The default Assert.Equal method compares - // the arrays by boxing each element that is very slow for large arrays. - if (!expected.AsSpan().SequenceEqual(actual.AsSpan())) - { - string expectedString = string.Join(", ", expected); - string actualString = string.Join(", ", actual); - throw new AssertActualExpectedException(expectedString, actualString, null); - } - } - - /// Validates that the two sets contains the same elements. XUnit doesn't display the full collections. - public static void Equal(HashSet expected, HashSet actual) - { - if (!actual.SetEquals(expected)) - { - throw new XunitException($"Expected: {string.Join(", ", expected)}{Environment.NewLine}Actual: {string.Join(", ", actual)}"); - } - } - - /// - /// Validates that the actual collection contains same items as expected collection. If the test fails, this will display: - /// 1. Count if two collection count are different; - /// 2. Missed expected collection item when found - /// - /// The collection that should contain same items as - /// - /// The comparer used to compare the items in two collections - public static void CollectionEqual(IEnumerable expected, IEnumerable actual, IEqualityComparer comparer) - { - var actualItemCountMapping = new Dictionary(comparer); - int actualCount = 0; - foreach (T actualItem in actual) - { - if (actualItemCountMapping.TryGetValue(actualItem, out ItemCount countInfo)) - { - countInfo.Original++; - countInfo.Remain++; - } - else - { - actualItemCountMapping[actualItem] = new ItemCount(1, 1); - } - - actualCount++; - } - - T[] expectedArray = expected.ToArray(); - int expectedCount = expectedArray.Length; - - if (expectedCount != actualCount) - { - throw new XunitException($"Expected count: {expectedCount}{Environment.NewLine}Actual count: {actualCount}"); - } - - for (int i = 0; i < expectedCount; i++) - { - T currentExpectedItem = expectedArray[i]; - if (!actualItemCountMapping.TryGetValue(currentExpectedItem, out ItemCount countInfo)) - { - throw new XunitException($"Expected: {currentExpectedItem} but not found"); - } - - if (countInfo.Remain == 0) - { - throw new XunitException($"Collections are not equal.{Environment.NewLine}Totally {countInfo.Original} {currentExpectedItem} in actual collection but expect more {currentExpectedItem}"); - } - - countInfo.Remain--; - } - } - - /// - /// Validates that the actual span is equal to the expected span. - /// If this fails, determine where the differences are and create an exception with that information. - /// - /// The array that should be equal to. - /// - public static void SequenceEqual(ReadOnlySpan expected, ReadOnlySpan actual) where T : IEquatable - { - // Use the SequenceEqual to compare the arrays for better performance. The default Assert.Equal method compares - // the arrays by boxing each element that is very slow for large arrays. - if (!expected.SequenceEqual(actual)) - { - if (expected.Length != actual.Length) - { - throw new XunitException($"Expected: Span of length {expected.Length}{Environment.NewLine}Actual: Span of length {actual.Length}"); - } - else - { - const int MaxDiffsToShow = 10; // arbitrary; enough to be useful, hopefully, but still manageable - - int diffCount = 0; - string message = $"Showing first {MaxDiffsToShow} differences{Environment.NewLine}"; - for (int i = 0; i < expected.Length; i++) - { - if (!expected[i].Equals(actual[i])) - { - diffCount++; - - // Add up to 10 differences to the exception message - if (diffCount <= MaxDiffsToShow) - { - message += $" Position {i}: Expected: {expected[i]}, Actual: {actual[i]}{Environment.NewLine}"; - } - } - } - - message += $"Total number of differences: {diffCount} out of {expected.Length}"; - - throw new XunitException(message); - } - } - } - - public static void FilledWith(T expected, ReadOnlySpan actual) - { - EqualityComparer comparer = EqualityComparer.Default; - - for (int i = 0; i < actual.Length; i++) - { - if (!comparer.Equals(expected, actual[i])) - { - throw new XunitException($"Expected {expected?.ToString() ?? "null"} at position {i}; actual {actual[i]?.ToString() ?? "null"}"); - } - } - } - - public static void SequenceEqual(Span expected, Span actual) where T : IEquatable => SequenceEqual((ReadOnlySpan)expected, (ReadOnlySpan)actual); - - public static void SequenceEqual(T[] expected, T[] actual) where T : IEquatable => SequenceEqual(expected.AsSpan(), actual.AsSpan()); - - public static void AtLeastOneEquals(T expected1, T expected2, T value) - { - EqualityComparer comparer = EqualityComparer.Default; - if (!(comparer.Equals(value, expected1) || comparer.Equals(value, expected2))) - throw new XunitException($"Expected: {expected1} || {expected2}{Environment.NewLine}Actual: {value}"); - } - - /// - /// Compares two strings, logs entire content if they are not equal. - /// - public static void Equal(string expected, string actual) - { - try - { - Assert.Equal(expected, actual); - } - catch (Exception e) - { - throw new XunitException( - e.Message + Environment.NewLine + - Environment.NewLine + - "Expected:" + Environment.NewLine + - expected + Environment.NewLine + - Environment.NewLine + - "Actual:" + Environment.NewLine + - actual + Environment.NewLine + - Environment.NewLine); - } - } - - public delegate void AssertThrowsActionReadOnly(ReadOnlySpan span); - - public delegate void AssertThrowsAction(Span span); - - // Cannot use standard Assert.Throws() when testing Span - Span and closures don't get along. - public static E AssertThrows(ReadOnlySpan span, AssertThrowsActionReadOnly action) where E : Exception - { - Exception exception; - - try - { - action(span); - exception = null; - } - catch (Exception ex) - { - exception = ex; - } - - switch(exception) - { - case null: - throw new ThrowsException(typeof(E)); - case E ex when (ex.GetType() == typeof(E)): - return ex; - default: - throw new ThrowsException(typeof(E), exception); - } - } - - public static E AssertThrows(Span span, AssertThrowsAction action) where E : Exception - { - Exception exception; - - try - { - action(span); - exception = null; - } - catch (Exception ex) - { - exception = ex; - } - - switch(exception) - { - case null: - throw new ThrowsException(typeof(E)); - case E ex when (ex.GetType() == typeof(E)): - return ex; - default: - throw new ThrowsException(typeof(E), exception); - } - } - - public static E Throws(string expectedParamName, ReadOnlySpan span, AssertThrowsActionReadOnly action) - where E : ArgumentException - { - E exception = AssertThrows(span, action); - Assert.Equal(expectedParamName, exception.ParamName); - return exception; - } - - public static E Throws(string expectedParamName, Span span, AssertThrowsAction action) - where E : ArgumentException - { - E exception = AssertThrows(span, action); - Assert.Equal(expectedParamName, exception.ParamName); - return exception; - } - - private class ItemCount - { - public int Original { get; set; } - public int Remain { get; set; } - - public ItemCount(int original, int remain) - { - Original = original; - Remain = remain; - } - } - - /// Verifies that two values are equal, within the . - /// The expected value - /// The value to be compared against - /// The total variance allowed between the expected and actual results. - /// Thrown when the values are not equal - public static void Equal(RectangleF expected, RectangleF actual, float variance) - { - if (!ComparisonHelpers.EqualsFloating(expected.X, actual.X, variance) - || !ComparisonHelpers.EqualsFloating(expected.Y, actual.Y, variance) - || !ComparisonHelpers.EqualsFloating(expected.Width, actual.Width, variance) - || !ComparisonHelpers.EqualsFloating(expected.Height, actual.Height, variance)) - { - throw new EqualException(expected, actual); - } - } - - /// Verifies that two values are equal, within the . - /// The expected value - /// The value to be compared against - /// The total variance allowed between the expected and actual results. - /// Thrown when the values are not equal - public static void Equal(T expected, T actual, T variance) - where T : struct, IFloatingPoint - { - if (!ComparisonHelpers.EqualsFloating(expected, actual, variance)) - { - throw new EqualException(ToStringPadded(expected), ToStringPadded(actual)); - } - - // We have a custom ToString here to ensure that edge cases (specifically +-0.0, - // but also NaN and +-infinity) are correctly and consistently represented. - static string ToStringPadded(T value) - { - if (T.IsNaN(value)) - { - return "NaN".PadLeft(10); - } - else if (T.IsPositiveInfinity(value)) - { - return "+\u221E".PadLeft(10); - } - else if (T.IsNegativeInfinity(value)) - { - return "-\u221E".PadLeft(10); - } - else if (IsNegativeZero(value)) - { - return "-0.0".PadLeft(10); - } - else if (IsPositiveZero(value)) - { - return "+0.0".PadLeft(10); - } - else - { - return $"{value,10:G9}"; - } - } - } - - private static unsafe bool IsNegativeZero(T value) - where T : IFloatingPoint - => T.IsZero(value) && T.IsNegative(value); - - private static unsafe bool IsPositiveZero(T value) - where T : IFloatingPoint - => T.IsZero(value) && T.IsPositive(value); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/GdiExtensions.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/GdiExtensions.cs deleted file mode 100644 index 790585670e0..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/GdiExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Numerics; - -namespace System; - -internal static class GdiExtensions -{ - public static string ToSystemColorString(this COLORREF colorRef) - => SystemCOLORs.ToSystemColorString(colorRef); - - public static Point TransformPoint(in this Matrix3x2 transform, Point point) - { - if (transform.IsIdentity) - { - return point; - } - - float y = point.Y; - float x = point.X; - - float xadd = y * transform.M21 + transform.M31; - float yadd = x * transform.M12 + transform.M32; - x *= transform.M11; - x += xadd; - y *= transform.M22; - y += yadd; - - return new Point((int)x, (int)y); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/SpanExtensions.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/SpanExtensions.cs deleted file mode 100644 index a43299aa580..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/SpanExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System; - -public static class SpanExtensions -{ - public static T2[] Transform(this ReadOnlySpan span, Func transform) - { - T2[] output = new T2[span.Length]; - for (int i = 0; i < span.Length; i++) - { - output[i] = transform(span[i]); - } - - return output; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/TheoryExtensions.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/TheoryExtensions.cs deleted file mode 100644 index aac1b9bfedd..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Extensions/TheoryExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; - -namespace System; - -public static class TheoryExtensions -{ - /// - /// Converts an IEnumerable into an Xunit theory compatible enumerable. - /// - public static TheoryData ToTheoryData(this IEnumerable data) - { - // Returning TheoryData rather than IEnumerable directly should - // encourage discover and usage of TheoryData classes for more - // complicated theories. Slightly easier to type as well. - return new TheoryDataAdapter(data.Select(d => new object[] { d })); - } - - private class TheoryDataAdapter : TheoryData, IEnumerable - { - private readonly IEnumerable _data; - - public TheoryDataAdapter(IEnumerable data) - { - _data = data; - } - - public new IEnumerator GetEnumerator() => _data.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/GdiHelper.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/GdiHelper.cs deleted file mode 100644 index 6d99d4c510d..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/GdiHelper.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System; - -/// -/// Utility class for Gdi related things. -/// -public static class GdiHelper -{ - static GdiHelper() - { - using var dc = GetDcScope.ScreenDC; - LogicalPixelsX = PInvoke.GetDeviceCaps(dc, GET_DEVICE_CAPS_INDEX.LOGPIXELSX); - LogicalPixelsY = PInvoke.GetDeviceCaps(dc, GET_DEVICE_CAPS_INDEX.LOGPIXELSY); - } - - /// - /// Logical pixels per inch horizontally. - /// - public static int LogicalPixelsX { get; private set; } - - /// - /// Logical pixels per inch vertically. - /// - public static int LogicalPixelsY { get; private set; } - - // private const int TwipsPerInch = 1440; - - /// - /// Himetric units per inch. - /// - public const int HiMetricPerInch = 2540; - - /// - /// Convert HiMetric units to pixels (width). - /// - public static int HimetricToPixelX(int himetric) - => (int)Math.Round((double)((long)LogicalPixelsX * himetric) / HiMetricPerInch, 0); - - /// - /// Convert Himetric units to pixels (height). - /// - public static int HimetricToPixelY(int himetric) - => (int)Math.Round((double)((long)LogicalPixelsY * himetric) / HiMetricPerInch, 0); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/GlobalUsings.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/GlobalUsings.cs deleted file mode 100644 index f5e1f631fa7..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/GlobalUsings.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -global using System.Diagnostics; -global using System.Diagnostics.CodeAnalysis; -global using Windows.Win32; -global using Windows.Win32.Foundation; -global using Windows.Win32.Graphics.Gdi; -global using Windows.Win32.UI.WindowsAndMessaging; -global using Xunit; diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/HdcDeviceContextAdapter.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/HdcDeviceContextAdapter.cs deleted file mode 100644 index c63a5379759..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/HdcDeviceContextAdapter.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; - -namespace System; - -/// -/// Simple adapter for passing as . Does not manage HDC -/// lifetime. -/// -internal class HdcDeviceContextAdapter : IDeviceContext -{ - private readonly HDC _hdc; - - public HdcDeviceContextAdapter(HDC hdc) => _hdc = hdc; - - public IntPtr GetHdc() => (IntPtr)_hdc; - public void ReleaseHdc() { } - public void Dispose() { } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/DataHelpers.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/DataHelpers.cs deleted file mode 100644 index a7ce7ef14b2..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/DataHelpers.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Numerics; -using System.Runtime.CompilerServices; - -namespace System.Windows.Forms.Metafiles; - -public static class DataHelpers -{ - public static unsafe Point[] PointArray(params int[] values) - { - if (values is null) - throw new ArgumentNullException(nameof(values)); - - if (values.Length % 2 != 0) - throw new ArgumentOutOfRangeException(nameof(values)); - - Point[] points = new Point[values.Length / 2]; - fixed (int* i = values) - fixed (Point* p = points) - { - Unsafe.CopyBlock(p, i, (uint)(sizeof(int) * values.Length)); - } - - return points; - } - - public static unsafe Point[] PointArray(Matrix3x2 transform, params int[] values) - { - Point[] points = PointArray(values); - for (int i = 0; i < points.Length; i++) - { - points[i] = transform.TransformPoint(points[i]); - } - - return points; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/EmfRecord.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/EmfRecord.cs deleted file mode 100644 index ffd635f77fe..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/EmfRecord.cs +++ /dev/null @@ -1,171 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable -using Windows.Win32.UI.ColorSystem; - -namespace System.Windows.Forms.Metafiles; - -internal readonly unsafe struct EmfRecord -{ - public HDC HDC { get; } - private readonly HANDLETABLE* _lpht; - private readonly ENHMETARECORD* _lpmr; - private readonly int _nHandles; - public LPARAM Data { get; } - - public EmfRecord( - HDC hdc, - HANDLETABLE* lpht, - ENHMETARECORD* lpmr, - int nHandles, - LPARAM data) - { - HDC = hdc; - _lpht = lpht; - _lpmr = lpmr; - _nHandles = nHandles; - Data = data; - } - - public ENHANCED_METAFILE_RECORD_TYPE Type => _lpmr->iType; - public ReadOnlySpan Params => _lpmr->dParm.AsReadOnlySpan(); - public ReadOnlySpan Handles => new(_lpht, _nHandles); - - public ENHMETAHEADER* HeaderRecord => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_HEADER ? (ENHMETAHEADER*)_lpmr : null; - public EMREXTSELECTCLIPRGN* ExtSelectClipRgnRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTSELECTCLIPRGN ? (EMREXTSELECTCLIPRGN*)_lpmr : null; - public EMRPOINTRECORD* SetViewportOrgExRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETVIEWPORTORGEX ? (EMRPOINTRECORD*)_lpmr : null; - public EMRPOINTRECORD* SetBrushOrgExRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETBRUSHORGEX ? (EMRPOINTRECORD*)_lpmr : null; - public EMRPOINTRECORD* SetWindowOrgExRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETWINDOWORGEX ? (EMRPOINTRECORD*)_lpmr : null; - public EMRPOINTRECORD* OffsetClipRgnRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_OFFSETCLIPRGN ? (EMRPOINTRECORD*)_lpmr : null; - public EMRPOINTRECORD* MoveToExRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_MOVETOEX ? (EMRPOINTRECORD*)_lpmr : null; - public EMRPOINTRECORD* LineToRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_LINETO ? (EMRPOINTRECORD*)_lpmr : null; - public EMRCREATEBRUSHINDIRECT* CreateBrushIndirectRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEBRUSHINDIRECT ? (EMRCREATEBRUSHINDIRECT*)_lpmr : null; - public EMRENUMRECORD* SetROP2Record - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETROP2 ? (EMRENUMRECORD*)_lpmr : null; - public EMRENUMRECORD* SetBkModeRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETBKMODE ? (EMRENUMRECORD*)_lpmr : null; - public EMRCREATEPEN* CreatePenRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEPEN ? (EMRCREATEPEN*)_lpmr : null; - public EMREXTCREATEPEN* ExtCreatePenRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTCREATEPEN ? (EMREXTCREATEPEN*)_lpmr : null; - public EMRINDEXRECORD* SelectObjectRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SELECTOBJECT ? (EMRINDEXRECORD*)_lpmr : null; - public EMRINDEXRECORD* DeleteObjectRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_DELETEOBJECT ? (EMRINDEXRECORD*)_lpmr : null; - public EMRBITBLT* BitBltRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_BITBLT ? (EMRBITBLT*)_lpmr : null; - public EMRENUMRECORD* SetIcmModeRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETICMMODE ? (EMRENUMRECORD*)_lpmr : null; - public EMRPOLY16* Polygon16Record - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYGON16 ? (EMRPOLY16*)_lpmr : null; - public EMRPOLY16* Polyline16Record - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYLINE16 ? (EMRPOLY16*)_lpmr : null; - public EMRPOLY16* PolyBezier16Record - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYBEZIER16 ? (EMRPOLY16*)_lpmr : null; - public EMRPOLY16* PolylineTo16Record - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYLINETO16 ? (EMRPOLY16*)_lpmr : null; - public EMRPOLY16* PolyBezierTo16Record - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYBEZIERTO16 ? (EMRPOLY16*)_lpmr : null; - public EMRPOLYPOLY16* PolyPolyline16Record - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYLINE16 ? (EMRPOLYPOLY16*)_lpmr : null; - public EMRPOLYPOLY16* PolyPolygon16Record - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYGON16 ? (EMRPOLYPOLY16*)_lpmr : null; - public EMRSETWORLDTRANSFORM* SetWorldTransformRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETWORLDTRANSFORM ? (EMRSETWORLDTRANSFORM*)_lpmr : null; - public EMRMODIFYWORLDTRANSFORM* ModifyWorldTransformRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_MODIFYWORLDTRANSFORM ? (EMRMODIFYWORLDTRANSFORM*)_lpmr : null; - public EMRSETCOLOR* SetBkColorRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETBKCOLOR ? (EMRSETCOLOR*)_lpmr : null; - public EMRSETCOLOR* SetTextColorRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETTEXTCOLOR ? (EMRSETCOLOR*)_lpmr : null; - public EMRCREATEDIBPATTERNBRUSHPT* CreateDibPatternBrushPtRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEDIBPATTERNBRUSHPT ? (EMRCREATEDIBPATTERNBRUSHPT*)_lpmr : null; - public EMRENUMRECORD* SetTextAlignRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETTEXTALIGN ? (EMRENUMRECORD*)_lpmr : null; - public EMREXTCREATEFONTINDIRECTW* ExtCreateFontIndirectWRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTCREATEFONTINDIRECTW ? (EMREXTCREATEFONTINDIRECTW*)_lpmr : null; - public EMREXTTEXTOUTW* ExtTextOutWRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTTEXTOUTW ? (EMREXTTEXTOUTW*)_lpmr : null; - public EMRENUMRECORD* SetMapModeRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_SETMAPMODE ? (EMRENUMRECORD*)_lpmr : null; - public EMRRECTRECORD* FillPathRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_FILLPATH ? (EMRRECTRECORD*)_lpmr : null; - public EMRRECTRECORD* StrokeAndFillPathRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_STROKEANDFILLPATH ? (EMRRECTRECORD*)_lpmr : null; - public EMRRECTRECORD* StrokePathRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_STROKEPATH ? (EMRRECTRECORD*)_lpmr : null; - public EMRRECTRECORD* ExcludeClipRectRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_EXCLUDECLIPRECT ? (EMRRECTRECORD*)_lpmr : null; - public EMRRECTRECORD* IntersetClipRectRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_INTERSECTCLIPRECT ? (EMRRECTRECORD*)_lpmr : null; - public EMRRECTRECORD* EllipseRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_ELLIPSE ? (EMRRECTRECORD*)_lpmr : null; - public EMRRECTRECORD* RectangleRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_RECTANGLE ? (EMRRECTRECORD*)_lpmr : null; - public EMRRESTOREDC* RestoreDCRecord - => Type == ENHANCED_METAFILE_RECORD_TYPE.EMR_RESTOREDC ? (EMRRESTOREDC*)_lpmr : null; - - public override string ToString() => Type switch - { - // Note that not all records have special handling yet- we're filling these in as we go. - ENHANCED_METAFILE_RECORD_TYPE.EMR_HEADER => HeaderRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTSELECTCLIPRGN => ExtSelectClipRgnRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETVIEWPORTORGEX => SetViewportOrgExRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETWINDOWORGEX => SetWindowOrgExRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_OFFSETCLIPRGN => OffsetClipRgnRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_MOVETOEX => MoveToExRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_LINETO => LineToRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEBRUSHINDIRECT => CreateBrushIndirectRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETBKMODE => SetBkModeRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETROP2 => SetROP2Record->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEPEN => CreatePenRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTCREATEPEN => ExtCreatePenRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SELECTOBJECT => SelectObjectRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_DELETEOBJECT => DeleteObjectRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_BITBLT => BitBltRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETICMMODE => SetIcmModeRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYLINE16 => Polyline16Record->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYBEZIER16 => PolyBezier16Record->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYGON16 => Polygon16Record->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYBEZIERTO16 => PolyBezierTo16Record->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYLINETO16 => PolylineTo16Record->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYGON16 => PolyPolygon16Record->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYLINE16 => PolyPolyline16Record->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETWORLDTRANSFORM => SetWorldTransformRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_MODIFYWORLDTRANSFORM => ModifyWorldTransformRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETTEXTCOLOR => SetTextColorRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETBKCOLOR => SetBkColorRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEDIBPATTERNBRUSHPT => CreateDibPatternBrushPtRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETTEXTALIGN => SetTextAlignRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTCREATEFONTINDIRECTW => ExtCreateFontIndirectWRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTTEXTOUTW => ExtTextOutWRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETMAPMODE => SetMapModeRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_FILLPATH => FillPathRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_STROKEANDFILLPATH => StrokeAndFillPathRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_STROKEPATH => StrokePathRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_EXCLUDECLIPRECT => ExcludeClipRectRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_INTERSECTCLIPRECT => IntersetClipRectRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_ELLIPSE => EllipseRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_RECTANGLE => RectangleRecord->ToString(), - ENHANCED_METAFILE_RECORD_TYPE.EMR_RESTOREDC => RestoreDCRecord->ToString(), - _ => $"[EMR{Type}]" - }; - - public string ToString(DeviceContextState state) => Type switch - { - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYLINE16 => Polyline16Record->ToString(state), - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYGON16 => Polygon16Record->ToString(state), - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYGON16 => PolyPolygon16Record->ToString(state), - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYLINE16 => PolyPolyline16Record->ToString(state), - _ => ToString() - }; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/EmfScope.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/EmfScope.cs deleted file mode 100644 index c4434fd1555..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/EmfScope.cs +++ /dev/null @@ -1,258 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.ComponentModel; -using System.Numerics; -using System.Runtime.InteropServices; -using System.Text; - -namespace System.Windows.Forms.Metafiles; - -internal class EmfScope : -#if DEBUG - DisposalTracking.Tracker, -#endif - IDisposable -{ - public HDC HDC { get; } - private HENHMETAFILE _hemf; - - public unsafe EmfScope() - : this(CreateEnhMetaFile()) - { - } - - public EmfScope(HDC hdc) - { - HDC = hdc; - _hemf = default; - } - - public EmfScope(HENHMETAFILE hemf) - { - _hemf = hemf; - } - - private static unsafe HDC CreateEnhMetaFile( - HDC hdc = default, - string? lpFilename = null, - RECT* lprc = null, - string? lpDesc = null) - { - fixed (char* pFileName = lpFilename) - fixed (char* pDesc = lpDesc) - { - HDC metafileHdc = PInvoke.CreateEnhMetaFile(hdc, pFileName, lprc, pDesc); - if (metafileHdc.IsNull) - { - throw new Win32Exception("Could not create metafile"); - } - - return metafileHdc; - } - } - - public static unsafe EmfScope Create() => new(); - - public HENHMETAFILE HENHMETAFILE - { - get - { - if (_hemf.IsNull) - { - if (HDC.IsNull) - { - return default; - } - - _hemf = PInvoke.CloseEnhMetaFile(HDC); - } - - return _hemf; - } - } - - public unsafe void Enumerate(ProcessRecordDelegate enumerator) - { - GCHandle enumeratorHandle = GCHandle.Alloc(enumerator); - try - { - var callback = Marshal.GetFunctionPointerForDelegate(CallBack); - PInvoke.EnumEnhMetaFile( - default, - HENHMETAFILE, - (delegate* unmanaged[Stdcall])callback, - (void*)(nint)enumeratorHandle, - (RECT*)null); - } - finally - { - if (enumeratorHandle.IsAllocated) - { - enumeratorHandle.Free(); - } - } - } - - /// - /// Allows enumerating the metafile records while tracking state. should be - /// initialized to the metafile DC state before any drawing has begun. - /// - /// - /// - /// State is whatever is current *before* the current record is "applied" as it is necessary to understand - /// what delta the actual record makes. - /// - /// - public unsafe void EnumerateWithState(ProcessRecordWithStateDelegate enumerator, DeviceContextState state) - { - Enumerate(stateTracker); - - bool stateTracker(ref EmfRecord record) - { - bool result = enumerator(ref record, state); - - // This must come *after* calling the nested enumerator so that the record reflects what is *about* - // to be applied. If we invert the model you wouldn't be able to tell what things like LineTo actually - // do as they only contain the destination point. - switch (record.Type) - { - // Not all records are handled yet. Backfilling in as we write specific tests. - case ENHANCED_METAFILE_RECORD_TYPE.EMR_SETTEXTALIGN: - state.TextAlign = record.SetTextAlignRecord->iMode; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_SETMAPMODE: - state.MapMode = record.SetMapModeRecord->iMode; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_SETBKMODE: - state.BackgroundMode = record.SetBkModeRecord->iMode; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_SETROP2: - state.Rop2Mode = record.SetROP2Record->iMode; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_SETTEXTCOLOR: - state.TextColor = record.SetTextColorRecord->crColor; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_SETBKCOLOR: - state.BackColor = record.SetBkColorRecord->crColor; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_MOVETOEX: - state.BrushOrigin = record.MoveToExRecord->point; - // The documentation indicates that the last MoveTo will be where CloseFigure draws a line to. - state.LastBeginPathBrushOrigin = state.BrushOrigin; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_LINETO: - state.BrushOrigin = record.LineToRecord->point; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_BEGINPATH: - state.LastBeginPathBrushOrigin = state.BrushOrigin; - state.InPath = true; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_ABORTPATH: - case ENHANCED_METAFILE_RECORD_TYPE.EMR_ENDPATH: - case ENHANCED_METAFILE_RECORD_TYPE.EMR_CLOSEFIGURE: - state.InPath = false; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTCREATEFONTINDIRECTW: - case ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEPALETTE: - case ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEPEN: - case ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTCREATEPEN: - case ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEMONOBRUSH: - case ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEBRUSHINDIRECT: - case ENHANCED_METAFILE_RECORD_TYPE.EMR_CREATEDIBPATTERNBRUSHPT: - // All of these records have their index as the first "parameter". - state.AddGdiObject(ref record, (int)record.Params[0]); - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_SELECTOBJECT: - state.SelectGdiObject(record.SelectObjectRecord); - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_DELETEOBJECT: - state.GdiObjects[(int)record.DeleteObjectRecord->index] = default; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTSELECTCLIPRGN: - state.ClipRegion = record.ExtSelectClipRgnRecord->ClippingRectangles; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_SETWORLDTRANSFORM: - state.Transform = record.SetWorldTransformRecord->xform; - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_MODIFYWORLDTRANSFORM: - var transform = record.ModifyWorldTransformRecord; - switch (transform->iMode) - { - case MODIFY_WORLD_TRANSFORM_MODE.MWT_IDENTITY: - state.Transform = Matrix3x2.Identity; - break; - case MODIFY_WORLD_TRANSFORM_MODE.MWT_LEFTMULTIPLY: - state.Transform = transform->xform * state.Transform; - break; - case MODIFY_WORLD_TRANSFORM_MODE.MWT_RIGHTMULTIPLY: - state.Transform = state.Transform * transform->xform; - break; - } - - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_SAVEDC: - state.SaveDC(); - break; - case ENHANCED_METAFILE_RECORD_TYPE.EMR_RESTOREDC: - state.RestoreDC(record.RestoreDCRecord->iRelative); - break; - } - - return result; - } - } - - public string RecordsToString() - { - StringBuilder sb = new StringBuilder(1024); - Enumerate((ref EmfRecord record) => - { - sb.AppendLine(record.ToString()); - return true; - }); - - return sb.ToString(); - } - - public string RecordsToStringWithState(DeviceContextState state) - { - StringBuilder sb = new StringBuilder(1024); - EnumerateWithState((ref EmfRecord record, DeviceContextState state) => - { - sb.AppendLine(record.ToString(state)); - return true; - }, - state); - - return sb.ToString(); - } - - private static unsafe BOOL CallBack( - HDC hdc, - HANDLETABLE* lpht, - ENHMETARECORD* lpmr, - int nHandles, - LPARAM data) - { - // Note that the record pointer is *only* valid during the callback. - GCHandle enumeratorHandle = GCHandle.FromIntPtr(data); - ProcessRecordDelegate enumerator = (ProcessRecordDelegate)enumeratorHandle.Target!; - var record = new EmfRecord(hdc, lpht, lpmr, nHandles, data); - return enumerator(ref record); - } - - public static implicit operator HDC(in EmfScope scope) => scope.HDC; - - public void Dispose() - { - if (!HDC.IsNull) - { - PInvoke.DeleteEnhMetaFile(HENHMETAFILE); - } - - GC.SuppressFinalize(this); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/ProcessRecordDelegate.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/ProcessRecordDelegate.cs deleted file mode 100644 index e741bfa43ea..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/ProcessRecordDelegate.cs +++ /dev/null @@ -1,8 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal delegate bool ProcessRecordDelegate(ref EmfRecord record); diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/ProcessRecordWithStateDelegate.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/ProcessRecordWithStateDelegate.cs deleted file mode 100644 index d9146533152..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/ProcessRecordWithStateDelegate.cs +++ /dev/null @@ -1,8 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal delegate bool ProcessRecordWithStateDelegate(ref EmfRecord record, DeviceContextState state); diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMR.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMR.cs deleted file mode 100644 index 4651cc01f0e..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMR.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMR -{ - public ENHANCED_METAFILE_RECORD_TYPE iType; - public uint nSize; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRBITBLT.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRBITBLT.cs deleted file mode 100644 index 018e457dbab..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRBITBLT.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; -using System.Numerics; -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMRBITBLT -{ - public EMR emr; - public RECT rclBounds; // Inclusive-inclusive bounds in device units - public int xDest; - public int yDest; - public int cxDest; - public int cyDest; - public ROP_CODE dwRop; - public int xSrc; - public int ySrc; - public Matrix3x2 xformSrc; // Source DC transform - public COLORREF crBkColorSrc; // Source DC BkColor in RGB - public DIB_USAGE iUsageSrc; // Source bitmap info color table usage - // (DIB_RGB_COLORS) - public uint offBmiSrc; // Offset to the source BITMAPINFO structure - public uint cbBmiSrc; // Size of the source BITMAPINFO structure - public uint offBitsSrc; // Offset to the source bitmap bits - public uint cbBitsSrc; // Size of the source bitmap bits - - public override string ToString() - { - RECT dest = new Rectangle(xDest, yDest, cxDest, cyDest); - return $@"[{nameof(EMRBITBLT)}] Bounds: {rclBounds} Destination: {dest} Rop: {dwRop}Source DC Color: {crBkColorSrc.ToSystemColorString()}"; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRCREATEBRUSHINDIRECT.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRCREATEBRUSHINDIRECT.cs deleted file mode 100644 index 3fc6eab6b8d..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRCREATEBRUSHINDIRECT.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMRCREATEBRUSHINDIRECT -{ - public EMR emr; - public uint ihBrush; - public LOGBRUSH32 lb; - - public override string ToString() - => $@"[{nameof(EMRCREATEBRUSHINDIRECT)}] Index: {ihBrush} Style: {lb.lbStyle} Color: {lb.lbColor.ToSystemColorString()}"; - - // This structure is used exclusively in EMRCREATEBRUSHINDIRECT - [StructLayout(LayoutKind.Sequential)] - internal struct LOGBRUSH32 - { - public BRUSH_STYLE lbStyle; - public COLORREF lbColor; - public uint lbHatch; - - public static implicit operator LOGBRUSH(LOGBRUSH32 logbrush) => new() - { - lbStyle = logbrush.lbStyle, - lbColor = logbrush.lbColor, - lbHatch = logbrush.lbHatch - }; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRCREATEDIBPATTERNBRUSHPT.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRCREATEDIBPATTERNBRUSHPT.cs deleted file mode 100644 index 0e6fa3b06de..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRCREATEDIBPATTERNBRUSHPT.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMRCREATEDIBPATTERNBRUSHPT -{ - public EMR emr; - public uint ihBrush; // Brush handle index - public uint iUsage; // Bitmap info color table usage - public uint offBmi; // Offset to the BITMAPINFO structure - public uint cbBmi; // Size of the BITMAPINFO structure - // The bitmap info is followed by the bitmap - // bits to form a packed DIB. - public uint offBits; // Offset to the bitmap bits - public uint cbBits; // Size of the bitmap bits - - public override string ToString() - => $"[{nameof(EMRCREATEDIBPATTERNBRUSHPT)}] Index: {ihBrush}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRCREATEPEN.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRCREATEPEN.cs deleted file mode 100644 index 4251c9dd463..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRCREATEPEN.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMRCREATEPEN -{ - public EMR emr; - public uint ihPen; - public LOGPEN lopn; - - public override string ToString() - => $@"[{nameof(EMRCREATEPEN)}] Index: {ihPen} Style: {lopn.lopnStyle} Width: {lopn.lopnWidth} Color: {lopn.lopnColor.ToSystemColorString()}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRENUMRECORD.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRENUMRECORD.cs deleted file mode 100644 index 0da5b8ac4de..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRENUMRECORD.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -/// -/// Record that has just a single enum value. -/// -/// -/// Not an actual Win32 define, encapsulates: -/// -/// - EMRSELECTCLIPPATH -/// - EMRSETBKMODE -/// - EMRSETMAPMODE -/// - EMRSETLAYOUT -/// - EMRSETPOLYFILLMODE -/// - EMRSETROP2 -/// - EMRSETSTRETCHBLTMODE -/// - EMRSETTEXTALIGN -/// -[StructLayout(LayoutKind.Sequential)] -internal struct EMRENUMRECORD where T : Enum -{ - public EMR emr; - public T iMode; - - public override string ToString() => $"[EMR{emr.iType}] Mode: {typeof(T).Name}_{iMode}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTCREATEFONTINDIRECTW.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTCREATEFONTINDIRECTW.cs deleted file mode 100644 index 14306f07a8a..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTCREATEFONTINDIRECTW.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMREXTCREATEFONTINDIRECTW -{ - public EMR emr; - public uint ihFont; - public EXTLOGFONTW elfw; - - public override string ToString() - => $@"[{nameof(EMREXTCREATEFONTINDIRECTW)}] Index: {ihFont} FaceName: '{elfw.elfLogFont.FaceName.ToString()}' Height: {elfw.elfLogFont.lfHeight} Weight: FW_{elfw.elfLogFont.lfWeight}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTCREATEPEN.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTCREATEPEN.cs deleted file mode 100644 index 1b1042c59f7..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTCREATEPEN.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMREXTCREATEPEN -{ - public EMR emr; - public uint ihPen; // Pen handle index - public uint offBmi; // Offset to the BITMAPINFO structure if any - public uint cbBmi; // Size of the BITMAPINFO structure if any - // The bitmap info is followed by the bitmap - // bits to form a packed DIB. - public uint offBits; // Offset to the brush bitmap bits if any - public uint cbBits; // Size of the brush bitmap bits if any - public EXTLOGPEN32 elp; // The extended pen with the style array. - - public override string ToString() - => $@"[{nameof(EMREXTCREATEPEN)}] Index: {ihPen} Style: {elp.elpPenStyle} Width: {elp.elpWidth}BrushStyle: {elp.elpBrushStyle} Color: {elp.elpColor.ToSystemColorString()}"; -} - -[StructLayout(LayoutKind.Sequential)] -internal struct EXTLOGPEN32 -{ - public PEN_STYLE elpPenStyle; - public uint elpWidth; - public BRUSH_STYLE elpBrushStyle; - public COLORREF elpColor; - public uint elpHatch; - public uint elpNumEntries; - public uint elpStyleEntry; - - public static implicit operator EXTLOGPEN32(LOGPEN logPen) => new() - { - elpPenStyle = logPen.lopnStyle, - elpWidth = (uint)logPen.lopnWidth.X, - elpColor = logPen.lopnColor - }; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTSELECTCLIPRGN.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTSELECTCLIPRGN.cs deleted file mode 100644 index 343ca889894..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTSELECTCLIPRGN.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; -using System.Text; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal unsafe struct EMREXTSELECTCLIPRGN -{ - public EMR emr; - public uint cbRgnData; // Size of region data in bytes - public RGN_COMBINE_MODE iMode; - public byte RgnData; - - public RGNDATAHEADER* RegionDataHeader - { - get - { - fixed (void* data = &RgnData) - { - return cbRgnData >= sizeof(RGNDATAHEADER) ? (RGNDATAHEADER*)data : null; - } - } - } - - public RECT[] ClippingRectangles => RGNDATAHEADER.GetRegionRects(RegionDataHeader); - - public override string ToString() - { - if (RegionDataHeader is null) - { - return $"[{nameof(EMREXTSELECTCLIPRGN)}] Mode: Set Default"; - } - - StringBuilder sb = new StringBuilder(512); - sb.Append($@"[{nameof(EMREXTSELECTCLIPRGN)}] Mode: {iMode} Bounds: {RegionDataHeader->rcBound} Rects: {RegionDataHeader->nCount}"); - - RECT[] clippingRects = ClippingRectangles; - for (int i = 0; i < clippingRects.Length; i++) - { - sb.Append($"\n\tRect index {i}: {clippingRects[i]}"); - } - - return sb.ToString(); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTTEXTOUTW.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTTEXTOUTW.cs deleted file mode 100644 index 1fdea4428a7..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMREXTTEXTOUTW.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMREXTTEXTOUTW -{ - public EMR emr; - public RECT rclBounds; // Inclusive-inclusive bounds in device units - public GM iGraphicsMode; // Current graphics mode - public float exScale; // X and Y scales from Page units to .01mm units - public float eyScale; // if graphics mode is GM_COMPATIBLE. - public EMRTEXT emrtext; // This is followed by the string and spacing - - public override string ToString() - => $@"[{nameof(EMREXTTEXTOUTW)}] Bounds: {rclBounds} Text: '{emrtext.GetText().ToString()}'"; - - internal enum GM : uint - { - COMPATIBLE = 0x00000001, - ADVANCED = 0x00000002 - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRINDEXRECORD.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRINDEXRECORD.cs deleted file mode 100644 index 26cb44240b8..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRINDEXRECORD.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -/// -/// Record that represents an index. -/// -/// -/// Not an actual Win32 define, encapsulates: -/// -/// - EMRSELECTOBJECT -/// - EMRDELETEOBJECT -/// - EMRSELECTPALETTE -/// -[StructLayout(LayoutKind.Sequential)] -internal struct EMRINDEXRECORD -{ - public EMR emr; - public uint index; - - public bool IsStockObject => (index & 0x80000000) != 0; - public GET_STOCK_OBJECT_FLAGS StockObject => (GET_STOCK_OBJECT_FLAGS)(index & ~0x80000000); - - public override string ToString() - => IsStockObject - ? $"[EMR{emr.iType}] StockObject: {StockObject}" - : $"[EMR{emr.iType}] Index: {index}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRMODIFYWORLDTRANSFORM.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRMODIFYWORLDTRANSFORM.cs deleted file mode 100644 index 3433ffc8d4d..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRMODIFYWORLDTRANSFORM.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Numerics; -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMRMODIFYWORLDTRANSFORM -{ - public EMR emr; - public Matrix3x2 xform; - public MODIFY_WORLD_TRANSFORM_MODE iMode; - - public override string ToString() => $"[{nameof(EMRMODIFYWORLDTRANSFORM)}] Mode: {iMode} Transform: {xform}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRPOINTRECORD.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRPOINTRECORD.cs deleted file mode 100644 index bd8531c593e..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRPOINTRECORD.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -/// -/// Record that just has a single point value. -/// -/// -/// Not an actual Win32 define, encapsulates: -/// -/// - EMRLINETO -/// - EMRMOVETOEX -/// - EMROFFSETCLIPRGN -/// - EMRSETVIEWPORTORGEX -/// - EMRSETWINDOWORGEX -/// - EMRSETBRUSHORGEX -/// -[StructLayout(LayoutKind.Sequential)] -internal struct EMRPOINTRECORD -{ - public EMR emr; - public Point point; - - public override string ToString() => $"[EMR{emr.iType}] Point: {point}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRPOLY16.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRPOLY16.cs deleted file mode 100644 index 8682738c802..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRPOLY16.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; -using System.Runtime.InteropServices; -using static Interop; - -namespace System.Windows.Forms.Metafiles; - -/// -/// Record that represents a 16 bit Poly record. -/// -/// -/// Not an actual Win32 define, encapsulates: -/// -/// - EMRPOLYLINE16 -/// - EMRPOLYBEZIER16 -/// - EMRPOLYGON16 -/// - EMRPOLYBEZIERTO16 -/// - EMRPOLYLINETO16 -/// -[StructLayout(LayoutKind.Sequential)] -internal struct EMRPOLY16 -{ - public EMR emr; - public RECT rclBounds; // Inclusive-inclusive bounds in device units - public uint cpts; - private POINTS _apts; - - public unsafe ReadOnlySpan points - { - get - { - fixed (POINTS* p = &_apts) - { - return new(p, checked((int)cpts)); - } - } - } - - public override string ToString() => $"[EMR{emr.iType}] Bounds: {rclBounds} Points: {string.Join(' ', points.ToArray())}"; - - public string ToString(DeviceContextState state) - { - Point[] transformedPoints = points.Transform(point => state.TransformPoint(point)); - return $"[EMR{emr.iType}] Bounds: {rclBounds} Points: {string.Join(' ', transformedPoints)}"; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRPOLYPOLY16.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRPOLYPOLY16.cs deleted file mode 100644 index cd7d742ac0f..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRPOLYPOLY16.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; -using System.Text; -using static Interop; - -namespace System.Windows.Forms.Metafiles; - -/// -/// Record that represents a 16 bit Poly record. -/// -/// -/// Not an actual Win32 define, encapsulates: -/// -/// - EMRPOLYPOLYLINE16 -/// - EMRPOLYPOLYBEZIER16 -/// - EMRPOLYPOLYGON16 -/// - EMRPOLYPOLYLINETO16 -/// -[StructLayout(LayoutKind.Sequential)] -internal struct EMRPOLYPOLY16 -{ - public EMR emr; - public RECT rclBounds; // Inclusive-inclusive bounds in device units - public uint nPolys; // Number of polys - public uint cpts; // Total number of points in all polys - public uint _aPolyCounts; // Array of point counts for each poly - - // Can't represent this as a field as it comes nPolys uints after cpts - // public POINTS apts[1]; // Array of points - - public override string ToString() => ToString(null); - - public string ToString(DeviceContextState? state) - { - StringBuilder sb = new StringBuilder(512); - sb.Append($"[EMR{emr.iType}] Bounds: {rclBounds} Poly count: {nPolys} Total points: {cpts}"); - - for (int i = 0; i < nPolys; i++) - { - if (state is null) - { - sb.Append($"\n\tPoly index {i}: {string.Join(' ', GetPointsForPoly(i).ToArray())}"); - } - else - { - sb.Append($"\n\tPoly index {i}: {string.Join(' ', GetPointsForPoly(i).Transform(p => state.TransformPoint(p)))}"); - } - } - - return sb.ToString(); - } - - public unsafe ReadOnlySpan aPolyCounts - { - get - { - fixed(uint* c = &_aPolyCounts) - { - return new(c, checked((int)nPolys)); - } - } - } - - public unsafe ReadOnlySpan GetPointsForPoly(int index) - { - if (index < 0 || index >= nPolys) - throw new ArgumentOutOfRangeException(nameof(index)); - - int current = 0; - fixed (void* s = &emr) - { - POINTS* currentPoint = (POINTS*)((byte*)s + sizeof(EMRPOLYPOLY16) + (sizeof(uint) * (nPolys - 1))); - var counts = aPolyCounts; - while (current != index) - { - currentPoint += counts[current]; - current++; - } - - return new ReadOnlySpan(currentPoint, (int)counts[current]); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRRECTRECORD.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRRECTRECORD.cs deleted file mode 100644 index cf55246e669..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRRECTRECORD.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -/// -/// Record that just has a single value. -/// -/// -/// Not an actual Win32 define, encapsulates: -/// -/// - EMRFILLPATH -/// - EMRSTROKEANDFILLPATH -/// - EMRSTROKEPATH -/// - EMREXCLUDECLIPRECT -/// - EMRINTERSECTCLIPRECT -/// - EMRELLIPSE -/// - EMRRECTANGLE -/// -[StructLayout(LayoutKind.Sequential)] -internal struct EMRRECTRECORD -{ - public EMR emr; - public RECT rect; - - public override string ToString() => $"[EMR{emr.iType}] RECT: {rect}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRRESTOREDC.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRRESTOREDC.cs deleted file mode 100644 index 393bcd6b9d0..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRRESTOREDC.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMRRESTOREDC -{ - public EMR emr; - public int iRelative; - - public override string ToString() => $"[{nameof(EMRRESTOREDC)}] Index: {iRelative}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRSETCOLOR.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRSETCOLOR.cs deleted file mode 100644 index b959003ea2b..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRSETCOLOR.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -/// -/// Record that represents a 16 bit Poly record. -/// -/// -/// Not an actual Win32 define, encapsulates: -/// -/// - EMRSETTEXTCOLOR -/// - EMRSETBKCOLOR -/// -[StructLayout(LayoutKind.Sequential)] -internal struct EMRSETCOLOR -{ - public EMR emr; - public COLORREF crColor; - - public override string ToString() - { - return $"[EMR{emr.iType}] Color: {crColor.ToSystemColorString()}"; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRSETWORLDTRANSFORM.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRSETWORLDTRANSFORM.cs deleted file mode 100644 index 365b4cf58e6..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRSETWORLDTRANSFORM.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Numerics; -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMRSETWORLDTRANSFORM -{ - public EMR emr; - public Matrix3x2 xform; - - public override string ToString() => $"[{nameof(EMRSETWORLDTRANSFORM)}] Transform: {xform}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRTEXT.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRTEXT.cs deleted file mode 100644 index bb15e729835..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/EMRTEXT.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct EMRTEXT -{ - public Point ptlReference; - public uint nChars; - public uint offString; // Offset to the string - public uint fOptions; - public RECT rcl; - public uint offDx; // Offset to the inter-character spacing array. - - public unsafe ReadOnlySpan GetText() - { - int offset = (int)offString - sizeof(EMREXTTEXTOUTW) + sizeof(EMRTEXT); - fixed (Point* p = &ptlReference) - { - byte* b = (byte*)(void*)p; - b += offset; - return new ReadOnlySpan((void*)b, (int)nChars); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/ENHMETAHEADER.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/ENHMETAHEADER.cs deleted file mode 100644 index 4c7f53cdc59..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/RecordTypes/ENHMETAHEADER.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Metafiles; - -[StructLayout(LayoutKind.Sequential)] -internal struct ENHMETAHEADER -{ - public uint iType; // Record typeEMR_HEADER - public uint nSize; // Record size in bytes. This may be greater - // than the sizeof(ENHMETAHEADER). - public RECT rclBounds; // Inclusive-inclusive bounds in device units - public RECT rclFrame; // Inclusive-inclusive Picture Frame of metafile in .01 mm units - public uint dSignature; // Signature. Must be ENHMETA_SIGNATURE. - public uint nVersion; // Version number - public uint nBytes; // Size of the metafile in bytes - public uint nRecords; // Number of records in the metafile - public ushort nHandles; // Number of handles in the handle table - // Handle index zero is reserved. - public ushort sReserved; // Reserved. Must be zero. - public uint nDescription; // Number of chars in the unicode description string - // This is 0 if there is no description string - public uint offDescription; // Offset to the metafile description record. - // This is 0 if there is no description string - public uint nPalEntries; // Number of entries in the metafile palette. - public Size szlDevice; // Size of the reference device in pixels - public Size szlMillimeters; // Size of the reference device in millimeters - - // The next three bring the size up to 100 bytes - public uint cbPixelFormat; // Size of PIXELFORMATDESCRIPTOR information - // This is 0 if no pixel format is set - public uint offPixelFormat; // Offset to PIXELFORMATDESCRIPTOR - // This is 0 if no pixel format is set - public BOOL bOpenGL; // TRUE if OpenGL commands are present in - // the metafile, otherwise FALSE - - // The next field brings the size to 108 bytes - public Size szlMicrometers; // Size of the reference device in micrometers - - public override string ToString() => $@"[{nameof(ENHMETAHEADER)}] Bounds: {rclBounds} Device Size: {szlDevice}Header Size: {nSize}"; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/ActionValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/ActionValidator.cs deleted file mode 100644 index a592f55003e..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/ActionValidator.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -/// -/// Simple delegate wrapping validator. -/// -internal class ActionValidator : IEmfValidator -{ - private readonly ENHANCED_METAFILE_RECORD_TYPE _recordType; - private readonly ProcessRecordDelegate? _processor; - private readonly ProcessRecordWithStateDelegate? _processorWithState; - - public ActionValidator(ENHANCED_METAFILE_RECORD_TYPE recordType, ProcessRecordDelegate processor) - { - _recordType = recordType; - _processor = processor; - } - - public ActionValidator(ENHANCED_METAFILE_RECORD_TYPE recordType, ProcessRecordWithStateDelegate processor) - { - _recordType = recordType; - _processorWithState = processor; - } - - public bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => recordType == _recordType; - - public void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - complete = true; - - _processor?.Invoke(ref record); - _processorWithState?.Invoke(ref record, state); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BackgroundModeValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BackgroundModeValidator.cs deleted file mode 100644 index b896f612c05..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BackgroundModeValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal class BackgroundModeValidator : IStateValidator -{ - private readonly BACKGROUND_MODE _backgroundMode; - public BackgroundModeValidator(BACKGROUND_MODE backgroundMode) => _backgroundMode = backgroundMode; - public void Validate(DeviceContextState state) => Assert.Equal(_backgroundMode, state.BackgroundMode); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BitBltValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BitBltValidator.cs deleted file mode 100644 index 2641c52067f..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BitBltValidator.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal sealed class BitBltValidator : StateValidator -{ - private readonly Rectangle? _bounds; - - /// Optional bounds to validate. - /// Optional device context state validation to perform. - public BitBltValidator( - RECT? bounds, - params IStateValidator[] stateValidators) : base(stateValidators) - { - _bounds = bounds; - } - - public override bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => recordType == ENHANCED_METAFILE_RECORD_TYPE.EMR_BITBLT; - - public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - base.Validate(ref record, state, out _); - - // We're only checking one BitBlt record, so this call completes our work. - complete = true; - - if (_bounds.HasValue) - { - EMRBITBLT* bitBlt = record.BitBltRecord; - Assert.Equal(_bounds.Value, (Rectangle)bitBlt->rclBounds); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BrushColorValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BrushColorValidator.cs deleted file mode 100644 index e5ae6688ef9..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BrushColorValidator.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal class BrushColorValidator : IStateValidator -{ - private readonly Color _brushColor; - public BrushColorValidator(Color brushColor) => _brushColor = brushColor; - public void Validate(DeviceContextState state) => Assert.Equal((COLORREF)_brushColor, state.SelectedBrush.lbColor); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BrushStyleValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BrushStyleValidator.cs deleted file mode 100644 index 26b508bc795..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BrushStyleValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal class BrushStyleValidator : IStateValidator -{ - private readonly BRUSH_STYLE _brushStyle; - public BrushStyleValidator(BRUSH_STYLE brushStyle) => _brushStyle = brushStyle; - public void Validate(DeviceContextState state) => Assert.Equal(_brushStyle, state.SelectedBrush.lbStyle); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BrushValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BrushValidator.cs deleted file mode 100644 index 96551a6c523..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/BrushValidator.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal class BrushValidator : IStateValidator -{ - private readonly Color _brushColor; - private readonly BRUSH_STYLE _brushStyle; - - public BrushValidator(Color brushColor, BRUSH_STYLE brushStyle) - { - _brushColor = brushColor; - _brushStyle = brushStyle; - } - - public void Validate(DeviceContextState state) - { - Assert.Equal((COLORREF)_brushColor, state.SelectedBrush.lbColor); - Assert.Equal(_brushStyle, state.SelectedBrush.lbStyle); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/ClippingValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/ClippingValidator.cs deleted file mode 100644 index 41671f8f322..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/ClippingValidator.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal class ClippingValidator : IStateValidator -{ - private readonly RECT[] _clippingRectangles; - public ClippingValidator(RECT[] clippingRectangles) => _clippingRectangles = clippingRectangles; - - public void Validate(DeviceContextState state) - => Assert.Equal(_clippingRectangles, state.ClipRegion); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/EmfValidator.WrappedXunitException.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/EmfValidator.WrappedXunitException.cs deleted file mode 100644 index 979af99637f..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/EmfValidator.WrappedXunitException.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using Xunit.Sdk; - -namespace System.Windows.Forms.Metafiles; - -internal static partial class EmfValidator -{ - private class WrappedXunitException : XunitException - { - public WrappedXunitException(string userMessage, XunitException innerException) - : base(userMessage, innerException) - { - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/EmfValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/EmfValidator.cs deleted file mode 100644 index 070c1fb84a5..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/EmfValidator.cs +++ /dev/null @@ -1,119 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using Xunit.Sdk; - -namespace System.Windows.Forms.Metafiles; - -internal static partial class EmfValidator -{ - internal static void Validate( - this EmfScope emf, - DeviceContextState state, - params IEmfValidator[] validationSteps) - { - if (state is null) - throw new ArgumentNullException(nameof(state)); - if (validationSteps is null) - throw new ArgumentNullException(nameof(validationSteps)); - - int currentIndex = 0; - IEmfValidator? currentValidator = validationSteps[currentIndex]; - - emf.EnumerateWithState((ref EmfRecord record, DeviceContextState state) => - { - if (currentValidator?.ShouldValidate(record.Type) ?? false) - { - try - { - currentValidator.Validate(ref record, state, out bool complete); - - if (complete) - { - // Current validator doesn't want to look at any more records. - currentIndex++; - currentValidator = currentIndex < validationSteps.Length - ? validationSteps[currentIndex] - : null; - } - } - catch (XunitException ex) - { - throw new WrappedXunitException( - $"\nValidator index {currentIndex}: {currentValidator!.GetType().Name} failed\n\n{emf.RecordsToString()}", - ex); - } - } - else - { - Assert.False(IsRenderingRecord(record.Type), $"Got unexpected {record.Type}\n\n{emf.RecordsToString()}"); - } - - return true; - }, - state); - - if (currentValidator is not null) - { - Assert.False( - currentValidator.FailIfIncomplete, - $"{currentValidator.GetType().Name} did not receive expected records\n\n{emf.RecordsToString()}"); - } - } - - private static bool IsRenderingRecord(ENHANCED_METAFILE_RECORD_TYPE recordType) - => recordType switch - { - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYBEZIER => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYGON => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYLINE => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYBEZIERTO => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYLINETO => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYLINE => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYGON => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETPIXELV => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_ANGLEARC => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_ELLIPSE => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_RECTANGLE => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_ROUNDRECT => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_ARC => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_CHORD => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_PIE => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTFLOODFILL => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_LINETO => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_ARCTO => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYDRAW => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_CLOSEFIGURE => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_FILLPATH => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_STROKEANDFILLPATH => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_STROKEPATH => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_FILLRGN => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_FRAMERGN => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_INVERTRGN => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_PAINTRGN => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_BITBLT => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_STRETCHBLT => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_MASKBLT => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_PLGBLT => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_SETDIBITSTODEVICE => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_STRETCHDIBITS => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTTEXTOUTA => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTTEXTOUTW => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYBEZIER16 => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYGON16 => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYLINE16 => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYBEZIERTO16 => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYLINETO16 => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYLINE16 => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYGON16 => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYDRAW16 => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYTEXTOUTA => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYTEXTOUTW => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_ALPHABLEND => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_TRANSPARENTBLT => true, - ENHANCED_METAFILE_RECORD_TYPE.EMR_GRADIENTFILL => true, - _ => false - }; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/FontFaceNameValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/FontFaceNameValidator.cs deleted file mode 100644 index d15759c815e..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/FontFaceNameValidator.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal class FontFaceNameValidator : IStateValidator -{ - private readonly string _fontFaceName; - - /// The font face name to validate. - public FontFaceNameValidator(string fontFaceName) => _fontFaceName = fontFaceName; - - public void Validate(DeviceContextState state) => Assert.Equal(_fontFaceName, state.SelectedFont.FaceName.ToString()); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/IEmfValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/IEmfValidator.cs deleted file mode 100644 index 62f1b0f4acc..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/IEmfValidator.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Windows.Forms.Metafiles; - -namespace System; - -internal interface IEmfValidator -{ - /// - /// Returns true if the given should be validated by this validator. - /// - bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType); - - /// - /// Validates the given . - /// - /// - /// True if the validator is finished validating. If false the validator will remain in scope for handling - /// the next record. - /// - void Validate(ref EmfRecord record, DeviceContextState state, out bool complete); - - /// - /// Return true if this validator is still in scope when all records have been processed. - /// - bool FailIfIncomplete => true; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/IStateValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/IStateValidator.cs deleted file mode 100644 index 0aac2e00646..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/IStateValidator.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal interface IStateValidator -{ - void Validate(DeviceContextState state); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/LineToValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/LineToValidator.cs deleted file mode 100644 index 802955ab8be..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/LineToValidator.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal sealed class LineToValidator : StateValidator -{ - private readonly Point? _from; - private readonly Point? _to; - - /// Optional source point to validate. - /// Optional destination point to validate. - /// Optional device context state validation to perform. - public LineToValidator( - Point? from, - Point? to, - params IStateValidator[] stateValidators) : base(stateValidators) - { - _from = from; - _to = to; - } - - public override bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => recordType == ENHANCED_METAFILE_RECORD_TYPE.EMR_LINETO; - - public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - base.Validate(ref record, state, out _); - - // We're only checking one LineTo record, so this call completes our work. - complete = true; - - EMRPOINTRECORD* lineTo = record.LineToRecord; - - if (_from.HasValue) - { - Assert.Equal(_from.Value, state.BrushOrigin); - } - - if (_to.HasValue) - { - Assert.Equal(_to.Value, lineTo->point); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenColorValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenColorValidator.cs deleted file mode 100644 index 74063ecf60d..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenColorValidator.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal class PenColorValidator : IStateValidator -{ - private readonly Color _penColor; - public PenColorValidator(Color penColor) => _penColor = penColor; - public void Validate(DeviceContextState state) => Assert.Equal((COLORREF)_penColor, state.SelectedPen.elpColor); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenStyleValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenStyleValidator.cs deleted file mode 100644 index ba8a2f8823c..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenStyleValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal class PenStyleValidator : IStateValidator -{ - private readonly PEN_STYLE _penStyle; - public PenStyleValidator(PEN_STYLE penStyle) => _penStyle = penStyle; - public void Validate(DeviceContextState state) => Assert.Equal(_penStyle, state.SelectedPen.elpPenStyle); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenValidator.cs deleted file mode 100644 index b9447e88bd5..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenValidator.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal class PenValidator : IStateValidator -{ - private readonly int _penWidth; - private readonly PEN_STYLE _penStyle; - private readonly Color _penColor; - - public PenValidator(int penWidth, Color penColor, PEN_STYLE penStyle) - { - _penWidth = penWidth; - _penColor = penColor; - _penStyle = penStyle; - } - - public void Validate(DeviceContextState state) - { - Assert.Equal(_penWidth, (int)state.SelectedPen.elpWidth); - Assert.Equal((COLORREF)_penColor, state.SelectedPen.elpColor); - Assert.Equal(_penStyle, state.SelectedPen.elpPenStyle); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenWidthValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenWidthValidator.cs deleted file mode 100644 index c0961e80f7a..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PenWidthValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal class PenWidthValidator : IStateValidator -{ - private readonly int _penWidth; - public PenWidthValidator(int penWidth) => _penWidth = penWidth; - public void Validate(DeviceContextState state) => Assert.Equal(_penWidth, (int)state.SelectedPen.elpWidth); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Poly16Validator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Poly16Validator.cs deleted file mode 100644 index 8fb3ab299c4..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Poly16Validator.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; -using static Interop; - -namespace System.Windows.Forms.Metafiles; - -internal abstract class Poly16Validator : StateValidator -{ - private readonly Rectangle? _bounds; - private readonly Point[]? _points; - - /// Optional bounds to validate. - /// Optional points to validate. - /// Optional device context state validation to perform. - public Poly16Validator( - RECT? bounds, - Point[]? points, - params IStateValidator[] stateValidators) : base(stateValidators) - { - _bounds = bounds; - _points = points; - } - - protected unsafe void Validate(EMRPOLY16* poly) - { - if (_bounds.HasValue) - { - Assert.Equal(_bounds.Value, (Rectangle)poly->rclBounds); - } - - if (_points is not null) - { - Assert.Equal(_points.Length, (int)poly->cpts); - Assert.Equal(_points, poly->points.Transform(p => p)); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PolyPoly16Validator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PolyPoly16Validator.cs deleted file mode 100644 index c0a56225b6b..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PolyPoly16Validator.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal abstract class PolyPoly16Validator : StateValidator -{ - private readonly Rectangle? _bounds; - private readonly int? _polyCount; - - /// Optional bounds to validate. - /// Number of expected polys. - /// Optional device context state validation to perform. - public PolyPoly16Validator( - RECT? bounds, - int? polyCount, - params IStateValidator[] stateValidators) : base(stateValidators) - { - // Full point validation still needs implemented - _polyCount = polyCount; - _bounds = bounds; - } - - protected unsafe void Validate(EMRPOLYPOLY16* poly) - { - if (_bounds.HasValue) - { - Assert.Equal(_bounds.Value, (Rectangle)poly->rclBounds); - } - - if (_polyCount.HasValue) - { - Assert.Equal(_polyCount.Value, (int)poly->nPolys); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PolyPolygon16Validator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PolyPolygon16Validator.cs deleted file mode 100644 index 95419758cc4..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PolyPolygon16Validator.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal class PolyPolygon16Validator : PolyPoly16Validator -{ - /// - public PolyPolygon16Validator( - RECT? bounds, - int? polyCount, - params IStateValidator[] stateValidators) : base( - bounds, - polyCount, - stateValidators) - { - } - - public override bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => recordType == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYGON16; - - public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - base.Validate(ref record, state, out _); - - // We're only checking one PolyPolygon16 record, so this call completes our work. - complete = true; - - Validate(record.PolyPolygon16Record); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PolyPolyline16Validator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PolyPolyline16Validator.cs deleted file mode 100644 index a736e36d9dd..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/PolyPolyline16Validator.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal class PolyPolyline16Validator : PolyPoly16Validator -{ - /// - public PolyPolyline16Validator( - RECT? bounds, - int? polyCount, - params IStateValidator[] stateValidators) : base( - bounds, - polyCount, - stateValidators) - { - } - - public override bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => recordType == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYPOLYLINE16; - - public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - base.Validate(ref record, state, out _); - - // We're only checking one PolyPolyline16 record, so this call completes our work. - complete = true; - - Validate(record.PolyPolyline16Record); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Polygon16Validator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Polygon16Validator.cs deleted file mode 100644 index df4065932a3..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Polygon16Validator.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal class Polygon16Validator : Poly16Validator -{ - /// - public Polygon16Validator( - RECT? bounds, - Point[]? points, - params IStateValidator[] stateValidators) : base( - bounds, - points, - stateValidators) - { - } - - public override bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => recordType == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYGON16; - - public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - base.Validate(ref record, state, out _); - - // We're only checking one Polygon16 record, so this call completes our work. - complete = true; - - Validate(record.Polygon16Record); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Polyline16Validator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Polyline16Validator.cs deleted file mode 100644 index 827988790a7..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Polyline16Validator.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal class Polyline16Validator : Poly16Validator -{ - /// - public Polyline16Validator( - RECT? bounds, - Point[]? points, - params IStateValidator[] stateValidators) : base( - bounds, - points, - stateValidators) - { - } - - public override bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => recordType == ENHANCED_METAFILE_RECORD_TYPE.EMR_POLYLINE16; - - public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - base.Validate(ref record, state, out _); - - // We're only checking one Polyline16 record, so this call completes our work. - complete = true; - - Validate(record.Polyline16Record); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/RectangleValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/RectangleValidator.cs deleted file mode 100644 index 77fe47552e3..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/RectangleValidator.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal sealed class RectangleValidator : StateValidator -{ - private readonly Rectangle? _bounds; - - /// Optional bounds to validate. - /// Optional device context state validation to perform. - public RectangleValidator( - RECT? bounds, - params IStateValidator[] stateValidators) : base(stateValidators) - { - _bounds = bounds; - } - - public override bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => recordType == ENHANCED_METAFILE_RECORD_TYPE.EMR_RECTANGLE; - - public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - base.Validate(ref record, state, out _); - - // We're only checking one Rectangle record, so this call completes our work. - complete = true; - - if (_bounds.HasValue) - { - EMRRECTRECORD* rectangle = record.RectangleRecord; - Assert.Equal(_bounds.Value, (Rectangle)rectangle->rect); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/RepeatValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/RepeatValidator.cs deleted file mode 100644 index 091bb77385d..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/RepeatValidator.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal sealed class RepeatValidator : IEmfValidator -{ - private readonly IEmfValidator _validator; - private int _count; - - public RepeatValidator(IEmfValidator validator, int count) - { - _validator = validator; - _count = count; - } - - public bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => _validator.ShouldValidate(recordType); - - public void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - if (_count <= 0) - throw new InvalidOperationException(); - - _validator.Validate(ref record, state, out _); - _count--; - complete = _count == 0; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Rop2Validator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Rop2Validator.cs deleted file mode 100644 index 282243ad255..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Rop2Validator.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal class Rop2Validator : IStateValidator -{ - private readonly R2_MODE _rop2Mode; - public Rop2Validator(R2_MODE rop2Mode) => _rop2Mode = rop2Mode; - public void Validate(DeviceContextState state) => Assert.Equal(_rop2Mode, state.Rop2Mode); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/SkipAllValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/SkipAllValidator.cs deleted file mode 100644 index 12611e4d689..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/SkipAllValidator.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal sealed class SkipAllValidator : IEmfValidator -{ - public static IEmfValidator Instance = new SkipAllValidator(); - - public bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => true; - - public void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - // Always want to remain in scope. - complete = false; - } - - // We don't require any more records to "pass" - public bool FailIfIncomplete => false; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/SkipToValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/SkipToValidator.cs deleted file mode 100644 index 1ee65af2273..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/SkipToValidator.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal sealed class SkipToValidator : IEmfValidator -{ - private readonly IEmfValidator _validator; - - public SkipToValidator(IEmfValidator validator) => _validator = validator; - - public bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => true; - - public void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - if (_validator.ShouldValidate(record.Type)) - { - // Hit our validator, pass through. - _validator.Validate(ref record, state, out complete); - return; - } - - // Still skipping. - complete = false; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/SkipTypesValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/SkipTypesValidator.cs deleted file mode 100644 index b0bde5bc89d..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/SkipTypesValidator.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -internal sealed class SkipTypesValidator : IEmfValidator -{ - private readonly ENHANCED_METAFILE_RECORD_TYPE[] _skipTypes; - - public SkipTypesValidator(params ENHANCED_METAFILE_RECORD_TYPE[] skipTypes) => _skipTypes = skipTypes; - - public bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => _skipTypes.Contains(recordType); - - public void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) => complete = true; -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/State.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/State.cs deleted file mode 100644 index c8ccf694ad3..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/State.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; -using System.Numerics; - -namespace System.Windows.Forms.Metafiles; - -internal static class State -{ - internal static IStateValidator BackgroundMode(BACKGROUND_MODE backgroundMode) => new BackgroundModeValidator(backgroundMode); - internal static IStateValidator Brush(Color brushColor, BRUSH_STYLE brushStyle) - => new BrushValidator(brushColor, brushStyle); - internal static IStateValidator BrushColor(Color brushColor) => new BrushColorValidator(brushColor); - internal static IStateValidator BrushStyle(BRUSH_STYLE brushStyle) => new BrushStyleValidator(brushStyle); - internal static IStateValidator Clipping(RECT[] clippingRectangles) => new ClippingValidator(clippingRectangles); - internal static IStateValidator FontFace(string fontFaceName) => new FontFaceNameValidator(fontFaceName); - internal static IStateValidator Pen(int penWidth, Color penColor, PEN_STYLE penStyle) - => new PenValidator(penWidth, penColor, penStyle); - internal static IStateValidator PenColor(Color penColor) => new PenColorValidator(penColor); - internal static IStateValidator PenStyle(PEN_STYLE penStyle) => new PenStyleValidator(penStyle); - internal static IStateValidator PenWidth(int penWidth) => new PenWidthValidator(penWidth); - internal static IStateValidator Rop2(R2_MODE rop2Mode) => new Rop2Validator(rop2Mode); - internal static IStateValidator TextColor(Color textColor) => new TextColorValidator(textColor); - internal static IStateValidator Transform(Matrix3x2 transform) => new TransformValidator(transform); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/StateValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/StateValidator.cs deleted file mode 100644 index 9ce077cda80..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/StateValidator.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -namespace System.Windows.Forms.Metafiles; - -/// -/// Base that handles optional validation of device context state. -/// -internal abstract class StateValidator : IEmfValidator -{ - private readonly IStateValidator[] _stateValidators; - public StateValidator(IStateValidator[] stateValidators) => _stateValidators = stateValidators; - public abstract bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType); - - public virtual void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - complete = false; - - if (_stateValidators is null) - { - return; - } - - foreach (IStateValidator validator in _stateValidators) - { - validator.Validate(state); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/TextColorValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/TextColorValidator.cs deleted file mode 100644 index 1102fdc5282..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/TextColorValidator.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal class TextColorValidator : IStateValidator -{ - private readonly Color _textColor; - public TextColorValidator(Color textColor) => _textColor = textColor; - public void Validate(DeviceContextState state) => Assert.Equal((COLORREF)_textColor, state.TextColor); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/TextOutValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/TextOutValidator.cs deleted file mode 100644 index 7ca90c29360..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/TextOutValidator.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal sealed class TextOutValidator : StateValidator -{ - private readonly string? _text; - private readonly Rectangle? _bounds; - - /// Optional text to validate. - /// Optional bounds to validate. - /// Optional device context state validation to perform. - public TextOutValidator( - string? text, - Rectangle? bounds = default, - params IStateValidator[] stateValidators) : base(stateValidators) - { - _text = text; - _bounds = bounds; - } - - public override bool ShouldValidate(ENHANCED_METAFILE_RECORD_TYPE recordType) => recordType == ENHANCED_METAFILE_RECORD_TYPE.EMR_EXTTEXTOUTW; - - public override unsafe void Validate(ref EmfRecord record, DeviceContextState state, out bool complete) - { - base.Validate(ref record, state, out _); - - // We're only checking one TextOut record, so this call completes our work. - complete = true; - - EMREXTTEXTOUTW* textOut = record.ExtTextOutWRecord; - - if (_text is not null) - { - Assert.Equal(_text, textOut->emrtext.GetText().ToString()); - } - - if (_bounds.HasValue) - { - Assert.Equal(_bounds.Value, (Rectangle)textOut->rclBounds); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/TransformValidator.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/TransformValidator.cs deleted file mode 100644 index d154d74385f..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/TransformValidator.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Numerics; - -namespace System.Windows.Forms.Metafiles; - -internal class TransformValidator : IStateValidator -{ - private readonly Matrix3x2 _transform; - public TransformValidator(Matrix3x2 transform) => _transform = transform; - public void Validate(DeviceContextState state) => Assert.Equal(_transform, state.Transform); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Validate.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Validate.cs deleted file mode 100644 index b655e81d323..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Metafiles/Validators/Validate.cs +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Drawing; - -namespace System.Windows.Forms.Metafiles; - -internal static class Validate -{ - /// Optional bounds to validate. - /// Optional points to validate. - /// Optional device context state validation to perform. - internal static IEmfValidator Polygon16( - Rectangle? bounds = default, - Point[]? points = default, - params IStateValidator[] stateValidators) => new Polygon16Validator( - bounds, - points, - stateValidators); - - /// Optional bounds to validate. - /// Optional points to validate. - /// Optional device context state validation to perform. - internal static IEmfValidator Polyline16( - Rectangle? bounds = default, - Point[]? points = default, - params IStateValidator[] stateValidators) => new Polyline16Validator( - bounds, - points, - stateValidators); - - /// Optional bounds to validate. - /// Optional count of polygons to validate. - /// Optional device context state validation to perform. - internal static IEmfValidator PolyPolygon16( - Rectangle? bounds = default, - int? polyCount = default, - params IStateValidator[] stateValidators) => new PolyPolygon16Validator( - bounds, - polyCount, - stateValidators); - - /// Optional bounds to validate. - /// Optional count of polygons to validate. - /// Optional device context state validation to perform. - internal static IEmfValidator PolyPolyline16( - Rectangle? bounds = default, - int? polyCount = default, - params IStateValidator[] stateValidators) => new PolyPolyline16Validator( - bounds, - polyCount, - stateValidators); - - /// Optional text to validate. - /// Optional bounds to validate. - /// Optional device context state validation to perform. - internal static IEmfValidator TextOut( - string? text = default, - Rectangle? bounds = default, - params IStateValidator[] stateValidators) => new TextOutValidator( - text, - bounds, - stateValidators); - - /// Optional source point to validate. - /// Optional destination point to validate. - /// Optional device context state validation to perform. - internal static IEmfValidator LineTo( - EasyPoint? from, - EasyPoint? to, - params IStateValidator[] stateValidators) => new LineToValidator( - from, - to, - stateValidators); - - /// Optional bounds to validate. - /// Optional device context state validation to perform. - internal static IEmfValidator Rectangle( - RECT? bounds, - params IStateValidator[] stateValidators) => new RectangleValidator( - bounds, - stateValidators); - - /// Optional bounds to validate. - /// Optional device context state validation to perform. - public static IEmfValidator BitBltValidator( - RECT? bounds, - params IStateValidator[] stateValidators) => new BitBltValidator( - bounds, - stateValidators); - - /// - /// Simple wrapper to allow doing an arbitrary action for a given . - /// - internal static IEmfValidator Action(ENHANCED_METAFILE_RECORD_TYPE recordType, ProcessRecordDelegate action) - => new ActionValidator(recordType, action); - - /// - /// Simple wrapper to allow doing an arbitrary action for a given . - /// - internal static IEmfValidator Action(ENHANCED_METAFILE_RECORD_TYPE recordType, ProcessRecordWithStateDelegate action) - => new ActionValidator(recordType, action); - - /// - /// Skip all records from this point. Use when you don't care about any further records. - /// - internal static IEmfValidator SkipAll() => SkipAllValidator.Instance; - - /// - /// Skip all output records that the given does not validate. - /// - internal static IEmfValidator SkipTo(IEmfValidator validator) => new SkipToValidator(validator); - - /// - /// Skips the next record of the given type. - /// - internal static IEmfValidator SkipType(ENHANCED_METAFILE_RECORD_TYPE type) => new SkipTypesValidator(type); - - /// - /// Skip the next record if it matches any of the given types. - /// - internal static IEmfValidator SkipTypes(params ENHANCED_METAFILE_RECORD_TYPE[] types) => new SkipTypesValidator(types); - - /// - /// Repeat the given validation number of times. - /// - internal static IEmfValidator Repeat(IEmfValidator validator, int count) => new RepeatValidator(validator, count); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/ModuleInitializer.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/ModuleInitializer.cs deleted file mode 100644 index bd13bfb703c..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/ModuleInitializer.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -namespace System; - -internal class ModuleInitializer -{ - [ModuleInitializer] - [SuppressMessage("Usage", "CA2255:The 'ModuleInitializer' attribute should not be used in libraries", Justification = "Intentional use of module initializer to register trace listener.")] - internal static void Initialize() - { - // Ensure the module initializer runs for the main test helper assembly - RuntimeHelpers.RunModuleConstructor(typeof(BoolDataAttribute).Module.ModuleHandle); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/NoAssertContext.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/NoAssertContext.cs deleted file mode 100644 index a479116fbfd..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/NoAssertContext.cs +++ /dev/null @@ -1,161 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -using System.Collections.Concurrent; - -namespace System; - -/// -/// Use (within a using) to eat asserts. -/// -public sealed class NoAssertContext : IDisposable -{ - // For any given thread we don't need to lock to decide how to route messages, as any messages for that - // given thread will not happen while we're in the constructor or dispose method on that thread. That - // means we can safely check to see if we've hooked our thread without locking (outside of using a - // concurrent collection to make sure the collection is in a known state). - // - // We do, however need to lock around hooking/unhooking our custom listener to make sure that we - // are rerouting correctly if multiple threads are creating/disposing this class concurrently. - - private static readonly object s_lock = new(); - private static bool s_hooked; - private static bool s_hasDefaultListener; - private static bool s_hasThrowingListener; - - private static readonly ConcurrentDictionary s_suppressedThreads = new(); - - // "Default" is the listener that terminates the process when debug assertions fail. - private static readonly TraceListener? s_defaultListener = Trace.Listeners["Default"]; - private static readonly NoAssertListener s_noAssertListener = new(); - - public NoAssertContext() - { - s_suppressedThreads.AddOrUpdate(Environment.CurrentManagedThreadId, 1, (key, oldValue) => oldValue + 1); - - // Lock to make sure we are hooked properly if two threads come into the constructor/dispose at the same time. - lock (s_lock) - { - if (!s_hooked) - { - // Hook our custom listener first so we don't lose assertions from other threads when - // we disconnect the default listener. - Trace.Listeners.Add(s_noAssertListener); - if (s_defaultListener is not null && Trace.Listeners.Contains(s_defaultListener)) - { - s_hasDefaultListener = true; - Trace.Listeners.Remove(s_defaultListener); - } - - if (Trace.Listeners.OfType().FirstOrDefault() is { } throwingTraceListener) - { - s_hasThrowingListener = true; - Trace.Listeners.Remove(throwingTraceListener); - } - - s_hooked = true; - } - } - } - - public void Dispose() - { - GC.SuppressFinalize(this); - - int currentThread = Environment.CurrentManagedThreadId; - if (s_suppressedThreads.TryRemove(currentThread, out int count)) - { - if (count > 1) - { - // We're in a nested assert context on a given thread, re-add with a decremented count. - // This doesn't need to be atomic as we're currently on the thread that would care about - // being rerouted. - s_suppressedThreads.TryAdd(currentThread, --count); - } - } - - lock (s_lock) - { - if (s_hooked && s_suppressedThreads.IsEmpty) - { - // We're the first to hit the need to unhook. Add the default listener back first to - // ensure we don't lose any asserts from other threads. - if (s_hasDefaultListener) - { - Trace.Listeners.Add(s_defaultListener!); - } - - if (s_hasThrowingListener) - { - Trace.Listeners.Add(ThrowingTraceListener.Instance); - } - - Trace.Listeners.Remove(s_noAssertListener); - s_hooked = false; - } - } - } - - ~NoAssertContext() - { - // We need this class to be used in a using to effectively rationalize about a test. - throw new InvalidOperationException($"Did not dispose {nameof(NoAssertContext)}"); - } - - private class NoAssertListener : TraceListener - { - public NoAssertListener() - : base(typeof(NoAssertListener).FullName) - { - } - - private TraceListener? DefaultListener - { - get - { - if (s_hasThrowingListener) - return ThrowingTraceListener.Instance; - else if (s_hasDefaultListener) - return s_defaultListener; - else - return null; - } - } - - public override void Fail(string? message) - { - if (!s_suppressedThreads.TryGetValue(Environment.CurrentManagedThreadId, out _)) - { - DefaultListener?.Fail(message); - } - } - - public override void Fail(string? message, string? detailMessage) - { - if (!s_suppressedThreads.TryGetValue(Environment.CurrentManagedThreadId, out _)) - { - DefaultListener?.Fail(message, detailMessage); - } - } - - // Write and WriteLine are virtual - - public override void Write(string? message) - { - if (!s_suppressedThreads.TryGetValue(Environment.CurrentManagedThreadId, out _)) - { - DefaultListener?.Write(message); - } - } - - public override void WriteLine(string? message) - { - if (!s_suppressedThreads.TryGetValue(Environment.CurrentManagedThreadId, out _)) - { - DefaultListener?.WriteLine(message); - } - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/PlatformDetection.Windows.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/PlatformDetection.Windows.cs deleted file mode 100644 index 4ee3ef4b15b..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/PlatformDetection.Windows.cs +++ /dev/null @@ -1,304 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using System.Security; -using Microsoft.Win32; - -namespace System; - -public static partial class PlatformDetection -{ - public static bool IsNetFramework => RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework", StringComparison.OrdinalIgnoreCase); - public static Version OSXVersion => throw new PlatformNotSupportedException(); - public static Version OpenSslVersion => throw new PlatformNotSupportedException(); - public static bool IsSuperUser => throw new PlatformNotSupportedException(); - public static bool IsCentos6 => false; - public static bool IsOpenSUSE => false; - public static bool IsUbuntu => false; - public static bool IsDebian => false; - public static bool IsAlpine => false; - public static bool IsDebian8 => false; - public static bool IsUbuntu1404 => false; - public static bool IsUbuntu1604 => false; - public static bool IsUbuntu1704 => false; - public static bool IsUbuntu1710 => false; - public static bool IsUbuntu1710OrHigher => false; - public static bool IsUbuntu1804 => false; - public static bool IsTizen => false; - public static bool IsNotFedoraOrRedHatFamily => true; - public static bool IsFedora => false; - public static bool IsWindowsNanoServer => (IsNotWindowsIoTCore && GetInstallationType().Equals("Nano Server", StringComparison.OrdinalIgnoreCase)); - public static bool IsWindowsServerCore => GetInstallationType().Equals("Server Core", StringComparison.OrdinalIgnoreCase); - public static int WindowsVersion => GetWindowsVersion(); - public static bool IsMacOsHighSierraOrHigher { get; } - public static Version ICUVersion => new(0, 0, 0, 0); - public static bool IsRedHatFamily => false; - public static bool IsNotRedHatFamily => true; - public static bool IsRedHatFamily6 => false; - public static bool IsRedHatFamily7 => false; - public static bool IsNotRedHatFamily6 => true; - - public static bool IsWindows10Version1607OrGreater => - GetWindowsVersion() == 10 && GetWindowsMinorVersion() == 0 && GetWindowsBuildNumber() >= 14393; - public static bool IsWindows10Version1703OrGreater => - GetWindowsVersion() == 10 && GetWindowsMinorVersion() == 0 && GetWindowsBuildNumber() >= 15063; - public static bool IsWindows10Version1709OrGreater => - GetWindowsVersion() == 10 && GetWindowsMinorVersion() == 0 && GetWindowsBuildNumber() >= 16299; - public static bool IsWindows10Version1803OrGreater => - GetWindowsVersion() == 10 && GetWindowsMinorVersion() == 0 && GetWindowsBuildNumber() >= 17134; - public static bool IsWindows11OrHigher => - GetWindowsVersion() == 10 && GetWindowsMinorVersion() == 0 && GetWindowsBuildNumber() >= 22000; - - // Windows OneCoreUAP SKU doesn't have httpapi.dll - public static bool IsNotOneCoreUAP => - File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "System32", "httpapi.dll")); - - public static bool IsWindowsIoTCore - { - get - { - int productType = GetWindowsProductType(); - if ((productType == PRODUCT_IOTUAPCOMMERCIAL) || - (productType == PRODUCT_IOTUAP)) - { - return true; - } - - return false; - } - } - - public static bool IsWindowsHomeEdition - { - get - { - int productType = GetWindowsProductType(); - switch (productType) - { - case PRODUCT_CORE: - case PRODUCT_CORE_COUNTRYSPECIFIC: - case PRODUCT_CORE_N: - case PRODUCT_CORE_SINGLELANGUAGE: - case PRODUCT_HOME_BASIC: - case PRODUCT_HOME_BASIC_N: - case PRODUCT_HOME_PREMIUM: - case PRODUCT_HOME_PREMIUM_N: - return true; - default: - return false; - } - } - } - - public static bool IsWindows => true; - public static bool IsWindows7 => GetWindowsVersion() == 6 && GetWindowsMinorVersion() == 1; - public static bool IsNotWindows7 => !IsWindows7; - public static bool IsWindows8x => GetWindowsVersion() == 6 && (GetWindowsMinorVersion() == 2 || GetWindowsMinorVersion() == 3); - - public static string LibcRelease => "glibc_not_found"; - public static string LibcVersion => "glibc_not_found"; - - public static string GetDistroVersionString() => $"WindowsProductType={GetWindowsProductType()} WindowsInstallationType={GetInstallationType()}"; - - private static int s_isInAppContainer = -1; - - public static bool IsInAppContainer - { - // This actually checks whether code is running in a modern app. - // Currently this is the only situation where we run in app container. - // If we want to distinguish the two cases in future, - // EnvironmentHelpers.IsAppContainerProcess in desktop code shows how to check for the AC token. - get - { - if (s_isInAppContainer != -1) - { - return s_isInAppContainer == 1; - } - - if (!IsWindows || IsWindows7) - { - s_isInAppContainer = 0; - return false; - } - - byte[] buffer = Array.Empty(); - uint bufferSize = 0; - try - { - int result = GetCurrentApplicationUserModelId(ref bufferSize, buffer); - switch (result) - { - case 15703: // APPMODEL_ERROR_NO_APPLICATION - s_isInAppContainer = 0; - break; - case 0: // ERROR_SUCCESS - case 122: // ERROR_INSUFFICIENT_BUFFER - // Success is actually insufficent buffer as we're really only looking for - // not NO_APPLICATION and we're not actually giving a buffer here. The - // API will always return NO_APPLICATION if we're not running under a - // WinRT process, no matter what size the buffer is. - s_isInAppContainer = 1; - break; - default: - throw new InvalidOperationException($"Failed to get AppId, result was {result}."); - } - } - catch (Exception e) - { - // We could catch this here, being friendly with older portable surface area should we - // desire to use this method elsewhere. - if (e.GetType().FullName.Equals("System.EntryPointNotFoundException", StringComparison.Ordinal)) - { - // API doesn't exist, likely pre Win8 - s_isInAppContainer = 0; - } - else - { - throw; - } - } - - return s_isInAppContainer == 1; - } - } - - private static int s_isWindowsElevated = -1; - - public static bool IsWindowsAndElevated - { - get - { - if (s_isWindowsElevated != -1) - { - return s_isWindowsElevated == 1; - } - - if (!IsWindows || IsInAppContainer) - { - s_isWindowsElevated = 0; - return false; - } - - Assert.True(OpenProcessToken(PInvoke.GetCurrentProcess(), TOKEN_READ, out IntPtr processToken)); - - try - { - Assert.True(GetTokenInformation( - processToken, TokenElevation, out uint tokenInfo, sizeof(uint), out uint returnLength)); - - s_isWindowsElevated = tokenInfo == 0 ? 0 : 1; - } - finally - { - PInvoke.CloseHandle((HANDLE)processToken); - } - - return s_isWindowsElevated == 1; - } - } - - private static string GetInstallationType() - { - string key = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion"; - string value = string.Empty; - - try - { - value = (string)Registry.GetValue(key, "InstallationType", defaultValue: ""); - } - catch (Exception e) when (e is SecurityException || e is InvalidCastException || e is PlatformNotSupportedException /* UAP */) - { - } - - return value; - } - - private static int GetWindowsProductType() - { - Assert.True(GetProductInfo(Environment.OSVersion.Version.Major, Environment.OSVersion.Version.Minor, 0, 0, out int productType)); - return productType; - } - - private static unsafe int GetWindowsMinorVersion() - { - var osvi = new RTL_OSVERSIONINFOEX - { - dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX) - }; - Assert.Equal(0, RtlGetVersion(ref osvi)); - return (int)osvi.dwMinorVersion; - } - - private static unsafe int GetWindowsBuildNumber() - { - var osvi = new RTL_OSVERSIONINFOEX - { - dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX) - }; - Assert.Equal(0, RtlGetVersion(ref osvi)); - return (int)osvi.dwBuildNumber; - } - - private const uint TokenElevation = 20; - private const uint STANDARD_RIGHTS_READ = 0x00020000; - private const uint TOKEN_QUERY = 0x0008; - private const uint TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY; - - [DllImport("advapi32.dll", SetLastError = true, ExactSpelling = true)] - private static extern bool GetTokenInformation( - IntPtr TokenHandle, - uint TokenInformationClass, - out uint TokenInformation, - uint TokenInformationLength, - out uint ReturnLength); - - private const int PRODUCT_IOTUAP = 0x0000007B; - private const int PRODUCT_IOTUAPCOMMERCIAL = 0x00000083; - private const int PRODUCT_CORE = 0x00000065; - private const int PRODUCT_CORE_COUNTRYSPECIFIC = 0x00000063; - private const int PRODUCT_CORE_N = 0x00000062; - private const int PRODUCT_CORE_SINGLELANGUAGE = 0x00000064; - private const int PRODUCT_HOME_BASIC = 0x00000002; - private const int PRODUCT_HOME_BASIC_N = 0x00000005; - private const int PRODUCT_HOME_PREMIUM = 0x00000003; - private const int PRODUCT_HOME_PREMIUM_N = 0x0000001A; - - [DllImport("kernel32.dll", SetLastError = false)] - private static extern bool GetProductInfo( - int dwOSMajorVersion, - int dwOSMinorVersion, - int dwSpMajorVersion, - int dwSpMinorVersion, - out int pdwReturnedProductType); - - [DllImport("ntdll.dll", ExactSpelling = true)] - private static extern int RtlGetVersion(ref RTL_OSVERSIONINFOEX lpVersionInformation); - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - private unsafe struct RTL_OSVERSIONINFOEX - { - internal uint dwOSVersionInfoSize; - internal uint dwMajorVersion; - internal uint dwMinorVersion; - internal uint dwBuildNumber; - internal uint dwPlatformId; - internal fixed char szCSDVersion[128]; - } - - private static unsafe int GetWindowsVersion() - { - var osvi = new RTL_OSVERSIONINFOEX - { - dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX) - }; - Assert.Equal(0, RtlGetVersion(ref osvi)); - return (int)osvi.dwMajorVersion; - } - - [DllImport("kernel32.dll", ExactSpelling = true)] - private static extern int GetCurrentApplicationUserModelId(ref uint applicationUserModelIdLength, byte[] applicationUserModelId); - - [DllImport("advapi32.dll", SetLastError = true, ExactSpelling = true)] - private static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle); -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/PlatformDetection.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/PlatformDetection.cs deleted file mode 100644 index 25fc44a1cf8..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/PlatformDetection.cs +++ /dev/null @@ -1,158 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace System; - -public static partial class PlatformDetection -{ - // - // Do not use the " { get; } = " pattern here. Having all the initialization happen in the type initializer - // means that one exception anywhere means all tests using PlatformDetection fail. If you feel a value is worth latching, - // do it in a way that failures don't cascade. - // - - public static bool HasWindowsShell => IsWindows && IsNotWindowsServerCore && IsNotWindowsNanoServer && IsNotWindowsIoTCore; - public static bool IsUap => IsInAppContainer || IsNetNative; - public static bool IsNetNative => RuntimeInformation.FrameworkDescription.StartsWith(".NET Native", StringComparison.OrdinalIgnoreCase); - public static bool IsNetCore => RuntimeInformation.FrameworkDescription.StartsWith(".NET Core", StringComparison.OrdinalIgnoreCase); - public static bool IsNotWindows8x => !IsWindows8x; - public static bool IsNotWindowsNanoServer => !IsWindowsNanoServer; - public static bool IsNotWindowsServerCore => !IsWindowsServerCore; - public static bool IsNotWindowsIoTCore => !IsWindowsIoTCore; - public static bool IsNotWindowsHomeEdition => !IsWindowsHomeEdition; - public static bool IsDrawingSupported => (IsNotWindowsNanoServer && IsNotWindowsIoTCore); - public static bool IsArmProcess => RuntimeInformation.ProcessArchitecture == Architecture.Arm; - public static bool IsNotArmProcess => !IsArmProcess; - public static bool IsArm64Process => RuntimeInformation.ProcessArchitecture == Architecture.Arm64; - public static bool IsNotArm64Process => !IsArm64Process; - public static bool IsArmOrArm64Process => IsArmProcess || IsArm64Process; - public static bool Is32BitProcess => IntPtr.Size == 4; - - public static bool IsMonoRuntime => Type.GetType("Mono.RuntimeStructs") is object; - public static bool IsNotMonoRuntime => !IsMonoRuntime; - public static bool IsMonoInterpreter => GetIsRunningOnMonoInterpreter(); - public static bool IsNativeAot => IsNotMonoRuntime && !IsReflectionEmitSupported; - - // Changed to `true` when trimming - public static bool IsBuiltWithAggressiveTrimming => IsNativeAot; - public static bool IsNotBuiltWithAggressiveTrimming => !IsBuiltWithAggressiveTrimming; - - public static bool IsNotInAppContainer => !IsInAppContainer; - public static bool IsWinRTSupported => IsWindows && !IsWindows7; - public static bool IsNotWinRTSupported => !IsWinRTSupported; - public static bool IsNotMacOsHighSierraOrHigher => !IsMacOsHighSierraOrHigher; - - public static bool IsDomainJoinedMachine => !Environment.MachineName.Equals(Environment.UserDomainName, StringComparison.OrdinalIgnoreCase); - - public static bool IsNotNetNative => !IsNetNative; - - // Windows - Schannel supports alpn from win8.1/2012 R2 and higher. - // Linux - OpenSsl supports alpn from openssl 1.0.2 and higher. - // OSX - SecureTransport doesn't expose alpn APIs. #30492 - public static bool SupportsAlpn => (IsWindows && !IsWindows7) || - (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && - (OpenSslVersion.Major >= 1 && (OpenSslVersion.Minor >= 1 || OpenSslVersion.Build >= 2))); - public static bool SupportsClientAlpn => SupportsAlpn || - (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && PlatformDetection.OSXVersion > new Version(10, 12)); - - // Officially, .Net Native only supports processes running in an AppContainer. However, the majority of tests still work fine - // in a normal Win32 process and we often do so as running in an AppContainer imposes a substantial tax in debuggability - // and investigatability. This predicate is used in ConditionalFacts to disable the specific tests that really need to be - // running in AppContainer when running on .NetNative. - public static bool IsNotNetNativeRunningAsConsoleApp => !(IsNetNative && !IsInAppContainer); - - private static readonly Lazy m_isWindowsSubsystemForLinux = new(GetIsWindowsSubsystemForLinux); - - public static bool IsWindowsSubsystemForLinux => m_isWindowsSubsystemForLinux.Value; - public static bool IsNotWindowsSubsystemForLinux => !IsWindowsSubsystemForLinux; - - private static bool GetIsWindowsSubsystemForLinux() - { - // https://github.com/Microsoft/BashOnWindows/issues/423#issuecomment-221627364 - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - const string versionFile = "/proc/version"; - if (File.Exists(versionFile)) - { - string s = File.ReadAllText(versionFile); - - if (s.Contains("Microsoft") || s.Contains("WSL")) - { - return true; - } - } - } - - return false; - } - - private static readonly Lazy s_largeArrayIsNotSupported = new(IsLargeArrayNotSupported); - - [MethodImpl(MethodImplOptions.NoOptimization)] - private static bool IsLargeArrayNotSupported() - { - try - { - var tmp = new byte[int.MaxValue]; - return tmp is null; - } - catch (OutOfMemoryException) - { - return true; - } - } - - public static bool IsNotIntMaxValueArrayIndexSupported => s_largeArrayIsNotSupported.Value; - - public static bool IsNonZeroLowerBoundArraySupported - { - get - { - if (s_lazyNonZeroLowerBoundArraySupported is null) - { - bool nonZeroLowerBoundArraysSupported = false; - try - { - Array.CreateInstance(typeof(int), new int[] { 5 }, new int[] { 5 }); - nonZeroLowerBoundArraysSupported = true; - } - catch (PlatformNotSupportedException) - { - } - - s_lazyNonZeroLowerBoundArraySupported = Tuple.Create(nonZeroLowerBoundArraysSupported); - } - - return s_lazyNonZeroLowerBoundArraySupported.Item1; - } - } - - private static volatile Tuple s_lazyNonZeroLowerBoundArraySupported; - - // Tracked in: https://github.com/dotnet/corert/issues/3643 in case we change our mind about this. - public static bool IsInvokingStaticConstructorsSupported => !PlatformDetection.IsNetNative; - - // System.Security.Cryptography.Xml.XmlDsigXsltTransform.GetOutput() relies on XslCompiledTransform which relies - // heavily on Reflection.Emit - public static bool IsXmlDsigXsltTransformSupported => !PlatformDetection.IsUap; - - private static bool GetIsRunningOnMonoInterpreter() - { -#if NETCOREAPP - return IsMonoRuntime && RuntimeFeature.IsDynamicCodeSupported && !RuntimeFeature.IsDynamicCodeCompiled; -#else - return false; -#endif - } - -#if NETCOREAPP - public static bool IsReflectionEmitSupported => RuntimeFeature.IsDynamicCodeSupported; - public static bool IsNotReflectionEmitSupported => !IsReflectionEmitSupported; -#else - public static bool IsReflectionEmitSupported => true; -#endif -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Properties/InternalsVisibleTo.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Properties/InternalsVisibleTo.cs deleted file mode 100644 index b8a60fe3ae0..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Properties/InternalsVisibleTo.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -// Awkward, but necessary to expose Interop based internals to other test libraries -[assembly: InternalsVisibleTo("System.Windows.Forms.Primitives.Tests, PublicKey=00000000000000000400000000000000")] -[assembly: InternalsVisibleTo("System.Windows.Forms.Tests, PublicKey=00000000000000000400000000000000")] -[assembly: InternalsVisibleTo("System.Windows.Forms.TestUtilities, PublicKey=00000000000000000400000000000000")] -[assembly: InternalsVisibleTo("System.Windows.Forms.Primitives.TestUtilities.Tests, PublicKey=00000000000000000400000000000000")] -[assembly: InternalsVisibleTo("System.Windows.Forms.Design.Tests, PublicKey=00000000000000000400000000000000")] -[assembly: InternalsVisibleTo("WinformsControlsTest, PublicKey=00000000000000000400000000000000")] -[assembly: InternalsVisibleTo("MauiListViewTests, PublicKey=00000000000000000400000000000000")] - -// This is needed in order to Moq internal interfaces for testing -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/System.Windows.Forms.Primitives.TestUtilities.csproj b/src/System.Windows.Forms.Primitives/tests/TestUtilities/System.Windows.Forms.Primitives.TestUtilities.csproj deleted file mode 100644 index d5bcc445d3e..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/System.Windows.Forms.Primitives.TestUtilities.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - System.Windows.Forms.Primitives.TestUtilities - true - System - - - - - - - - - - - - - - - - diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/System/Windows/Forms/BinaryFormat/BinaryFormatTestExtensions.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/System/Windows/Forms/BinaryFormat/BinaryFormatTestExtensions.cs deleted file mode 100644 index b5e8a2cdbb2..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/System/Windows/Forms/BinaryFormat/BinaryFormatTestExtensions.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; - -namespace System.Windows.Forms.BinaryFormat; - -internal static class BinaryFormatTestExtensions -{ - /// - /// Serializes the object using the and reads it into a . - /// - public static BinaryFormattedObject SerializeAndParse(this object source) => new(source.Serialize()); - - /// - /// Serializes the object using the . - /// - public static Stream Serialize(this object source) - { - MemoryStream stream = new(); - using var formatterScope = new BinaryFormatterScope(enable: true); -#pragma warning disable SYSLIB0011 // Type or member is obsolete - BinaryFormatter formatter = new(); -#pragma warning restore SYSLIB0011 - formatter.Serialize(stream, source); - stream.Position = 0; - return stream; - } - - /// - /// Returns `true` if the would use the for the purposes - /// of designer serialization (either through Resx or IPropertyBag for ActiveXImpl). - /// - public static bool IsBinaryFormatted(this Type type) - { - bool iSerializable = type.IsAssignableTo(typeof(ISerializable)); -#pragma warning disable SYSLIB0050 // Type or member is obsolete - bool serializable = type.IsSerializable; -#pragma warning restore SYSLIB0050 - - if (!iSerializable && !serializable) - { - return false; - } - - TypeConverter converter; - try - { - converter = TypeDescriptor.GetConverter(type); - } - catch (Exception) - { - // No valid type converter. - return true; - } - - return !((converter.CanConvertFrom(typeof(string)) && converter.CanConvertTo(typeof(string))) - || (converter.CanConvertFrom(typeof(byte[])) && converter.CanConvertTo(typeof(byte[])))); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/SystemCOLORs.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/SystemCOLORs.cs deleted file mode 100644 index 8f00854e431..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/SystemCOLORs.cs +++ /dev/null @@ -1,91 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System; - -internal static class SystemCOLORs -{ - private static readonly Dictionary> s_systemColors = CreateColorDictionary(); - - private static readonly Dictionary s_names = new() - { - { SYS_COLOR_INDEX.COLOR_SCROLLBAR, "COLOR_SCROLLBAR" }, - { SYS_COLOR_INDEX.COLOR_BACKGROUND, "COLOR_BACKGROUND" }, - { SYS_COLOR_INDEX.COLOR_ACTIVECAPTION, "COLOR_ACTIVECAPTION" }, - { SYS_COLOR_INDEX.COLOR_INACTIVECAPTION, "COLOR_INACTIVECAPTION" }, - { SYS_COLOR_INDEX.COLOR_MENU, "COLOR_MENU" }, - { SYS_COLOR_INDEX.COLOR_WINDOW, "COLOR_WINDOW" }, - { SYS_COLOR_INDEX.COLOR_WINDOWFRAME, "COLOR_WINDOWFRAME" }, - { SYS_COLOR_INDEX.COLOR_MENUTEXT, "COLOR_MENUTEXT" }, - { SYS_COLOR_INDEX.COLOR_WINDOWTEXT, "COLOR_WINDOWTEXT" }, - { SYS_COLOR_INDEX.COLOR_CAPTIONTEXT, "COLOR_CAPTIONTEXT" }, - { SYS_COLOR_INDEX.COLOR_ACTIVEBORDER, "COLOR_ACTIVEBORDER" }, - { SYS_COLOR_INDEX.COLOR_INACTIVEBORDER, "COLOR_INACTIVEBORDER" }, - { SYS_COLOR_INDEX.COLOR_APPWORKSPACE, "COLOR_APPWORKSPACE" }, - { SYS_COLOR_INDEX.COLOR_HIGHLIGHT, "COLOR_HIGHLIGHT" }, - { SYS_COLOR_INDEX.COLOR_HIGHLIGHTTEXT, "COLOR_HIGHLIGHTTEXT" }, - { SYS_COLOR_INDEX.COLOR_BTNFACE, "COLOR_BTNFACE" }, - { SYS_COLOR_INDEX.COLOR_BTNSHADOW, "COLOR_BTNSHADOW" }, - { SYS_COLOR_INDEX.COLOR_GRAYTEXT, "COLOR_GRAYTEXT" }, - { SYS_COLOR_INDEX.COLOR_BTNTEXT, "COLOR_BTNTEXT" }, - { SYS_COLOR_INDEX.COLOR_INACTIVECAPTIONTEXT, "COLOR_INACTIVECAPTIONTEXT" }, - { SYS_COLOR_INDEX.COLOR_BTNHIGHLIGHT, "COLOR_BTNHIGHLIGHT" }, - { SYS_COLOR_INDEX.COLOR_3DDKSHADOW, "COLOR_3DDKSHADOW" }, - { SYS_COLOR_INDEX.COLOR_3DLIGHT, "COLOR_3DLIGHT" }, - { SYS_COLOR_INDEX.COLOR_INFOTEXT, "COLOR_INFOTEXT" }, - { SYS_COLOR_INDEX.COLOR_INFOBK, "COLOR_INFOBK" }, - { SYS_COLOR_INDEX.COLOR_HOTLIGHT, "COLOR_HOTLIGHT" }, - { SYS_COLOR_INDEX.COLOR_GRADIENTACTIVECAPTION, "COLOR_GRADIENTACTIVECAPTION" }, - { SYS_COLOR_INDEX.COLOR_GRADIENTINACTIVECAPTION, "COLOR_GRADIENTINACTIVECAPTION" }, - { SYS_COLOR_INDEX.COLOR_MENUHILIGHT, "COLOR_MENUHILIGHT" }, - { SYS_COLOR_INDEX.COLOR_MENUBAR, "COLOR_MENUBAR" }, - }; - - public static bool TryGetSystemColor(COLORREF colorRef, out List colors) - => s_systemColors.TryGetValue(colorRef, out colors); - - public static string ToSystemColorString(COLORREF colorRef) - { - if (TryGetSystemColor(colorRef, out List colors)) - { - string colorString = string.Join(", ", colors.Select(c => s_names[c])); - return $"{colorRef} ({colorString})"; - } - else - { - return colorRef.ToString(); - } - } - - private static Dictionary> CreateColorDictionary() - { - Dictionary> dictionary = new(); - - for (int i = 0; i <= (int)SYS_COLOR_INDEX.COLOR_MENUBAR; i++) - { - if (i == 25) - { - // Only undefined value - continue; - } - - COLORREF colorRef = (COLORREF)PInvoke.GetSysColor((SYS_COLOR_INDEX)i); - - if (dictionary.TryGetValue(colorRef, out List colors)) - { - colors.Add((SYS_COLOR_INDEX)i); - } - else - { - List colorList = new() - { - (SYS_COLOR_INDEX)i - }; - - dictionary.Add(colorRef, colorList); - } - } - - return dictionary; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/EditClass.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/EditClass.cs deleted file mode 100644 index 2e53e1f9225..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/EditClass.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System; - -internal class EditClass : WindowClass -{ - public EditClass() : base(PInvoke.WC_EDIT) - { - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/EditControl.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/EditControl.cs deleted file mode 100644 index 0ea04ead502..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/EditControl.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; - -namespace System; - -internal class EditControl : Window -{ - private static readonly EditClass s_editClass = new(); - - public EditControl(string windowName = default, - WINDOW_STYLE style = WINDOW_STYLE.WS_OVERLAPPED, - WINDOW_EX_STYLE extendedStyle = WINDOW_EX_STYLE.WS_EX_CLIENTEDGE | WINDOW_EX_STYLE.WS_EX_LEFT | WINDOW_EX_STYLE.WS_EX_LTRREADING, - bool isMainWindow = false, - Window parentWindow = default, - nint parameters = default, - HMENU menuHandle = default) - : base(s_editClass, new Rectangle(0, 0, 100, 50), windowName, style, extendedStyle, isMainWindow, parentWindow, parameters, menuHandle) - { - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/Window.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/Window.cs deleted file mode 100644 index 9bf9c7c8349..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/Window.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; - -namespace System; - -internal class Window : IDisposable, IHandle -{ - private readonly WindowClass _windowClass; - - public HWND Handle { get; } - - public Window( - WindowClass windowClass, - Rectangle bounds, - string windowName = default, - WINDOW_STYLE style = WINDOW_STYLE.WS_OVERLAPPED, - WINDOW_EX_STYLE extendedStyle = default, - bool isMainWindow = false, - Window parentWindow = default, - nint parameters = default, - HMENU menuHandle = default) - { - _windowClass = windowClass; - if (!_windowClass.IsRegistered) - { - _windowClass.Register(); - } - - Handle = _windowClass.CreateWindow( - bounds, - windowName, - style, - extendedStyle, - isMainWindow, - parentWindow?.Handle ?? default, - parameters, - menuHandle); - } - - public void Dispose() - { - if (!Handle.IsNull) - { - PInvoke.DestroyWindow(Handle); - } - - GC.SuppressFinalize(this); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/WindowClass.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/WindowClass.cs deleted file mode 100644 index 36885ee3215..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Win32/WindowClass.cs +++ /dev/null @@ -1,232 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Reflection; -using System.Runtime.InteropServices; - -namespace System; - -internal class WindowClass -{ - private static RECT DefaultBounds - => new(PInvoke.CW_USEDEFAULT, PInvoke.CW_USEDEFAULT, PInvoke.CW_USEDEFAULT, PInvoke.CW_USEDEFAULT); - - // Stash the delegate to keep it from being collected - private readonly WNDPROC _windowProcedure; - private WNDCLASSW _wndClass; - private readonly string _className; - private readonly string _menuName; - - public ATOM Atom { get; private set; } - public HWND MainWindow { get; private set; } - public HINSTANCE ModuleInstance { get; } - - /// - /// Constructor. - /// - /// Name, or default will be generated. - /// Module to associate with the window. The entry assembly is the default. - /// Use (HINSTANCE)(-1) for no background brush. - /// Use (HICON)(-1) for no icon. - /// Use (HCURSOR)(-1) for no cursor. - /// Menu name, can not set with . - /// Menu id, can not set with . - [UnconditionalSuppressMessage("SingleFile", "IL3002:Avoid calling members marked with 'RequiresAssemblyFilesAttribute' when publishing as a single-file", Justification = "Test only binary and not shippable.")] - public unsafe WindowClass( - string className = default, - HINSTANCE moduleInstance = default, - WNDCLASS_STYLES classStyle = WNDCLASS_STYLES.CS_HREDRAW | WNDCLASS_STYLES.CS_VREDRAW, - HBRUSH backgroundBrush = default, - HICON icon = default, - HCURSOR cursor = default, - string menuName = null, - int menuId = 0, - int classExtraBytes = 0, - int windowExtraBytes = 0) - { - // Handle default values - className ??= Guid.NewGuid().ToString(); - - if (backgroundBrush.IsNull) - { - backgroundBrush = PInvoke.GetSysColorBrush(SYS_COLOR_INDEX.COLOR_WINDOW); - } - else if (backgroundBrush == (HBRUSH)(-1)) - { - backgroundBrush = default; - } - - if (icon.IsNull) - { - icon = PInvoke.LoadIcon((HINSTANCE)0, (PCWSTR)(char*)PInvoke.IDI_APPLICATION); - } - else if (icon == (-1)) - { - icon = default; - } - - if (cursor == default) - { - cursor = PInvoke.LoadCursor((HINSTANCE)0, (PCWSTR)(char*)PInvoke.IDC_ARROW); - } - else if (cursor == (-1)) - { - cursor = default; - } - - if (moduleInstance.IsNull) - Marshal.GetHINSTANCE(Assembly.GetCallingAssembly().Modules.First()); - - if (menuId != 0 && menuName is not null) - throw new ArgumentException($"Can't set both {nameof(menuName)} and {nameof(menuId)}."); - - _windowProcedure = WNDPROC; - ModuleInstance = moduleInstance; - - _className = className; - _menuName = menuName ?? string.Empty; - - _wndClass = new WNDCLASSW - { - style = classStyle, - lpfnWndProc = (delegate* unmanaged[Stdcall])Marshal.GetFunctionPointerForDelegate(_windowProcedure), - cbClsExtra = classExtraBytes, - cbWndExtra = windowExtraBytes, - hInstance = moduleInstance, - hIcon = icon, - hCursor = cursor, - hbrBackground = backgroundBrush, - lpszMenuName = (char*)menuId - }; - } - - public bool IsRegistered => Atom.IsValid || ModuleInstance.IsNull; - - public unsafe WindowClass Register() - { - fixed (char* name = _className) - fixed (char* menuName = _menuName) - { - _wndClass.lpszClassName = name; - if (!string.IsNullOrEmpty(_menuName)) - _wndClass.lpszMenuName = menuName; - - ATOM atom = PInvoke.RegisterClass(in _wndClass); - if (!atom.IsValid) - { - throw new Win32Exception(); - } - - Atom = atom; - return this; - } - } - - public IntPtr CreateWindow( - string windowName = null, - WINDOW_STYLE style = WINDOW_STYLE.WS_OVERLAPPED, - WINDOW_EX_STYLE extendedStyle = default, - bool isMainWindow = false, - HWND parentWindow = default, - nint parameters = default, - HMENU menuHandle = default) - { - return CreateWindow( - DefaultBounds, - windowName, - style, - extendedStyle, - isMainWindow, - parentWindow, - parameters, - menuHandle); - } - - public unsafe HWND CreateWindow( - RECT bounds, - string windowName = null, - WINDOW_STYLE style = WINDOW_STYLE.WS_OVERLAPPED, - WINDOW_EX_STYLE extendedStyle = default, - bool isMainWindow = false, - HWND parentWindow = default, - nint parameters = default, - HMENU menuHandle = default) - { - if (!IsRegistered) - throw new ArgumentException("Window class must be registered before using."); - - fixed (char* wn = windowName) - { - HWND window; - if (Atom.IsValid) - { - window = PInvoke.CreateWindowEx( - dwExStyle: extendedStyle, - lpClassName: (PCWSTR)(char*)Atom.Value, - lpWindowName: (PCWSTR)wn, - dwStyle: style, - X: bounds.X, - Y: bounds.Y, - nWidth: bounds.Width, - nHeight: bounds.Height, - hWndParent: parentWindow, - hMenu: menuHandle, - hInstance: (HINSTANCE)0, - lpParam: (void*)parameters); - } - else - { - fixed (char* cn = _className) - { - window = PInvoke.CreateWindowEx( - dwExStyle: extendedStyle, - lpClassName: (PCWSTR)cn, - lpWindowName: (PCWSTR)wn, - dwStyle: style, - X: bounds.X, - Y: bounds.Y, - nWidth: bounds.Width, - nHeight: bounds.Height, - hWndParent: parentWindow, - hMenu: menuHandle, - hInstance: (HINSTANCE)0, - lpParam: (void*)parameters); - } - } - - if (window.IsNull) - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - - if (!Atom.IsValid) - { - Atom = PInvoke.GetClassLong(window, GET_CLASS_LONG_INDEX.GCW_ATOM); - } - - if (isMainWindow) - { - MainWindow = window; - } - - return window; - } - } - - protected virtual LRESULT WNDPROC(HWND hWnd, MessageId msg, WPARAM wParam, LPARAM lParam) - { - switch (msg) - { - case PInvoke.WM_DESTROY: - if (hWnd == MainWindow) - { - PInvoke.PostQuitMessage(0); - } - - return (LRESULT)0; - } - - return PInvoke.DefWindowProc(hWnd, (uint)msg, wParam, lParam); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Windows/Win32/System/Com/ComClassFactory.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Windows/Win32/System/Com/ComClassFactory.cs deleted file mode 100644 index b25bc1ce816..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Windows/Win32/System/Com/ComClassFactory.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Runtime.InteropServices; - -namespace Windows.Win32.System.Com; - -/// -/// Wraps an from a dynamically loaded assembly. -/// -internal unsafe class ComClassFactory : IDisposable -{ - private readonly string _filePath; - public Guid ClassId { get; } - private readonly HINSTANCE _instance; - private readonly IClassFactory* _classFactory; - - private const string ExportMethodName = "DllGetClassObject"; - - public ComClassFactory( - string filePath, - Guid classId) - { - _filePath = filePath; - ClassId = classId; - _instance = PInvoke.LoadLibraryEx(filePath, default); - if (_instance.IsNull) - { - throw new Win32Exception(); - } - - // Dynamically get the class factory method. - - // HRESULT DllGetClassObject( - // [in] REFCLSID rclsid, - // [in] REFIID riid, - // [out] LPVOID* ppv - // ); - - FARPROC proc = PInvoke.GetProcAddress(_instance, ExportMethodName); - IClassFactory* classFactory; - ((delegate* unmanaged)proc.Value)( - &classId, IID.Get(), - (void**)&classFactory).ThrowOnFailure(); - _classFactory = classFactory; - } - - internal HRESULT CreateInstance(out IUnknown* unknown) - { - unknown = default; - fixed (IUnknown** u = &unknown) - { - return _classFactory->CreateInstance(null, IID.Get(), (void**)u); - } - } - - internal HRESULT CreateInstance(out object unknown) - { - HRESULT result = CreateInstance(out IUnknown* punk); - unknown = punk is null ? null : Marshal.GetObjectForIUnknown((nint)punk); - return result; - } - - public void Dispose() - { - _classFactory->Release(); - PInvoke.FreeLibrary(_instance); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Windows/Win32/System/Ole/DropTargetMock.cs b/src/System.Windows.Forms.Primitives/tests/TestUtilities/Windows/Win32/System/Ole/DropTargetMock.cs deleted file mode 100644 index acf7a3d531c..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/TestUtilities/Windows/Win32/System/Ole/DropTargetMock.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Windows.Win32.System.Com; -using Windows.Win32.System.SystemServices; - -namespace Windows.Win32.System.Ole; - -internal unsafe class DropTargetMock : IDropTarget.Interface, IManagedWrapper -{ - public virtual HRESULT DragEnter(IDataObject* pDataObj, MODIFIERKEYS_FLAGS grfKeyState, POINTL pt, DROPEFFECT* pdwEffect) - { - throw new NotImplementedException(); - } - - public virtual HRESULT DragOver(MODIFIERKEYS_FLAGS grfKeyState, POINTL pt, DROPEFFECT* pdwEffect) - { - throw new NotImplementedException(); - } - - public virtual HRESULT DragLeave() - { - throw new NotImplementedException(); - } - - public virtual HRESULT Drop(IDataObject* pDataObj, MODIFIERKEYS_FLAGS grfKeyState, POINTL pt, DROPEFFECT* pdwEffect) - { - throw new NotImplementedException(); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/GlobalUsings.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/GlobalUsings.cs deleted file mode 100644 index 46aa0cc2626..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/GlobalUsings.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -global using Windows.Win32; -global using Windows.Win32.Foundation; -global using Windows.Win32.Graphics.Gdi; -global using Windows.Win32.UI.WindowsAndMessaging; -global using Xunit; -global using FluentAssertions; diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/LVITEMWTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/LVITEMWTests.cs deleted file mode 100644 index ae6d6810398..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/LVITEMWTests.cs +++ /dev/null @@ -1,91 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using static Interop.ComCtl32; - -namespace System.Windows.Forms.Tests.InteropTests; - -public class LVITEMWTests -{ - [Fact] - public unsafe void UpdateText_should_throw_AOOR_if_cchTextMax_less_than_1() - { - var lvi = new LVITEMW - { - cchTextMax = 0, - }; - - Assert.Throws(() => lvi.UpdateText("012345")); - } - -#pragma warning disable xUnit1026 // Theory methods should use all of their parameters - [Theory] - [MemberData(nameof(UpdateText_TestData))] - public unsafe void UpdateText_should_limit_input_text_to_cchTextMax_less_1_text_longer(string originalText, int maxLength, string newText, string expected) - { - fixed (char* pOriginalText = originalText) - { - var lvi = new LVITEMW - { - cchTextMax = maxLength, - pszText = pOriginalText - }; - - lvi.UpdateText(newText); - - var text = new string(lvi.pszText); - Assert.Equal(expected, text); - Assert.Equal(maxLength - 1, text.Length); - Assert.Equal(text.Length + 1, lvi.cchTextMax); - Assert.Equal(maxLength, lvi.cchTextMax); - } - } -#pragma warning restore xUnit1026 // Theory methods should use all of their parameters - - public static IEnumerable UpdateText_TestData() - { - yield return new object[] { "abcdefg", "abcdefg".Length, "0123456", "012345" }; - yield return new object[] { "abcdefg", "abcdefg".Length, "0123456789", "012345" }; - } - - [Fact] - public unsafe void UpdateText_should_set_cchTextMax_to_input_text_length_plus_1_if_text_shorter() - { - string originalText = "abcdefghi"; - fixed (char* pOriginalText = originalText) - { - var lvi = new LVITEMW - { - cchTextMax = originalText.Length, - pszText = pOriginalText - }; - - lvi.UpdateText("012345"); - - var sText = new ReadOnlySpan(lvi.pszText, lvi.cchTextMax); - - var text = new string(lvi.pszText); - Assert.Equal("012345", text); - Assert.Equal(lvi.cchTextMax, text.Length + 1); - } - } - - [Fact] - public unsafe void UpdateText_should_set_null_terminated_text() - { - string originalText = "abcdefghi"; - fixed (char* pOriginalText = originalText) - { - var lvi = new LVITEMW - { - cchTextMax = originalText.Length, - pszText = pOriginalText - }; - - lvi.UpdateText("012345"); - - var sText = new ReadOnlySpan(lvi.pszText, lvi.cchTextMax); - Assert.Equal(sText.ToArray(), new char[] { '0', '1', '2', '3', '4', '5', '\0' }); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/MCGRIDINFOTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/MCGRIDINFOTests.cs deleted file mode 100644 index 130451f2f8c..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/MCGRIDINFOTests.cs +++ /dev/null @@ -1,150 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using static Interop.ComCtl32; - -namespace System.Windows.Forms.Primitives.Tests.Interop.ComCtl32; - -public class MCGRIDINFOTests -{ - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void MCGRIDINFO_x32_Size() - { - if (Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(84, sizeof(MCGRIDINFO)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void MCGRIDINFO_x32_Marshal_Size() - { - if (Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(84, Marshal.SizeOf()); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void MCGRIDINFO_x32_ensure_layout() - { - if (Environment.Is64BitProcess) - { - return; - } - - MCGRIDINFO sut = new MCGRIDINFO(); - byte* addr = (byte*)&sut; - - Assert.Equal(0, (byte*)&sut.cbSize - addr); // 4, UINT - Assert.Equal(4, (byte*)&sut.dwPart - addr); // 4, DWORD - Assert.Equal(8, (byte*)&sut.dwFlags - addr); // 4, DWORD - Assert.Equal(12, (byte*)&sut.iCalendar - addr); // 4, int - Assert.Equal(16, (byte*)&sut.iRow - addr); // 4, int - Assert.Equal(20, (byte*)&sut.iCol - addr); // 4, int - Assert.Equal(24, (byte*)&sut.bSelected - addr); // 4, BOOL - Assert.Equal(28, (byte*)&sut.stStart - addr); // 16, SYSTEMTIME - Assert.Equal(44, (byte*)&sut.stEnd - addr); // 16, SYSTEMTIME - Assert.Equal(60, (byte*)&sut.rc - addr); // 16, RECT - Assert.Equal(76, (byte*)&sut.pszName - addr); // 4, PWSTR - Assert.Equal(80, (byte*)&sut.cchName - addr); // 4, size_t - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public void MCGRIDINFO_x32_Marshal_OffsetOf_IsCorrect() - { - if (Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(0, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.cbSize))); // 4, UINT - Assert.Equal(4, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.dwPart))); // 4, DWORD - Assert.Equal(8, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.dwFlags))); // 4, DWORD - Assert.Equal(12, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.iCalendar))); // 4, int - Assert.Equal(16, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.iRow))); // 4, int - Assert.Equal(20, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.iCol))); // 4, int - Assert.Equal(24, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.bSelected))); // 4, BOOL - Assert.Equal(28, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.stStart))); // 16, SYSTEMTIME - Assert.Equal(44, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.stEnd))); // 16, SYSTEMTIME - Assert.Equal(60, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.rc))); // 16, RECT - Assert.Equal(76, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.pszName))); // 8, PWSTR - Assert.Equal(80, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.cchName))); // 8, size_t - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void MCGRIDINFO_x64_Size() - { - if (!Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(96, sizeof(MCGRIDINFO)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public void MCGRIDINFO_x64_Marshal_Size() - { - if (!Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(96, Marshal.SizeOf()); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void MCGRIDINFO_x64_ensure_layout() - { - if (!Environment.Is64BitProcess) - { - return; - } - - MCGRIDINFO sut = new MCGRIDINFO(); - byte* addr = (byte*)&sut; - - Assert.Equal(0, (byte*)&sut.cbSize - addr); // 4, UINT - Assert.Equal(4, (byte*)&sut.dwPart - addr); // 4, DWORD - Assert.Equal(8, (byte*)&sut.dwFlags - addr); // 4, DWORD - Assert.Equal(12, (byte*)&sut.iCalendar - addr); // 4, int - Assert.Equal(16, (byte*)&sut.iRow - addr); // 4, int - Assert.Equal(20, (byte*)&sut.iCol - addr); // 4, int - Assert.Equal(24, (byte*)&sut.bSelected - addr); // 4, BOOL - Assert.Equal(28, (byte*)&sut.stStart - addr); // 16, SYSTEMTIME - Assert.Equal(44, (byte*)&sut.stEnd - addr); // 16, SYSTEMTIME - Assert.Equal(60, (byte*)&sut.rc - addr); // 16, RECT - // 4 bytes alignment 76 -> 80 - Assert.Equal(80, (byte*)&sut.pszName - addr); // 8, PWSTR - Assert.Equal(88, (byte*)&sut.cchName - addr); // 8, size_t - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public void MCGRIDINFO_x64_Marshal_OffsetOf_IsCorrect() - { - if (!Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(0, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.cbSize))); // 4, UINT - Assert.Equal(4, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.dwPart))); // 4, DWORD - Assert.Equal(8, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.dwFlags))); // 4, DWORD - Assert.Equal(12, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.iCalendar))); // 4, int - Assert.Equal(16, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.iRow))); // 4, int - Assert.Equal(20, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.iCol))); // 4, int - Assert.Equal(24, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.bSelected))); // 4, BOOL - Assert.Equal(28, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.stStart))); // 16, SYSTEMTIME - Assert.Equal(44, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.stEnd))); // 16, SYSTEMTIME - Assert.Equal(60, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.rc))); // 16, RECT - // 4 bytes alignment 76 -> 80 - Assert.Equal(80, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.pszName))); // 8, PWSTR - Assert.Equal(88, (int)Marshal.OffsetOf(nameof(MCGRIDINFO.cchName))); // 8, size_t - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/TASKDIALOGCONFIGIconUnionTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/TASKDIALOGCONFIGIconUnionTests.cs deleted file mode 100644 index cfa44e0b62d..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/TASKDIALOGCONFIGIconUnionTests.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using static Interop.ComCtl32; - -namespace System.Windows.Forms.Primitives.Tests.Interop.ComCtl32; - -public class TASKDIALOGCONFIGIconUnionTests -{ - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void TASKDIALOGCONFIGIconUnion_x32_Size() - { - if (Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(4, sizeof(TASKDIALOGCONFIG.IconUnion)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void TASKDIALOGCONFIGIconUnion_x32_ensure_layout() - { - if (Environment.Is64BitProcess) - { - return; - } - - TASKDIALOGCONFIG.IconUnion sut = new TASKDIALOGCONFIG.IconUnion(); - byte* addr = (byte*)&sut; - - Assert.Equal(0, (byte*)&sut.hIcon - addr); // 4, HICON - Assert.Equal(0, (byte*)&sut.pszIcon - addr); // 4, PCWSTR - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void TASKDIALOGCONFIGIconUnion_x64_Size() - { - if (!Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(8, sizeof(TASKDIALOGCONFIG.IconUnion)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void TASKDIALOGCONFIGIconUnion_x64_ensure_layout() - { - if (!Environment.Is64BitProcess) - { - return; - } - - TASKDIALOGCONFIG.IconUnion sut = new TASKDIALOGCONFIG.IconUnion(); - byte* addr = (byte*)&sut; - - Assert.Equal(0, (byte*)&sut.hIcon - addr); // 8, HICON - Assert.Equal(0, (byte*)&sut.pszIcon - addr); // 8, PCWSTR - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/TASKDIALOGCONFIGTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/TASKDIALOGCONFIGTests.cs deleted file mode 100644 index 788e97eba9a..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/TASKDIALOGCONFIGTests.cs +++ /dev/null @@ -1,105 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using static Interop.ComCtl32; - -namespace System.Windows.Forms.Primitives.Tests.Interop.ComCtl32; - -public class TASKDIALOGCONFIGTests -{ - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void TASKDIALOGCONFIG_x32_Size() - { - if (Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(96, sizeof(TASKDIALOGCONFIG)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void TASKDIALOGCONFIG_x32_ensure_layout() - { - if (Environment.Is64BitProcess) - { - return; - } - - TASKDIALOGCONFIG sut = new TASKDIALOGCONFIG(); - byte* addr = (byte*)&sut; - - Assert.Equal(0, (byte*)&sut.cbSize - addr); // 4, UINT - Assert.Equal(4, (byte*)&sut.hwndParent - addr); // 4, HWND - Assert.Equal(8, (byte*)&sut.hInstance - addr); // 4, HINSTANCE - Assert.Equal(12, (byte*)&sut.dwFlags - addr); // 4, TASKDIALOG_FLAGS - Assert.Equal(16, (byte*)&sut.dwCommonButtons - addr); // 4, TASKDIALOG_COMMON_BUTTON_FLAGS - Assert.Equal(20, (byte*)&sut.pszWindowTitle - addr); // 4, PCWSTR - Assert.Equal(24, (byte*)&sut.mainIcon - addr); // 4, union { HICON; PCWSTR; } - Assert.Equal(28, (byte*)&sut.pszMainInstruction - addr); // 4, PCWSTR - Assert.Equal(32, (byte*)&sut.pszContent - addr); // 4, PCWSTR - Assert.Equal(36, (byte*)&sut.cButtons - addr); // 4, UINT - Assert.Equal(40, (byte*)&sut.pButtons - addr); // 4, const TASKDIALOG_BUTTON * - Assert.Equal(44, (byte*)&sut.nDefaultButton - addr); // 4, int - Assert.Equal(48, (byte*)&sut.cRadioButtons - addr); // 4, UINT - Assert.Equal(52, (byte*)&sut.pRadioButtons - addr); // 4, const TASKDIALOG_BUTTON * - Assert.Equal(56, (byte*)&sut.nDefaultRadioButton - addr); // 4, int - Assert.Equal(60, (byte*)&sut.pszVerificationText - addr); // 4, PCWSTR - Assert.Equal(64, (byte*)&sut.pszExpandedInformation - addr); // 4, PCWSTR - Assert.Equal(68, (byte*)&sut.pszExpandedControlText - addr); // 4, PCWSTR - Assert.Equal(72, (byte*)&sut.pszCollapsedControlText - addr); // 4, PCWSTR - Assert.Equal(76, (byte*)&sut.footerIcon - addr); // 4, union { HICON; PCWSTR; } - Assert.Equal(80, (byte*)&sut.pszFooter - addr); // 4, PCWSTR - Assert.Equal(84, (byte*)&sut.pfCallback - addr); // 4, PFTASKDIALOGCALLBACK - Assert.Equal(88, (byte*)&sut.lpCallbackData - addr); // 4, LONG_PTR - Assert.Equal(92, (byte*)&sut.cxWidth - addr); // 4, UINT - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void TASKDIALOGCONFIG_x64_Size() - { - if (!Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(160, sizeof(TASKDIALOGCONFIG)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void TASKDIALOGCONFIG_x64_ensure_layout() - { - if (!Environment.Is64BitProcess) - { - return; - } - - TASKDIALOGCONFIG sut = new TASKDIALOGCONFIG(); - byte* addr = (byte*)&sut; - - Assert.Equal(0, (byte*)&sut.cbSize - addr); // 4, UINT - Assert.Equal(4, (byte*)&sut.hwndParent - addr); // 8, HWND - Assert.Equal(12, (byte*)&sut.hInstance - addr); // 8, HINSTANCE - Assert.Equal(20, (byte*)&sut.dwFlags - addr); // 4, TASKDIALOG_FLAGS - Assert.Equal(24, (byte*)&sut.dwCommonButtons - addr); // 4, TASKDIALOG_COMMON_BUTTON_FLAGS - Assert.Equal(28, (byte*)&sut.pszWindowTitle - addr); // 8, PCWSTR - Assert.Equal(36, (byte*)&sut.mainIcon - addr); // 8, union { HICON; PCWSTR; } - Assert.Equal(44, (byte*)&sut.pszMainInstruction - addr); // 8, PCWSTR - Assert.Equal(52, (byte*)&sut.pszContent - addr); // 8, PCWSTR - Assert.Equal(60, (byte*)&sut.cButtons - addr); // 4, UINT - Assert.Equal(64, (byte*)&sut.pButtons - addr); // 8, const TASKDIALOG_BUTTON * - Assert.Equal(72, (byte*)&sut.nDefaultButton - addr); // 4, int - Assert.Equal(76, (byte*)&sut.cRadioButtons - addr); // 4, UINT - Assert.Equal(80, (byte*)&sut.pRadioButtons - addr); // 8, const TASKDIALOG_BUTTON * - Assert.Equal(88, (byte*)&sut.nDefaultRadioButton - addr); // 4, int - Assert.Equal(92, (byte*)&sut.pszVerificationText - addr); // 8, PCWSTR - Assert.Equal(100, (byte*)&sut.pszExpandedInformation - addr); // 8, PCWSTR - Assert.Equal(108, (byte*)&sut.pszExpandedControlText - addr); // 8, PCWSTR - Assert.Equal(116, (byte*)&sut.pszCollapsedControlText - addr); // 8, PCWSTR - Assert.Equal(124, (byte*)&sut.footerIcon - addr); // 8, union { HICON; PCWSTR; } - Assert.Equal(132, (byte*)&sut.pszFooter - addr); // 8, PCWSTR - Assert.Equal(140, (byte*)&sut.pfCallback - addr); // 8, PFTASKDIALOGCALLBACK - Assert.Equal(148, (byte*)&sut.lpCallbackData - addr); // 8, LONG_PTR - Assert.Equal(156, (byte*)&sut.cxWidth - addr); // 4, UINT - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/TASKDIALOG_BUTTONTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/TASKDIALOG_BUTTONTests.cs deleted file mode 100644 index 92178253ef6..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/ComCtl32/TASKDIALOG_BUTTONTests.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using static Interop.ComCtl32; - -namespace System.Windows.Forms.Primitives.Tests.Interop.ComCtl32; - -public class TASKDIALOG_BUTTONTests -{ - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void TASKDIALOG_BUTTON_x32_Size() - { - if (Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(8, sizeof(TASKDIALOG_BUTTON)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void TASKDIALOG_BUTTON_x32_ensure_layout() - { - if (Environment.Is64BitProcess) - { - return; - } - - TASKDIALOG_BUTTON sut = new TASKDIALOG_BUTTON(); - byte* addr = (byte*)&sut; - - Assert.Equal(0, (byte*)&sut.nButtonID - addr); // 4, int - Assert.Equal(4, (byte*)&sut.pszButtonText - addr); // 4, PCWSTR - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void TASKDIALOG_BUTTON_x64_Size() - { - if (!Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(12, sizeof(TASKDIALOG_BUTTON)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void TASKDIALOG_BUTTON_x64_ensure_layout() - { - if (!Environment.Is64BitProcess) - { - return; - } - - TASKDIALOG_BUTTON sut = new TASKDIALOG_BUTTON(); - byte* addr = (byte*)&sut; - - Assert.Equal(0, (byte*)&sut.nButtonID - addr); // 4, int - Assert.Equal(4, (byte*)&sut.pszButtonText - addr); // 8, PCWSTR - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Comdlg32/PRINTDLGWTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Comdlg32/PRINTDLGWTests.cs deleted file mode 100644 index 3f18186e61a..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Comdlg32/PRINTDLGWTests.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using static Interop.Comdlg32; - -namespace System.Windows.Forms.Primitives.Tests.Interop.Comdlg32; - -public class PRINTDLGWTests -{ - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void PRINTDLGW_32_Size() - { - if (Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(66, sizeof(PRINTDLGW_32)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void PRINTDLGW_32_ensure_layout() - { - if (Environment.Is64BitProcess) - { - return; - } - - PRINTDLGW_32 sut = new PRINTDLGW_32(); - byte* addr = (byte*)&sut; - - Assert.Equal(0, (byte*)&sut._lStructSize - addr); // 4, DWORD - Assert.Equal(4, (byte*)&sut._hwndOwner - addr); // 4, HWND - Assert.Equal(8, (byte*)&sut._hDevMode - addr); // 4, HGLOBAL - Assert.Equal(12, (byte*)&sut._hDevNames - addr); // 4, HGLOBAL - Assert.Equal(16, (byte*)&sut._hDC - addr); // 4, HDC - Assert.Equal(20, (byte*)&sut._flags - addr); // 4, DWORD - Assert.Equal(24, (byte*)&sut._nFromPage - addr); // 2, WORD - Assert.Equal(26, (byte*)&sut._nToPage - addr); // 2, WORD - Assert.Equal(28, (byte*)&sut._nMinPage - addr); // 2, WORD - Assert.Equal(30, (byte*)&sut._nMaxPage - addr); // 2, WORD - Assert.Equal(32, (byte*)&sut._nCopies - addr); // 2, WORD - Assert.Equal(34, (byte*)&sut._hInstance - addr); // 4, HINSTANCE - Assert.Equal(38, (byte*)&sut._lCustData - addr); // 4, LPARAM - Assert.Equal(42, (byte*)&sut._lpfnPrintHook - addr); // 4, LPPRINTHOOKPROC - Assert.Equal(46, (byte*)&sut._lpfnSetupHook - addr); // 4, LPSETUPHOOKPROC - Assert.Equal(50, (byte*)&sut._lpPrintTemplateName - addr); // 4, LPCWSTR - Assert.Equal(54, (byte*)&sut._lpSetupTemplateName - addr); // 4, LPCWSTR - Assert.Equal(58, (byte*)&sut._hPrintTemplate - addr); // 4, HGLOBAL - Assert.Equal(62, (byte*)&sut._hSetupTemplate - addr); // 4, HGLOBAL - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void PRINTDLGW_64_Size() - { - if (!Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(120, sizeof(PRINTDLGW_64)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void PRINTDLGW_64_ensure_layout() - { - if (!Environment.Is64BitProcess) - { - return; - } - - PRINTDLGW_64 sut = new PRINTDLGW_64(); - byte* addr = (byte*)&sut; - - Assert.Equal(0, (byte*)&sut._lStructSize - addr); // 8, DWORD - Assert.Equal(8, (byte*)&sut._hwndOwner - addr); // 8, HWND - Assert.Equal(16, (byte*)&sut._hDevMode - addr); // 8, HGLOBAL - Assert.Equal(24, (byte*)&sut._hDevNames - addr); // 8, HGLOBAL - Assert.Equal(32, (byte*)&sut._hDC - addr); // 8, HDC - Assert.Equal(40, (byte*)&sut._flags - addr); // 8, DWORD - Assert.Equal(44, (byte*)&sut._nFromPage - addr); // 2, WORD - Assert.Equal(46, (byte*)&sut._nToPage - addr); // 2, WORD - Assert.Equal(48, (byte*)&sut._nMinPage - addr); // 2, WORD - Assert.Equal(50, (byte*)&sut._nMaxPage - addr); // 2, WORD - Assert.Equal(52, (byte*)&sut._nCopies - addr); // 2, WORD - // 2 bytes alignment 54 -> 56 - Assert.Equal(56, (byte*)&sut._hInstance - addr); // 8, HINSTANCE - Assert.Equal(64, (byte*)&sut._lCustData - addr); // 8, LPARAM - Assert.Equal(72, (byte*)&sut._lpfnPrintHook - addr); // 8, LPPRINTHOOKPROC - Assert.Equal(80, (byte*)&sut._lpfnSetupHook - addr); // 8, LPSETUPHOOKPROC - Assert.Equal(88, (byte*)&sut._lpPrintTemplateName - addr); // 8, LPCWSTR - Assert.Equal(96, (byte*)&sut._lpSetupTemplateName - addr); // 8, LPCWSTR - Assert.Equal(104, (byte*)&sut._hPrintTemplate - addr); // 8, HGLOBAL - Assert.Equal(112, (byte*)&sut._hSetupTemplate - addr); // 8, HGLOBAL - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Gdi32/GetStockObjectTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Gdi32/GetStockObjectTests.cs deleted file mode 100644 index 700ddea1b86..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Gdi32/GetStockObjectTests.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Gdi32Tests; - -public class GetStockObjectTests -{ - [Theory] - [InlineData((int)GET_STOCK_OBJECT_FLAGS.BLACK_BRUSH, 0x00000000, (uint)BRUSH_STYLE.BS_SOLID)] - [InlineData((int)GET_STOCK_OBJECT_FLAGS.NULL_BRUSH, 0x00000000, (uint)BRUSH_STYLE.BS_HOLLOW)] - [InlineData((int)GET_STOCK_OBJECT_FLAGS.WHITE_BRUSH, 0x00FFFFFF, (uint)BRUSH_STYLE.BS_SOLID)] - public void GetStockBrushes(int id, uint color, uint brushStyle) - { - HGDIOBJ hgdiobj = PInvoke.GetStockObject((GET_STOCK_OBJECT_FLAGS)id); - Assert.False(hgdiobj.IsNull); - - PInvoke.GetObject(hgdiobj, out LOGBRUSH logBrush); - Assert.Equal(color, logBrush.lbColor); - Assert.Equal((BRUSH_STYLE)brushStyle, logBrush.lbStyle); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/GdiPlus/ARGBTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/GdiPlus/ARGBTests.cs deleted file mode 100644 index c998e1caed7..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/GdiPlus/ARGBTests.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; - -namespace System.Windows.Forms.Tests.Interop.GdiPlus; - -public class ARGBTests -{ - [Theory] - [InlineData(0x0000_0000, 0x00, 0x00, 0x00, 0x00)] - [InlineData(0xFFFF_FFFF, 0xFF, 0xFF, 0xFF, 0xFF)] - [InlineData(0xFF00_0000, 0x00, 0x00, 0x00, 0xFF)] - [InlineData(0x00AA_0000, 0xAA, 0x00, 0x00, 0x00)] - [InlineData(0x0000_BB00, 0x00, 0xBB, 0x00, 0x00)] - [InlineData(0x0000_00CC, 0x00, 0x00, 0xCC, 0x00)] - public void Construction_Raw(uint value, byte r, byte g, byte b, byte a) - { - ARGB fromValue = new ARGB((int)value); - Assert.Equal(a, fromValue.A); - Assert.Equal(r, fromValue.R); - Assert.Equal(g, fromValue.G); - Assert.Equal(b, fromValue.B); - ARGB fromBytes = new ARGB(a, r, g, b); - Assert.Equal((int)value, fromBytes.Value); - } - - [Theory] - [MemberData(nameof(Colors))] - public void ToFromColor(Color color) - { - ARGB argb = color; - Assert.Equal(color.ToArgb(), argb.Value); - Color backAgain = argb; - Assert.Equal(color.ToArgb(), backAgain.ToArgb()); - } - - public static TheoryData Colors => - new() - { - Color.CornflowerBlue, - Color.Transparent, - Color.BurlyWood - }; -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Kernel32/FILETIMETests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Kernel32/FILETIMETests.cs deleted file mode 100644 index daba6eeae7a..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Kernel32/FILETIMETests.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Tests.Interop.Kernel32; - -// NB: doesn't require thread affinity -public class FILETIMETests -{ - [Fact] - public unsafe void FILETIME_Sizeof_Invoke_ReturnsExpected() - { - Assert.Equal(8, Marshal.SizeOf()); - Assert.Equal(8, sizeof(PInvoke.FILETIME)); - } - - [Fact] - public void FILETIME_Ctor_Default() - { - var ft = new PInvoke.FILETIME(); - Assert.Equal(0u, ft.dwLowDateTime); - Assert.Equal(0u, ft.dwHighDateTime); - } - - [Fact] - public void FILETIME_Ctor_DateTime() - { - var dt = new DateTime(2020, 05, 13, 13, 3, 12, DateTimeKind.Utc).ToLocalTime(); - var ft = new PInvoke.FILETIME(dt); - Assert.Equal(3680495616u, ft.dwLowDateTime); - Assert.Equal(30812454u, ft.dwHighDateTime); - } - - [Fact] - public void FILETIME_ToDateTime_Invoke_ReturnsExpected() - { - var ft = new PInvoke.FILETIME() - { - dwLowDateTime = 3680495616u, - dwHighDateTime = 30812454u - }; - Assert.Equal(new DateTime(2020, 05, 13, 13, 3, 12, DateTimeKind.Utc).ToLocalTime(), ft.ToDateTime()); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Kernel32/SYSTEMTIMETests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Kernel32/SYSTEMTIMETests.cs deleted file mode 100644 index 94f3377005d..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Kernel32/SYSTEMTIMETests.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Tests.Interop.Kernel32; - -public class SYSTEMTIMETests -{ - [Fact] - public unsafe void SYSTEMTIME_Sizeof_ReturnsExpected() - { - Assert.Equal(16, Marshal.SizeOf()); - Assert.Equal(16, sizeof(SYSTEMTIME)); - } - - [Fact] - public void SYSTEMTIME_Ctor_Default() - { - var st = new SYSTEMTIME(); - - Assert.Equal(0, st.wYear); - Assert.Equal(0, st.wMonth); - Assert.Equal(0, st.wDayOfWeek); - Assert.Equal(0, st.wDay); - Assert.Equal(0, st.wHour); - Assert.Equal(0, st.wMinute); - Assert.Equal(0, st.wSecond); - Assert.Equal(0, st.wMilliseconds); - } - - [Fact] - public void SYSTEMTIME_CastToDateTime_ReturnsExpected() - { - var st = new SYSTEMTIME() - { - wYear = 2021, - wMonth = 5, - wDay = 3, - wHour = 6, - wMinute = 15, - wSecond = 30, - wMilliseconds = 50 - }; - - DateTime dt = (DateTime)st; // cast to DateTime implicitly - - Assert.Equal(st.wYear, dt.Year); - Assert.Equal(st.wMonth, dt.Month); - Assert.Equal(DayOfWeek.Monday, dt.DayOfWeek); - Assert.Equal(st.wDay, dt.Day); - Assert.Equal(st.wHour, dt.Hour); - Assert.Equal(st.wMinute, dt.Minute); - Assert.Equal(st.wSecond, dt.Second); - Assert.Equal(st.wMilliseconds, dt.Millisecond); - } - - [Fact] - public void SYSTEMTIME_CastToDateTime_ThrowsException_IfArgumentsAreIncorrect() - { - var st = new SYSTEMTIME() - { - wYear = 9999, - wMonth = 99, - wDay = 99, - wHour = 99, - wMinute = 99, - wSecond = 99, - wMilliseconds = 9999 - }; - DateTime dt; - - Assert.Throws(() => dt = (DateTime)st); // cast to DateTime implicitly with incorrect arguments - } - - [Fact] - public void SYSTEMTIME_CastToDateTime_ReturnsMinValue_IfValueIsDefault() - { - var st = new SYSTEMTIME(); - DateTime dt; - - using (new NoAssertContext()) - { - dt = (DateTime)st; // cast to DateTime implicitly - } - - Assert.Equal(DateTime.MinValue, dt); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Mocks/MockCursor.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Mocks/MockCursor.cs deleted file mode 100644 index dfb4a71d68e..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Mocks/MockCursor.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Drawing; -using System.Runtime.InteropServices; - -namespace System.Windows.Forms.Primitives.Tests.Interop.Mocks; - -public class MockCursor : IDisposable -{ - private HCURSOR _handle; - private readonly bool _ownHandle = true; - private readonly PCWSTR _resourceId; - - internal MockCursor(PCWSTR nResourceId) - { - // We don't delete stock cursors. - _ownHandle = false; - _resourceId = nResourceId; - _handle = PInvoke.LoadCursor(HINSTANCE.Null, nResourceId); - if (_handle.IsNull) - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - } - - public void Dispose() - { - if (!_handle.IsNull && _ownHandle) - { - PInvoke.DestroyCursor(_handle); - _handle = HCURSOR.Null; - } - } - - internal HCURSOR Handle => _handle.IsNull ? throw new ObjectDisposedException(nameof(MockCursor)) : _handle; - - public Size Size => SystemInformation.CursorSize; -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Ole32/CADWORDTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Ole32/CADWORDTests.cs deleted file mode 100644 index 6aa04748197..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Ole32/CADWORDTests.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using Windows.Win32.System.Ole; - -namespace System.Windows.Forms.Primitives.Ole32Tests; - -public class CADWORDTests -{ - [Fact] - public void CADWORD_ConvertAndFree_SingleItem() - { - CADWORD ca = CreateIntVector(2020); - - uint[] values = ca.ConvertAndFree(); - Assert.Equal(1, values.Length); - Assert.Equal(2020u, values[0]); - } - - [Fact] - public void CADWORD_ConvertAndFree_EmptyStruct() - { - CADWORD ca = default; - - uint[] values = ca.ConvertAndFree(); - Assert.Empty(values); - } - - private static CADWORD CreateIntVector(params uint[] values) - => CreateIntVector(allocations: null, values); - - private static unsafe CADWORD CreateIntVector(IList? allocations, params uint[] values) - { - CADWORD ca = new() - { - cElems = (uint)values.Length, - pElems = (uint*)Marshal.AllocCoTaskMem(sizeof(uint) * values.Length) - }; - - allocations?.Add((IntPtr)ca.pElems); - - Span elements = new(ca.pElems, values.Length); - for (int i = 0; i < values.Length; i++) - { - elements[i] = values[i]; - } - - return ca; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Ole32/CALPOLESTRTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Ole32/CALPOLESTRTests.cs deleted file mode 100644 index 5d5abf2a5ec..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Ole32/CALPOLESTRTests.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using Windows.Win32.System.Ole; - -namespace System.Windows.Forms.Primitives.Ole32Tests; - -public class CALPOLESTRTests -{ - [Fact] - public void CALPOLESTR_ConvertAndFree_SingleItem() - { - CALPOLESTR ca = CreateStringVector("Swizzle"); - - string?[] values = ca.ConvertAndFree(); - Assert.Equal(1, values.Length); - Assert.Equal("Swizzle", values[0]); - } - - [Fact] - public void CALPOLESTR_ConvertAndFree_EmptyStruct() - { - CALPOLESTR ca = default; - - string?[] values = ca.ConvertAndFree(); - Assert.Empty(values); - } - - private static CALPOLESTR CreateStringVector(params string[] values) - => CreateStringVector(allocations: null, values); - - private static unsafe CALPOLESTR CreateStringVector(IList? allocations, params string[] values) - { - CALPOLESTR ca = new() - { - cElems = (uint)values.Length, - pElems = (PWSTR*)Marshal.AllocCoTaskMem(IntPtr.Size * values.Length) - }; - - allocations?.Add((IntPtr)ca.pElems); - - Span elements = new(ca.pElems, values.Length); - for (int i = 0; i < values.Length; i++) - { - IntPtr nativeCopy = Marshal.StringToCoTaskMemUni(values[i]); - allocations?.Add(nativeCopy); - elements[i] = nativeCopy; - } - - return ca; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Ole32/IPictureTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Ole32/IPictureTests.cs deleted file mode 100644 index 92ee2e4ce05..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Ole32/IPictureTests.cs +++ /dev/null @@ -1,88 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Windows.Forms.Primitives.Tests.Interop.Mocks; -using Windows.Win32.System.Com; -using Windows.Win32.System.Ole; -using Windows.Win32.System.Variant; - -namespace System.Windows.Forms.Primitives.Tests.Interop.Ole32; - -[Collection("Sequential")] -public unsafe class IPictureTests -{ - [StaFact] - public void GetIPictureFromCursor() - { - using MockCursor arrow = new MockCursor(PInvoke.IDC_ARROW); - - using var picture = IPicture.CreateFromIcon(Icon.FromHandle(arrow.Handle), copy: true); - Assert.False(picture.IsNull); - Assert.Equal(PICTYPE.PICTYPE_ICON, picture.Value->Type); - - int height = picture.Value->Height; - Assert.Equal(arrow.Size.Height, GdiHelper.HimetricToPixelY(height)); - int width = picture.Value->Width; - Assert.Equal(arrow.Size.Width, GdiHelper.HimetricToPixelX(width)); - } - - [StaFact] - public void GetIPictureFromImage() - { - using MockCursor arrow = new MockCursor(PInvoke.IDC_ARROW); - using Icon icon = Icon.FromHandle(arrow.Handle); - using Bitmap bitmap = icon.ToBitmap(); - using var picture = IPicture.CreateFromImage(bitmap); - Assert.False(picture.IsNull); - Assert.Equal(PICTYPE.PICTYPE_BITMAP, picture.Value->Type); - - int height = picture.Value->Height; - Assert.Equal(bitmap.Size.Height, GdiHelper.HimetricToPixelY(height)); - int width = picture.Value->Width; - Assert.Equal(bitmap.Size.Width, GdiHelper.HimetricToPixelX(width)); - } - - [StaFact] - public void GetIPictureDispFromImage() - { - using Icon icon = SystemIcons.Question; - using Bitmap bitmap = icon.ToBitmap(); - using var picture = IPictureDisp.CreateFromImage(bitmap); - Assert.False(picture.IsNull); - using VARIANT variant = new(); - - IDispatch* dispatch = (IDispatch*)picture.Value; - dispatch->TryGetProperty(PInvoke.DISPID_PICT_TYPE, &variant).ThrowOnFailure(); - Assert.Equal(PICTYPE.PICTYPE_BITMAP, (PICTYPE)variant.data.iVal); - - dispatch->TryGetProperty(PInvoke.DISPID_PICT_HEIGHT, &variant).ThrowOnFailure(); - Assert.Equal(bitmap.Size.Height, GdiHelper.HimetricToPixelY((int)variant.data.uintVal)); - - dispatch->TryGetProperty(PInvoke.DISPID_PICT_WIDTH, &variant).ThrowOnFailure(); - Assert.Equal(bitmap.Size.Width, GdiHelper.HimetricToPixelX((int)variant.data.uintVal)); - } - - [StaFact] - public void GetPictureFromIPicture() - { - using Icon icon = SystemIcons.Exclamation; - using Bitmap bitmap = icon.ToBitmap(); - using var picture = IPicture.CreateFromImage(bitmap); - Assert.False(picture.IsNull); - using Image? image = picture.Value->ToImage(); - Assert.NotNull(image); - Assert.Equal(bitmap.Size, image.Size); - } - - [StaFact] - public void GetPictureFromIPictureDisp() - { - using Bitmap bitmap = new Bitmap(100, 200); - using var picture = IPictureDisp.CreateFromImage(bitmap); - Assert.False(picture.IsNull); - using Image? image = picture.Value->ToImage(); - Assert.NotNull(image); - Assert.Equal(bitmap.Size, image.Size); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/DECIMALTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/DECIMALTests.cs deleted file mode 100644 index 0262a1f73e4..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/DECIMALTests.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using static Interop; - -namespace System.Windows.Forms.Tests.Interop.Oleaut32; - -// NB: doesn't require thread affinity -public class DECIMALTests -{ - [Fact] - public unsafe void DECIMAL_Sizeof_Invoke_ReturnsExpected() - { - Assert.Equal(16, Marshal.SizeOf()); - Assert.Equal(16, sizeof(DECIMAL)); - } - - [Fact] - public void DECIMAL_ToDecimal_InvokeEmpty_ReturnsExpected() - { - var dec = new DECIMAL(); - Assert.Equal(0m, dec.ToDecimal()); - } - - [Theory] - [InlineData((double)int.MinValue)] - [InlineData(-1.2)] - [InlineData(0)] - [InlineData(1.2)] - [InlineData((double)int.MaxValue)] - public void DECIMAL_ToDecimal_InvokeCustom_ReturnsExpected(double value) - { - HRESULT hr = VarDecFromR8(value, out DECIMAL dec); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal((decimal)value, dec.ToDecimal()); - } - - [DllImport(Libraries.Oleaut32, ExactSpelling = true)] - private static extern HRESULT VarDecFromR8(double dblIn, out DECIMAL pdecOut); -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/ITypeInfoTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/ITypeInfoTests.cs deleted file mode 100644 index 28caada8a3f..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/ITypeInfoTests.cs +++ /dev/null @@ -1,381 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Runtime.InteropServices; -using Windows.Win32.System.Com; -using Windows.Win32.System.Ole; -using Windows.Win32.System.Variant; - -namespace System.Windows.Forms.Primitives.Tests.Interop.Oleaut32; - -[Collection("Sequential")] -public class ITypeInfoTests -{ - [StaFact] - public unsafe void ITypeInfo_AddressOfMember_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - try - { - void* pvObj; - typeInfo.Value->AddressOfMember(6, INVOKEKIND.INVOKE_FUNC, &pvObj); - } - catch (COMException ex) - { - Assert.Equal((int)HRESULT.TYPE_E_BADMODULEKIND, ex.HResult); - return; - } - - Assert.Fail("Exception was not thrown"); - } - - [StaFact] - public unsafe void ITypeInfo_CreateInstance_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - try - { - void* pvObj; - typeInfo.Value->CreateInstance(null, IID.Get(), &pvObj); - } - catch (COMException ex) - { - Assert.Equal((int)HRESULT.TYPE_E_BADMODULEKIND, ex.HResult); - return; - } - - Assert.Fail("Exception was not thrown"); - } - - [StaFact] - public unsafe void ITypeInfo_GetContainingTypeLib_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - using ComScope typeLib = new(null); - uint index = uint.MaxValue; - typeInfo.Value->GetContainingTypeLib(typeLib, &index); - - Assert.NotEqual(0u, index); - } - - [StaFact] - public unsafe void ITypeInfo_GetDllEntry_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - using BSTR dllName = new("DllName"); - using BSTR name = new("Name"); - ushort wOrdinal = ushort.MaxValue; - - try - { - typeInfo.Value->GetDllEntry(6, INVOKEKIND.INVOKE_FUNC, &dllName, &name, &wOrdinal); - } - catch (COMException ex) - { - Assert.Equal((int)HRESULT.TYPE_E_BADMODULEKIND, ex.HResult); - Assert.True(dllName.Length == 0); - Assert.True(name.Length == 0); - Assert.Equal(0u, wOrdinal); - return; - } - - Assert.Fail("Exception was not thrown"); - } - - [StaFact] - public unsafe void ITypeInfo_GetDocumentation_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - using BSTR name = new("Name"); - using BSTR docString = new("DocString"); - uint dwHelpContext = uint.MaxValue; - using BSTR helpFile = new("HelpFile"); - typeInfo.Value->GetDocumentation(4, &name, &docString, &dwHelpContext, &helpFile); - Assert.Equal("Width", name.ToString()); - Assert.True(docString.Length == 0); - Assert.Equal(0u, dwHelpContext); - Assert.True(helpFile.Length == 0); - } - - [StaFact] - public unsafe void ITypeInfo_GetFuncDesc_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - FUNCDESC* pFuncDesc = null; - try - { - typeInfo.Value->GetFuncDesc(0, &pFuncDesc); - Assert.Equal(6, pFuncDesc->memid); - Assert.True(pFuncDesc->lprgscode is null); - Assert.NotEqual(IntPtr.Zero, (IntPtr)pFuncDesc->lprgelemdescParam); - Assert.Equal(FUNCKIND.FUNC_DISPATCH, pFuncDesc->funckind); - Assert.Equal(INVOKEKIND.INVOKE_FUNC, pFuncDesc->invkind); - Assert.Equal(CALLCONV.CC_STDCALL, pFuncDesc->callconv); - Assert.Equal(10, pFuncDesc->cParams); - Assert.Equal(0, pFuncDesc->cParamsOpt); - Assert.Equal(0, pFuncDesc->oVft); - Assert.Equal(0, pFuncDesc->cScodes); - Assert.Equal(VARENUM.VT_VOID, pFuncDesc->elemdescFunc.tdesc.vt); - Assert.True(pFuncDesc->elemdescFunc.tdesc.Anonymous.lpadesc is null); - Assert.True(pFuncDesc->elemdescFunc.Anonymous.paramdesc.pparamdescex is null); - Assert.True(pFuncDesc->elemdescFunc.Anonymous.paramdesc.pparamdescex is null); - } - finally - { - typeInfo.Value->ReleaseFuncDesc(pFuncDesc); - } - } - - [StaFact] - public unsafe void ITypeInfo_GetIDsOfNames_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - fixed (char* width = "Width") - fixed (char* other = "Other") - { - var rgszNames = new PWSTR[] { width, other }; - var rgDispId = new int[rgszNames.Length]; - fixed (PWSTR* pRgszNames = rgszNames) - fixed (int* pRgDispId = rgDispId) - { - typeInfo.Value->GetIDsOfNames(pRgszNames, (uint)rgszNames.Length, pRgDispId); - Assert.Equal(new PWSTR[] { width, other }, rgszNames); - Assert.Equal(new int[] { (int)PInvoke.DISPID_PICT_WIDTH, PInvoke.DISPID_UNKNOWN }, rgDispId); - } - } - } - - [StaFact] - public unsafe void ITypeInfo_GetImplTypeFlags_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - IMPLTYPEFLAGS implTypeFlags = (IMPLTYPEFLAGS)(-1); - typeInfo.Value->GetImplTypeFlags(0, &implTypeFlags); - Assert.NotEqual(IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT, implTypeFlags); - } - - [StaFact] - public unsafe void ITypeInfo_GetMops_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - using BSTR mops = new("Mops"); - typeInfo.Value->GetMops(4, &mops); - Assert.True(mops.Length == 0); - } - - [StaFact] - public unsafe void ITypeInfo_GetNames_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - BSTR* rgszNames = stackalloc BSTR[2]; - rgszNames[0] = new BSTR("Name1"); - rgszNames[1] = new BSTR("Name2"); - uint cNames = 0; - typeInfo.Value->GetNames(4, rgszNames, 2u, &cNames); - Assert.Equal("Width", rgszNames[0].ToString()); - Assert.Equal("Name2", rgszNames[1].ToString()); - Assert.Equal(1u, cNames); - - rgszNames[0].Dispose(); - rgszNames[1].Dispose(); - } - - [StaFact] - public unsafe void ITypeInfo_GetRefTypeInfo_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - uint refType = uint.MaxValue; - typeInfo.Value->GetRefTypeOfImplType(0, &refType); - Assert.NotEqual(0u, refType); - - using ComScope refTypeInfo = new(null); - typeInfo.Value->GetRefTypeInfo(refType, refTypeInfo); - } - - [StaFact] - public unsafe void ITypeInfo_GetRefTypeOfImplType_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - uint refType = uint.MaxValue; - typeInfo.Value->GetRefTypeOfImplType(0, &refType); - Assert.NotEqual(0u, refType); - } - - [StaFact] - public unsafe void ITypeInfo_GetTypeAttr_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - TYPEATTR* pTypeAttr = null; - try - { - typeInfo.Value->GetTypeAttr(&pTypeAttr); - Assert.Equal(typeof(IPictureDisp).GUID, pTypeAttr->guid); - Assert.Equal(0u, pTypeAttr->lcid); - Assert.Equal(0u, pTypeAttr->dwReserved); - Assert.Equal(PInvoke.DISPID_UNKNOWN, pTypeAttr->memidConstructor); - Assert.Equal(PInvoke.DISPID_UNKNOWN, pTypeAttr->memidDestructor); - Assert.True(pTypeAttr->lpstrSchema.IsNull); - Assert.Equal((uint)IntPtr.Size, pTypeAttr->cbSizeInstance); - Assert.Equal(TYPEKIND.TKIND_DISPATCH, pTypeAttr->typekind); - Assert.Equal(1, pTypeAttr->cFuncs); - Assert.Equal(5, pTypeAttr->cVars); - Assert.Equal(1, pTypeAttr->cImplTypes); - Assert.Equal(7 * IntPtr.Size, pTypeAttr->cbSizeVft); - Assert.Equal((ushort)IntPtr.Size, pTypeAttr->cbAlignment); - Assert.Equal(0x1000, pTypeAttr->wTypeFlags); - Assert.Equal(0, pTypeAttr->wMajorVerNum); - Assert.Equal(0, pTypeAttr->wMinorVerNum); - Assert.Equal(VARENUM.VT_EMPTY, pTypeAttr->tdescAlias.vt); - Assert.Equal((nuint)0, pTypeAttr->idldescType.dwReserved); - Assert.Equal(IDLFLAGS.IDLFLAG_NONE, pTypeAttr->idldescType.wIDLFlags); - } - finally - { - typeInfo.Value->ReleaseTypeAttr(pTypeAttr); - } - } - - [StaFact] - public unsafe void ITypeInfo_GetTypeComp_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - using ComScope typeComp = new(null); - typeInfo.Value->GetTypeComp(typeComp); - } - - [StaFact] - public unsafe void ITypeInfo_GetVarDesc_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - VARDESC* pVarDesc = null; - try - { - typeInfo.Value->GetVarDesc(3, &pVarDesc); - Assert.Equal(4, pVarDesc->memid); - Assert.True(pVarDesc->lpstrSchema.IsNull); - Assert.True(pVarDesc->Anonymous.lpvarValue is null); - Assert.Equal(VARENUM.VT_USERDEFINED, pVarDesc->elemdescVar.tdesc.vt); - Assert.False(pVarDesc->elemdescVar.tdesc.Anonymous.lpadesc is null); - Assert.True(pVarDesc->elemdescVar.Anonymous.paramdesc.pparamdescex is null); - Assert.Equal(PARAMFLAGS.PARAMFLAG_NONE, pVarDesc->elemdescVar.Anonymous.paramdesc.wParamFlags); - Assert.Equal(VARFLAGS.VARFLAG_FREADONLY, pVarDesc->wVarFlags); - Assert.Equal(VARKIND.VAR_DISPATCH, pVarDesc->varkind); - } - finally - { - typeInfo.Value->ReleaseVarDesc(pVarDesc); - } - } - - [StaFact] - public unsafe void ITypeInfo_Invoke_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var iPictureDisp = IPictureDisp.CreateFromImage(image); - Assert.False(iPictureDisp.IsNull); - using ComScope typeInfo = new(null); - ((IDispatch*)iPictureDisp.Value)->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - - DISPPARAMS dispParams = default; - VARIANT varResult = default; - EXCEPINFO excepInfo = default; - uint argErr = 0; - - try - { - typeInfo.Value->Invoke( - iPictureDisp, - (int)PInvoke.DISPID_PICT_WIDTH, - DISPATCH_FLAGS.DISPATCH_PROPERTYGET, - &dispParams, - &varResult, - &excepInfo, - &argErr); - } - catch (COMException ex) - { - Assert.Equal((int)HRESULT.DISP_E_MEMBERNOTFOUND, ex.HResult); - Assert.Equal(default, varResult); - Assert.Equal(0u, argErr); - return; - } - - Assert.Fail("Exception was not thrown"); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/SAFEARRAYTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/SAFEARRAYTests.cs deleted file mode 100644 index 0c5d15d9f80..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/SAFEARRAYTests.cs +++ /dev/null @@ -1,405 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable disable - -using System.Runtime.InteropServices; -using Windows.Win32.System.Com; -using Windows.Win32.System.Ole; -using Windows.Win32.System.Variant; -using static Windows.Win32.System.Com.ADVANCED_FEATURE_FLAGS; -using static Windows.Win32.System.Variant.VARENUM; - -namespace System.Windows.Forms.Tests.Interop.SafeArrayTests; - -public unsafe class SAFEARRAYTests -{ - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public void SAFEARRAY_Sizeof_InvokeX86_ReturnsExpected() - { - if (Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(24, Marshal.SizeOf()); - Assert.Equal(24, sizeof(SAFEARRAY)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public void SAFEARRAY_Sizeof_InvokeX64_ReturnsExpected() - { - if (!Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(32, Marshal.SizeOf()); - Assert.Equal(32, sizeof(SAFEARRAY)); - } - - public static IEnumerable Create_TestData() - { - yield return new object[] { VT_I4, FADF_HAVEVARTYPE, 4 }; - yield return new object[] { VT_I8, FADF_HAVEVARTYPE, 8 }; - yield return new object[] { VT_BSTR, FADF_HAVEVARTYPE | FADF_BSTR, IntPtr.Size }; - yield return new object[] { VT_UNKNOWN, FADF_HAVEIID | FADF_UNKNOWN, IntPtr.Size }; - yield return new object[] { VT_DISPATCH, FADF_HAVEIID | FADF_DISPATCH, IntPtr.Size }; - } - - [StaTheory] - [MemberData(nameof(Create_TestData))] - public void SAFEARRAY_CreateSingleDimension_GetProperties_Success(ushort vt, ushort expectedFeatures, uint expectedCbElements) - { - var saBound = new SAFEARRAYBOUND - { - cElements = 10, - lLbound = 1 - }; - SAFEARRAY* psa = PInvoke.SafeArrayCreate((VARENUM)vt, 1, &saBound); - Assert.True(psa != null); - - try - { - Assert.Equal(1u, psa->cDims); - Assert.Equal((ADVANCED_FEATURE_FLAGS)expectedFeatures, psa->fFeatures); - Assert.Equal(expectedCbElements, psa->cbElements); - Assert.Equal(0u, psa->cLocks); - Assert.True(psa->pvData != null); - Assert.Equal(10u, psa->rgsabound._0.cElements); - Assert.Equal(1, psa->rgsabound._0.lLbound); - - VARENUM arrayVt = VT_EMPTY; - HRESULT hr = PInvoke.SafeArrayGetVartype(psa, &arrayVt); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal((VARENUM)vt, arrayVt); - } - finally - { - HRESULT hr = PInvoke.SafeArrayDestroy(psa); - Assert.Equal(HRESULT.S_OK, hr); - } - } - - [StaFact] - public void SAFEARRAY_CreateSingleDimensionRECORD_GetProperties_Success() - { - var saBound = new SAFEARRAYBOUND - { - cElements = 10, - lLbound = 1 - }; - - using ComScope recordInfo = new(new CustomRecordInfo().GetComInterface()); - - SAFEARRAY* psa = PInvoke.SafeArrayCreateEx(VT_RECORD, 1, &saBound, recordInfo); - Assert.True(psa != null); - - try - { - Assert.Equal(1u, psa->cDims); - Assert.Equal(FADF_RECORD, psa->fFeatures); - Assert.Equal((uint)sizeof(int), psa->cbElements); - Assert.Equal(0u, psa->cLocks); - Assert.True(psa->pvData != null); - Assert.Equal(10u, psa->rgsabound._0.cElements); - Assert.Equal(1, psa->rgsabound._0.lLbound); - - VARENUM arrayVt = VT_EMPTY; - HRESULT hr = PInvoke.SafeArrayGetVartype(psa, &arrayVt); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_RECORD, arrayVt); - } - finally - { - HRESULT hr = PInvoke.SafeArrayDestroy(psa); - Assert.Equal(HRESULT.S_OK, hr); - } - } - - private class CustomRecordInfo : IRecordInfo.Interface - { - public IRecordInfo* GetComInterface() => (IRecordInfo*)Marshal.GetComInterfaceForObject(this); - - public HRESULT RecordInit(void* pvNew) => throw new NotImplementedException(); - - public HRESULT RecordClear(void* pvExisting) => throw new NotImplementedException(); - - public HRESULT RecordCopy(void* pvExisting, void* pvNew) => throw new NotImplementedException(); - - public Func<(Guid, HRESULT)> GetGuidAction { get; set; } - - public HRESULT GetGuid(Guid* pguid) - { - (Guid guid, HRESULT hr) = GetGuidAction(); - *pguid = guid; - return hr; - } - - public HRESULT GetName(BSTR* pbstrName) => throw new NotImplementedException(); - - public HRESULT GetSize(uint* pcbSize) - { - *pcbSize = (uint)sizeof(int); - return HRESULT.S_OK; - } - - public HRESULT GetTypeInfo(ITypeInfo** ppTypeInfo) => throw new NotImplementedException(); - - public HRESULT GetField(void* pvData, PCWSTR szFieldName, VARIANT* pvarField) => throw new NotImplementedException(); - - public HRESULT GetFieldNoCopy(void* pvData, PCWSTR szFieldName, VARIANT* pvarField, void** ppvDataCArray) => throw new NotImplementedException(); - - public HRESULT PutField(uint wFlags, void* pvData, PCWSTR szFieldName, VARIANT* pvarField) => throw new NotImplementedException(); - - public HRESULT PutFieldNoCopy(uint wFlags, void* pvData, PCWSTR szFieldName, VARIANT* pvarField) => throw new NotImplementedException(); - - public HRESULT GetFieldNames(uint* pcNames, BSTR* rgBstrNames) => throw new NotImplementedException(); - - public BOOL IsMatchingType(IRecordInfo* pRecordInfoInfo) => throw new NotImplementedException(); - - public void* RecordCreate() => throw new NotImplementedException(); - - public HRESULT RecordCreateCopy(void* pvSource, void** ppvDest) => throw new NotImplementedException(); - - public HRESULT RecordDestroy(void* pvRecord) => throw new NotImplementedException(); - } - - [StaTheory] - [MemberData(nameof(Create_TestData))] - public void SAFEARRAY_CreateMultipleDimensions_GetProperties_Success(ushort vt, ushort expectedFeatures, uint expectedCbElements) - { - SAFEARRAYBOUND* saBounds = stackalloc SAFEARRAYBOUND[2]; - saBounds[0] = new SAFEARRAYBOUND - { - cElements = 10, - lLbound = 1 - }; - saBounds[1] = new SAFEARRAYBOUND - { - cElements = 20, - lLbound = 0 - }; - SAFEARRAY* psa = PInvoke.SafeArrayCreate((VARENUM)vt, 2, saBounds); - Assert.True(psa != null); - - try - { - Assert.Equal(2u, psa->cDims); - Assert.Equal((ADVANCED_FEATURE_FLAGS)expectedFeatures, psa->fFeatures); - Assert.Equal(expectedCbElements, psa->cbElements); - Assert.Equal(0u, psa->cLocks); - Assert.True(psa->pvData != null); - Assert.Equal(20u, psa->rgsabound._0.cElements); - Assert.Equal(0, psa->rgsabound._0.lLbound); - Assert.Equal(10u, ((SAFEARRAYBOUND*)&psa->rgsabound)[1].cElements); - Assert.Equal(1, ((SAFEARRAYBOUND*)&psa->rgsabound)[1].lLbound); - - VARENUM arrayVt = VT_EMPTY; - HRESULT hr = PInvoke.SafeArrayGetVartype(psa, &arrayVt); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal((VARENUM)vt, arrayVt); - } - finally - { - HRESULT hr = PInvoke.SafeArrayDestroy(psa); - Assert.Equal(HRESULT.S_OK, hr); - } - } - - [StaFact] - public void SAFEARRAY_GetValue_InvokeSingleDimensional_ReturnsExpected() - { - var saBound = new SAFEARRAYBOUND - { - cElements = 10, - lLbound = 0 - }; - SAFEARRAY* psa = PInvoke.SafeArrayCreate(VT_I4, 1, &saBound); - Assert.True(psa != null); - - try - { - Span indices1 = stackalloc int[] { 0 }; - Span indices2 = stackalloc int[] { 1 }; - - fixed (int* pIndices1 = indices1) - fixed (int* pIndices2 = indices2) - { - int value1 = 1; - HRESULT hr = PInvoke.SafeArrayPutElement(psa, pIndices1, &value1); - Assert.Equal(HRESULT.S_OK, hr); - - int value2 = 2; - hr = PInvoke.SafeArrayPutElement(psa, pIndices2, &value2); - Assert.Equal(HRESULT.S_OK, hr); - - int result = -1; - hr = PInvoke.SafeArrayGetElement(psa, pIndices1, &result); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(1, result); - - hr = PInvoke.SafeArrayGetElement(psa, pIndices2, &result); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(2, result); - } - - Assert.Equal(1, psa->GetValue(indices1)); - Assert.Equal(2, psa->GetValue(indices2)); - } - finally - { - PInvoke.SafeArrayDestroy(psa); - } - } - - [StaFact] - public void SAFEARRAY_GetValue_InvokeSingleDimensionalNonZeroLowerBound_ReturnsExpected() - { - var saBound = new SAFEARRAYBOUND - { - cElements = 10, - lLbound = -5 - }; - SAFEARRAY* psa = PInvoke.SafeArrayCreate(VT_I4, 1, &saBound); - Assert.True(psa != null); - - try - { - Span indices1 = stackalloc int[] { -5 }; - Span indices2 = stackalloc int[] { -4 }; - - fixed (int* pIndices1 = indices1) - fixed (int* pIndices2 = indices2) - { - int value1 = 1; - HRESULT hr = PInvoke.SafeArrayPutElement(psa, pIndices1, &value1); - Assert.Equal(HRESULT.S_OK, hr); - - int value2 = 2; - hr = PInvoke.SafeArrayPutElement(psa, pIndices2, &value2); - Assert.Equal(HRESULT.S_OK, hr); - - int result = -1; - hr = PInvoke.SafeArrayGetElement(psa, pIndices1, &result); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(1, result); - - hr = PInvoke.SafeArrayGetElement(psa, pIndices2, &result); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(2, result); - } - - Assert.Equal(1, psa->GetValue(indices1)); - Assert.Equal(2, psa->GetValue(indices2)); - } - finally - { - PInvoke.SafeArrayDestroy(psa); - } - } - - [StaFact] - public void SAFEARRAY_GetValue_InvokeMultiDimensional_ReturnsExpected() - { - SAFEARRAYBOUND* saBounds = stackalloc SAFEARRAYBOUND[2]; - saBounds[0] = new SAFEARRAYBOUND - { - cElements = 10, - lLbound = 0 - }; - saBounds[1] = new SAFEARRAYBOUND - { - cElements = 20, - lLbound = 0 - }; - SAFEARRAY* psa = PInvoke.SafeArrayCreate(VT_I4, 2, saBounds); - Assert.True(psa != null); - - try - { - Span indices1 = stackalloc int[] { 0, 0 }; - Span indices2 = stackalloc int[] { 1, 2 }; - - fixed (int* pIndices1 = indices1) - fixed (int* pIndices2 = indices2) - { - int value1 = 1; - HRESULT hr = PInvoke.SafeArrayPutElement(psa, pIndices1, &value1); - Assert.Equal(HRESULT.S_OK, hr); - - int value2 = 2; - hr = PInvoke.SafeArrayPutElement(psa, pIndices2, &value2); - Assert.Equal(HRESULT.S_OK, hr); - - int result = -1; - hr = PInvoke.SafeArrayGetElement(psa, pIndices1, &result); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(1, result); - - hr = PInvoke.SafeArrayGetElement(psa, pIndices2, &result); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(2, result); - } - - Assert.Equal(1, psa->GetValue(indices1)); - Assert.Equal(2, psa->GetValue(indices2)); - } - finally - { - PInvoke.SafeArrayDestroy(psa); - } - } - - [StaFact] - public void SAFEARRAY_GetValue_InvokeMultiDimensionalNonZeroLowerBound_ReturnsExpected() - { - SAFEARRAYBOUND* saBounds = stackalloc SAFEARRAYBOUND[2]; - saBounds[0] = new SAFEARRAYBOUND - { - cElements = 10, - lLbound = -5 - }; - saBounds[1] = new SAFEARRAYBOUND - { - cElements = 20, - lLbound = -4 - }; - SAFEARRAY* psa = PInvoke.SafeArrayCreate(VT_I4, 2, saBounds); - Assert.True(psa != null); - - try - { - Span indices1 = stackalloc int[] { -5, -4 }; - Span indices2 = stackalloc int[] { -4, -3 }; - - fixed (int* pIndices1 = indices1) - fixed (int* pIndices2 = indices2) - { - int value1 = 1; - HRESULT hr = PInvoke.SafeArrayPutElement(psa, pIndices1, &value1); - Assert.Equal(HRESULT.S_OK, hr); - - int value2 = 2; - hr = PInvoke.SafeArrayPutElement(psa, pIndices2, &value2); - Assert.Equal(HRESULT.S_OK, hr); - - int result = -1; - hr = PInvoke.SafeArrayGetElement(psa, pIndices1, &result); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(1, result); - - hr = PInvoke.SafeArrayGetElement(psa, pIndices2, &result); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(2, result); - } - - Assert.Equal(1, psa->GetValue(indices1)); - Assert.Equal(2, psa->GetValue(indices2)); - } - finally - { - PInvoke.SafeArrayDestroy(psa); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/VARIANTTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/VARIANTTests.cs deleted file mode 100644 index bd19d46ec3d..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Oleaut32/VARIANTTests.cs +++ /dev/null @@ -1,5845 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable disable - -using System.Runtime.InteropServices; -using Windows.Win32.System.Com; -using Windows.Win32.System.Ole; -using Windows.Win32.System.Variant; -using static Windows.Win32.System.Com.ADVANCED_FEATURE_FLAGS; -using static Windows.Win32.System.Variant.VARENUM; -using static Interop; - -namespace System.Windows.Forms.Tests.Interop.Oleaut32; - -public unsafe class VARIANTTests -{ - private static VARIANT Create(VARENUM type) - => new () { vt = type }; - - private static VARIANT Create(VARENUM type, void* value) - => new() - { - vt = type, - data = new() { byref = value } - }; - - private static VARIANT Create(bool value) - => new() - { - vt = VT_BOOL, - data = new() { boolVal = value ? VARIANT_BOOL.VARIANT_TRUE : VARIANT_BOOL.VARIANT_FALSE } - }; - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public void VARIANT_Sizeof_InvokeX86_ReturnsExpected() - { - if (Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(16, Marshal.SizeOf()); - Assert.Equal(16, sizeof(VARIANT)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public void VARIANT_Sizeof_InvokeX64_ReturnsExpected() - { - if (!Environment.Is64BitProcess) - { - return; - } - - Assert.Equal(24, Marshal.SizeOf()); - Assert.Equal(24, sizeof(VARIANT)); - } - - [StaTheory] - [InlineData((ushort)VT_EMPTY, false)] - [InlineData((ushort)VT_BOOL, false)] - [InlineData((ushort)(VT_BYREF), true)] - [InlineData((ushort)(VT_BOOL | VT_BYREF), true)] - [InlineData((ushort)(VT_BOOL | VT_BYREF | VT_ARRAY), true)] - [InlineData((ushort)(VT_BOOL | VT_BYREF | VT_VECTOR), true)] - [InlineData((ushort)(VT_BOOL | VT_ARRAY), false)] - [InlineData((ushort)(VT_BOOL | VT_VECTOR), false)] - public void VARIANT_Byref_Get_ReturnsExpected(ushort vt, bool expected) - { - using VARIANT variant = Create((VARENUM)vt); - Assert.Equal(expected, variant.Byref); - } - - [StaTheory] - [InlineData((ushort)VT_EMPTY, (ushort)VT_EMPTY)] - [InlineData((ushort)VT_BOOL, (ushort)VT_BOOL)] - [InlineData((ushort)(VT_BYREF), (ushort)VT_EMPTY)] - [InlineData((ushort)(VT_BOOL | VT_BYREF), (ushort)VT_BOOL)] - public void VARIANT_Type_Get_ReturnsExpected(ushort vt, ushort expected) - { - using VARIANT variant = Create((VARENUM)vt); - Assert.Equal((VARENUM)expected, variant.Type); - } - - [StaTheory] - [InlineData((ushort)VT_EMPTY)] - [InlineData((ushort)(VT_EMPTY | VT_BYREF))] - [InlineData((ushort)VT_UNKNOWN)] - [InlineData((ushort)(VT_UNKNOWN | VT_BYREF))] - [InlineData((ushort)VT_DISPATCH)] - [InlineData((ushort)(VT_DISPATCH | VT_BYREF))] - [InlineData((ushort)VT_BSTR)] - [InlineData((ushort)(VT_BSTR | VT_BYREF))] - [InlineData((ushort)VT_BOOL)] - [InlineData((ushort)(VT_BOOL | VT_BYREF))] - public void VARIANT_Clear_InvokeDefault_Success(ushort vt) - { - using VARIANT variant = Create((VARENUM)vt); - variant.Clear(); - Assert.Equal(VT_EMPTY, variant.vt); - Assert.True(variant.Anonymous.Anonymous.Anonymous.punkVal is null); - } - - [StaFact] - public void VARIANT_Clear_InvokeCustom_Success() - { - using VARIANT variant = Create(true); - variant.Clear(); - Assert.Equal(VT_EMPTY, variant.vt); - Assert.True(variant.Anonymous.Anonymous.Anonymous.punkVal is null); - } - - [StaFact] - public void VARIANT_Clear_InvokeBSTR_Success() - { - using VARIANT variant = new() - { - vt = VT_BSTR, - data = new() { bstrVal = new BSTR("abc") } - }; - - variant.Clear(); - Assert.Equal(VT_EMPTY, variant.vt); - Assert.True(variant.Anonymous.Anonymous.Anonymous.pbstrVal is null); - } - - [StaTheory] - [InlineData((ushort)VT_EMPTY)] - [InlineData((ushort)(VT_EMPTY | VT_BYREF))] - [InlineData((ushort)VT_UNKNOWN)] - [InlineData((ushort)(VT_UNKNOWN | VT_BYREF))] - [InlineData((ushort)VT_DISPATCH)] - [InlineData((ushort)(VT_DISPATCH | VT_BYREF))] - [InlineData((ushort)VT_BSTR)] - [InlineData((ushort)(VT_BSTR | VT_BYREF))] - [InlineData((ushort)VT_BOOL)] - [InlineData((ushort)(VT_BOOL | VT_BYREF))] - public void VARIANT_Dispose_InvokeDefault_Success(ushort vt) - { - using VARIANT variant = Create((VARENUM)vt); - variant.Dispose(); - Assert.Equal(VT_EMPTY, variant.vt); - Assert.True(variant.Anonymous.Anonymous.Anonymous.punkVal is null); - } - - [StaFact] - public void VARIANT_Dispose_InvokeCustom_Success() - { - using VARIANT variant = Create(true); - variant.Dispose(); - Assert.Equal(VT_EMPTY, variant.vt); - Assert.True(variant.Anonymous.Anonymous.Anonymous.punkVal is null); - } - - [StaFact] - public void VARIANT_Dispose_InvokeBSTR_Success() - { - using VARIANT variant = new() - { - vt = VT_BSTR, - data = new() { bstrVal = new BSTR("abc") } - }; - variant.Dispose(); - Assert.Equal(VT_EMPTY, variant.vt); - Assert.True(variant.Anonymous.Anonymous.Anonymous.pbstrVal is null); - } - - public static IEnumerable ToObject_TestData() - { - if (IntPtr.Size == 8) - { - yield return new object[] { VT_I1, unchecked((nint)long.MinValue), (sbyte)0 }; - } - - yield return new object[] { VT_I1, (nint)int.MinValue, (sbyte)0 }; - yield return new object[] { VT_I1, (nint)short.MinValue, (sbyte)0 }; - yield return new object[] { VT_I1, (nint)sbyte.MinValue, sbyte.MinValue }; - yield return new object[] { VT_I1, (nint)(-10), (sbyte)(-10) }; - yield return new object[] { VT_I1, (nint)0, (sbyte)0 }; - yield return new object[] { VT_I1, (nint)10, (sbyte)10 }; - yield return new object[] { VT_I1, (nint)sbyte.MaxValue, sbyte.MaxValue }; - yield return new object[] { VT_I1, (nint)short.MaxValue, (sbyte)(-1) }; - yield return new object[] { VT_I1, (nint)int.MaxValue, (sbyte)(-1) }; - if (IntPtr.Size == 8) - { - yield return new object[] { VT_I1, unchecked((nint)long.MaxValue), (sbyte)(-1) }; - } - - yield return new object[] { VT_UI1, (nint)(-10), (byte)246 }; - yield return new object[] { VT_UI1, (nint)0, (byte)0 }; - yield return new object[] { VT_UI1, (nint)10, (byte)10 }; - yield return new object[] { VT_UI1, (nint)byte.MaxValue, byte.MaxValue }; - yield return new object[] { VT_UI1, (nint)ushort.MaxValue, byte.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { VT_UI1, unchecked((nint)uint.MaxValue), byte.MaxValue }; - } - - yield return new object[] { VT_UI1, (nint)(-1), byte.MaxValue }; - - if (IntPtr.Size == 8) - { - yield return new object[] { VT_I2, unchecked((nint)long.MinValue), (short)0 }; - } - - yield return new object[] { VT_I2, (nint)int.MinValue, (short)0 }; - yield return new object[] { VT_I2, (nint)short.MinValue, short.MinValue }; - yield return new object[] { VT_I2, (nint)sbyte.MinValue, (short)sbyte.MinValue }; - yield return new object[] { VT_I2, (nint)(-10), (short)(-10) }; - yield return new object[] { VT_I2, (nint)0, (short)0 }; - yield return new object[] { VT_I2, (nint)10, (short)10 }; - yield return new object[] { VT_I2, (nint)sbyte.MaxValue, (short)sbyte.MaxValue }; - yield return new object[] { VT_I2, (nint)short.MaxValue, short.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { VT_I2, unchecked((nint)long.MaxValue), (short)(-1) }; - } - - yield return new object[] { VT_UI2, (nint)(-10), (ushort)65526 }; - yield return new object[] { VT_UI2, (nint)0, (ushort)0 }; - yield return new object[] { VT_UI2, (nint)10, (ushort)10 }; - yield return new object[] { VT_UI2, (nint)byte.MaxValue, (ushort)byte.MaxValue }; - yield return new object[] { VT_UI2, (nint)ushort.MaxValue, ushort.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { VT_UI2, unchecked((nint)uint.MaxValue), ushort.MaxValue }; - } - - yield return new object[] { VT_UI2, (nint)(-1), ushort.MaxValue }; - - if (IntPtr.Size == 8) - { - yield return new object[] { VT_I4, unchecked((nint)long.MinValue), 0 }; - } - - yield return new object[] { VT_I4, (nint)int.MinValue, int.MinValue }; - yield return new object[] { VT_I4, (nint)short.MinValue, (int)short.MinValue }; - yield return new object[] { VT_I4, (nint)sbyte.MinValue, (int)sbyte.MinValue }; - yield return new object[] { VT_I4, (nint)(-10), -10 }; - yield return new object[] { VT_I4, (nint)0, 0 }; - yield return new object[] { VT_I4, (nint)10, 10 }; - yield return new object[] { VT_I4, (nint)sbyte.MaxValue, (int)sbyte.MaxValue }; - yield return new object[] { VT_I4, (nint)short.MaxValue, (int)short.MaxValue }; - yield return new object[] { VT_I4, (nint)int.MaxValue, int.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { VT_I4, unchecked((nint)long.MaxValue), -1 }; - } - - yield return new object[] { VT_UI4, (nint)(-10), (uint)4294967286 }; - yield return new object[] { VT_UI4, (nint)0, (uint)0 }; - yield return new object[] { VT_UI4, (nint)10, (uint)10 }; - yield return new object[] { VT_UI4, (nint)byte.MaxValue, (uint)byte.MaxValue }; - yield return new object[] { VT_UI4, (nint)ushort.MaxValue, (uint)ushort.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { VT_UI4, unchecked((nint)uint.MaxValue), uint.MaxValue }; - } - - yield return new object[] { VT_UI4, (nint)(-1), uint.MaxValue }; - - if (IntPtr.Size == 8) - { - yield return new object[] { VT_INT, unchecked((nint)long.MinValue), 0 }; - } - - yield return new object[] { VT_INT, (nint)int.MinValue, int.MinValue }; - yield return new object[] { VT_INT, (nint)short.MinValue, (int)short.MinValue }; - yield return new object[] { VT_INT, (nint)sbyte.MinValue, (int)sbyte.MinValue }; - yield return new object[] { VT_INT, (nint)(-10), -10 }; - yield return new object[] { VT_INT, (nint)0, 0 }; - yield return new object[] { VT_INT, (nint)10, 10 }; - yield return new object[] { VT_INT, (nint)sbyte.MaxValue, (int)sbyte.MaxValue }; - yield return new object[] { VT_INT, (nint)short.MaxValue, (int)short.MaxValue }; - yield return new object[] { VT_INT, (nint)int.MaxValue, int.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { VT_INT, unchecked((nint)long.MaxValue), -1 }; - } - - yield return new object[] { VT_UINT, (nint)(-10), (uint)4294967286 }; - yield return new object[] { VT_UINT, (nint)0, (uint)0 }; - yield return new object[] { VT_UINT, (nint)10, (uint)10 }; - yield return new object[] { VT_UINT, (nint)byte.MaxValue, (uint)byte.MaxValue }; - yield return new object[] { VT_UINT, (nint)ushort.MaxValue, (uint)ushort.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { VT_UINT, unchecked((nint)uint.MaxValue), uint.MaxValue }; - } - - yield return new object[] { VT_UINT, (nint)(-1), uint.MaxValue }; - - yield return new object[] { VT_BOOL, (nint)(-1), true }; - yield return new object[] { VT_BOOL, (nint)0, false }; - yield return new object[] { VT_BOOL, (nint)1, true }; - - if (IntPtr.Size == 8) - { - yield return new object[] { VT_ERROR, unchecked((nint)long.MinValue), 0 }; - } - - yield return new object[] { VT_ERROR, (nint)int.MinValue, int.MinValue }; - yield return new object[] { VT_ERROR, (nint)short.MinValue, (int)short.MinValue }; - yield return new object[] { VT_ERROR, (nint)sbyte.MinValue, (int)sbyte.MinValue }; - yield return new object[] { VT_ERROR, (nint)(-10), -10 }; - yield return new object[] { VT_ERROR, (nint)0, 0 }; - yield return new object[] { VT_ERROR, (nint)10, 10 }; - yield return new object[] { VT_ERROR, (nint)sbyte.MaxValue, (int)sbyte.MaxValue }; - yield return new object[] { VT_ERROR, (nint)short.MaxValue, (int)short.MaxValue }; - yield return new object[] { VT_ERROR, (nint)int.MaxValue, int.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { VT_ERROR, unchecked((nint)long.MaxValue), -1 }; - } - } - - [StaTheory] - [MemberData(nameof(ToObject_TestData))] - public void VARIANT_ToObject_Invoke_ReturnsExpected(ushort vt, nint data, object expected) - { - using VARIANT variant = Create((VARENUM)vt, (IUnknown*)data); - AssertToObjectEqual(expected, variant); - } - - [StaTheory] - [MemberData(nameof(ToObject_TestData))] - public void VARIANT_ToObject_InvokeBYREF_ReturnsExpected(ushort vt, nint data, object expected) - { - using VARIANT variant = Create((VARENUM)vt | VT_BYREF, (IUnknown*)&data); - AssertToObjectEqual(expected, variant); - } - - public static IEnumerable BYREFNoData_TestData() - { - yield return new object[] { VT_I2 }; - yield return new object[] { VT_I4 }; - yield return new object[] { VT_R4 }; - yield return new object[] { VT_R8 }; - yield return new object[] { VT_CY }; - yield return new object[] { VT_DATE }; - yield return new object[] { VT_BSTR }; - yield return new object[] { VT_DISPATCH }; - yield return new object[] { VT_ERROR }; - yield return new object[] { VT_BOOL }; - yield return new object[] { VT_VARIANT }; - yield return new object[] { VT_UNKNOWN }; - yield return new object[] { VT_DECIMAL }; - yield return new object[] { VT_I1 }; - yield return new object[] { VT_UI1 }; - yield return new object[] { VT_UI2 }; - yield return new object[] { VT_UI4 }; - yield return new object[] { VT_I8 }; - yield return new object[] { VT_UI8 }; - yield return new object[] { VT_INT }; - yield return new object[] { VT_UINT }; - yield return new object[] { VT_VOID }; - yield return new object[] { VT_HRESULT }; - yield return new object[] { VT_PTR }; - yield return new object[] { VT_SAFEARRAY }; - yield return new object[] { VT_CARRAY }; - yield return new object[] { VT_USERDEFINED }; - yield return new object[] { VT_LPSTR }; - yield return new object[] { VT_LPWSTR }; - yield return new object[] { VT_RECORD }; - yield return new object[] { VT_INT_PTR }; - yield return new object[] { VT_UINT_PTR }; - yield return new object[] { VT_FILETIME }; - yield return new object[] { VT_BLOB }; - yield return new object[] { VT_STREAM }; - yield return new object[] { VT_STORAGE }; - yield return new object[] { VT_STREAMED_OBJECT }; - yield return new object[] { VT_STORED_OBJECT }; - yield return new object[] { VT_BLOB_OBJECT }; - yield return new object[] { VT_CF }; - yield return new object[] { VT_CLSID }; - yield return new object[] { VT_VERSIONED_STREAM }; - yield return new object[] { VT_BSTR_BLOB }; - } - - [StaTheory] - [MemberData(nameof(BYREFNoData_TestData))] - public void VARIANT_ToObject_BYREFNoData_Throws(ushort vt) - { - using VARIANT variant = Create((VARENUM)vt | VT_BYREF); - AssertToObjectThrows(variant); - } - - public static IEnumerable ToObject_I8_TestData() - { - if (IntPtr.Size == 8) - { - yield return new object[] { unchecked((nint)long.MinValue), long.MinValue }; - yield return new object[] { (nint)int.MinValue, (long)int.MinValue }; - yield return new object[] { (nint)short.MinValue, (long)short.MinValue }; - yield return new object[] { (nint)sbyte.MinValue, (long)sbyte.MinValue }; - yield return new object[] { (nint)(-10), (long)(-10) }; - } - - yield return new object[] { (nint)0, (long)0 }; - yield return new object[] { (nint)10, (long)10 }; - yield return new object[] { (nint)sbyte.MaxValue, (long)sbyte.MaxValue }; - yield return new object[] { (nint)short.MaxValue, (long)short.MaxValue }; - yield return new object[] { (nint)int.MaxValue, (long)int.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { unchecked((nint)long.MaxValue), long.MaxValue }; - } - } - - [Theory] - [MemberData(nameof(ToObject_I8_TestData))] - public void VARIANT_ToObject_I8_ReturnsExpected(nint data, long expected) - { - using VARIANT variant = Create(VT_I8, (IUnknown*)data); - AssertToObjectEqual(expected, variant); - } - - public static IEnumerable ToObject_I8BYREF_TestData() - { - yield return new object[] { long.MinValue }; - yield return new object[] { int.MinValue }; - yield return new object[] { short.MinValue }; - yield return new object[] { sbyte.MinValue }; - yield return new object[] { -10, }; - yield return new object[] { 0, }; - yield return new object[] { 10, }; - yield return new object[] { sbyte.MaxValue }; - yield return new object[] { short.MaxValue }; - yield return new object[] { int.MaxValue }; - yield return new object[] { long.MaxValue }; - } - - [Theory] - [MemberData(nameof(ToObject_I8BYREF_TestData))] - public void VARIANT_ToObject_I8BYREF_ReturnsExpected(long data) - { - using VARIANT variant = Create(VT_I8 | VT_BYREF, (IUnknown*)&data); - AssertToObjectEqual(data, variant); - } - - public static IEnumerable ToObject_UI8_TestData() - { - if (IntPtr.Size == 8) - { - yield return new object[] { (nint)(-10), (ulong)18446744073709551606 }; - } - - yield return new object[] { (nint)0, (ulong)0 }; - yield return new object[] { (nint)10, (ulong)10 }; - yield return new object[] { (nint)byte.MaxValue, (ulong)byte.MaxValue }; - yield return new object[] { (nint)ushort.MaxValue, (ulong)ushort.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { unchecked((nint)uint.MaxValue), (ulong)uint.MaxValue }; - yield return new object[] { (nint)(-1L), ulong.MaxValue }; - } - } - - [Theory] - [MemberData(nameof(ToObject_UI8_TestData))] - public void VARIANT_ToObject_UI8_ReturnsExpected(nint data, ulong expected) - { - using VARIANT variant = Create(VT_UI8, (IUnknown*)data); - AssertToObjectEqual(expected, variant); - } - - public static IEnumerable ToObject_UI8BYREF_TestData() - { - yield return new object[] { 0 }; - yield return new object[] { 10 }; - yield return new object[] { byte.MaxValue }; - yield return new object[] { ushort.MaxValue }; - yield return new object[] { uint.MaxValue }; - yield return new object[] { ulong.MaxValue }; - } - - [Theory] - [MemberData(nameof(ToObject_UI8BYREF_TestData))] - public void VARIANT_ToObject_UI8BYREF_ReturnsExpected(ulong data) - { - using VARIANT variant = Create(VT_UI8 | VT_BYREF, (IUnknown*)&data); - AssertToObjectEqual(data, variant); - } - - public static IEnumerable ToObject_CY_TestData() - { - yield return new object[] { (nint)0, 0.0m }; - yield return new object[] { (nint)10, 0.001m }; - yield return new object[] { (nint)10000, 1m }; - yield return new object[] { (nint)123456, 12.3456m }; - if (IntPtr.Size == 8) - { - yield return new object[] { (nint)(-10), -0.001m }; - yield return new object[] { (nint)(-10000), -1m }; - yield return new object[] { (nint)(-123456), -12.3456m }; - } - } - - [Theory] - [MemberData(nameof(ToObject_CY_TestData))] - public void VARIANT_ToObject_CY_ReturnsExpected(nint data, decimal expected) - { - using VARIANT variant = Create(VT_CY, (IUnknown*)data); - AssertToObjectEqual(expected, variant); - } - - public static IEnumerable ToObject_CYBYREF_TestData() - { - yield return new object[] { 0, 0.0m }; - yield return new object[] { 10, 0.001m }; - yield return new object[] { 10000, 1m }; - yield return new object[] { 123456, 12.3456m }; - yield return new object[] { -10, -0.001m }; - yield return new object[] { -10000, -1m }; - yield return new object[] { -123456, -12.3456m }; - } - - [Theory] - [MemberData(nameof(ToObject_CYBYREF_TestData))] - public void VARIANT_ToObject_CYBYREF_ReturnsExpected(long data, decimal expected) - { - using VARIANT variant = Create(VT_CY | VT_BYREF, (IUnknown*)&data); - AssertToObjectEqual(expected, variant); - } - - public static IEnumerable ToObject_R4_TestData() - { - yield return new object[] { (nint)0, 0.0f }; - yield return new object[] { (nint)1067030938, 1.2f }; - if (IntPtr.Size == 8) - { - yield return new object[] { unchecked((nint)3214514586), -1.2f }; - yield return new object[] { unchecked((nint)4290772992), float.NaN }; - } - } - - [Theory] - [MemberData(nameof(ToObject_R4_TestData))] - public void VARIANT_ToObject_R4_ReturnsExpected(nint data, float expected) - { - using VARIANT variant = Create(VT_R4, (IUnknown*)data); - AssertToObjectEqual(expected, variant); - } - - public static IEnumerable ToObject_R4BYREF_TestData() - { - yield return new object[] { 0.0f }; - yield return new object[] { 1.2f }; - yield return new object[] { -1.2f }; - yield return new object[] { float.NaN }; - } - - [Theory] - [MemberData(nameof(ToObject_R4BYREF_TestData))] - public void VARIANT_ToObject_R4BYREF_ReturnsExpected(float data) - { - using VARIANT variant = new() - { - vt = VT_R4 | VT_BYREF, - data = new() - { - pfltVal = &data - } - }; - - AssertToObjectEqual(data, variant); - } - - public static IEnumerable ToObject_R8_TestData() - { - yield return new object[] { (nint)0, 0.0 }; - if (IntPtr.Size == 8) - { - yield return new object[] { unchecked((nint)4608083138725491507), 1.2 }; - yield return new object[] { unchecked((nint)(-4615288898129284301)), -1.2 }; - yield return new object[] { unchecked((nint)(-2251799813685248)), double.NaN }; - } - } - - [Theory] - [MemberData(nameof(ToObject_R8_TestData))] - public void VARIANT_ToObject_R8_ReturnsExpected(nint data, double expected) - { - using VARIANT variant = Create(VT_R8, (IUnknown*)data); - AssertToObjectEqual(expected, variant); - } - - public static IEnumerable ToObject_R8BYREF_TestData() - { - yield return new object[] { 0.0 }; - yield return new object[] { 1.2 }; - yield return new object[] { -1.2 }; - yield return new object[] { double.NaN }; - } - - [Theory] - [MemberData(nameof(ToObject_R8BYREF_TestData))] - public void VARIANT_ToObject_R8BYREF_ReturnsExpected(double data) - { - using VARIANT variant = Create(VT_R8 | VT_BYREF, (IUnknown*)&data); - AssertToObjectEqual(data, variant); - } - - public static IEnumerable NULL_TestData() - { - yield return new object[] { IntPtr.Zero }; - yield return new object[] { (nint)1 }; - } - - [StaTheory] - [MemberData(nameof(NULL_TestData))] - public void VARIANT_ToObject_NULL_Success(nint data) - { - using VARIANT variant = Create(VT_BYREF | VT_NULL, (IUnknown*)data); - AssertToObjectEqual(Convert.DBNull, variant); - } - - [StaTheory] - [MemberData(nameof(NULL_TestData))] - public void VARIANT_ToObject_NULLBYREFData_Success(nint data) - { - using VARIANT variant = Create(VT_BYREF | VT_NULL, (IUnknown*)&data); - AssertToObjectEqual(Convert.DBNull, variant); - } - - [StaFact] - public void VARIANT_ToObject_NULLBYREFNoData_Success() - { - using VARIANT variant = Create(VT_BYREF | VT_NULL); - AssertToObjectEqual(Convert.DBNull, variant); - } - - public static IEnumerable EMPTY_TestData() - { - yield return new object[] { IntPtr.Zero }; - yield return new object[] { (nint)1 }; - } - - [StaTheory] - [MemberData(nameof(EMPTY_TestData))] - public void VARIANT_ToObject_EMPTY_Success(nint data) - { - using VARIANT variant = Create(VT_EMPTY, (IUnknown*)data); - AssertToObjectEqual(null, variant); - } - - [StaTheory] - [MemberData(nameof(EMPTY_TestData))] - public void VARIANT_ToObject_EMPTYBYREFData_Success(nint data) - { - using VARIANT variant = Create(VT_BYREF | VT_EMPTY, (IUnknown*)&data); - AssertToObject(variant, value => - { - if (IntPtr.Size == 8) - { - Assert.Equal((ulong)(IntPtr)variant.Anonymous.Anonymous.Anonymous.ppunkVal, value); - } - else - { - Assert.Equal((uint)(IntPtr)variant.Anonymous.Anonymous.Anonymous.ppunkVal, value); - } - }); - } - - [StaFact] - public void VARIANT_ToObject_EMPTYBYREFNoData_Success() - { - using VARIANT variant = Create(VT_BYREF | VT_EMPTY); - AssertToObject(variant, value => - { - if (IntPtr.Size == 8) - { - Assert.Equal((ulong)0, value); - } - else - { - Assert.Equal((uint)0, value); - } - }); - } - - public static IEnumerable HRESULT_TestData() - { - yield return new object[] { (nint)int.MinValue, int.MinValue }; - yield return new object[] { (nint)short.MinValue, (int)short.MinValue }; - yield return new object[] { (nint)sbyte.MinValue, (int)sbyte.MinValue }; - yield return new object[] { (nint)(-10), -10 }; - yield return new object[] { (nint)0, 0 }; - yield return new object[] { (nint)10, 10 }; - yield return new object[] { (nint)sbyte.MaxValue, (int)sbyte.MaxValue }; - yield return new object[] { (nint)short.MaxValue, (int)short.MaxValue }; - yield return new object[] { (nint)int.MaxValue, int.MaxValue }; - if (IntPtr.Size == 8) - { - yield return new object[] { unchecked((nint)long.MinValue), 0 }; - yield return new object[] { unchecked((nint)long.MaxValue), -1 }; - } - } - - [StaTheory] - [MemberData(nameof(HRESULT_TestData))] - public void VARIANT_ToObject_HRESULT_Success(nint data, int expected) - { - using VARIANT variant = Create(VT_HRESULT, (IUnknown*)data); - AssertToObjectEqualExtension(expected, variant); - } - - [StaTheory] - [MemberData(nameof(HRESULT_TestData))] - public void VARIANT_ToObject_HRESULTBYREF_Success(nint data, int expected) - { - using VARIANT variant = Create(VT_HRESULT | VT_BYREF, (IUnknown*)&data); - AssertToObjectEqualExtension(expected, variant); - } - - [StaFact] - public void VARIANT_ToObject_FILETIME_Success() - { - using VARIANT variant = new(); - var dt = new DateTime(2020, 05, 13, 13, 3, 12); - var ft = new PInvoke.FILETIME(dt); - HRESULT hr = InitPropVariantFromFileTime(&ft, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_FILETIME, variant.vt); - - AssertToObjectEqualExtension(new DateTime(2020, 05, 13, 13, 3, 12), variant); - } - - [StaTheory] - [InlineData(-10)] - public void VARIANT_ToObject_InvalidFILETIME_ThrowsArgumentOutOfRangeException(int value) - { - using VARIANT variant = new() - { - Anonymous = new() - { - Anonymous = new() - { - vt = VT_FILETIME, - Anonymous = new() { cyVal = new() { int64 = value } } - } - } - }; - - Assert.Throws("fileTime", () => variant.ToObject()); - } - - [StaFact] - public void VARIANT_ToObject_DateFromFILETIME_Success() - { - using VARIANT variant = new(); - var dt = new DateTime(2020, 05, 13, 13, 3, 12, DateTimeKind.Utc).ToLocalTime(); - var ft = new PInvoke.FILETIME(dt); - HRESULT hr = InitVariantFromFileTime(&ft, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_DATE, variant.vt); - - AssertToObjectEqual(new DateTime(2020, 05, 13, 13, 3, 12, DateTimeKind.Utc).ToUniversalTime(), variant); - } - - [StaFact] - public void VARIANT_ToObject_Date_Success() - { - var dt = new DateTime(2020, 05, 13, 13, 3, 12); - double date = dt.ToOADate(); - using VARIANT variant = new() - { - Anonymous = new() - { - Anonymous = new() - { - vt = VT_DATE, - Anonymous = new() { date = date } - } - } - }; - - AssertToObjectEqual(new DateTime(2020, 05, 13, 13, 3, 12), variant); - } - - [StaFact] - public void VARIANT_ToObject_DateEmpty_Success() - { - using VARIANT variant = Create(VT_DATE); - AssertToObjectEqual(new DateTime(1899, 12, 30), variant); - } - - [StaFact] - public void VARIANT_ToObject_DateBYREF_Success() - { - var dt = new DateTime(2020, 05, 13, 13, 3, 12); - double date = dt.ToOADate(); - using VARIANT variant = new() - { - Anonymous = new() - { - Anonymous = new() - { - vt = VT_DATE | VT_BYREF, - Anonymous = new() { pdate = &date } - } - } - }; - - AssertToObjectEqual(new DateTime(2020, 05, 13, 13, 3, 12), variant); - } - - [StaFact] - public void VARIANT_ToObject_DateBYREFEmpty_Success() - { - double date = 0; - using VARIANT variant = Create(VT_DATE | VT_BYREF); - variant.data.pdate = &date; - - AssertToObjectEqual(new DateTime(1899, 12, 30), variant); - } - - [StaTheory] - [InlineData(null)] - [InlineData("")] - [InlineData("text")] - public void VARIANT_ToObject_BSTR_ReturnsExpected(string text) - { - using VARIANT variant = new() - { - vt = VT_BSTR, - data = new() { bstrVal = new BSTR(text) } - }; - AssertToObjectEqual(text, variant); - } - - [StaFact] - public void VARIANT_ToObject_BSTRNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_BSTR); - AssertToObjectEqual(null, variant); - } - - [StaTheory] - [InlineData("")] - [InlineData("text")] - public void VARIANT_ToObject_BSTRBYREF_ReturnsExpected(string text) - { - // ByRef VARIANTs are not freed - using BSTR bstr = new(text); - using VARIANT variant = new() - { - vt = VT_BSTR | VT_BYREF, - data = new() { pbstrVal = &bstr } - }; - AssertToObjectEqual(text, variant); - } - - [StaTheory] - [InlineData(null)] - [InlineData("")] - [InlineData("text")] - public void VARIANT_ToObject_LPWSTR_ReturnsExpected(string text) - { - using VARIANT variant = Create(VT_LPWSTR, (IUnknown*)(void*)Marshal.StringToCoTaskMemUni(text)); - AssertToObjectEqualExtension(text, variant); - } - - [StaFact] - public void VARIANT_ToObject_LPWSTRNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_LPWSTR); - AssertToObjectEqualExtension(null, variant); - } - - [StaTheory] - [InlineData("")] - [InlineData("text")] - public void VARIANT_ToObject_LPWSTRBYREF_ReturnsExpected(string text) - { - fixed (char* t = text) - { - // Not freed when by ref, can just pin. - using VARIANT variant = Create(VT_LPWSTR | VT_BYREF, &t); - AssertToObjectEqualExtension(text, variant); - } - } - - [StaTheory] - [InlineData(null)] - [InlineData("")] - [InlineData("text")] - public void VARIANT_ToObject_LPSTR_ReturnsExpected(string text) - { - using VARIANT variant = Create(VT_LPSTR, (void*)Marshal.StringToCoTaskMemAnsi(text)); - AssertToObjectEqualExtension(text, variant); - } - - [StaFact] - public void VARIANT_ToObject_LPSTRNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_LPSTR); - AssertToObjectEqualExtension(null, variant); - } - - [StaTheory] - [InlineData("")] - [InlineData("text")] - public void VARIANT_ToObject_LPSTRBYREF_ReturnsExpected(string text) - { - IntPtr ptr = Marshal.StringToCoTaskMemAnsi(text); - try - { - using VARIANT variant = Create(VT_LPSTR | VT_BYREF, &ptr); - AssertToObjectEqualExtension(text, variant); - } - finally - { - Marshal.FreeCoTaskMem(ptr); - } - } - - [StaFact] - public void VARIANT_ToObject_Dispatch_ReturnsExpected() - { - var o = new object(); - IntPtr pUnk = Marshal.GetIUnknownForObject(o); - using VARIANT variant = Create(VT_DISPATCH, (void*)pUnk); - AssertToObjectEqual(o, variant); - } - - [StaFact] - public void VARIANT_ToObject_DispatchNoData_ReturnsNull() - { - using VARIANT variant = Create(VT_DISPATCH); - AssertToObjectEqual(null, variant); - } - - [StaFact] - public void VARIANT_ToObject_DispatchBYREF_ReturnsExpected() - { - var o = new object(); - using ComScope unknown = new((IUnknown*)(void*)Marshal.GetIUnknownForObject(o)); - using VARIANT variant = Create(VT_DISPATCH | VT_BYREF, &unknown); - AssertToObjectEqual(o, variant); - } - - [StaFact] - public void VARIANT_ToObject_DispatchBYREFNullData_ReturnsNull() - { - IUnknown* unknown = null; - using VARIANT variant = Create(VT_DISPATCH | VT_BYREF, &unknown); - AssertToObjectEqual(null, variant); - } - - [StaFact] - public void VARIANT_ToObject_UNKNOWN_ReturnsExpected() - { - var o = new object(); - IntPtr pUnk = Marshal.GetIUnknownForObject(o); - using VARIANT variant = Create(VT_UNKNOWN, (void*)Marshal.GetIUnknownForObject(o)); - AssertToObjectEqual(o, variant); - } - - [StaFact] - public void VARIANT_ToObject_UNKNOWNNoData_ReturnsNull() - { - using VARIANT variant = Create(VT_UNKNOWN); - AssertToObjectEqual(null, variant); - } - - [StaFact] - public void VARIANT_ToObject_UNKNOWNBYREF_ReturnsExpected() - { - var o = new object(); - using ComScope unknown = new((IUnknown*)(void*)Marshal.GetIUnknownForObject(o)); - using VARIANT variant = Create(VT_UNKNOWN | VT_BYREF, &unknown); - AssertToObjectEqual(o, variant); - } - - [StaFact] - public void VARIANT_ToObject_UNKNOWNBYREFNullData_ReturnsNull() - { - IUnknown* unknown = null; - using VARIANT variant = Create(VT_UNKNOWN | VT_BYREF, &unknown); - AssertToObjectEqual(null, variant); - } - - [StaFact] - public void VARIANT_ToObject_I4VARIANTBYREF_ReturnsExpected() - { - using VARIANT target = new() - { - Anonymous = new() - { - Anonymous = new() - { - vt = VT_I4, - Anonymous = new() { llVal = 10 } - } - } - }; - - using VARIANT variant = Create(VT_VARIANT | VT_BYREF, &target); - AssertToObjectEqual(10, variant); - } - - [StaFact] - public void VARIANT_ToObject_BSTRVARIANTBYREF_ReturnsExpected() - { - using VARIANT target = new() - { - vt = VT_BSTR, - data = new() { bstrVal = new BSTR("test") } - }; - using VARIANT variant = Create(VT_VARIANT | VT_BYREF, &target); - AssertToObjectEqual("test", variant); - } - - [StaFact] - public void VARIANT_ToObject_EMPTYVARIANTBYREF_ThrowsInvalidOleVariantTypeException() - { - using VARIANT target = Create(VT_EMPTY); - using VARIANT variant = Create(VT_VARIANT | VT_BYREF, &target); - AssertToObjectEqual(null, variant); - } - - [StaFact] - public void VARIANT_ToObject_BYREFVARIANTBYREF_ThrowsInvalidOleVariantTypeException() - { - int lval = 10; - using VARIANT target = new() - { - Anonymous = new() - { - Anonymous = new() - { - vt = VT_BYREF | VT_I4, - Anonymous = new() { plVal = &lval } - } - } - }; - - using VARIANT variant = Create(VT_VARIANT | VT_BYREF, &target); - AssertToObjectThrows(variant); - } - - [StaFact] - public void VARIANT_ToObject_VARIANT_ThrowsArgumentException() - { - using VARIANT variant = Create(VT_VARIANT); - AssertToObjectThrows(variant); - } - - public static IEnumerable Decimal_I8_TestData() - { - yield return new object[] { long.MinValue, (decimal)long.MinValue }; - yield return new object[] { -123, -123m }; - yield return new object[] { 0, 0m }; - yield return new object[] { 123, 123m }; - yield return new object[] { long.MaxValue, (decimal)long.MaxValue }; - } - - [StaTheory] - [MemberData(nameof(Decimal_I8_TestData))] - public void VARIANT_ToObject_DecimalI8_ReturnsExpected(long i8, decimal expected) - { - VarDecFromI8(i8, out DECIMAL d); - VARIANT_ToObject_Decimal_ReturnsExpected(d, expected); - VARIANT_ToObject_DecimalBYREF_ReturnsExpected(d, expected); - } - - public static IEnumerable Decimal_R8_TestData() - { - yield return new object[] { -10e12, -10e12m }; - yield return new object[] { -123.456, -123.456m }; - yield return new object[] { 0.0, 0m }; - yield return new object[] { 123.456, 123.456m }; - yield return new object[] { 10e12, 10e12m }; - } - - [StaTheory] - [MemberData(nameof(Decimal_R8_TestData))] - public void VARIANT_ToObject_DecimalR8_ReturnsExpected(double r8, decimal expected) - { - VarDecFromR8(r8, out DECIMAL d); - VARIANT_ToObject_Decimal_ReturnsExpected(d, expected); - VARIANT_ToObject_DecimalBYREF_ReturnsExpected(d, expected); - } - - public static IEnumerable Decimal_TestData() - { - yield return new object[] { new DECIMAL(), 0.0m }; - } - - [StaTheory] - [MemberData(nameof(Decimal_TestData))] - public void VARIANT_ToObject_Decimal_ReturnsExpected(object d, decimal expected) - { - VARIANT variant = new(); - *(DECIMAL*)(&variant) = (DECIMAL)d; - variant.Anonymous.Anonymous.vt = VT_DECIMAL; - AssertToObjectEqual(expected, variant); - } - - [StaTheory] - [MemberData(nameof(Decimal_TestData))] - public void VARIANT_ToObject_DecimalBYREF_ReturnsExpected(object d, decimal expected) - { - DECIMAL asD = (DECIMAL)d; - using VARIANT variant = Create(VT_DECIMAL | VT_BYREF, &asD); - AssertToObjectEqual(expected, variant); - } - - [StaFact] - public void VARIANT_ToObject_CLSID_ReturnsExpected() - { - var guid = Guid.NewGuid(); - using VARIANT variant = new(); - HRESULT hr = InitPropVariantFromCLSID(&guid, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_CLSID, variant.vt); - - AssertToObjectEqualExtension(guid, variant); - } - - public static IEnumerable VOID_TestData() - { - yield return new object[] { IntPtr.Zero }; - yield return new object[] { (IntPtr)1 }; - } - - [StaTheory] - [MemberData(nameof(VOID_TestData))] - public void VARIANT_ToObject_VOID_ReturnsExpected(IntPtr data) - { - using VARIANT variant = Create(VT_VOID, (void*)data); - IntPtr pv = (IntPtr)(&variant); - Assert.Null(Marshal.GetObjectForNativeVariant(pv)); - } - - [StaTheory] - [InlineData((ushort)VT_USERDEFINED)] - [InlineData((ushort)(VT_USERDEFINED | VT_BYREF))] - public void VARIANT_ToObject_USERDATA_ThrowsArgumentException(ushort vt) - { - using VARIANT variant = Create((VARENUM)vt); - AssertToObjectThrows(variant); - } - - [StaTheory] - [InlineData((ushort)(VT_VOID | VT_BYREF))] - [InlineData((ushort)VT_PTR)] - [InlineData((ushort)(VT_PTR | VT_BYREF))] - [InlineData((ushort)VT_SAFEARRAY)] - [InlineData((ushort)(VT_SAFEARRAY | VT_BYREF))] - [InlineData((ushort)VT_CARRAY)] - [InlineData((ushort)(VT_CARRAY | VT_BYREF))] - [InlineData((ushort)VT_RECORD)] - [InlineData((ushort)(VT_RECORD | VT_BYREF))] - [InlineData((ushort)VT_BLOB)] - [InlineData((ushort)(VT_BLOB | VT_BYREF))] - [InlineData((ushort)VT_STREAM)] - [InlineData((ushort)(VT_STREAM | VT_BYREF))] - [InlineData((ushort)VT_STORAGE)] - [InlineData((ushort)(VT_STORAGE | VT_BYREF))] - [InlineData((ushort)VT_STREAMED_OBJECT)] - [InlineData((ushort)(VT_STREAMED_OBJECT | VT_BYREF))] - [InlineData((ushort)VT_STORED_OBJECT)] - [InlineData((ushort)(VT_STORED_OBJECT | VT_BYREF))] - [InlineData((ushort)VT_BLOB_OBJECT)] - [InlineData((ushort)(VT_BLOB_OBJECT | VT_BYREF))] - [InlineData((ushort)VT_CF)] - [InlineData((ushort)(VT_CF | VT_BYREF))] - [InlineData((ushort)(VT_BSTR_BLOB | VT_BYREF))] - [InlineData((ushort)VT_ILLEGAL)] - [InlineData((ushort)VT_INT_PTR)] - [InlineData((ushort)VT_UINT_PTR)] - [InlineData(127)] - [InlineData(0x000F)] - [InlineData(0x0020)] - [InlineData(0x0021)] - [InlineData(0x0022)] - [InlineData(0x0023)] - [InlineData(0x0024)] - public void VARIANT_ToObject_CantConvert_ThrowsArgumentException(ushort vt) - { - using VARIANT variant = Create((VARENUM)vt); - AssertToObjectThrows(variant); - } - - [StaTheory] - [InlineData(128)] - [InlineData(129)] - [InlineData((ushort)VT_BSTR_BLOB)] - public void VARIANT_ToObject_Illegal_ThrowsInvalidOleVariantTypeException(ushort vt) - { - using VARIANT variant = Create((VARENUM)vt); - AssertToObjectThrows(variant); - } - - public static IEnumerable VectorI1_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new sbyte[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorI1_TestData))] - public void VARIANT_ToObject_VECTORI1_ReturnsExpected(sbyte[] result) - { - VARIANT variant = new(); - try - { - fixed (sbyte* pResult = result) - { - HRESULT hr = InitPropVariantFromBuffer(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_UI1, variant.vt); - } - - // I1 and UI1 have the same size. - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_I1; - AssertToObjectEqualExtension(result, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORI1NoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_I1); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorUI1_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new byte[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorUI1_TestData))] - public void VARIANT_ToObject_VECTORUI1_ReturnsExpected(byte[] result) - { - using VARIANT variant = new(); - fixed (byte* pResult = result) - { - HRESULT hr = InitPropVariantFromBuffer(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_UI1, variant.vt); - } - - AssertToObjectEqualExtension(result, variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORUI1NoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_UI1); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorI2_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new short[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorI2_TestData))] - public void VARIANT_ToObject_VECTORI2_ReturnsExpected(short[] result) - { - using VARIANT variant = new(); - fixed (short* pResult = result) - { - HRESULT hr = InitPropVariantFromInt16Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I2, variant.vt); - } - - AssertToObjectEqualExtension(result, variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORI2NoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_I2); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorUI2_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new ushort[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorUI2_TestData))] - public void VARIANT_ToObject_VECTORUI2_ReturnsExpected(ushort[] result) - { - using VARIANT variant = new(); - fixed (ushort* pResult = result) - { - HRESULT hr = InitPropVariantFromUInt16Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_UI2, variant.vt); - } - - AssertToObjectEqualExtension(result, variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORUI2NoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_UI2); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorBOOL_TestData() - { - yield return new object[] { Array.Empty(), Array.Empty() }; - yield return new object[] { new BOOL[] { BOOL.TRUE, BOOL.FALSE, BOOL.TRUE }, new bool[] { true, false, true } }; - } - - [StaTheory] - [MemberData(nameof(VectorBOOL_TestData))] - public void VARIANT_ToObject_VECTORBOOL_ReturnsExpected(object result, bool[] expected) - { - using VARIANT variant = new(); - BOOL[] boolResult = (BOOL[])result; - fixed (BOOL* pResult = boolResult) - { - HRESULT hr = InitPropVariantFromBooleanVector(pResult, (uint)boolResult.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_BOOL, variant.vt); - } - - AssertToObjectEqualExtension(expected, variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORBOOLNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_BOOL); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorI4_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new int[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorI4_TestData))] - public void VARIANT_ToObject_VECTORI4_ReturnsExpected(int[] result) - { - using VARIANT variant = new(); - fixed (int* pResult = result) - { - HRESULT hr = InitPropVariantFromInt32Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I4, variant.vt); - } - - AssertToObjectEqualExtension(result, variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORI4NoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_I4); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorUI4_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new uint[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorUI4_TestData))] - public void VARIANT_ToObject_VECTORUI4_ReturnsExpected(uint[] result) - { - using VARIANT variant = new(); - fixed (uint* pResult = result) - { - HRESULT hr = InitPropVariantFromUInt32Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_UI4, variant.vt); - } - - AssertToObjectEqualExtension(result, variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORUI4NoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_UI4); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorINT_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new int[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorINT_TestData))] - public void VARIANT_ToObject_VECTORINT_ReturnsExpected(int[] result) - { - VARIANT variant = new(); - try - { - fixed (int* pResult = result) - { - HRESULT hr = InitPropVariantFromInt32Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I4, variant.vt); - } - - // I4 and INT have the same size. - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_INT; - AssertToObjectEqualExtension(result, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORINTNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_INT); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorUINT_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new uint[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorUINT_TestData))] - public void VARIANT_ToObject_VECTORUINT_ReturnsExpected(uint[] result) - { - VARIANT variant = new(); - try - { - fixed (uint* pResult = result) - { - HRESULT hr = InitPropVariantFromUInt32Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_UI4, variant.vt); - } - - // UI4 and UINT have the same size. - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_UINT; - AssertToObjectEqualExtension(result, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORUINTNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_UINT); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorI8_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new long[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorI8_TestData))] - public void VARIANT_ToObject_VECTORI8_ReturnsExpected(long[] result) - { - using VARIANT variant = new(); - fixed (long* pResult = result) - { - HRESULT hr = InitPropVariantFromInt64Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I8, variant.vt); - } - - AssertToObjectEqualExtension(result, variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORI8NoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_I8); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorUI8_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new ulong[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorUI8_TestData))] - public void VARIANT_ToObject_VECTORUI8_ReturnsExpected(ulong[] result) - { - using VARIANT variant = new(); - fixed (ulong* pResult = result) - { - HRESULT hr = InitPropVariantFromUInt64Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_UI8, variant.vt); - } - - AssertToObjectEqualExtension(result, variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORUI8NoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_UI8); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorR4_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new float[] { 1.1f, 2.2f, 3.3f } }; - } - - [StaTheory] - [MemberData(nameof(VectorR4_TestData))] - public void VARIANT_ToObject_VECTORR4_ReturnsExpected(float[] result) - { - VARIANT variant = new(); - try - { - fixed (float* pResult = result) - { - HRESULT hr = InitPropVariantFromInt32Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I4, variant.vt); - } - - // I4 and R4 are the same size. - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_R4; - AssertToObjectEqualExtension(result, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORR4NoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_R4); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorR8_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new double[] { 1.1, 2.2, 3.3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorR8_TestData))] - public void VARIANT_ToObject_VECTORR8_ReturnsExpected(double[] result) - { - using VARIANT variant = new(); - fixed (double* pResult = result) - { - HRESULT hr = InitPropVariantFromDoubleVector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_R8, variant.vt); - } - - AssertToObjectEqualExtension(result, variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORR8NoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_R8); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorERROR_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new uint[] { 1, 2, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorERROR_TestData))] - public void VARIANT_ToObject_VECTORERROR_ReturnsExpected(uint[] result) - { - VARIANT variant = new(); - try - { - fixed (uint* pResult = result) - { - HRESULT hr = InitPropVariantFromUInt32Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_UI4, variant.vt); - } - - // UI4 and ERROR are the same size. - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_ERROR; - AssertToObjectEqualExtension(result, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORERRORNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_ERROR); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorCY_TestData() - { - yield return new object[] { Array.Empty(), Array.Empty() }; - yield return new object[] { new long[] { 11000, 22000, 30000 }, new decimal[] { 1.1m, 2.2m, 3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorCY_TestData))] - public void VARIANT_ToObject_VECTORCY_ReturnsExpected(long[] result, decimal[] expected) - { - VARIANT variant = new(); - try - { - fixed (long* pResult = result) - { - HRESULT hr = InitPropVariantFromInt64Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I8, variant.vt); - } - - // I8 and CY have the same size. - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_CY; - AssertToObjectEqualExtension(expected, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORCYNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_CY); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorDATE_TestData() - { - yield return new object[] { Array.Empty(), Array.Empty() }; - - var d1 = new DateTime(2020, 05, 13, 13, 3, 12); - var d2 = new DateTime(2020, 05, 13, 13, 3, 11); - var d3 = new DateTime(2020, 3, 13, 13, 3, 12); - yield return new object[] { new double[] { d1.ToOADate(), d2.ToOADate(), d3.ToOADate() }, new DateTime[] { d1, d2, d3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorDATE_TestData))] - public void VARIANT_ToObject_VECTORDATE_ReturnsExpected(double[] result, DateTime[] expected) - { - VARIANT variant = new(); - try - { - fixed (double* pResult = result) - { - HRESULT hr = InitPropVariantFromDoubleVector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_R8, variant.vt); - } - - // R8 and DATE have the same size. - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_DATE; - AssertToObjectEqualExtension(expected, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORDATENoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_DATE); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorFILETIME_TestData() - { - yield return new object[] { Array.Empty(), Array.Empty() }; - - var d1 = new DateTime(2020, 05, 13, 13, 3, 12); - var d2 = new DateTime(2020, 05, 13, 13, 3, 11); - var d3 = new DateTime(2020, 3, 13, 13, 3, 12); - yield return new object[] { new PInvoke.FILETIME[] { new PInvoke.FILETIME(d1), new PInvoke.FILETIME(d2), new PInvoke.FILETIME(d3) }, new DateTime[] { d1, d2, d3 } }; - } - - [StaTheory] - [MemberData(nameof(VectorFILETIME_TestData))] - public void VARIANT_ToObject_VECTORFILETIME_ReturnsExpected(object result, DateTime[] expected) - { - using VARIANT variant = new(); - PInvoke.FILETIME[] fileTimeResult = (PInvoke.FILETIME[])result; - fixed (PInvoke.FILETIME* pResult = fileTimeResult) - { - HRESULT hr = InitPropVariantFromFileTimeVector(pResult, (uint)fileTimeResult.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_FILETIME, variant.vt); - } - - AssertToObjectEqualExtension(expected, variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORFILETIMENoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_FILETIME); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - public static IEnumerable VectorCLSID_TestData() - { - yield return new object[] { Array.Empty() }; - yield return new object[] { new Guid[] { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() } }; - } - - [StaTheory] - [MemberData(nameof(VectorCLSID_TestData))] - public void VARIANT_ToObject_VECTORCLSID_ReturnsExpected(Guid[] result) - { - VARIANT variant = new(); - try - { - fixed (Guid* pResult = result) - { - HRESULT hr = InitPropVariantFromBuffer(pResult, (uint)(result.Length * sizeof(Guid)), &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_UI1, variant.vt); - } - - variant.Anonymous.Anonymous.Anonymous.ca.cElems = (uint)(variant.Anonymous.Anonymous.Anonymous.ca.cElems / sizeof(Guid)); - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_CLSID; - AssertToObjectEqualExtension(result, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORCLSIDNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_CLSID); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORBSTR_ReturnsExpected() - { - VARIANT variant = new(); - IntPtr ptr1 = Marshal.StringToBSTR("text"); - IntPtr ptr2 = Marshal.StringToBSTR(""); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - fixed (IntPtr* pResult = result) - { - if (IntPtr.Size == 4) - { - HRESULT hr = InitPropVariantFromInt32Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I4, variant.vt); - } - else - { - HRESULT hr = InitPropVariantFromInt64Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I8, variant.vt); - } - } - - // I4/I8 and BSTR have same size. - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_BSTR; - AssertToObjectEqualExtension(new string[] { null, "text", "" }, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORBSTRNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_BSTR); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORLPWSTR_ReturnsExpected() - { - VARIANT variant = new(); - IntPtr ptr1 = Marshal.StringToCoTaskMemUni("text"); - IntPtr ptr2 = Marshal.StringToCoTaskMemUni(""); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - fixed (IntPtr* pResult = result) - { - if (IntPtr.Size == 4) - { - HRESULT hr = InitPropVariantFromInt32Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I4, variant.vt); - } - else - { - HRESULT hr = InitPropVariantFromInt64Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I8, variant.vt); - } - } - - // I4/I8 and LPWSTR have same size. - variant.vt = VT_VECTOR | VT_LPWSTR; - AssertToObjectEqualExtension(new string[] { null, "text", "" }, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORLPWSTRNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_LPWSTR); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORLPSTR_ReturnsExpected() - { - VARIANT variant = new(); - IntPtr ptr1 = Marshal.StringToCoTaskMemAnsi("text"); - IntPtr ptr2 = Marshal.StringToCoTaskMemAnsi(""); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - fixed (IntPtr* pResult = result) - { - if (IntPtr.Size == 4) - { - HRESULT hr = InitPropVariantFromInt32Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I4, variant.vt); - } - else - { - HRESULT hr = InitPropVariantFromInt64Vector(pResult, (uint)result.Length, &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_I8, variant.vt); - } - } - - // I4/I8 and LPSTR have same size. - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_LPSTR; - AssertToObjectEqualExtension(new string[] { null, "text", "" }, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORLPSTRNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_LPSTR); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - [StaFact] - public void VARIANT_ToObject_VECTORVARIANT_ReturnsExpected() - { - VARIANT variant = new(); - try - { - VARIANT variant1 = Create(VT_I4); - variant1.data.llVal = 1; - VARIANT variant2 = Create(VT_UI4); - variant2.data.ullVal = 2; - var result = new VARIANT[] { variant1, variant2 }; - fixed (VARIANT* pResult = result) - { - HRESULT hr = InitPropVariantFromBuffer(pResult, (uint)(result.Length * sizeof(VARIANT)), &variant); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_VECTOR | VT_UI1, variant.vt); - } - - variant.data.ca.cElems = (uint)(variant.data.ca.cElems / sizeof(VARIANT)); - variant.Anonymous.Anonymous.vt = VT_VECTOR | VT_VARIANT; - AssertToObjectEqualExtension(new object[] { 1, 2u }, variant); - } - finally - { - variant.Dispose(); - } - } - - [StaFact] - public void VARIANT_ToObject_VECTORVARIANTNoData_ReturnsExpected() - { - using VARIANT variant = Create(VT_VECTOR | VT_VARIANT); - AssertToObjectEqualExtension(Array.Empty(), variant); - } - - [StaTheory] - [InlineData((ushort)VT_EMPTY)] - [InlineData((ushort)VT_DECIMAL)] - [InlineData((ushort)VT_UNKNOWN)] - [InlineData((ushort)VT_DISPATCH)] - [InlineData((ushort)VT_NULL)] - [InlineData((ushort)VT_CF)] - [InlineData((ushort)VT_VOID)] - [InlineData((ushort)VT_PTR)] - [InlineData((ushort)VT_SAFEARRAY)] - [InlineData((ushort)VT_CARRAY)] - [InlineData((ushort)VT_RECORD)] - [InlineData((ushort)VT_BLOB)] - [InlineData((ushort)VT_STREAM)] - [InlineData((ushort)VT_STORAGE)] - [InlineData((ushort)VT_STREAMED_OBJECT)] - [InlineData((ushort)VT_STORED_OBJECT)] - [InlineData((ushort)VT_BLOB_OBJECT)] - [InlineData(127)] - [InlineData(0x000F)] - [InlineData(0x0020)] - [InlineData(0x0021)] - [InlineData(0x0022)] - [InlineData(0x0023)] - [InlineData(0x0024)] - public void VARIANT_ToObject_VECTORInvalidType_ThrowsArgumentException(ushort vt) - { - using VARIANT variant = new() - { - vt = VT_VECTOR | (VARENUM)vt - }; - Assert.Throws(() => variant.ToObject()); - } - - [StaTheory] - [InlineData(128)] - [InlineData(129)] - [InlineData((ushort)VT_BSTR_BLOB)] - public void VARIANT_ToObject_VECTORInvalidTypeNoData_ThrowsInvalidOleVariantTypeException(ushort vt) - { - using VARIANT variant = new() - { - vt = VT_VECTOR | (VARENUM)vt - }; - AssertToObjectThrows(variant); - } - - [StaTheory] - [MemberData(nameof(VectorUI1_TestData))] - public void VARIANT_ToObject_ARRAYUI1SingleDimension_ReturnsExpected(byte[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI1, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI1 - }; - variant.data.parray = psa; - - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUI1_TestData))] - public void VARIANT_ToObject_ARRAYUI1SingleDimensionNonZeroLowerBounds_ReturnsExpected(byte[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI1, result, 1); - using VARIANT variant = Create(VT_ARRAY | VT_UI1); - variant.data.parray = psa; - - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(byte).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionUI1_TestData() - { - yield return new object[] { new byte[0, 0] }; - yield return new object[] - { - new byte[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUI1_TestData))] - public void VARIANT_ToObject_ARRAYUI1MultiDimension_ReturnsExpected(byte[,] result) - { - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI1 - }; - variant.data.parray = CreateSafeArray(VT_UI1, result); - - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(byte).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUI1_TestData))] - public void VARIANT_ToObject_ARRAYUI1MultiDimensionNonZeroLowerBound_ReturnsExpected(byte[,] result) - { - using VARIANT variant = new() { vt = VT_ARRAY | VT_UI1 }; - variant.data.parray = CreateSafeArray(VT_UI1, result, 1, 2); - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(byte).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorI1_TestData))] - public void VARIANT_ToObject_ARRAYI1SingleDimension_ReturnsExpected(sbyte[] result) - { - using VARIANT variant = new() { vt = VT_ARRAY | VT_I1 }; - variant.data.parray = CreateSafeArray(VT_I1, result); - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorI1_TestData))] - public void VARIANT_ToObject_ARRAYI1SingleDimensionNonZeroLowerBounds_ReturnsExpected(sbyte[] result) - { - using VARIANT variant = new() { vt = VT_ARRAY | VT_I1 }; - variant.data.parray = CreateSafeArray(VT_I1, result, 1); - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(sbyte).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionI1_TestData() - { - yield return new object[] { new sbyte[0, 0] }; - yield return new object[] - { - new sbyte[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionI1_TestData))] - public void VARIANT_ToObject_ARRAYI1MultiDimension_ReturnsExpected(sbyte[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I1, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I1, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(sbyte).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionI1_TestData))] - public void VARIANT_ToObject_ARRAYI1MultiDimensionNonZeroLowerBound_ReturnsExpected(sbyte[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I1, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I1, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(sbyte).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorI2_TestData))] - public void VARIANT_ToObject_ARRAYI2SingleDimension_ReturnsExpected(short[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I2, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I2, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorI2_TestData))] - public void VARIANT_ToObject_ARRAYI2SingleDimensionNonZeroLowerBounds_ReturnsExpected(short[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I2, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I2, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(short).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionI2_TestData() - { - yield return new object[] { new short[0, 0] }; - yield return new object[] - { - new short[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionI2_TestData))] - public void VARIANT_ToObject_ARRAYI2MultiDimension_ReturnsExpected(short[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I2, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I2, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(short).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionI2_TestData))] - public void VARIANT_ToObject_ARRAYI2MultiDimensionNonZeroLowerBound_ReturnsExpected(short[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I2, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I2, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(short).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUI2_TestData))] - public void VARIANT_ToObject_ARRAYUI2SingleDimension_ReturnsExpected(ushort[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI2, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI2, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUI2_TestData))] - public void VARIANT_ToObject_ARRAYUI2SingleDimensionNonZeroLowerBounds_ReturnsExpected(ushort[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI2, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI2, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(ushort).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionUI2_TestData() - { - yield return new object[] { new ushort[0, 0] }; - yield return new object[] - { - new ushort[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUI2_TestData))] - public void VARIANT_ToObject_ARRAYUI2MultiDimension_ReturnsExpected(ushort[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI2, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI2, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(ushort).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUI2_TestData))] - public void VARIANT_ToObject_ARRAYUI2MultiDimensionNonZeroLowerBound_ReturnsExpected(ushort[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI2, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI2, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(ushort).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorI4_TestData))] - public void VARIANT_ToObject_ARRAYI4SingleDimension_ReturnsExpected(int[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I4, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorI4_TestData))] - public void VARIANT_ToObject_ARRAYI4SingleDimensionNonZeroLowerBounds_ReturnsExpected(int[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I4, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionI4_TestData() - { - yield return new object[] { new int[0, 0] }; - yield return new object[] - { - new int[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionI4_TestData))] - public void VARIANT_ToObject_ARRAYI4MultiDimension_ReturnsExpected(int[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I4, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionI4_TestData))] - public void VARIANT_ToObject_ARRAYI4MultiDimensionNonZeroLowerBound_ReturnsExpected(int[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I4, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorI4_TestData))] - public void VARIANT_ToObject_INTArrayI4SingleDimension_ReturnsExpected(int[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_INT, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorI4_TestData))] - public void VARIANT_ToObject_INTArrayI4SingleDimensionNonZeroLowerBounds_ReturnsExpected(int[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_INT, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionI4_TestData))] - public void VARIANT_ToObject_INTArrayI4MultiDimension_ReturnsExpected(int[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_INT, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionI4_TestData))] - public void VARIANT_ToObject_INTArrayI4MultiDimensionNonZeroLowerBound_ReturnsExpected(int[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_INT, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUI4_TestData))] - public void VARIANT_ToObject_ARRAYUI4SingleDimension_ReturnsExpected(uint[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI4, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUI4_TestData))] - public void VARIANT_ToObject_ARRAYUI4SingleDimensionNonZeroLowerBounds_ReturnsExpected(uint[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI4, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionUI4_TestData() - { - yield return new object[] { new uint[0, 0] }; - yield return new object[] - { - new uint[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUI4_TestData))] - public void VARIANT_ToObject_ARRAYUI4MultiDimension_ReturnsExpected(uint[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI4, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUI4_TestData))] - public void VARIANT_ToObject_ARRAYUI4MultiDimensionNonZeroLowerBound_ReturnsExpected(uint[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI4, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUI4_TestData))] - public void VARIANT_ToObject_UINTArrayUI4SingleDimension_ReturnsExpected(uint[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UINT, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUI4_TestData))] - public void VARIANT_ToObject_UINTArrayUI4SingleDimensionNonZeroLowerBounds_ReturnsExpected(uint[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UINT, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUI4_TestData))] - public void VARIANT_ToObject_UINTArrayUI4MultiDimension_ReturnsExpected(uint[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UINT, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUI4_TestData))] - public void VARIANT_ToObject_UINTArrayUI4MultiDimensionNonZeroLowerBound_ReturnsExpected(uint[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UINT, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorINT_TestData))] - public void VARIANT_ToObject_ARRAYINTSingleDimension_ReturnsExpected(int[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_INT, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_INT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorINT_TestData))] - public void VARIANT_ToObject_ARRAYINTSingleDimensionNonZeroLowerBounds_ReturnsExpected(int[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_INT, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_INT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionINT_TestData() - { - yield return new object[] { new int[0, 0] }; - yield return new object[] - { - new int[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionINT_TestData))] - public void VARIANT_ToObject_ARRAYINTMultiDimension_ReturnsExpected(int[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_INT, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_INT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionINT_TestData))] - public void VARIANT_ToObject_ARRAYINTMultiDimensionNonZeroLowerBound_ReturnsExpected(int[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_INT, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_INT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorINT_TestData))] - public void VARIANT_ToObject_I4ArrayINTSingleDimension_ReturnsExpected(int[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I4, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_INT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorINT_TestData))] - public void VARIANT_ToObject_I4ArrayINTSingleDimensionNonZeroLowerBounds_ReturnsExpected(int[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I4, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_INT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionINT_TestData))] - public void VARIANT_ToObject_I4ArrayINTMultiDimension_ReturnsExpected(int[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I4, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_INT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionINT_TestData))] - public void VARIANT_ToObject_I4ArrayINTMultiDimensionNonZeroLowerBound_ReturnsExpected(int[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I4, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_INT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(int).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUINT_TestData))] - public void VARIANT_ToObject_ARRAYUINTSingleDimension_ReturnsExpected(uint[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UINT, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UINT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUINT_TestData))] - public void VARIANT_ToObject_ARRAYUINTSingleDimensionNonZeroLowerBounds_ReturnsExpected(uint[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UINT, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UINT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionUINT_TestData() - { - yield return new object[] { new uint[0, 0] }; - yield return new object[] - { - new uint[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUINT_TestData))] - public void VARIANT_ToObject_ARRAYUINTMultiDimension_ReturnsExpected(uint[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UINT, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UINT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUINT_TestData))] - public void VARIANT_ToObject_ARRAYUINTMultiDimensionNonZeroLowerBound_ReturnsExpected(uint[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UINT, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UINT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUINT_TestData))] - public void VARIANT_ToObject_UI4ArrayUINTSingleDimension_ReturnsExpected(uint[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI4, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UINT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUINT_TestData))] - public void VARIANT_ToObject_UI4ArrayUINTSingleDimensionNonZeroLowerBounds_ReturnsExpected(uint[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI4, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UINT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUINT_TestData))] - public void VARIANT_ToObject_UI4ArrayUINTMultiDimension_ReturnsExpected(uint[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI4, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UINT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUINT_TestData))] - public void VARIANT_ToObject_UI4ArrayUINTMultiDimensionNonZeroLowerBound_ReturnsExpected(uint[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI4, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UINT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorI8_TestData))] - public void VARIANT_ToObject_ARRAYI8SingleDimension_ReturnsExpected(long[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I8, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorI8_TestData))] - public void VARIANT_ToObject_ARRAYI8SingleDimensionNonZeroLowerBounds_ReturnsExpected(long[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I8, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(long).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionI8_TestData() - { - yield return new object[] { new long[0, 0] }; - yield return new object[] - { - new long[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionI8_TestData))] - public void VARIANT_ToObject_ARRAYI8MultiDimension_ReturnsExpected(long[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I8, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(long).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionI8_TestData))] - public void VARIANT_ToObject_ARRAYI8MultiDimensionNonZeroLowerBound_ReturnsExpected(long[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_I8, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(long).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUI8_TestData))] - public void VARIANT_ToObject_ARRAYUI8SingleDimension_ReturnsExpected(ulong[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI8, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorUI8_TestData))] - public void VARIANT_ToObject_ARRAYUI8SingleDimensionNonZeroLowerBounds_ReturnsExpected(ulong[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI8, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(ulong).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionUI8_TestData() - { - yield return new object[] { new ulong[0, 0] }; - yield return new object[] - { - new ulong[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUI8_TestData))] - public void VARIANT_ToObject_ARRAYUI8MultiDimension_ReturnsExpected(ulong[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI8, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(ulong).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionUI8_TestData))] - public void VARIANT_ToObject_ARRAYUI8MultiDimensionNonZeroLowerBound_ReturnsExpected(ulong[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_UI8, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UI8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(ulong).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorR4_TestData))] - public void VARIANT_ToObject_ARRAYR4SingleDimension_ReturnsExpected(float[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_R4, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_R4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorR4_TestData))] - public void VARIANT_ToObject_ARRAYR4SingleDimensionNonZeroLowerBounds_ReturnsExpected(float[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_R4, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_R4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(float).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionR4_TestData() - { - yield return new object[] { new float[0, 0] }; - yield return new object[] - { - new float[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionR4_TestData))] - public void VARIANT_ToObject_ARRAYR4MultiDimension_ReturnsExpected(float[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_R4, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_R4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(float).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionR4_TestData))] - public void VARIANT_ToObject_ARRAYR4MultiDimensionNonZeroLowerBound_ReturnsExpected(float[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_R4, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_R4, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(float).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorR8_TestData))] - public void VARIANT_ToObject_ARRAYR8SingleDimension_ReturnsExpected(double[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_R8, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_R8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorR8_TestData))] - public void VARIANT_ToObject_ARRAYR8SingleDimensionNonZeroLowerBounds_ReturnsExpected(double[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_R8, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_R8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(double).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionR8_TestData() - { - yield return new object[] { new double[0, 0] }; - yield return new object[] - { - new double[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionR8_TestData))] - public void VARIANT_ToObject_ARRAYR8MultiDimension_ReturnsExpected(double[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_R8, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_R8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(double).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionR8_TestData))] - public void VARIANT_ToObject_ARRAYR8MultiDimensionNonZeroLowerBound_ReturnsExpected(double[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_R8, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_R8, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(double).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorERROR_TestData))] - public void VARIANT_ToObject_ARRAYERRORSingleDimension_ReturnsExpected(uint[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_ERROR, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_ERROR, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorERROR_TestData))] - public void VARIANT_ToObject_ARRAYERRORSingleDimensionNonZeroLowerBounds_ReturnsExpected(uint[] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_ERROR, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_ERROR, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable MultiDimensionERROR_TestData() - { - yield return new object[] { new uint[0, 0] }; - yield return new object[] - { - new uint[2, 3] - { - { 1, 2, 3 }, - { 4, 5, 6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionERROR_TestData))] - public void VARIANT_ToObject_ARRAYERRORMultiDimension_ReturnsExpected(uint[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_ERROR, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_ERROR, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionERROR_TestData))] - public void VARIANT_ToObject_ARRAYERRORMultiDimensionNonZeroLowerBound_ReturnsExpected(int[,] result) - { - SAFEARRAY* psa = CreateSafeArray(VT_ERROR, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_ERROR, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(uint).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(result, array); - }); - } - - public static IEnumerable ArrayBOOL_TestData() - { - yield return new object[] { Array.Empty(), Array.Empty() }; - yield return new object[] { new VARIANT_BOOL[] { VARIANT_BOOL.VARIANT_TRUE, VARIANT_BOOL.VARIANT_FALSE, VARIANT_BOOL.VARIANT_TRUE }, new bool[] { true, false, true } }; - } - - [StaTheory] - [MemberData(nameof(ArrayBOOL_TestData))] - public void VARIANT_ToObject_ARRAYBOOLSingleDimension_ReturnsExpected(object result, bool[] expected) - { - VARIANT_BOOL[] boolResult = (VARIANT_BOOL[])result; - SAFEARRAY* psa = CreateSafeArray(VT_BOOL, boolResult); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_BOOL, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(expected.Length, array.GetLength(0)); - Assert.Equal(expected, array); - }); - } - - [StaTheory] - [MemberData(nameof(ArrayBOOL_TestData))] - public void VARIANT_ToObject_ARRAYBOOLSingleDimensionNonZeroLowerBounds_ReturnsExpected(object result, bool[] expected) - { - VARIANT_BOOL[] boolResult = (VARIANT_BOOL[])result; - SAFEARRAY* psa = CreateSafeArray(VT_BOOL, boolResult, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_BOOL, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(bool).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(expected.Length, array.GetLength(0)); - Assert.Equal(expected, array); - }); - } - - public static IEnumerable MultiDimensionBOOL_TestData() - { - yield return new object[] { new VARIANT_BOOL[0, 0], new bool[0, 0] }; - yield return new object[] - { - new VARIANT_BOOL[2, 3] - { - { VARIANT_BOOL.VARIANT_TRUE, VARIANT_BOOL.VARIANT_FALSE, VARIANT_BOOL.VARIANT_TRUE }, - { VARIANT_BOOL.VARIANT_FALSE, VARIANT_BOOL.VARIANT_TRUE, VARIANT_BOOL.VARIANT_FALSE } - }, - new bool[2, 3] - { - { true, false, true }, - { false, true, false } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionBOOL_TestData))] - public void VARIANT_ToObject_ARRAYBOOLMultiDimension_ReturnsExpected(object result, bool[,] expected) - { - VARIANT_BOOL[,] boolResult = (VARIANT_BOOL[,])result; - SAFEARRAY* psa = CreateSafeArray(VT_BOOL, boolResult); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_BOOL, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(bool).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(expected.GetLength(0), array.GetLength(0)); - Assert.Equal(expected.GetLength(1), array.GetLength(1)); - Assert.Equal(expected, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionBOOL_TestData))] - public void VARIANT_ToObject_ARRAYBOOLMultiDimensionNonZeroLowerBound_ReturnsExpected(object result, bool[,] expected) - { - VARIANT_BOOL[,] boolResult = (VARIANT_BOOL[,])result; - SAFEARRAY* psa = CreateSafeArray(VT_BOOL, boolResult, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_BOOL, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(bool).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(expected.GetLength(0), array.GetLength(0)); - Assert.Equal(expected.GetLength(1), array.GetLength(1)); - Assert.Equal(expected, array); - }); - } - - public static IEnumerable ArrayDECIMAL_TestData() - { - yield return new object[] { Array.Empty(), Array.Empty() }; - - VarDecFromR8(1.1, out DECIMAL d1); - VarDecFromR8(2.2, out DECIMAL d2); - VarDecFromR8(3.3, out DECIMAL d3); - yield return new object[] { new DECIMAL[] { d1, d2, d3 }, new decimal[] { 1.1m, 2.2m, 3.3m } }; - } - - [StaTheory] - [MemberData(nameof(ArrayDECIMAL_TestData))] - public void VARIANT_ToObject_ARRAYDECIMALSingleDimension_ReturnsExpected(object result, decimal[] expected) - { - DECIMAL[] decimalResult = (DECIMAL[])result; - SAFEARRAY* psa = CreateSafeArray(VT_DECIMAL, decimalResult); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DECIMAL, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(expected.Length, array.GetLength(0)); - Assert.Equal(expected, array); - }); - } - - [StaTheory] - [MemberData(nameof(ArrayDECIMAL_TestData))] - public void VARIANT_ToObject_ARRAYDECIMALSingleDimensionNonZeroLowerBounds_ReturnsExpected(object result, decimal[] expected) - { - DECIMAL[] decimalResult = (DECIMAL[])result; - SAFEARRAY* psa = CreateSafeArray(VT_DECIMAL, decimalResult, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DECIMAL, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(decimal).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(expected.Length, array.GetLength(0)); - Assert.Equal(expected, array); - }); - } - - public static IEnumerable MultiDimensionDECIMAL_TestData() - { - yield return new object[] { new DECIMAL[0, 0], new decimal[0, 0] }; - VarDecFromR8(1.1, out DECIMAL d1); - VarDecFromR8(2.2, out DECIMAL d2); - VarDecFromR8(3.3, out DECIMAL d3); - VarDecFromR8(3.1, out DECIMAL d4); - VarDecFromR8(2.2, out DECIMAL d5); - VarDecFromR8(1.3, out DECIMAL d6); - yield return new object[] - { - new DECIMAL[2, 3] - { - { d1, d2, d3 }, - { d4, d5, d6 } - }, - new decimal[2, 3] - { - { 1.1m, 2.2m, 3.3m }, - { 3.1m, 2.2m, 1.3m } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionDECIMAL_TestData))] - public void VARIANT_ToObject_ARRAYDECIMALMultiDimension_ReturnsExpected(object result, decimal[,] expected) - { - DECIMAL[,] decimalResult = (DECIMAL[,])result; - SAFEARRAY* psa = CreateSafeArray(VT_DECIMAL, decimalResult); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DECIMAL, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(decimal).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(expected.GetLength(0), array.GetLength(0)); - Assert.Equal(expected.GetLength(1), array.GetLength(1)); - Assert.Equal(expected, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionDECIMAL_TestData))] - public void VARIANT_ToObject_ARRAYDECIMALMultiDimensionNonZeroLowerBound_ReturnsExpected(object result, decimal[,] expected) - { - DECIMAL[,] decimalResult = (DECIMAL[,])result; - SAFEARRAY* psa = CreateSafeArray(VT_DECIMAL, decimalResult, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DECIMAL, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(decimal).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(expected.GetLength(0), array.GetLength(0)); - Assert.Equal(expected.GetLength(1), array.GetLength(1)); - Assert.Equal(expected, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorCY_TestData))] - public void VARIANT_ToObject_ARRAYCYSingleDimension_ReturnsExpected(long[] result, decimal[] expected) - { - SAFEARRAY* psa = CreateSafeArray(VT_CY, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_CY, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(expected.Length, array.GetLength(0)); - Assert.Equal(expected, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorCY_TestData))] - public void VARIANT_ToObject_ARRAYCYSingleDimensionNonZeroLowerBounds_ReturnsExpected(long[] result, decimal[] expected) - { - SAFEARRAY* psa = CreateSafeArray(VT_CY, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_CY, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(decimal).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(expected.Length, array.GetLength(0)); - Assert.Equal(expected, array); - }); - } - - public static IEnumerable MultiDimensionCY_TestData() - { - yield return new object[] { new long[0, 0], new decimal[0, 0] }; - yield return new object[] - { - new long[2, 3] - { - { 11000, 22000, 33000 }, - { 31000, 22000, 13000 } - }, - new decimal[2, 3] - { - { 1.1m, 2.2m, 3.3m }, - { 3.1m, 2.2m, 1.3m } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionCY_TestData))] - public void VARIANT_ToObject_ARRAYCYMultiDimension_ReturnsExpected(long[,] result, decimal[,] expected) - { - SAFEARRAY* psa = CreateSafeArray(VT_CY, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_CY, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(decimal).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(expected.GetLength(0), array.GetLength(0)); - Assert.Equal(expected.GetLength(1), array.GetLength(1)); - Assert.Equal(expected, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionCY_TestData))] - public void VARIANT_ToObject_ARRAYCYMultiDimensionNonZeroLowerBound_ReturnsExpected(long[,] result, decimal[,] expected) - { - SAFEARRAY* psa = CreateSafeArray(VT_CY, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_CY, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(decimal).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(expected.GetLength(0), array.GetLength(0)); - Assert.Equal(expected.GetLength(1), array.GetLength(1)); - Assert.Equal(expected, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorDATE_TestData))] - public void VARIANT_ToObject_ARRAYDATESingleDimension_ReturnsExpected(double[] result, DateTime[] expected) - { - SAFEARRAY* psa = CreateSafeArray(VT_DATE, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DATE, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(expected.Length, array.GetLength(0)); - Assert.Equal(expected, array); - }); - } - - [StaTheory] - [MemberData(nameof(VectorDATE_TestData))] - public void VARIANT_ToObject_ARRAYDATESingleDimensionNonZeroLowerBounds_ReturnsExpected(double[] result, DateTime[] expected) - { - SAFEARRAY* psa = CreateSafeArray(VT_DATE, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DATE, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(DateTime).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(expected.Length, array.GetLength(0)); - Assert.Equal(expected, array); - }); - } - - public static IEnumerable MultiDimensionDATE_TestData() - { - yield return new object[] { new double[0, 0], new DateTime[0, 0] }; - - var d1 = new DateTime(2020, 05, 13, 13, 3, 12); - var d2 = new DateTime(2020, 05, 13, 13, 3, 11); - var d3 = new DateTime(2020, 3, 13, 13, 3, 12); - var d4 = new DateTime(1892, 1, 2, 3, 4, 5, 6); - var d5 = new DateTime(2010, 2, 3, 4, 5, 6); - var d6 = new DateTime(8000, 10, 11, 12, 13, 14); - yield return new object[] - { - new double[2, 3] - { - { d1.ToOADate(), d2.ToOADate(), d3.ToOADate() }, - { d4.ToOADate(), d5.ToOADate(), d6.ToOADate() } - }, - new DateTime[2, 3] - { - { d1, d2, d3 }, - { d4, d5, d6 } - } - }; - } - - [StaTheory] - [MemberData(nameof(MultiDimensionDATE_TestData))] - public void VARIANT_ToObject_ARRAYDATEMultiDimension_ReturnsExpected(double[,] result, DateTime[,] expected) - { - SAFEARRAY* psa = CreateSafeArray(VT_DATE, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DATE, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(DateTime).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(expected.GetLength(0), array.GetLength(0)); - Assert.Equal(expected.GetLength(1), array.GetLength(1)); - Assert.Equal(expected, array); - }); - } - - [StaTheory] - [MemberData(nameof(MultiDimensionDATE_TestData))] - public void VARIANT_ToObject_ARRAYDATEMultiDimensionNonZeroLowerBound_ReturnsExpected(double[,] result, DateTime[,] expected) - { - SAFEARRAY* psa = CreateSafeArray(VT_DATE, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DATE, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(DateTime).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(expected.GetLength(0), array.GetLength(0)); - Assert.Equal(expected.GetLength(1), array.GetLength(1)); - Assert.Equal(expected, array); - }); - } - - [StaFact] - public void VARIANT_ToObject_ARRAYBSTRSingleDimension_ReturnsExpected() - { - IntPtr ptr1 = Marshal.StringToBSTR("text"); - IntPtr ptr2 = Marshal.StringToBSTR(""); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - SAFEARRAY* psa = CreateSafeArray(VT_BSTR, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_BSTR, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(new string[] { null, "text", "" }, array); - }); - } - finally - { - Marshal.FreeBSTR(ptr1); - Marshal.FreeBSTR(ptr2); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYBSTRSingleDimensionNonZeroLowerBound_ReturnsExpected() - { - IntPtr ptr1 = Marshal.StringToBSTR("text"); - IntPtr ptr2 = Marshal.StringToBSTR(""); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - SAFEARRAY* psa = CreateSafeArray(VT_BSTR, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_BSTR, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(string).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(new string[] { null, "text", "" }, array); - }); - } - finally - { - Marshal.FreeBSTR(ptr1); - Marshal.FreeBSTR(ptr2); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYBSTRMultiDimension_ReturnsExpected() - { - IntPtr ptr1 = Marshal.StringToBSTR("text"); - IntPtr ptr2 = Marshal.StringToBSTR(""); - IntPtr ptr3 = Marshal.StringToBSTR("text3"); - IntPtr ptr4 = Marshal.StringToBSTR("text4"); - IntPtr ptr5 = Marshal.StringToBSTR("text5"); - try - { - var result = new IntPtr[2, 3] - { - { IntPtr.Zero, ptr1, ptr2 }, - { ptr3, ptr4, ptr5 } - }; - SAFEARRAY* psa = CreateSafeArray(VT_BSTR, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_BSTR, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(string).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(new string[,] - { - { null, "text", "" }, - { "text3", "text4", "text5" } - }, array); - }); - } - finally - { - Marshal.FreeBSTR(ptr1); - Marshal.FreeBSTR(ptr2); - Marshal.FreeBSTR(ptr3); - Marshal.FreeBSTR(ptr4); - Marshal.FreeBSTR(ptr5); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYBSTRMultiDimensionNonZeroLowerBound_ReturnsExpected() - { - IntPtr ptr1 = Marshal.StringToBSTR("text"); - IntPtr ptr2 = Marshal.StringToBSTR(""); - IntPtr ptr3 = Marshal.StringToBSTR("text3"); - IntPtr ptr4 = Marshal.StringToBSTR("text4"); - IntPtr ptr5 = Marshal.StringToBSTR("text5"); - try - { - var result = new IntPtr[2, 3] - { - { IntPtr.Zero, ptr1, ptr2 }, - { ptr3, ptr4, ptr5 } - }; - SAFEARRAY* psa = CreateSafeArray(VT_BSTR, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_BSTR, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(string).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(new string[,] - { - { null, "text", "" }, - { "text3", "text4", "text5" } - }, array); - }); - } - finally - { - Marshal.FreeBSTR(ptr1); - Marshal.FreeBSTR(ptr2); - Marshal.FreeBSTR(ptr3); - Marshal.FreeBSTR(ptr4); - Marshal.FreeBSTR(ptr5); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYUNKNOWNSingleDimension_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - SAFEARRAY* psa = CreateSafeArray(VT_UNKNOWN, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UNKNOWN, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(new object[] { null, o1, o2 }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYUNKNOWNSingleDimensionNonZeroLowerBound_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - SAFEARRAY* psa = CreateSafeArray(VT_UNKNOWN, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UNKNOWN, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(new object[] { null, o1, o2 }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYUNKNOWNMultiDimension_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - var o3 = new object(); - var o4 = new object(); - var o5 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - IntPtr ptr3 = Marshal.GetIUnknownForObject(o3); - IntPtr ptr4 = Marshal.GetIUnknownForObject(o4); - IntPtr ptr5 = Marshal.GetIUnknownForObject(o5); - try - { - var result = new IntPtr[2, 3] - { - { IntPtr.Zero, ptr1, ptr2 }, - { ptr3, ptr4, ptr5 } - }; - SAFEARRAY* psa = CreateSafeArray(VT_UNKNOWN, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UNKNOWN, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(new object[,] - { - { null, o1, o2 }, - { o3, o4, o5 } - }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - Marshal.Release(ptr3); - Marshal.Release(ptr4); - Marshal.Release(ptr5); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYUNKNOWNMultiDimensionNonZeroLowerBound_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - var o3 = new object(); - var o4 = new object(); - var o5 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - IntPtr ptr3 = Marshal.GetIUnknownForObject(o3); - IntPtr ptr4 = Marshal.GetIUnknownForObject(o4); - IntPtr ptr5 = Marshal.GetIUnknownForObject(o5); - try - { - var result = new IntPtr[2, 3] - { - { IntPtr.Zero, ptr1, ptr2 }, - { ptr3, ptr4, ptr5 } - }; - SAFEARRAY* psa = CreateSafeArray(VT_UNKNOWN, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UNKNOWN, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(new object[,] - { - { null, o1, o2 }, - { o3, o4, o5 } - }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - Marshal.Release(ptr3); - Marshal.Release(ptr4); - Marshal.Release(ptr5); - } - } - - [StaFact] - public void VARIANT_ToObject_DISPATCHArrayUNKNOWNSingleDimension_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - SAFEARRAY* psa = CreateSafeArray(VT_DISPATCH, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UNKNOWN, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(new object[] { null, o1, o2 }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - } - } - - [StaFact] - public void VARIANT_ToObject_DISPATCHArrayUNKNOWNSingleDimensionNonZeroLowerBound_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - SAFEARRAY* psa = CreateSafeArray(VT_DISPATCH, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UNKNOWN, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(new object[] { null, o1, o2 }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - } - } - - [StaFact] - public void VARIANT_ToObject_DISPATCHArrayUNKNOWNMultiDimension_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - var o3 = new object(); - var o4 = new object(); - var o5 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - IntPtr ptr3 = Marshal.GetIUnknownForObject(o3); - IntPtr ptr4 = Marshal.GetIUnknownForObject(o4); - IntPtr ptr5 = Marshal.GetIUnknownForObject(o5); - try - { - var result = new IntPtr[2, 3] - { - { IntPtr.Zero, ptr1, ptr2 }, - { ptr3, ptr4, ptr5 } - }; - SAFEARRAY* psa = CreateSafeArray(VT_DISPATCH, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UNKNOWN, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(new object[,] - { - { null, o1, o2 }, - { o3, o4, o5 } - }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - Marshal.Release(ptr3); - Marshal.Release(ptr4); - Marshal.Release(ptr5); - } - } - - [StaFact] - public void VARIANT_ToObject_DISPATCHArrayUNKNOWNMultiDimensionNonZeroLowerBound_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - var o3 = new object(); - var o4 = new object(); - var o5 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - IntPtr ptr3 = Marshal.GetIUnknownForObject(o3); - IntPtr ptr4 = Marshal.GetIUnknownForObject(o4); - IntPtr ptr5 = Marshal.GetIUnknownForObject(o5); - try - { - var result = new IntPtr[2, 3] - { - { IntPtr.Zero, ptr1, ptr2 }, - { ptr3, ptr4, ptr5 } - }; - SAFEARRAY* psa = CreateSafeArray(VT_DISPATCH, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_UNKNOWN, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(new object[,] - { - { null, o1, o2 }, - { o3, o4, o5 } - }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - Marshal.Release(ptr3); - Marshal.Release(ptr4); - Marshal.Release(ptr5); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYDISPATCHSingleDimension_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - SAFEARRAY* psa = CreateSafeArray(VT_DISPATCH, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DISPATCH, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(new object[] { null, o1, o2 }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYDISPATCHSingleDimensionNonZeroLowerBound_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - try - { - var result = new IntPtr[] { IntPtr.Zero, ptr1, ptr2 }; - SAFEARRAY* psa = CreateSafeArray(VT_DISPATCH, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DISPATCH, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(new object[] { null, o1, o2 }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYDISPATCHMultiDimension_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - var o3 = new object(); - var o4 = new object(); - var o5 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - IntPtr ptr3 = Marshal.GetIUnknownForObject(o3); - IntPtr ptr4 = Marshal.GetIUnknownForObject(o4); - IntPtr ptr5 = Marshal.GetIUnknownForObject(o5); - try - { - var result = new IntPtr[2, 3] - { - { IntPtr.Zero, ptr1, ptr2 }, - { ptr3, ptr4, ptr5 } - }; - SAFEARRAY* psa = CreateSafeArray(VT_DISPATCH, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DISPATCH, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(new object[,] - { - { null, o1, o2 }, - { o3, o4, o5 } - }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - Marshal.Release(ptr3); - Marshal.Release(ptr4); - Marshal.Release(ptr5); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYDISPATCHMultiDimensionNonZeroLowerBound_ReturnsExpected() - { - var o1 = new object(); - var o2 = new object(); - var o3 = new object(); - var o4 = new object(); - var o5 = new object(); - IntPtr ptr1 = Marshal.GetIUnknownForObject(o1); - IntPtr ptr2 = Marshal.GetIUnknownForObject(o2); - IntPtr ptr3 = Marshal.GetIUnknownForObject(o3); - IntPtr ptr4 = Marshal.GetIUnknownForObject(o4); - IntPtr ptr5 = Marshal.GetIUnknownForObject(o5); - try - { - var result = new IntPtr[2, 3] - { - { IntPtr.Zero, ptr1, ptr2 }, - { ptr3, ptr4, ptr5 } - }; - SAFEARRAY* psa = CreateSafeArray(VT_DISPATCH, result, 1, 2); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_DISPATCH, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(2, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(new object[,] - { - { null, o1, o2 }, - { o3, o4, o5 } - }, array); - }); - } - finally - { - Marshal.Release(ptr1); - Marshal.Release(ptr2); - Marshal.Release(ptr3); - Marshal.Release(ptr4); - Marshal.Release(ptr5); - } - } - - [StaFact] - public void VARIANT_ToObject_ARRAYVARIANTSingleDimension_ReturnsExpected() - { - using VARIANT v1 = new() - { - vt = VT_I4, - data = new() - { - llVal = 1 - } - }; - using VARIANT v2 = new() - { - vt = VT_I4, - data = new() - { - llVal = 2 - } - }; - using VARIANT v3 = new() - { - vt = VT_I4, - data = new() - { - llVal = 3 - } - }; - var result = new VARIANT[] { v1, v2, v3 }; - SAFEARRAY* psa = CreateSafeArray(VT_VARIANT, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_VARIANT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(array); - Assert.Equal(1, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(new object[] { 1, 2, 3 }, array); - }); - } - - [StaFact] - public void VARIANT_ToObject_ARRAYVARIANTSingleDimensionNonZeroLowerBound_ReturnsExpected() - { - using VARIANT v1 = new() - { - vt = VT_I4, - data = new() - { - llVal = 1 - } - }; - using VARIANT v2 = new() - { - vt = VT_I4, - data = new() - { - llVal = 2 - } - }; - using VARIANT v3 = new() - { - vt = VT_I4, - data = new() - { - llVal = 3 - } - }; - var result = new VARIANT[] { v1, v2, v3 }; - SAFEARRAY* psa = CreateSafeArray(VT_VARIANT, result, 1); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_VARIANT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(1), array); - Assert.Equal(1, array.Rank); - Assert.Equal(1, array.GetLowerBound(0)); - Assert.Equal(result.Length, array.GetLength(0)); - Assert.Equal(new object[] { 1, 2, 3 }, array); - }); - } - - [StaFact] - public void VARIANT_ToObject_ARRAYVARIANTMultiDimension_ReturnsExpected() - { - using VARIANT v1 = new() - { - vt = VT_I4, - data = new() - { - llVal = 1 - } - }; - using VARIANT v2 = new() - { - vt = VT_I4, - data = new() - { - llVal = 2 - } - }; - using VARIANT v3 = new() - { - vt = VT_I4, - data = new() - { - llVal = 3 - } - }; - using VARIANT v4 = new() - { - vt = VT_I4, - data = new() - { - llVal = 4 - } - }; - using VARIANT v5 = new() - { - vt = VT_I4, - data = new() - { - llVal = 5 - } - }; - using VARIANT v6 = new() - { - vt = VT_I4, - data = new() - { - llVal = 6 - } - }; - - var result = new VARIANT[2, 3] - { - { v1, v2, v3 }, - { v4, v5, v6 } - }; - SAFEARRAY* psa = CreateSafeArray(VT_VARIANT, result); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_VARIANT, - data = new() - { - parray = psa - } - }; - AssertToObject(variant, value => - { - Array array = (Array)value; - Assert.IsType(typeof(object).MakeArrayType(2), array); - Assert.Equal(2, array.Rank); - Assert.Equal(0, array.GetLowerBound(0)); - Assert.Equal(0, array.GetLowerBound(1)); - Assert.Equal(result.GetLength(0), array.GetLength(0)); - Assert.Equal(result.GetLength(1), array.GetLength(1)); - Assert.Equal(new object[,] - { - { 1, 2, 3 }, - { 4, 5, 6 } - }, array); - }); - } - - [StaTheory] - [InlineData((ushort)VT_I1)] - [InlineData((ushort)VT_UI1)] - [InlineData((ushort)VT_I2)] - [InlineData((ushort)VT_UI2)] - [InlineData((ushort)VT_I4)] - [InlineData((ushort)VT_UI4)] - [InlineData((ushort)VT_I8)] - [InlineData((ushort)VT_UI8)] - [InlineData((ushort)VT_BSTR)] - [InlineData((ushort)VT_LPWSTR)] - [InlineData((ushort)VT_LPSTR)] - [InlineData((ushort)VT_UNKNOWN)] - [InlineData((ushort)VT_DISPATCH)] - [InlineData((ushort)VT_EMPTY)] - [InlineData((ushort)VT_NULL)] - [InlineData((ushort)VT_CF)] - [InlineData((ushort)VT_VOID)] - [InlineData((ushort)VT_PTR)] - [InlineData((ushort)VT_SAFEARRAY)] - [InlineData((ushort)VT_CARRAY)] - [InlineData((ushort)VT_RECORD)] - [InlineData((ushort)VT_BLOB)] - [InlineData((ushort)VT_STREAM)] - [InlineData((ushort)VT_STORAGE)] - [InlineData((ushort)VT_STREAMED_OBJECT)] - [InlineData((ushort)VT_STORED_OBJECT)] - [InlineData((ushort)VT_BLOB_OBJECT)] - public void VARIANT_ToObject_ARRAYNoData_ReturnsExpected(ushort vt) - { - SAFEARRAY* psa = CreateSafeArray(VT_I1, Array.Empty()); - using VARIANT variant = new() - { - vt = VT_ARRAY | (VARENUM)vt - }; - AssertToObjectEqual(null, variant); - } - - [StaTheory] - [InlineData(128)] - [InlineData(129)] - [InlineData((ushort)VT_BSTR_BLOB)] - public void VARIANT_ToObject_ARRAYInvalidTypeNoData_ThrowsInvalidOleVariantTypeException(ushort vt) - { - SAFEARRAY* psa = CreateSafeArray(VT_I1, Array.Empty()); - using VARIANT variant = new() - { - vt = VT_ARRAY | (VARENUM)vt - }; - AssertToObjectThrows(variant); - } - - [StaFact] - public void VARIANT_ToObject_ARRAYVECTOR_ThrowsInvalidOleVariantTypeException() - { - SAFEARRAY* psa = CreateSafeArray(VT_I1, Array.Empty()); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_VECTOR | VT_I4 - }; - Assert.Throws(() => variant.ToObject()); - } - - [StaFact] - public void VARIANT_ToObject_ARRAYTypeEMPTY_ThrowsInvalidOleVariantTypeException() - { - SAFEARRAY* psa = CreateSafeArray(VT_I1, Array.Empty()); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_EMPTY, - data = new() - { - parray = psa - } - }; - AssertToObjectThrows(variant); - } - - [StaTheory] - [InlineData((ushort)VT_I1, (ushort)VT_UI1)] - [InlineData((ushort)VT_UI1, (ushort)VT_I1)] - [InlineData((ushort)VT_I2, (ushort)VT_UI2)] - [InlineData((ushort)VT_UI2, (ushort)VT_I2)] - [InlineData((ushort)VT_I4, (ushort)VT_UI4)] - [InlineData((ushort)VT_UI4, (ushort)VT_I4)] - [InlineData((ushort)VT_INT, (ushort)VT_UINT)] - [InlineData((ushort)VT_INT, (ushort)VT_I2)] - [InlineData((ushort)VT_INT, (ushort)VT_I8)] - [InlineData((ushort)VT_UINT, (ushort)VT_INT)] - [InlineData((ushort)VT_UINT, (ushort)VT_UI2)] - [InlineData((ushort)VT_UINT, (ushort)VT_UI8)] - [InlineData((ushort)VT_I8, (ushort)VT_UI8)] - [InlineData((ushort)VT_UI8, (ushort)VT_I8)] - [InlineData((ushort)VT_UNKNOWN, (ushort)VT_DISPATCH)] - [InlineData((ushort)VT_UNKNOWN, (ushort)VT_I4)] - [InlineData((ushort)VT_UNKNOWN, (ushort)VT_UI4)] - [InlineData((ushort)VT_UNKNOWN, (ushort)VT_I8)] - [InlineData((ushort)VT_UNKNOWN, (ushort)VT_UI8)] - [InlineData((ushort)VT_DISPATCH, (ushort)VT_I4)] - [InlineData((ushort)VT_DISPATCH, (ushort)VT_UI4)] - [InlineData((ushort)VT_DISPATCH, (ushort)VT_I8)] - [InlineData((ushort)VT_DISPATCH, (ushort)VT_UI8)] - public void VARIANT_ToObject_ARRAYTypeDifferent_ThrowsSafeArrayTypeMismatchException(ushort arrayVt, ushort vt) - { - SAFEARRAY* psa = CreateSafeArray((VARENUM)arrayVt, Array.Empty()); - using VARIANT variant = new() - { - vt = VT_ARRAY | (VARENUM)vt, - data = new() - { - parray = psa - } - }; - AssertToObjectThrows(variant); - } - - [StaTheory] - [InlineData((ushort)VT_INT_PTR)] - [InlineData((ushort)VT_UINT_PTR)] - public void VARIANT_ToObject_ARRAYTypeInvalid_ThrowsArgumentException(ushort vt) - { - SAFEARRAY* psa = CreateSafeArray((VARENUM)vt, Array.Empty()); - using VARIANT variant = new() - { - vt = VT_ARRAY | (VARENUM)vt, - data = new() - { - parray = psa - } - }; - AssertToObjectThrows(variant); - } - - [StaTheory] - [InlineData(33)] - [InlineData(255)] - [InlineData(256)] - [InlineData(512)] - public void VARIANT_ARRAYBigRank_ThrowsTypeLoadException(int rank) - { - SAFEARRAYBOUND* saBounds = stackalloc SAFEARRAYBOUND[rank]; - for (uint i = 0; i < rank; i++) - { - saBounds[i] = new SAFEARRAYBOUND - { - cElements = 0, - lLbound = 0 - }; - } - - SAFEARRAY* psa = PInvoke.SafeArrayCreate(VT_I4, (uint)rank, saBounds); - using VARIANT variant = new() - { - vt = VT_ARRAY | VT_I4, - data = new() - { - parray = psa - } - }; - AssertToObjectThrows(variant); - } - - private static unsafe SAFEARRAY* CreateSafeArray(VARENUM vt, T[] result, int lbound = 0) where T : unmanaged - { - var saBound = new SAFEARRAYBOUND - { - cElements = (uint)result.Length, - lLbound = lbound - }; - SAFEARRAY* psa = PInvoke.SafeArrayCreate(vt, 1, &saBound); - Assert.True(psa != null); - - VARENUM arrayVt = VT_EMPTY; - HRESULT hr = PInvoke.SafeArrayGetVartype(psa, &arrayVt); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(vt, arrayVt); - - for (int i = 0; i < result.Length; i++) - { - T value = result[i]; - int index = i + lbound; - // Insert pointers directly. - if (value is IntPtr valuePtr) - { - hr = PInvoke.SafeArrayPutElement(psa, &index, (void*)valuePtr); - } - else - { - hr = PInvoke.SafeArrayPutElement(psa, &index, &value); - } - - Assert.Equal(HRESULT.S_OK, hr); - } - - return psa; - } - - private unsafe SAFEARRAY* CreateSafeArray(VARENUM vt, T[,] multiDimArray, int lbound1 = 0, int lbound2 = 0) where T : unmanaged - { - SAFEARRAYBOUND* saBounds = stackalloc SAFEARRAYBOUND[2]; - saBounds[0] = new SAFEARRAYBOUND - { - cElements = (uint)multiDimArray.GetLength(0), - lLbound = lbound1 - }; - saBounds[1] = new SAFEARRAYBOUND - { - cElements = (uint)multiDimArray.GetLength(1), - lLbound = lbound2 - }; - SAFEARRAY* psa = PInvoke.SafeArrayCreate(vt, 2, saBounds); - Assert.True(psa != null); - - VARENUM arrayVt = VT_EMPTY; - HRESULT hr = PInvoke.SafeArrayGetVartype(psa, &arrayVt); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(vt, arrayVt); - - for (int i = 0; i < multiDimArray.GetLength(0); i++) - { - for (int j = 0; j < multiDimArray.GetLength(1); j++) - { - int* indices = stackalloc int[] { i + lbound1, j + lbound2 }; - T value = multiDimArray[i, j]; - // Insert pointers directly. - if (value is IntPtr valuePtr) - { - hr = PInvoke.SafeArrayPutElement(psa, indices, (void*)valuePtr); - } - else - { - hr = PInvoke.SafeArrayPutElement(psa, indices, &value); - } - - Assert.Equal(HRESULT.S_OK, hr); - } - } - - return psa; - } - - [StaFact] - public void ToObject_RECORDRecordData_ReturnsExpected() - { - int record = 1; - IntPtr mem = Marshal.AllocCoTaskMem(sizeof(int)); - (*(int*)mem) = record; - CustomRecordInfo recordInfo = new() - { - GetGuidAction = () => (typeof(int).GUID, HRESULT.S_OK) - }; - - using VARIANT variant = new() { vt = VT_RECORD }; - variant.data.Anonymous.pRecInfo = recordInfo.GetComInterface(); - variant.data.Anonymous.pvRecord = mem.ToPointer(); - - // Records actually don't work in .NET Core... -#if false - AssertToObjectEqual(1, variant); -#else - AssertToObjectThrows(variant); -#endif - } - - [StaFact] - public void ToObject_RECORDNullRecordData_ReturnsNull() - { - CustomRecordInfo recordInfo = new(); - using VARIANT variant = new() { vt = VT_RECORD }; - variant.data.Anonymous.pRecInfo = recordInfo.GetComInterface(); - AssertToObjectEqual(null, variant); - } - - [StaFact] - public void ToObject_RECORDNullRecordInfo_ThrowsArgumentException() - { - int record = 1; - IntPtr mem = Marshal.AllocCoTaskMem(sizeof(int)); - (*(int*)mem) = record; - - using VARIANT variant = new() { vt = VT_RECORD }; - variant.data.Anonymous.pvRecord = mem.ToPointer(); - AssertToObjectThrows(variant); - } - - [StaFact] - public void ToObject_RECORDInvalidGetGuidHRData_ThrowsArgumentException() - { - int record = 1; - IntPtr mem = Marshal.AllocCoTaskMem(sizeof(int)); - (*(int*)mem) = record; - - CustomRecordInfo recordInfo = new() - { - GetGuidAction = () => (Guid.Empty, HRESULT.DISP_E_DIVBYZERO) - }; - - using VARIANT variant = new() { vt = VT_RECORD }; - variant.data.Anonymous.pRecInfo = recordInfo.GetComInterface(); - variant.data.Anonymous.pvRecord = mem.ToPointer(); - - // Records actually don't work in .NET Core... -#if false - AssertToObjectThrows(variant); -#endif - } - - [StaFact] - public void ToObject_RECORDInvalidGetGuidHRNoData_ReturnsNull() - { - CustomRecordInfo recordInfo = new() - { - GetGuidAction = () => (Guid.Empty, HRESULT.DISP_E_DIVBYZERO) - }; - - using VARIANT variant = new() { vt = VT_RECORD }; - variant.data.Anonymous.pRecInfo = recordInfo.GetComInterface(); - AssertToObjectEqual(null, variant); - } - - public static IEnumerable RECORD_TestData() - { - yield return new object[] { Guid.Empty }; - yield return new object[] { new Guid("8856f961-340a-11d0-a96b-00c04fd705a2") }; - } - - [StaTheory] - [MemberData(nameof(RECORD_TestData))] - public void ToObject_RECORDInvalidGuidData_ThrowsArgumentException(Guid guid) - { - int record = 1; - IntPtr mem = Marshal.AllocCoTaskMem(sizeof(int)); - (*(int*)mem) = record; - - CustomRecordInfo recordInfo = new CustomRecordInfo - { - GetGuidAction = () => (guid, HRESULT.S_OK) - }; - - using VARIANT variant = new() { vt = VT_RECORD }; - variant.data.Anonymous.pRecInfo = recordInfo.GetComInterface(); - variant.data.Anonymous.pvRecord = mem.ToPointer(); - - AssertToObjectThrows(variant); - } - - [StaTheory] - [MemberData(nameof(RECORD_TestData))] - public void ToObject_RECORDInvalidGuidNoData_ReturnsNull(Guid guid) - { - CustomRecordInfo recordInfo = new() - { - GetGuidAction = () => (guid, HRESULT.S_OK) - }; - - using VARIANT variant = new() { vt = VT_RECORD }; - variant.data.Anonymous.pRecInfo = recordInfo.GetComInterface(); - AssertToObjectEqual(null, variant); - } - - [StaFact] - public void ToObject_RECORDARRAYValid_ReturnsExpected() - { - var result = new int[] { 1, 2 }; - CustomRecordInfo recordInfo = new() - { - GetGuidAction = () => (typeof(int).GUID, HRESULT.S_OK) - }; - - using ComScope pRecordInfo = new(recordInfo.GetComInterface()); - using VARIANT variant = new() { vt = VT_ARRAY | VT_RECORD }; - variant.data.parray = CreateRecordSafeArray(result, pRecordInfo); - - // Records actually don't work in .NET Core... -#if false - AssertToObjectEqual(new int[] { 0, 0 }, variant); -#endif - } - - [StaFact] - public void ToObject_RECORDARRAYInvalidFFeatures_ThrowsArgumentException() - { - var result = new int[] { 1, 2 }; - CustomRecordInfo recordInfo = new(); - using ComScope pRecordInfo = new(recordInfo.GetComInterface()); - SAFEARRAY* psa = CreateRecordSafeArray(result, pRecordInfo); - psa->fFeatures &= ~FADF_RECORD; - try - { - using VARIANT variant = new() { vt = VT_ARRAY | VT_RECORD }; - variant.data.parray = psa; - AssertToObjectThrows(variant); - } - finally - { - // Make sure disposal works. - psa->fFeatures |= FADF_RECORD; - } - } - - [StaFact] - public void ToObject_RECORDARRAYInvalidGetGuidHR_ThrowsArgumentException() - { - var result = new int[] { 1, 2 }; - CustomRecordInfo record = new() - { - GetGuidAction = () => (Guid.Empty, HRESULT.DISP_E_DIVBYZERO) - }; - - using ComScope pRecordInfo = new(record.GetComInterface()); - using VARIANT variant = new() { vt = VT_ARRAY | VT_RECORD }; - variant.data.parray = CreateRecordSafeArray(result, pRecordInfo); - - VARIANT copy = variant; - IntPtr pv = (IntPtr)(©); - Assert.Throws(() => Marshal.GetObjectForNativeVariant(pv)); - Assert.Throws(() => variant.ToObject()); - } - - public static IEnumerable RECORDARRAY_InvalidGuid_TestData() - { - yield return new object[] { Guid.Empty }; - yield return new object[] { new Guid("8856f961-340a-11d0-a96b-00c04fd705a2") }; - } - - [StaTheory] - [MemberData(nameof(RECORDARRAY_InvalidGuid_TestData))] - public void ToObject_RECORDARRAY_InvokeInvalidGuid_ThrowsArgumentException(Guid guid) - { - var result = new int[] { 1, 2 }; - CustomRecordInfo record = new() - { - GetGuidAction = () => (guid, HRESULT.S_OK) - }; - - using ComScope pRecordInfo = new(record.GetComInterface()); - using VARIANT variant = new() { vt = VT_ARRAY | VT_RECORD }; - variant.data.parray = CreateRecordSafeArray(result, pRecordInfo); - AssertToObjectThrows(variant); - } - - private class CustomRecordInfo : IRecordInfo.Interface - { - public IRecordInfo* GetComInterface() => (IRecordInfo*)Marshal.GetComInterfaceForObject(this); - - public HRESULT RecordInit(void* pvNew) => throw new NotImplementedException(); - - public HRESULT RecordClear(void* pvExisting) => throw new NotImplementedException(); - - public HRESULT RecordCopy(void* pvExisting, void* pvNew) => throw new NotImplementedException(); - - public Func<(Guid, HRESULT)> GetGuidAction { get; set; } - - public HRESULT GetGuid(Guid* pguid) - { - (Guid guid, HRESULT hr) = GetGuidAction(); - *pguid = guid; - return hr; - } - - public HRESULT GetName(BSTR* pbstrName) => throw new NotImplementedException(); - - public HRESULT GetSize(uint* pcbSize) - { - *pcbSize = (uint)sizeof(int); - return HRESULT.S_OK; - } - - public HRESULT GetTypeInfo(ITypeInfo** ppTypeInfo) => throw new NotImplementedException(); - - public HRESULT GetField(void* pvData, PCWSTR szFieldName, VARIANT* pvarField) => throw new NotImplementedException(); - - public HRESULT GetFieldNoCopy(void* pvData, PCWSTR szFieldName, VARIANT* pvarField, void** ppvDataCArray) => throw new NotImplementedException(); - - public HRESULT PutField(uint wFlags, void* pvData, PCWSTR szFieldName, VARIANT* pvarField) => throw new NotImplementedException(); - - public HRESULT PutFieldNoCopy(uint wFlags, void* pvData, PCWSTR szFieldName, VARIANT* pvarField) => throw new NotImplementedException(); - - public HRESULT GetFieldNames(uint* pcNames, BSTR* rgBstrNames) => throw new NotImplementedException(); - - public BOOL IsMatchingType(IRecordInfo* pRecordInfoInfo) => throw new NotImplementedException(); - - public void* RecordCreate() => throw new NotImplementedException(); - - public HRESULT RecordCreateCopy(void* pvSource, void** ppvDest) => throw new NotImplementedException(); - - public HRESULT RecordDestroy(void* pvRecord) => throw new NotImplementedException(); - } - - private static SAFEARRAY* CreateRecordSafeArray(T[] result, IRecordInfo* recordInfo, int lbound = 0) - { - var saBound = new SAFEARRAYBOUND - { - cElements = (uint)result.Length, - lLbound = lbound - }; - SAFEARRAY* psa = PInvoke.SafeArrayCreateEx(VT_RECORD, 1, &saBound, recordInfo); - Assert.True(psa != null); - - VARENUM arrayVt = VT_EMPTY; - HRESULT hr = PInvoke.SafeArrayGetVartype(psa, &arrayVt); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VT_RECORD, arrayVt); - - return psa; - } - - private static void AssertToObjectThrows(VARIANT variant) where T : Exception - { - VARIANT copy = variant; - IntPtr pv = (IntPtr)(©); - Assert.Throws(() => Marshal.GetObjectForNativeVariant(pv)); - - Assert.Throws(() => variant.ToObject()); - } - - private static void AssertToObjectEqual(object expected, VARIANT variant) - => AssertToObject(variant, actual => Assert.Equal(expected, actual)); - - private static void AssertToObjectEqualExtension(object expected, VARIANT variant) where T : Exception - { - // Not supported type. - VARIANT copy = variant; - IntPtr pv = (IntPtr)(©); - Assert.Throws(() => Marshal.GetObjectForNativeVariant(pv)); - - Assert.Equal(expected, variant.ToObject()); - } - - private static void AssertToObject(VARIANT variant, Action action) - { - IntPtr pv = (IntPtr)(&variant); - action(Marshal.GetObjectForNativeVariant(pv)); - - action(variant.ToObject()); - } - - [Fact] - public void MarshallingFromExchangeTypes() - { - // These are the common TypeConverter types we're using. - - using (VARIANT variant = new()) - { - byte[] bytes = { 1, 2, 3 }; - Marshal.GetNativeVariantForObject(bytes, (nint)(void*)&variant); - Assert.Equal(VT_UI1 | VT_ARRAY, variant.vt); - } - - using (VARIANT variant = new()) - { - string value = "Testing"; - Marshal.GetNativeVariantForObject(value, (nint)(void*)&variant); - Assert.Equal(VT_BSTR, variant.vt); - } - } - - [Fact] - public void MarshallingFromIntAndUint() - { - // Interop marshals as VT_I4/VT_UI4 and not VT_INT/VT_UINT - VARIANT variant = new(); - int intValue = 42; - Marshal.GetNativeVariantForObject(intValue, (nint)(void*)&variant); - variant.vt.Should().Be(VT_I4); - uint uintValue = 42; - Marshal.GetNativeVariantForObject(uintValue, (nint)(void*)&variant); - variant.vt.Should().Be(VT_UI4); - } - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromCLSID(Guid* clsid, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromFileTime(PInvoke.FILETIME* pftIn, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitVariantFromFileTime(PInvoke.FILETIME* pftIn, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromBuffer(void* pv, uint cb, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromInt16Vector(void* pv, uint cb, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromUInt16Vector(void* pv, uint cb, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromBooleanVector(void* pv, uint cb, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromInt32Vector(void* pv, uint cb, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromUInt32Vector(void* pv, uint cb, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromInt64Vector(void* pv, uint cb, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromUInt64Vector(void* pv, uint cb, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromDoubleVector(void* pv, uint cb, VARIANT* ppropvar); - - [DllImport(Libraries.Propsys, ExactSpelling = true)] - private static extern unsafe HRESULT InitPropVariantFromFileTimeVector(void* pv, uint cb, VARIANT* ppropvar); - - [DllImport(Libraries.Oleaut32, ExactSpelling = true)] - private static extern HRESULT VarDecFromI8(long i64In, out DECIMAL pdecOut); - - [DllImport(Libraries.Oleaut32, ExactSpelling = true)] - private static extern HRESULT VarDecFromR8(double dblIn, out DECIMAL pdecOut); -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/PARAMTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/PARAMTests.cs deleted file mode 100644 index a9a2924539c..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/PARAMTests.cs +++ /dev/null @@ -1,124 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using static Interop; - -namespace System.Windows.Forms.Primitives.Tests.Interop; - -public class PARAMTests -{ - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void FromLowHigh_x32_Result() - { - Assert.Equal((int)0x03040102, (int)PARAM.FromLowHigh(0x0102, 0x0304)); - Assert.Equal(unchecked((int)0xF3F4F1F2), (int)PARAM.FromLowHigh(0xF1F2, 0xF3F4)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void FromLowHigh_x64_Result() - { - Assert.Equal((long)0x0000000003040102, (long)PARAM.FromLowHigh(0x0102, 0x0304)); - Assert.Equal(unchecked((long)0xFFFFFFFFF3F4F1F2), (long)PARAM.FromLowHigh(0xF1F2, 0xF3F4)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void FromLowHighUnsigned_x32_Result() - { - Assert.Equal((int)0x03040102, (int)PARAM.FromLowHighUnsigned(0x0102, 0x0304)); - Assert.Equal(unchecked((int)0xF3F4F1F2), (int)PARAM.FromLowHighUnsigned(0xF1F2, 0xF3F4)); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void FromLowHighUnsigned_x64_Result() - { - if (Environment.Is64BitProcess) - { - Assert.Equal((long)0x0000000003040102, (long)PARAM.FromLowHighUnsigned(0x0102, 0x0304)); - Assert.Equal((long)0x00000000F3F4F1F2, (long)PARAM.FromLowHighUnsigned(0xF1F2, 0xF3F4)); - } - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void LOWORD_x32_Result() - { - Assert.Equal(0x0304, PARAM.LOWORD((nint)0x01020304)); - Assert.Equal(0xF3F4, PARAM.LOWORD(unchecked((nint)0xF1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void LOWORD_x64_Result() - { - Assert.Equal(0x0304, PARAM.LOWORD(unchecked((nint)0x0506070801020304))); - Assert.Equal(0xF3F4, PARAM.LOWORD(unchecked((nint)0xF5F6F7F8F1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void HIWORD_x32_Result() - { - Assert.Equal(0x0102, PARAM.HIWORD((nint)0x01020304)); - Assert.Equal(0xF1F2, PARAM.HIWORD(unchecked((nint)0xF1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void HIWORD_x64_Result() - { - Assert.Equal(0x0102, PARAM.HIWORD(unchecked((nint)0x0506070801020304))); - Assert.Equal(0xF1F2, PARAM.HIWORD(unchecked((nint)0xF5F6F7F8F1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void SignedLOWORD_x32_Result() - { - Assert.Equal((short)0x0304, PARAM.SignedLOWORD((nint)0x01020304)); - Assert.Equal(unchecked((short)0xF3F4), PARAM.SignedLOWORD(unchecked((nint)0xF1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void SignedLOWORD_x64_Result() - { - Assert.Equal((short)0x0304, PARAM.SignedLOWORD(unchecked((nint)0x0506070801020304))); - Assert.Equal(unchecked((short)0xF3F4), PARAM.SignedLOWORD(unchecked((nint)0xF5F6F7F8F1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void SignedHIWORD_x32_Result() - { - Assert.Equal((short)0x0102, PARAM.SignedHIWORD((nint)0x01020304)); - Assert.Equal(unchecked((short)0xF1F2), PARAM.SignedHIWORD(unchecked((nint)0xF1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void SignedHIWORD_x64_Result() - { - Assert.Equal((short)0x0102, PARAM.SignedHIWORD(unchecked((nint)0x0506070801020304))); - Assert.Equal(unchecked((short)0xF1F2), PARAM.SignedHIWORD(unchecked((nint)0xF5F6F7F8F1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void ToInt_x32_Result() - { - Assert.Equal((int)0x01020304, PARAM.ToInt((nint)0x01020304)); - Assert.Equal(unchecked((int)0xF1F2F3F4), PARAM.ToInt(unchecked((nint)0xF1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void ToInt_x64_Result() - { - Assert.Equal((int)0x01020304, PARAM.ToInt(unchecked((nint)0x0506070801020304))); - Assert.Equal(unchecked((int)0xF1F2F3F4), PARAM.ToInt(unchecked((nint)0xF5F6F7F8F1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is32bit))] - public unsafe void ToUInt_x32_Result() - { - Assert.Equal((uint)0x01020304, PARAM.ToUInt((nint)0x01020304)); - Assert.Equal((uint)0xF1F2F3F4, PARAM.ToUInt(unchecked((nint)0xF1F2F3F4))); - } - - [ConditionalFact(typeof(ArchitectureDetection), nameof(ArchitectureDetection.Is64bit))] - public unsafe void ToUInt_x64_Result() - { - Assert.Equal((uint)0x01020304, PARAM.ToUInt(unchecked((nint)0x0506070801020304))); - Assert.Equal((uint)0xF1F2F3F4, PARAM.ToUInt(unchecked((nint)0xF5F6F7F8F1F2F3F4))); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Richedit/CHARFORMAT2WTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Richedit/CHARFORMAT2WTests.cs deleted file mode 100644 index 96b70a5fb31..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Richedit/CHARFORMAT2WTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using static Interop.Richedit; - -namespace System.Windows.Forms.Tests.Interop.Richedit; - -// NB: doesn't require thread affinity -public class CHARFORMAT2WTests -{ - [Fact] - public unsafe void CharFormat_Size() - { - Assert.Equal(116, sizeof(CHARFORMAT2W)); - } - - [Fact] - public unsafe void CharFormat_FaceName() - { - CHARFORMAT2W charFormat = default; - charFormat.FaceName = "TwoFace"; - Assert.Equal("TwoFace", charFormat.FaceName.ToString()); - - // Set a smaller name to make sure it gets terminated properly. - charFormat.FaceName = "Face"; - Assert.Equal("Face", charFormat.FaceName.ToString()); - - // CHARFORMAT has space for 32 characters, we want to see it gets - // cut to 31 to make room for the null. - string bigString = new('*', 32); - - charFormat.FaceName = bigString; - Assert.True(charFormat.FaceName.SequenceEqual(bigString.AsSpan().Slice(1))); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Richedit/EDITSTREAMTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Richedit/EDITSTREAMTests.cs deleted file mode 100644 index cbf0783375e..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Richedit/EDITSTREAMTests.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using static Interop.Richedit; - -namespace System.Windows.Forms.Tests.Interop.Richedit; - -public class EDITSTREAMTests -{ - [Fact] - public unsafe void EditStream_Size_Get_ReturnsExpected() - { - if (IntPtr.Size == 4) - { - Assert.Equal(12, sizeof(EDITSTREAM)); - } - else - { - Assert.Equal(20, sizeof(EDITSTREAM)); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Shell32/ShellItemTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Shell32/ShellItemTests.cs deleted file mode 100644 index b928c0d1c86..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/Shell32/ShellItemTests.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using Windows.Win32.UI.Shell.Common; - -namespace System.Windows.Forms.Tests.Interop.Shell32Tests; - -public class ShellItemTests -{ - [Fact] - public unsafe void SHParseDisplayName_ValidPath() - { - string path = Path.GetTempPath(); - uint rgflnOut = default; - HRESULT result = PInvoke.SHParseDisplayName(path, pbc: null, out ITEMIDLIST* ppidl, 0, &rgflnOut); - try - { - Assert.Equal(HRESULT.S_OK, result); - Assert.NotEqual(0, (nint)ppidl); - } - finally - { - if (ppidl is not null) - { - Marshal.FreeCoTaskMem((nint)ppidl); - } - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/User32/GetWindowTextTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/User32/GetWindowTextTests.cs deleted file mode 100644 index 52452706fef..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/User32/GetWindowTextTests.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Primitives.Tests.Interop.User32; - -public class GetWindowTextTests -{ - [StaFact] - public void GetWindowText_DoesNotTruncateText() - { - CallGetWindowText(useBeforeGetTextLengthCallback: false); - } - - [StaFact] - public void GetWindowText_DoesNotLoopInfinitely() - { - CallGetWindowText(useBeforeGetTextLengthCallback: true); - } - - private void CallGetWindowText(bool useBeforeGetTextLengthCallback) - { - const string shortText = "A"; - - // Use a long string that exceeds the initial buffer size (16). - string longText = new('X', 50); - - var windowClass = new ChangeWindowTextClass(); - windowClass.Register(); - HWND windowHandle = (HWND)windowClass.CreateWindow(shortText); - - windowClass.BeforeGetTextCallback = () => longText; - if (useBeforeGetTextLengthCallback) - { - windowClass.BeforeGetTextLengthCallback = () => shortText; - } - - string result = PInvoke.GetWindowText(windowHandle); - PInvoke.DestroyWindow(windowHandle); - - Assert.Equal(longText, result); - } - - private class ChangeWindowTextClass : WindowClass - { - public Func? BeforeGetTextLengthCallback - { - get; - set; - } - - public Func? BeforeGetTextCallback - { - get; - set; - } - - protected override LRESULT WNDPROC(HWND hWnd, MessageId msg, WPARAM wParam, LPARAM lParam) - { - switch (msg) - { - case PInvoke.WM_GETTEXTLENGTH: - string? text = BeforeGetTextLengthCallback?.Invoke(); - if (text is not null) - { - PInvoke.SetWindowText(hWnd, text); - } - - break; - case PInvoke.WM_GETTEXT: - text = BeforeGetTextCallback?.Invoke(); - if (text is not null) - { - PInvoke.SetWindowText(hWnd, text); - } - - break; - } - - return base.WNDPROC(hWnd, msg, wParam, lParam); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/User32/LOGFONTWTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/User32/LOGFONTWTests.cs deleted file mode 100644 index cb3dc932d32..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/User32/LOGFONTWTests.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Primitives.Tests.Interop.User32; - -public class LOGFONTWTests -{ - [Fact] - public unsafe void LogFont_Size() - { - Assert.Equal(92, sizeof(LOGFONTW)); - } - - [Fact] - public unsafe void LogFont_FaceName() - { - LOGFONTW logFont = default; - logFont.FaceName = "TwoFace"; - Assert.Equal("TwoFace", logFont.FaceName.ToString()); - - // Set a smaller name to make sure it gets terminated properly. - logFont.FaceName = "Face"; - Assert.Equal("Face", logFont.FaceName.ToString()); - - // LOGFONT has space for 32 characters, we want to see it gets - // cut to 31 to make room for the null. - string bigString = new('*', 32); - - logFont.FaceName = bigString; - Assert.True(logFont.FaceName.SequenceEqual(bigString.AsSpan().Slice(1))); - } - - [Fact] - public unsafe void CreateFontIndirect() - { - LOGFONTW logFont = default; - HFONT handle = PInvoke.CreateFontIndirect(&logFont); - Assert.False(handle.IsNull); - Assert.True(PInvoke.DeleteObject(handle)); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/User32/SystemParametersInfoWTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/User32/SystemParametersInfoWTests.cs deleted file mode 100644 index 2e06516a80c..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Interop/User32/SystemParametersInfoWTests.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; - -namespace System.Windows.Forms.Primitives.Tests.Interop.User32; - -public class SystemParametersInfoWTests -{ - [Fact] - public void SystemParametersInfoW_check_fonts() - { - NONCLIENTMETRICSW data = default; - - bool result = PInvoke.SystemParametersInfo(ref data); - Assert.True(result); - - Font captionFont = Font.FromLogFont(data.lfCaptionFont); - AreEqual(SystemFonts.CaptionFont!, captionFont); - - Font menuFont = Font.FromLogFont(data.lfMenuFont); - AreEqual(SystemFonts.CaptionFont!, menuFont); - - Font messageFont = Font.FromLogFont(data.lfMessageFont); - AreEqual(SystemFonts.MessageBoxFont!, messageFont); - - Font smCaptionFont = Font.FromLogFont(data.lfSmCaptionFont); - AreEqual(SystemFonts.SmallCaptionFont!, smCaptionFont); - - Font statusFont = Font.FromLogFont(data.lfStatusFont); - AreEqual(SystemFonts.StatusFont!, statusFont); - - static void AreEqual(Font expected, Font actual) - { - Assert.Equal(expected.Name, actual.Name); - Assert.Equal(expected.SizeInPoints, actual.SizeInPoints); - Assert.Equal(expected.GdiCharSet, actual.GdiCharSet); - Assert.Equal(expected.Style, actual.Style); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Properties/launchSettings.json b/src/System.Windows.Forms.Primitives/tests/UnitTests/Properties/launchSettings.json deleted file mode 100644 index 0fc24c85f30..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "System.Windows.Forms.Primitives.Tests": { - "commandName": "Project", - "nativeDebugging": true - } - } -} \ No newline at end of file diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System.Windows.Forms.Primitives.Tests.csproj b/src/System.Windows.Forms.Primitives/tests/UnitTests/System.Windows.Forms.Primitives.Tests.csproj deleted file mode 100644 index 404fa8ed4f8..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System.Windows.Forms.Primitives.Tests.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - $(TargetFramework)-windows7.0 - true - System.Windows.Forms.Primitives.Tests - true - $(NoWarn);618 - $(NoWarn);IDE0090 - enable - true - - - - - - - - - - - - - - diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/BufferScopeTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/BufferScopeTests.cs deleted file mode 100644 index 8b7311c019a..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/BufferScopeTests.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Tests; - -public unsafe class BufferScopeTests -{ - [Fact] - public void Construct_WithStackAlloc() - { - using BufferScope buffer = new(stackalloc char[10]); - Assert.Equal(10, buffer.Length); - buffer[0] = 'Y'; - Assert.Equal("Y", buffer[..1].ToString()); - } - - [Fact] - public void Construct_WithStackAlloc_GrowAndCopy() - { - using BufferScope buffer = new(stackalloc char[10]); - Assert.Equal(10, buffer.Length); - buffer[0] = 'Y'; - buffer.EnsureCapacity(64, copy: true); - Assert.True(buffer.Length >= 64); - Assert.Equal("Y", buffer[..1].ToString()); - } - - [Fact] - public void Construct_WithStackAlloc_Pin() - { - using BufferScope buffer = new(stackalloc char[10]); - Assert.Equal(10, buffer.Length); - buffer[0] = 'Y'; - fixed (char* c = buffer) - { - Assert.Equal('Y', *c); - *c = 'Z'; - } - - Assert.Equal("Z", buffer[..1].ToString()); - } - - [Fact] - public void Construct_GrowAndCopy() - { - using BufferScope buffer = new(32); - Assert.True(buffer.Length >= 32); - buffer[0] = 'Y'; - buffer.EnsureCapacity(64, copy: true); - Assert.True(buffer.Length >= 64); - Assert.Equal("Y", buffer[..1].ToString()); - } - - [Fact] - public void Construct_Pin() - { - using BufferScope buffer = new(64); - Assert.True(buffer.Length >= 64); - buffer[0] = 'Y'; - fixed (char* c = buffer) - { - Assert.Equal('Y', *c); - *c = 'Z'; - } - - Assert.Equal("Z", buffer[..1].ToString()); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Automation/TestAccessors.UiaTextRangeTestAccessor.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Automation/TestAccessors.UiaTextRangeTestAccessor.cs deleted file mode 100644 index 770a1742f73..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Automation/TestAccessors.UiaTextRangeTestAccessor.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms.Automation; - -namespace System; - -public static partial class TestAccessors -{ - internal class UiaTextRangeTestAccessor : TestAccessor - { - // Accessor for static members - private static readonly dynamic Static = typeof(UiaTextRange).TestAccessor().Dynamic; - - public UiaTextRangeTestAccessor(UiaTextRange instance) - : base(instance) { } - - public int _start - { - get => Dynamic._start; - set => Dynamic._start = value; - } - - public int _end - { - get => Dynamic._end; - set => Dynamic._end = value; - } - - public UiaTextProvider _provider => Dynamic._provider; - - public CapStyle GetCapStyle(WINDOW_STYLE windowStyle) => Dynamic.GetCapStyle(windowStyle); - - public double GetFontSize(LOGFONTW logfont) => Dynamic.GetFontSize(logfont); - - public HorizontalTextAlignment GetHorizontalTextAlignment(WINDOW_STYLE windowStyle) - => Dynamic.GetHorizontalTextAlignment(windowStyle); - - public bool GetReadOnly() => Dynamic.GetReadOnly(); - - public void MoveTo(int start, int end) => Dynamic.MoveTo(start, end); - - public void ValidateEndpoints() => Dynamic.ValidateEndpoints(); - - public bool AtParagraphBoundary(string text, int index) => Static.AtParagraphBoundary(text, index); - - public bool AtWordBoundary(string text, int index) => Static.AtWordBoundary(text, index); - - public COLORREF GetBackgroundColor() => Static.GetBackgroundColor(); - - public string GetFontName(LOGFONTW logfont) => Static.GetFontName(logfont); - - public bool IsApostrophe(char ch) => Static.IsApostrophe(ch); - - public FW GetFontWeight(LOGFONTW logfont) => Static.GetFontWeight(logfont); - - public COLORREF GetForegroundColor() => Static.GetForegroundColor(); - - public bool GetItalic(LOGFONTW logfont) => Static.GetItalic(logfont); - - public TextDecorationLineStyle GetStrikethroughStyle(LOGFONTW logfont) => Static.GetStrikethroughStyle(logfont); - - public TextDecorationLineStyle GetUnderlineStyle(LOGFONTW logfont) => Static.GetUnderlineStyle(logfont); - } - - internal static UiaTextRangeTestAccessor TestAccessor(this UiaTextRange textRange) - => new(textRange); -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Automation/UiaTextProviderTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Automation/UiaTextProviderTests.cs deleted file mode 100644 index b0a9e7296a1..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Automation/UiaTextProviderTests.cs +++ /dev/null @@ -1,123 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Windows.Forms.Automation; -using Moq; -using Windows.Win32.UI.Input.KeyboardAndMouse; - -namespace System.Windows.Forms.Primitives.Tests.Automation; - -public class UiaTextProviderTests -{ - [StaFact] - public void UiaTextProvider_GetEditStyle_ContainsMultilineStyle_ForMultilineTextBox() - { - // EditControl Multiline is true when EditControl has ES_MULTILINE style - using EditControl textBox = new EditControl( - style: WINDOW_STYLE.WS_OVERLAPPED - | WINDOW_STYLE.WS_VISIBLE - | (WINDOW_STYLE)(PInvoke.ES_MULTILINE | PInvoke.ES_LEFT | PInvoke.ES_AUTOHSCROLL | PInvoke.ES_AUTOVSCROLL)); - Mock providerMock = new Mock(MockBehavior.Strict); - - WINDOW_STYLE actual = UiaTextProvider.GetWindowStyle(textBox); - Assert.True(((int)actual & PInvoke.ES_MULTILINE) != 0); - } - - [StaFact] - public void UiaTextProvider_GetEditStyle_DoesntContainMultilineStyle_ForSinglelineTextBox() - { - // EditControl Multiline is false when EditControl doesn't have ES_MULTILINE style - using EditControl textBox = new EditControl( - style: WINDOW_STYLE.WS_OVERLAPPED - | WINDOW_STYLE.WS_VISIBLE - | (WINDOW_STYLE)(PInvoke.ES_LEFT | PInvoke.ES_AUTOHSCROLL | PInvoke.ES_AUTOVSCROLL)); - Mock providerMock = new Mock(MockBehavior.Strict); - - WINDOW_STYLE actual = UiaTextProvider.GetWindowStyle(textBox); - Assert.False(((int)actual & PInvoke.ES_MULTILINE) != 0); - } - - [StaFact] - public void UiaTextProvider_GetWindowStyle_ContainsVisible() - { - using EditControl textBox = new EditControl( - style: WINDOW_STYLE.WS_OVERLAPPED - | WINDOW_STYLE.WS_VISIBLE - | (WINDOW_STYLE)(PInvoke.ES_MULTILINE | PInvoke.ES_LEFT | PInvoke.ES_AUTOHSCROLL | PInvoke.ES_AUTOVSCROLL)); - Mock providerMock = new Mock(MockBehavior.Strict); - - WINDOW_STYLE actual = UiaTextProvider.GetWindowStyle(textBox); - Assert.True(actual.HasFlag(WINDOW_STYLE.WS_VISIBLE)); - } - - [StaFact] - public void UiaTextProvider_GetWindowExStyle_ContainsClientedge() - { - using EditControl textBox = new EditControl( - style: WINDOW_STYLE.WS_OVERLAPPED | WINDOW_STYLE.WS_VISIBLE); - Mock providerMock = new Mock(MockBehavior.Strict); - - WINDOW_EX_STYLE actual = UiaTextProvider.GetWindowExStyle(textBox); - Assert.True(actual.HasFlag(WINDOW_EX_STYLE.WS_EX_CLIENTEDGE)); - } - - [StaFact] - public void UiaTextProvider_RectArrayToDoubleArray_ReturnsCorrectValue() - { - Mock providerMock = new Mock(MockBehavior.Strict); - - double[] expected = { 0, 0, 10, 5, 10, 10, 20, 30 }; - double[] actual = UiaTextProvider.RectListToDoubleArray(new List - { - new Rectangle(0, 0, 10, 5), - new Rectangle(10, 10, 20, 30) - }); - - Assert.Equal(8, actual.Length); - - for (int i = 0; i < expected.Length; i++) - { - Assert.Equal(expected[i], actual[i]); - } - } - -#pragma warning disable CS8625 // RectArrayToDoubleArray doesn't accept a null parameter - [StaFact] - public void UiaTextProvider_RectArrayToDoubleArray_NullParameter_ReturnsNull() - { - Mock providerMock = new Mock(MockBehavior.Strict); - - double[] actual = UiaTextProvider.RectListToDoubleArray(null); - Assert.Empty(actual); - } -#pragma warning restore CS8625 - - [StaFact] - public void UiaTextProvider_RectArrayToDoubleArray_EmptyArrayParameter_ReturnsEmptyArrayResult() - { - Mock providerMock = new Mock(MockBehavior.Strict); - - double[] actual = UiaTextProvider.RectListToDoubleArray(new List()); - Assert.Empty(actual); - } - - [StaFact] - public unsafe void UiaTextProvider_SendInput_SendsOneInput() - { - Mock providerMock = new Mock(MockBehavior.Strict); - INPUT keyboardInput = new INPUT(); - - int actual = providerMock.Object.SendInput(1, ref keyboardInput, sizeof(INPUT)); - Assert.Equal(1, actual); - } - - [StaFact] - public void UiaTextProvider_SendKeyboardInputVK_SendsOneInput() - { - Mock providerMock = new Mock(MockBehavior.Strict); - - int actual = providerMock.Object.SendKeyboardInputVK(VIRTUAL_KEY.VK_LEFT, true); - Assert.Equal(1, actual); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Automation/UiaTextRangeTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Automation/UiaTextRangeTests.cs deleted file mode 100644 index b2373a2b2c4..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Automation/UiaTextRangeTests.cs +++ /dev/null @@ -1,1215 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Runtime.InteropServices; -using System.Windows.Forms.Automation; -using Moq; -using static Interop; -using static Interop.UiaCore; - -namespace System.Windows.Forms.Primitives.Tests.Automation; - -public class UiaTextRangeTests -{ - // Used to get access to the test accessor for static members - private const UiaTextRange StaticNullTextRange = null!; - - [StaTheory] - [InlineData(0, 0)] - [InlineData(0, 5)] - [InlineData(5, 10)] - [InlineData(1, 1)] - public void UiaTextRange_Constructor_InitializesProvider_And_CorrectEndpoints(int start, int end) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - Assert.Equal(start, textRange.Start); - Assert.Equal(end, textRange.End); - Assert.Equal(enclosingElement, ((ITextRangeProvider)textRange).GetEnclosingElement()); - - object actual = textRange.TestAccessor()._provider; - - Assert.Equal(provider, actual); - } - - [StaTheory] - [InlineData(-10, 0, 0, 0)] - [InlineData(0, -10, 0, 0)] - [InlineData(5, 0, 5, 5)] - [InlineData(-1, -1, 0, 0)] - [InlineData(10, 5, 10, 10)] - [InlineData(-5, 5, 0, 5)] - [InlineData(5, -5, 5, 5)] - public void UiaTextRange_Constructor_InitializesProvider_And_CorrectEndpoints_IfEndpointsincorrect(int start, int end, int expectedStart, int expectedEnd) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - Assert.Equal(expectedStart, textRange.Start); - Assert.Equal(expectedEnd, textRange.End); - } - -#pragma warning disable CS8625 // UiaTextRange constructor doesn't accept a provider null parameter - [StaFact] - public void UiaTextRange_Constructor_Provider_Null_ThrowsException() - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Assert.Throws(() => new UiaTextRange(enclosingElement, null, 0, 5)); - } -#pragma warning restore CS8625 - -#pragma warning disable CS8625 // UiaTextRange constructor doesn't accept an enclosingElement null parameter - [StaFact] - public void UiaTextRange_Constructor_Control_Null_ThrowsException() - { - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - Assert.Throws(() => new UiaTextRange(null, provider, 0, 5)); - } -#pragma warning restore CS8625 - - [StaTheory] - [InlineData(3, -5)] - [InlineData(-5, 3)] - [InlineData(-3, -5)] - public void UiaTextRange_Constructor_SetCorrectValues_IfNegativeStartEnd(int start, int end) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - Assert.True(textRange.Start >= 0); - Assert.True(textRange.End >= 0); - } - - [StaTheory] - [InlineData(0)] - [InlineData(5)] - [InlineData(int.MaxValue)] - public void UiaTextRange_End_Get_ReturnsCorrectValue(int end) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end); - Assert.Equal(end, textRange.End); - } - - [StaTheory] - [InlineData(0)] - [InlineData(5)] - [InlineData(int.MaxValue)] - public void UiaTextRange_End_SetCorrectly(int end) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 0); - textRange.End = end; - int actual = textRange.End < textRange.Start ? textRange.Start : textRange.End; - Assert.Equal(end, actual); - } - - [StaFact] - public void UiaTextRange_End_SetCorrect_IfValueIncorrect() - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 5, end: 10); - textRange.End = 3; /*Incorrect value*/ - Assert.Equal(textRange.Start, textRange.End); - - textRange.End = 6; - Assert.Equal(6, textRange.End); - - textRange.End = -10; /*Incorrect value*/ - Assert.Equal(textRange.Start, textRange.End); - } - - [StaTheory] - [InlineData(0, 0, 0)] - [InlineData(5, 5, 0)] - [InlineData(3, 15, 12)] - [InlineData(0, 10, 10)] - [InlineData(6, 10, 4)] - public void UiaTextRange_Length_ReturnsCorrectValue(int start, int end, int expected) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - Assert.Equal(expected, textRange.Length); - } - - [StaTheory] - [InlineData(-5, 0)] - [InlineData(0, -5)] - [InlineData(-5, -5)] - [InlineData(10, 5)] - public void UiaTextRange_Length_ReturnsCorrectValue_IfIncorrectStartEnd(int start, int end) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, 3, 10); - - var testAccessor = textRange.TestAccessor(); - testAccessor._start = start; - testAccessor._end = end; - - Assert.Equal(0, textRange.Length); - } - - [StaTheory] - [InlineData(0)] - [InlineData(5)] - [InlineData(int.MaxValue)] - public void UiaTextRange_Start_Get_ReturnsCorrectValue(int start) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 0); - - textRange.TestAccessor()._start = start; - - Assert.Equal(start, textRange.Start); - } - - [StaTheory] - [InlineData(0)] - [InlineData(5)] - [InlineData(int.MaxValue)] - public void UiaTextRange_Start_SetCorrectly(int start) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 0); - textRange.Start = start; - int actual = textRange.Start < textRange.End ? textRange.End : textRange.Start; - Assert.Equal(start, actual); - } - - [StaFact] - public void UiaTextRange_Start_Set_Correct_IfValueIncorrect() - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 4, end: 8); - textRange.Start = -10; - Assert.Equal(0, textRange.Start); - Assert.Equal(8, textRange.End); - } - - [StaFact] - public void UiaTextRange_Start_Set_Correct_IfValueMoreThanEnd() - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 4, end: 10); - textRange.Start = 15; // More than End = 10 - Assert.True(textRange.Start <= textRange.End); - } - - [StaFact] - public void UiaTextRange_ITextRangeProvider_Clone_ReturnsCorrectValue() - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 3, end: 9); - UiaTextRange actual = (UiaTextRange)((ITextRangeProvider)textRange).Clone(); - Assert.Equal(textRange.Start, actual.Start); - Assert.Equal(textRange.End, actual.End); - } - - [StaTheory] - [InlineData(3, 9, true)] - [InlineData(0, 2, false)] - public void UiaTextRange_ITextRangeProvider_Compare_ReturnsCorrectValue(int start, int end, bool expected) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange1 = new UiaTextRange(enclosingElement, provider, start: 3, end: 9); - UiaTextRange textRange2 = new UiaTextRange(enclosingElement, provider, start, end); - bool actual = ((ITextRangeProvider)textRange1).Compare(textRange2); - Assert.Equal(expected, actual); - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_CompareEndpoints_ReturnsCorrectValue_TestData() - { - yield return new object[] { TextPatternRangeEndpoint.Start, 3, 9, TextPatternRangeEndpoint.Start, 0 }; - yield return new object[] { TextPatternRangeEndpoint.End, 3, 9, TextPatternRangeEndpoint.Start, 6 }; - yield return new object[] { TextPatternRangeEndpoint.Start, 3, 9, TextPatternRangeEndpoint.End, -6 }; - yield return new object[] { TextPatternRangeEndpoint.End, 3, 9, TextPatternRangeEndpoint.End, 0 }; - yield return new object[] { TextPatternRangeEndpoint.Start, 0, 0, TextPatternRangeEndpoint.Start, 3 }; - yield return new object[] { TextPatternRangeEndpoint.End, 0, 0, TextPatternRangeEndpoint.Start, 9 }; - yield return new object[] { TextPatternRangeEndpoint.End, 1, 15, TextPatternRangeEndpoint.End, -6 }; - yield return new object[] { TextPatternRangeEndpoint.Start, 1, 15, TextPatternRangeEndpoint.End, -12 }; - } - - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_CompareEndpoints_ReturnsCorrectValue_TestData))] - public void UiaTextRange_ITextRangeProvider_CompareEndpoints_ReturnsCorrectValue( - int endpoint, - int targetStart, - int targetEnd, - int targetEndpoint, - int expected) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 3, end: 9); - UiaTextRange targetRange = new UiaTextRange(enclosingElement, provider, start: targetStart, end: targetEnd); - int actual = ((ITextRangeProvider)textRange).CompareEndpoints((TextPatternRangeEndpoint)endpoint, targetRange, (TextPatternRangeEndpoint)targetEndpoint); - Assert.Equal(expected, actual); - } - - [StaTheory] - [InlineData(2, 2, 2, 3)] - [InlineData(8, 9, 8, 9)] - [InlineData(0, 3, 0, 3)] - public void UiaTextRange_ITextRangeProvider_ExpandToEnclosingUnit_ExpandsToCharacter(int start, int end, int expandedStart, int expandedEnd) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.TextLength).Returns("words, words, words".Length); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - ((ITextRangeProvider)textRange).ExpandToEnclosingUnit(TextUnit.Character); - Assert.Equal(expandedStart, textRange.Start); - Assert.Equal(expandedEnd, textRange.End); - } - - [StaTheory] - [InlineData(2, 3, 0, 5)] - [InlineData(8, 8, 7, 12)] - [InlineData(16, 17, 14, 19)] - public void UiaTextRange_ITextRangeProvider_ExpandToEnclosingUnit_ExpandsToWord(int start, int end, int expandedStart, int expandedEnd) - { - string testText = "words, words, words"; - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.Text).Returns(testText); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - ((ITextRangeProvider)textRange).ExpandToEnclosingUnit(TextUnit.Word); - Assert.Equal(expandedStart, textRange.Start); - Assert.Equal(expandedEnd, textRange.End); - } - - [StaTheory] - [InlineData(2, 4, 0, 12)] - [InlineData(15, 16, 12, 25)] - [InlineData(27, 28, 25, 36)] - public void UiaTextRange_ITextRangeProvider_ExpandToEnclosingUnit_ExpandsToLine(int start, int end, int expandedStart, int expandedEnd) - { - string testText = -@"First line -second line -third line."; - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.Text).Returns(testText); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - providerMock.Setup(m => m.LinesCount).Returns(3); - providerMock.Setup(m => m.GetLineIndex(0)).Returns(0); - providerMock.Setup(m => m.GetLineIndex(1)).Returns(12); - providerMock.Setup(m => m.GetLineIndex(2)).Returns(25); - providerMock.Setup(m => m.GetLineFromCharIndex(2)).Returns(0); - providerMock.Setup(m => m.GetLineFromCharIndex(4)).Returns(0); - providerMock.Setup(m => m.GetLineFromCharIndex(15)).Returns(1); - providerMock.Setup(m => m.GetLineFromCharIndex(16)).Returns(1); - providerMock.Setup(m => m.GetLineFromCharIndex(27)).Returns(2); - providerMock.Setup(m => m.GetLineFromCharIndex(28)).Returns(2); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - ((ITextRangeProvider)textRange).ExpandToEnclosingUnit(TextUnit.Line); - Assert.Equal(expandedStart, textRange.Start); - Assert.Equal(expandedEnd, textRange.End); - } - - [StaTheory] - [InlineData(2, 4, 0, 24)] - [InlineData(30, 30, 24, 49)] - [InlineData(49, 60, 49, 72)] - public void UiaTextRange_ITextRangeProvider_ExpandToEnclosingUnit_ExpandsToParagraph(int start, int end, int expandedStart, int expandedEnd) - { - string testText = -@"This is the first line -this is the second line -this is the third line."; - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.Text).Returns(testText); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - ((ITextRangeProvider)textRange).ExpandToEnclosingUnit(TextUnit.Paragraph); - Assert.Equal(expandedStart, textRange.Start); - Assert.Equal(expandedEnd, textRange.End); - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_ExpandToEnclosingUnit_ExpandsToAllText_TestData() - { - yield return new object[] { 5, 8, TextUnit.Page, 0, 72 }; - yield return new object[] { 10, 10, TextUnit.Format, 0, 72 }; - yield return new object[] { 10, 10, TextUnit.Document, 0, 72 }; - } - - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_ExpandToEnclosingUnit_ExpandsToAllText_TestData))] - internal void UiaTextRange_ITextRangeProvider_ExpandToEnclosingUnit_ExpandsToAllText(int start, int end, TextUnit textUnit, int expandedStart, int expandedEnd) - { - string testText = -@"This is the first line -this is the second line -this is the third line."; - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - ((ITextRangeProvider)textRange).ExpandToEnclosingUnit(textUnit); - Assert.Equal(expandedStart, textRange.Start); - Assert.Equal(expandedEnd, textRange.End); - } - - [StaTheory] - [InlineData(true)] - [InlineData(false)] - internal void UiaTextRange_ITextRangeProvider_FindAttribute_Returns_null(bool backward) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 0); - Array textAttributeIdentifiers = Enum.GetValues(typeof(TextAttributeIdentifier)); - - foreach (int textAttributeIdentifier in textAttributeIdentifiers) - { - ITextRangeProvider? actual = ((ITextRangeProvider)textRange).FindAttribute(textAttributeIdentifier, new object(), backward); - Assert.Null(actual); - } - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_FindText_Returns_Correct_TestData() - { - yield return new object?[] { "text", "text", BOOL.FALSE, BOOL.FALSE }; - yield return new object?[] { "other", null, BOOL.FALSE, BOOL.FALSE }; - yield return new object?[] { "TEXT", "text", BOOL.FALSE, BOOL.TRUE }; - yield return new object?[] { "TEXT", null, BOOL.FALSE, BOOL.FALSE }; - } - - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_FindText_Returns_Correct_TestData))] - internal void UiaTextRange_ITextRangeProvider_FindText_Returns_Correct(string textToSearch, string? foundText, BOOL backward, BOOL ignoreCase) - { - string testText = "Test text to find something."; - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.Text).Returns(testText); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 28); - - ITextRangeProvider? actual = ((ITextRangeProvider)textRange).FindText(textToSearch, backward, ignoreCase); - - if (foundText is not null) - { - Assert.Equal(foundText, actual?.GetText(5000)); - } - else - { - Assert.Null(actual); - } - } - -#pragma warning disable CS8625 // FindText doesn't accept a text null parameter - [StaFact] - internal void UiaTextRange_ITextRangeProvider_FindText_ReturnsNull_IfTextNull() - { - using (new NoAssertContext()) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 28); - ITextRangeProvider? actual = ((ITextRangeProvider)textRange).FindText(null, BOOL.TRUE, BOOL.TRUE); - Assert.Null(actual); - } - } -#pragma warning restore CS8625 - - private static object? notSupportedValue; - - [DllImport(Libraries.UiaCore, ExactSpelling = true)] - private static extern int UiaGetReservedNotSupportedValue([MarshalAs(UnmanagedType.IUnknown)] out object notSupportedValue); - - public static object UiaGetReservedNotSupportedValue() - { - if (notSupportedValue is null) - { - UiaGetReservedNotSupportedValue(out notSupportedValue); - } - - return notSupportedValue; - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_GetAttributeValue_Returns_Correct_TestData() - { - yield return new object[] { TextAttributeIdentifier.BackgroundColorAttributeId, (int)(uint)(COLORREF)PInvoke.GetSysColor(SYS_COLOR_INDEX.COLOR_WINDOW) }; - yield return new object[] { TextAttributeIdentifier.CapStyleAttributeId, CapStyle.None }; - yield return new object[] { TextAttributeIdentifier.FontNameAttributeId, "Segoe UI" }; - yield return new object[] { TextAttributeIdentifier.FontSizeAttributeId, 9.0 }; - yield return new object[] { TextAttributeIdentifier.FontWeightAttributeId, FW.NORMAL }; - yield return new object[] { TextAttributeIdentifier.ForegroundColorAttributeId, (int)(uint)new COLORREF() }; - yield return new object[] { TextAttributeIdentifier.HorizontalTextAlignmentAttributeId, HorizontalTextAlignment.Left }; - yield return new object[] { TextAttributeIdentifier.IsItalicAttributeId, false }; - yield return new object[] { TextAttributeIdentifier.IsReadOnlyAttributeId, false }; - yield return new object[] { TextAttributeIdentifier.StrikethroughStyleAttributeId, TextDecorationLineStyle.None }; - yield return new object[] { TextAttributeIdentifier.UnderlineStyleAttributeId, TextDecorationLineStyle.None }; - - yield return new object[] { TextAttributeIdentifier.AnimationStyleAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.BulletStyleAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.CultureAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.IndentationFirstLineAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.IndentationLeadingAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.IndentationTrailingAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.IsHiddenAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.IsSubscriptAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.IsSuperscriptAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.MarginBottomAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.MarginLeadingAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.MarginTopAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.MarginTrailingAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.OutlineStylesAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.OverlineColorAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.OverlineStyleAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.StrikethroughColorAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.TabsAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.TextFlowDirectionsAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.UnderlineColorAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.AnnotationTypesAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.AnnotationObjectsAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.StyleNameAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.StyleIdAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.LinkAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.IsActiveAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.SelectionActiveEndAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.CaretPositionAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.CaretBidiModeAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.LineSpacingAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.BeforeParagraphSpacingAttributeId, UiaGetReservedNotSupportedValue() }; - yield return new object[] { TextAttributeIdentifier.AfterParagraphSpacingAttributeId, UiaGetReservedNotSupportedValue() }; - } - - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_GetAttributeValue_Returns_Correct_TestData))] - internal void UiaTextRange_ITextRangeProvider_GetAttributeValue_Returns_Correct(int attributeId, object attributeValue) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - using Font font = new Font("Segoe UI", 9, FontStyle.Regular); - providerMock.Setup(m => m.Logfont).Returns(LOGFONTW.FromFont(font)); - providerMock.Setup(m => m.WindowStyle).Returns(PInvoke.ES_LEFT); - providerMock.Setup(m => m.IsReadOnly).Returns(false); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 28); - object? actual = ((ITextRangeProvider)textRange).GetAttributeValue(attributeId); - Assert.Equal(attributeValue, actual); - } - - [StaFact] - public void UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsEmpty_for_EmptyText() - { - Mock enclosingElementMock = new Mock(MockBehavior.Strict); - Rectangle expected = new Rectangle(10, 33, 96, 19); - enclosingElementMock.Setup(m => m.GetPropertyValue(UIA.BoundingRectanglePropertyId)).Returns(new double[] { 10, 33, 96, 19 }); - IRawElementProviderSimple enclosingElement = enclosingElementMock.Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(p => p.Text).Returns(""); - providerMock.Setup(p => p.TextLength).Returns(0); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 0); - var actual = ((ITextRangeProvider)textRange).GetBoundingRectangles(); - Assert.Equal(UiaTextProvider.BoundingRectangleAsArray(expected), actual); - } - - [StaFact] - public void UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsEmpty_for_DegenerateRange() - { - Mock enclosingElementMock = new Mock(MockBehavior.Strict); - enclosingElementMock.Setup(m => m.GetPropertyValue(UIA.BoundingRectanglePropertyId)).Returns(new Rectangle(10, 33, 96, 19)); - IRawElementProviderSimple enclosingElement = enclosingElementMock.Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(p => p.Text).Returns("abcde"); - providerMock.Setup(p => p.TextLength).Returns(5); - providerMock.Setup(p => p.IsMultiline).Returns(false); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 0); - var actual = ((ITextRangeProvider)textRange).GetBoundingRectangles(); - Assert.Empty(actual); - } - - [StaFact] - public void UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsExpected_for_Endline() - { - Mock enclosingElementMock = new Mock(MockBehavior.Strict); - enclosingElementMock.Setup(m => m.GetPropertyValue(UIA.BoundingRectanglePropertyId)).Returns(new double[] {10, 33, 96, 19 }); - IRawElementProviderSimple enclosingElement = enclosingElementMock.Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(p => p.Text).Returns("abc"); - providerMock.Setup(p => p.TextLength).Returns(3); - providerMock.Setup(p => p.PointToScreen(It.IsAny())).Returns(Point.Empty); - using Font font = new Font("Arial", 9f, FontStyle.Regular); - providerMock.Setup(m => m.Logfont).Returns(LOGFONTW.FromFont(font)); - UiaTextProvider provider = providerMock.Object; - - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 3, end: 3); - double actualWidth = ((ITextRangeProvider)textRange).GetBoundingRectangles()[2]; // {X,Y,Width,Height} - - Assert.Equal(UiaTextProvider.EndOfLineWidth, actualWidth); - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsCorrectValue_for_SingleLine_TestData() - { - yield return new object[] { 3, 6, new double[] { 27, 34, 11, 14 } }; - yield return new object[] { 0, 2, new double[] { 11, 34, 16, 15 } }; - } - - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsCorrectValue_for_SingleLine_TestData))] - public void UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsCorrectValue_for_SingleLine(int start, int end, double[] expected) - { - string testText = "Test text."; - Mock enclosingElementMock = new Mock(MockBehavior.Strict); - enclosingElementMock.Setup(m => m.GetPropertyValue(UIA.BoundingRectanglePropertyId)).Returns(new Rectangle(10, 33, 96, 19)); - IRawElementProviderSimple enclosingElement = enclosingElementMock.Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.Text).Returns(testText); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - providerMock.Setup(m => m.IsMultiline).Returns(false); - providerMock.Setup(m => m.BoundingRectangle).Returns(new Rectangle(1, 1, 94, 15)); - providerMock.Setup(m => m.GetPositionFromChar(3)).Returns(new Point(17, 0)); - providerMock.Setup(m => m.GetPositionFromChar(0)).Returns(new Point(1, 0)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(5, testText)).Returns(new Point(28, 0)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(1, testText)).Returns(new Point(17, 0)); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - double[] actual = ((ITextRangeProvider)textRange).GetBoundingRectangles(); - - // Acceptable deviation of 1 px. - for (int i = 0; i < actual.Length; i++) - { - Assert.True(actual[i] >= 0 && actual[i] >= expected[i] - 1 && actual[i] <= expected[i] + 1); - } - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsCorrectValue_for_MultiLine_TestData() - { - yield return new object[] { 0, 63, new double[] { 32, 131, 103, 12, 32, 148, 85, 12, 32, 165, 83, 12, 32, 182, 90, 12, 32, 199, 40, 12 } }; // Whole text - yield return new object[] { 23, 53, new double[] { 72, 148, 45, 12, 32, 165, 83, 12, 32, 182, 56, 12 } }; // "xt with several lines and num" text is selected - } - - /// All returned values of mock methods and properties were taken from a real TextBox. - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsCorrectValue_for_MultiLine_TestData))] - public void UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsCorrectValue_for_MultiLine(int start, int end, double[] expected) - { - string testText = -@"Some long long -test text with several lines -and numbers 12345"; - - Mock enclosingElementMock = new Mock(MockBehavior.Strict); - enclosingElementMock.Setup(m => m.GetPropertyValue(UIA.BoundingRectanglePropertyId)).Returns(new double[] {27, 128, 128, 155 }); - - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.IsReadingRTL).Returns(false); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - providerMock.Setup(m => m.Text).Returns(testText); - providerMock.Setup(m => m.BoundingRectangle).Returns(new Rectangle(5, 1, 118, 153)); - providerMock.Setup(m => m.IsMultiline).Returns(true); - providerMock.Setup(m => m.FirstVisibleLine).Returns(0); - providerMock.Setup(m => m.LinesPerPage).Returns(9); - using Font font = new Font("Arial", 9f, FontStyle.Regular); - providerMock.Setup(m => m.Logfont).Returns(LOGFONTW.FromFont(font)); - - // Offset by enclosing element's coordinates - providerMock.Setup(m => m.RectangleToScreen(It.IsAny())) - .Returns((Rectangle rect) => new Rectangle(rect.X + 27, rect.Y + 128, rect.Width, rect.Height)); - - providerMock.Setup(m => m.GetLineFromCharIndex(0)).Returns(0); - providerMock.Setup(m => m.GetLineFromCharIndex(14)).Returns(0); - providerMock.Setup(m => m.GetLineFromCharIndex(23)).Returns(1); - providerMock.Setup(m => m.GetLineFromCharIndex(31)).Returns(2); - providerMock.Setup(m => m.GetLineFromCharIndex(44)).Returns(2); - providerMock.Setup(m => m.GetLineFromCharIndex(52)).Returns(3); - providerMock.Setup(m => m.GetLineFromCharIndex(58)).Returns(4); - providerMock.Setup(m => m.GetLineFromCharIndex(62)).Returns(4); - - providerMock.Setup(m => m.GetPositionFromChar(0)).Returns(new Point(5, 1)); - providerMock.Setup(m => m.GetPositionFromChar(16)).Returns(new Point(5, 18)); - providerMock.Setup(m => m.GetPositionFromChar(23)).Returns(new Point(45, 18)); - providerMock.Setup(m => m.GetPositionFromChar(31)).Returns(new Point(5, 35)); - providerMock.Setup(m => m.GetPositionFromChar(46)).Returns(new Point(5, 52)); - providerMock.Setup(m => m.GetPositionFromChar(58)).Returns(new Point(5, 69)); - - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(15, testText)).Returns(new Point(108, 1)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(30, testText)).Returns(new Point(90, 18)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(45, testText)).Returns(new Point(88, 35)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(52, testText)).Returns(new Point(61, 52)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(57, testText)).Returns(new Point(95, 52)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(62, testText)).Returns(new Point(45, 69)); - - providerMock.Setup(m => m.GetLineIndex(1)).Returns(16); - providerMock.Setup(m => m.GetLineIndex(2)).Returns(31); - providerMock.Setup(m => m.GetLineIndex(3)).Returns(46); - providerMock.Setup(m => m.GetLineIndex(4)).Returns(58); - - UiaTextRange textRange = new UiaTextRange(enclosingElementMock.Object, providerMock.Object, start, end); - var actual = ((ITextRangeProvider)textRange).GetBoundingRectangles(); - Assert.Equal(expected, actual); - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsCorrectValue_for_MultiLine_And_RTL_TestData() - { - yield return new object[] { 0, 63, new double[] { 47, 131, 103, 12, 67, 148, 83, 12, 67, 165, 83, 12, 62, 182, 88, 12, 110, 199, 40, 12 } }; // Whole text - yield return new object[] { 23, 53, new double[] { 107, 148, 43, 12, 67, 165, 83, 12, 64, 182, 56, 12 } }; // "xt with several lines and num" text is selected - } - - /// All returned values of mock methods and properties were taken from a real TextBox. - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsCorrectValue_for_MultiLine_And_RTL_TestData))] - public void UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsCorrectValue_for_MultiLine_And_RTL(int start, int end, double[] expected) - { - string testText = -@"Some long long -test text with several lines -and numbers 12345"; - - Mock enclosingElementMock = new Mock(MockBehavior.Strict); - enclosingElementMock.Setup(m => m.GetPropertyValue(UIA.BoundingRectanglePropertyId)).Returns(new double[] { 27, 128, 128, 155 }); - - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.IsReadingRTL).Returns(true); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - providerMock.Setup(m => m.Text).Returns(testText); - providerMock.Setup(m => m.BoundingRectangle).Returns(new Rectangle(5, 1, 118, 153)); - providerMock.Setup(m => m.IsMultiline).Returns(true); - providerMock.Setup(m => m.FirstVisibleLine).Returns(0); - providerMock.Setup(m => m.LinesPerPage).Returns(9); - using Font font = new Font("Arial", 9f, FontStyle.Regular); - providerMock.Setup(m => m.Logfont).Returns(LOGFONTW.FromFont(font)); - - // Offset by enclosing element's coordinates - providerMock.Setup(m => m.RectangleToScreen(It.IsAny())) - .Returns((Rectangle rect) => new Rectangle(rect.X + 27, rect.Y + 128, rect.Width, rect.Height)); - - providerMock.Setup(m => m.GetLineFromCharIndex(0)).Returns(0); - providerMock.Setup(m => m.GetLineFromCharIndex(14)).Returns(0); - providerMock.Setup(m => m.GetLineFromCharIndex(23)).Returns(1); - providerMock.Setup(m => m.GetLineFromCharIndex(31)).Returns(2); - providerMock.Setup(m => m.GetLineFromCharIndex(44)).Returns(2); - providerMock.Setup(m => m.GetLineFromCharIndex(52)).Returns(3); - providerMock.Setup(m => m.GetLineFromCharIndex(58)).Returns(4); - providerMock.Setup(m => m.GetLineFromCharIndex(62)).Returns(4); - - providerMock.Setup(m => m.GetPositionFromChar(0)).Returns(new Point(22, 1)); - providerMock.Setup(m => m.GetPositionFromChar(16)).Returns(new Point(42, 18)); - providerMock.Setup(m => m.GetPositionFromChar(23)).Returns(new Point(82, 18)); - providerMock.Setup(m => m.GetPositionFromChar(31)).Returns(new Point(42, 35)); - providerMock.Setup(m => m.GetPositionFromChar(46)).Returns(new Point(37, 52)); - providerMock.Setup(m => m.GetPositionFromChar(58)).Returns(new Point(83, 69)); - - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(15, testText)).Returns(new Point(125, 1)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(30, testText)).Returns(new Point(127, 18)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(45, testText)).Returns(new Point(125, 35)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(52, testText)).Returns(new Point(93, 52)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(57, testText)).Returns(new Point(127, 52)); - providerMock.Setup(m => m.GetPositionFromCharForUpperRightCorner(62, testText)).Returns(new Point(123, 69)); - - providerMock.Setup(m => m.GetLineIndex(1)).Returns(16); - providerMock.Setup(m => m.GetLineIndex(2)).Returns(31); - providerMock.Setup(m => m.GetLineIndex(3)).Returns(46); - providerMock.Setup(m => m.GetLineIndex(4)).Returns(58); - - UiaTextRange textRange = new UiaTextRange(enclosingElementMock.Object, providerMock.Object, start, end); - var actual = ((ITextRangeProvider)textRange).GetBoundingRectangles(); - Assert.Equal(expected, actual); - } - - [StaFact] - public void UiaTextRange_ITextRangeProvider_GetEnclosingElement_ReturnsCorrectValue() - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 0); - IRawElementProviderSimple actual = ((ITextRangeProvider)textRange).GetEnclosingElement(); - Assert.Equal(enclosingElement, actual); - } - - [StaTheory] - [InlineData(0, 0, 0, "")] - [InlineData(0, 0, 5, "")] - [InlineData(0, 10, -5, "Some long ")] - [InlineData(0, 10, 0, "")] - [InlineData(0, 10, 10, "Some long ")] - [InlineData(0, 10, 20, "Some long ")] - [InlineData(0, 25, 7, "Some lo")] - [InlineData(0, 300, 400, "Some long long test text")] - [InlineData(5, 15, 7, "long lo")] - [InlineData(5, 15, 25, "long long ")] - [InlineData(5, 15, 300, "long long ")] - [InlineData(5, 24, 400, "long long test text")] - [InlineData(5, 25, 0, "")] - [InlineData(5, 25, 7, "long lo")] - [InlineData(5, 300, -5, "long long test text")] - [InlineData(5, 300, 7, "long lo")] - [InlineData(5, 300, 300, "long long test text")] - public void UiaTextRange_ITextRangeProvider_GetText_ReturnsCorrectValue(int start, int end, int maxLength, string expected) - { - string testText = "Some long long test text"; - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.Text).Returns(testText); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - string actual = ((ITextRangeProvider)textRange).GetText(maxLength); - Assert.Equal(expected, actual); - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_Move_MovesCorrectly_TestData() - { - yield return new object[] { 0, 5, TextUnit.Character, 1, 6, 6 }; - yield return new object[] { 1, 6, TextUnit.Character, 5, 11, 11 }; - yield return new object[] { 0, 5, TextUnit.Character, -2, 0, 0 }; - yield return new object[] { 3, 6, TextUnit.Character, -2, 1, 1 }; - yield return new object[] { 1, 2, TextUnit.Word, 1, 4, 4 }; - yield return new object[] { 1, 2, TextUnit.Word, 5, 11, 11 }; - yield return new object[] { 12, 14, TextUnit.Word, -2, 8, 8 }; - yield return new object[] { 12, 14, TextUnit.Word, -10, 0, 0 }; - } - - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_Move_MovesCorrectly_TestData))] - internal void UiaTextRange_ITextRangeProvider_Move_MovesCorrectly(int start, int end, TextUnit unit, int count, int expectedStart, int expectedEnd) - { - string testText = -@"This is the text to move on - line 1 -This is the line 2 -This is the line 3"; - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.Text).Returns(testText); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - int result = ((ITextRangeProvider)textRange).Move(unit, count); - Assert.Equal(expectedStart, textRange.Start); - Assert.Equal(expectedEnd, textRange.End); - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_MoveEndpointByUnit_MovesCorrectly_TestData() - { - yield return new object[] { 0, 5, TextPatternRangeEndpoint.Start, TextUnit.Character, 1, 1, 5 }; - yield return new object[] { 1, 6, TextPatternRangeEndpoint.Start, TextUnit.Character, 5, 6, 6 }; - yield return new object[] { 0, 5, TextPatternRangeEndpoint.Start, TextUnit.Character, -2, 0, 5 }; - yield return new object[] { 3, 6, TextPatternRangeEndpoint.Start, TextUnit.Character, -2, 1, 6 }; - yield return new object[] { 3, 6, TextPatternRangeEndpoint.End, TextUnit.Character, 1, 3, 7 }; - yield return new object[] { 3, 6, TextPatternRangeEndpoint.End, TextUnit.Character, -1, 3, 5 }; - yield return new object[] { 1, 2, TextPatternRangeEndpoint.Start, TextUnit.Word, 1, 4, 4 }; - yield return new object[] { 1, 2, TextPatternRangeEndpoint.Start, TextUnit.Word, 5, 11, 11 }; - yield return new object[] { 12, 14, TextPatternRangeEndpoint.Start, TextUnit.Word, -1, 11, 14 }; - yield return new object[] { 12, 14, TextPatternRangeEndpoint.Start, TextUnit.Word, -2, 8, 14 }; - } - - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_MoveEndpointByUnit_MovesCorrectly_TestData))] - internal void UiaTextRange_ITextRangeProvider_MoveEndpointByUnit_MovesCorrectly(int start, int end, TextPatternRangeEndpoint endpoint, TextUnit unit, int count, int expectedStart, int expectedEnd) - { - string testText = -@"This is the text to move on - line 1 -This is the line 2 -This is the line 3"; - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.Text).Returns(testText); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - ((ITextRangeProvider)textRange).MoveEndpointByUnit(endpoint, unit, count); - Assert.Equal(expectedStart, textRange.Start); - Assert.Equal(expectedEnd, textRange.End); - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_MoveEndpointByRange_MovesCorrectly_TestData() - { - yield return new object[] { 0, 5, TextPatternRangeEndpoint.Start, 7, 10, TextPatternRangeEndpoint.Start, 7, 7 }; - yield return new object[] { 0, 5, TextPatternRangeEndpoint.Start, 7, 10, TextPatternRangeEndpoint.End, 10, 10 }; - yield return new object[] { 0, 5, TextPatternRangeEndpoint.End, 7, 10, TextPatternRangeEndpoint.Start, 0, 7 }; - yield return new object[] { 0, 5, TextPatternRangeEndpoint.End, 7, 10, TextPatternRangeEndpoint.End, 0, 10 }; - } - - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_MoveEndpointByRange_MovesCorrectly_TestData))] - internal void UiaTextRange_ITextRangeProvider_MoveEndpointByRange_MovesCorrectly(int start, int end, TextPatternRangeEndpoint endpoint, int targetRangeStart, int targetRangeEnd, TextPatternRangeEndpoint targetEndpoint, int expectedStart, int expectedEnd) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - UiaTextRange targetRange = new UiaTextRange(enclosingElement, provider, targetRangeStart, targetRangeEnd); - ((ITextRangeProvider)textRange).MoveEndpointByRange(endpoint, targetRange, targetEndpoint); - Assert.Equal(expectedStart, textRange.Start); - Assert.Equal(expectedEnd, textRange.End); - } - - [StaTheory] - [InlineData(0, 0)] - [InlineData(0, 10)] - [InlineData(5, 10)] - public void UiaTextRange_ITextRangeProvider_Select_ReturnsCorrectValue(int start, int end) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.SetSelection(start, end)); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - ((ITextRangeProvider)textRange).Select(); - providerMock.Verify(m => m.SetSelection(start, end), Times.Once()); - } - - [StaFact] - public void UiaTextRange_ITextRangeProvider_AddToSelection_DoesntThrowException() - { - // Check an app doesn't crash when calling AddToSelection method. - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, 3, 7); - ((ITextRangeProvider)textRange).AddToSelection(); - } - - [StaFact] - public void UiaTextRange_ITextRangeProvider_RemoveFromSelection_DoesntThrowException() - { - // Check an app doesn't crash when calling RemoveFromSelection method. - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, 3, 7); - ((ITextRangeProvider)textRange).RemoveFromSelection(); - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_ScrollIntoView_Multiline_CallsLineScrollCorrectly_TestData() - { - yield return new object[] { 30, 35, 30, 1, 30, 0, 1 }; - yield return new object[] { 60, 65, 60, 2, 60, 2, 0 }; - } - - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_ScrollIntoView_Multiline_CallsLineScrollCorrectly_TestData))] - public void UiaTextRange_ITextRangeProvider_ScrollIntoView_Multiline_CallsLineScrollCorrectly(int start, int end, int charIndex, int lineForCharIndex, int charactersHorizontal, int linesVertical, int firstVisibleLine) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - - var providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(p => p.IsMultiline).Returns(true); - providerMock.Setup(p => p.GetLineFromCharIndex(charIndex)).Returns(lineForCharIndex); - providerMock.Setup(p => p.LineScroll(charactersHorizontal, linesVertical)).Returns(true); - providerMock.Setup(p => p.FirstVisibleLine).Returns(firstVisibleLine); - - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - ((ITextRangeProvider)textRange).ScrollIntoView(BOOL.TRUE); - providerMock.Verify(e => e.LineScroll(charactersHorizontal, linesVertical), Times.Once()); - } - - public static IEnumerable UiaTextRange_ITextRangeProvider_ScrollIntoView_SingleLine_ExecutesCorrectly_TestData() - { - yield return new object[] { 0, 30, true, false }; - yield return new object[] { 70, 85, true, false }; - } - - [StaTheory] - [MemberData(nameof(UiaTextRange_ITextRangeProvider_ScrollIntoView_SingleLine_ExecutesCorrectly_TestData))] - public void UiaTextRange_ITextRangeProvider_ScrollIntoView_SingleLine_ExecutesCorrectly(int start, int end, bool scrollable, bool readingRTL) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - int visibleStart = 40; - int visibleEnd = 60; - - var providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(p => p.IsMultiline).Returns(false); - providerMock.Setup(p => p.IsScrollable).Returns(scrollable); - providerMock.Setup(p => p.IsReadingRTL).Returns(readingRTL); - providerMock.Setup(p => p.GetVisibleRangePoints(out visibleStart, out visibleEnd)); - - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - ((ITextRangeProvider)textRange).ScrollIntoView(BOOL.TRUE); - providerMock.Verify(p => p.GetVisibleRangePoints(out visibleStart, out visibleEnd), Times.Exactly(2)); - } - - [StaFact] - public void UiaTextRange_ITextRangeProvider_GetChildren_ReturnsCorrectValue() - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 0); - IRawElementProviderSimple[] actual = ((ITextRangeProvider)textRange).GetChildren(); - Assert.Empty(actual); - } - - [StaTheory] - [InlineData("", 0, true)] - [InlineData("", 5, true)] - [InlineData("", -5, true)] - [InlineData("Some text", 0, true)] - [InlineData("Some text", 5, false)] - [InlineData("Some text", 6, false)] - [InlineData("Some text", 99, true)] - [InlineData("Some text", -5, true)] - [InlineData("Some, text", 4, false)] - [InlineData("Some text", 4, false)] - [InlineData("1dsf'21gj", 3, false)] - [InlineData("1dsf'21gj", 4, false)] - [InlineData("1dsf'21gj", 6, false)] - [InlineData("1d??sf'21gj", 6, false)] - public void UiaTextRange_private_AtParagraphBoundary_ReturnsCorrectValue(string text, int index, bool expected) - { - bool actual = StaticNullTextRange.TestAccessor().AtParagraphBoundary(text, index); - Assert.Equal(expected, actual); - } - - [StaTheory] - [InlineData("", 0, true)] - [InlineData("", 5, true)] - [InlineData("", -5, true)] - [InlineData("Some text", 0, true)] - [InlineData("Some text", 5, true)] - [InlineData("Some text", 6, false)] - [InlineData("Some text", 99, true)] - [InlineData("Some text", -5, true)] - [InlineData("Some, text", 4, true)] - [InlineData("Some text", 4, true)] - [InlineData("1dsf'21gj", 3, false)] - [InlineData("1dsf'21gj", 4, false)] - [InlineData("1dsf'21gj", 6, false)] - [InlineData("1d??sf'21gj", 6, false)] - public void UiaTextRange_private_AtWordBoundary_ReturnsCorrectValue(string text, int index, bool expected) - { - bool actual = StaticNullTextRange.TestAccessor().AtWordBoundary(text, index); - Assert.Equal(expected, actual); - } - - [StaTheory] - [InlineData('\'', true)] - [InlineData((char)0x2019, true)] - [InlineData('\t', false)] - [InlineData('t', false)] - public void UiaTextRange_private_IsApostrophe_ReturnsCorrectValue(char ch, bool expected) - { - bool actual = StaticNullTextRange.TestAccessor().IsApostrophe(ch); - Assert.Equal(expected, actual); - } - - [StaTheory] - [InlineData(PInvoke.ES_CENTER, (int)HorizontalTextAlignment.Centered)] - [InlineData(PInvoke.ES_LEFT, (int)HorizontalTextAlignment.Left)] - [InlineData(PInvoke.ES_RIGHT, (int)HorizontalTextAlignment.Right)] - public void UiaTextRange_private_GetHorizontalTextAlignment_ReturnsCorrectValue(int style, int expected) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, 0, 0); - - HorizontalTextAlignment actual = textRange.TestAccessor().GetHorizontalTextAlignment((WINDOW_STYLE)style); - - Assert.Equal((HorizontalTextAlignment)expected, actual); - } - - [StaTheory] - [InlineData((PInvoke.ES_UPPERCASE | PInvoke.ES_LEFT | PInvoke.ES_MULTILINE | PInvoke.ES_READONLY | PInvoke.ES_AUTOHSCROLL), (int)CapStyle.AllCap)] - [InlineData((PInvoke.ES_LOWERCASE | PInvoke.ES_LEFT | PInvoke.ES_MULTILINE | PInvoke.ES_READONLY | PInvoke.ES_AUTOHSCROLL), (int)CapStyle.None)] - public void UiaTextRange_private_GetCapStyle_ReturnsExpectedValue(int editStyle, int expected) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, 0, 0); - - CapStyle actual = textRange.TestAccessor().GetCapStyle((WINDOW_STYLE)editStyle); - - Assert.Equal((CapStyle)expected, actual); - } - - [StaTheory] - [InlineData(true)] - [InlineData(false)] - public void UiaTextRange_private_GetReadOnly_ReturnsCorrectValue(bool readOnly) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.IsReadOnly).Returns(readOnly); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, 0, 0); - - bool actual = textRange.TestAccessor().GetReadOnly(); - - Assert.Equal(readOnly, actual); - } - - [StaFact] - public void UiaTextRange_private_GetBackgroundColor_ReturnsExpectedValue() - { - COLORREF actual = StaticNullTextRange.TestAccessor().GetBackgroundColor(); - uint expected = 0x00ffffff; // WINDOW system color - Assert.Equal(expected, actual); - } - - [StaTheory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - [InlineData("Some test text")] - public void UiaTextRange_private_GetFontName_ReturnsExpectedValue(string faceName) - { - LOGFONTW logfont = new() - { - FaceName = faceName - }; - - string actual = StaticNullTextRange.TestAccessor().GetFontName(logfont); - - Assert.Equal(faceName ?? "", actual); - } - - [StaTheory] - [InlineData(1, 1)] - [InlineData(5, 5)] - [InlineData(5.3, 5)] - [InlineData(9.5, 10)] - [InlineData(18, 18)] - [InlineData(18.8, 19)] - [InlineData(100, 100)] - public void UiaTextRange_private_GetFontSize_ReturnsCorrectValue(float fontSize, double expected) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - using Font font = new Font("Arial", fontSize, FontStyle.Regular); - providerMock.Setup(m => m.Logfont).Returns(LOGFONTW.FromFont(font)); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, 5, 20); - - double actual = textRange.TestAccessor().GetFontSize(provider.Logfont); - - Assert.Equal(expected, actual); - } - - [StaTheory] - [InlineData(FW.BLACK)] - [InlineData(FW.BOLD)] - [InlineData(FW.DEMIBOLD)] - [InlineData(FW.DONTCARE)] - [InlineData(FW.EXTRABOLD)] - [InlineData(FW.EXTRALIGHT)] - [InlineData(FW.LIGHT)] - [InlineData(FW.MEDIUM)] - [InlineData(FW.NORMAL)] - [InlineData(FW.THIN)] - public void UiaTextRange_private_GetFontWeight_ReturnsCorrectValue(object fontWeight) - { - LOGFONTW logfont = new() { lfWeight = (int)fontWeight }; - FW actual = StaticNullTextRange.TestAccessor().GetFontWeight(logfont); - Assert.Equal(fontWeight, actual); - } - - [StaFact] - public void UiaTextRange_private_GetForegroundColor_ReturnsCorrectValue() - { - COLORREF actual = StaticNullTextRange.TestAccessor().GetForegroundColor(); - Assert.Equal(new COLORREF(), actual); - } - - [StaTheory] - [InlineData(0, false)] - [InlineData(5, true)] - public void UiaTextRange_private_GetItalic_ReturnsCorrectValue(byte ifItalic, bool expected) - { - LOGFONTW logfont = new LOGFONTW() { lfItalic = ifItalic }; - - bool actual = StaticNullTextRange.TestAccessor().GetItalic(logfont); - - Assert.Equal(expected, actual); - } - - [StaTheory] - [InlineData(0, (int)TextDecorationLineStyle.None)] - [InlineData(5, (int)TextDecorationLineStyle.Single)] - public void UiaTextRange_private_GetStrikethroughStyle_ReturnsCorrectValue(byte ifStrikeOut, int expected) - { - LOGFONTW logfont = new LOGFONTW() { lfStrikeOut = ifStrikeOut }; - TextDecorationLineStyle actual = StaticNullTextRange.TestAccessor().GetStrikethroughStyle(logfont); - - Assert.Equal((TextDecorationLineStyle)expected, actual); - } - - [StaTheory] - [InlineData(0, (int)TextDecorationLineStyle.None)] - [InlineData(5, (int)TextDecorationLineStyle.Single)] - public void UiaTextRange_private_GetUnderlineStyle_ReturnsCorrectValue(byte ifUnderline, int expected) - { - LOGFONTW logfont = new LOGFONTW() { lfUnderline = ifUnderline }; - TextDecorationLineStyle actual = StaticNullTextRange.TestAccessor().GetUnderlineStyle(logfont); - - Assert.Equal((TextDecorationLineStyle)expected, actual); - } - - [StaTheory] - [InlineData(0, 0)] - [InlineData(0, 10)] - [InlineData(5, 10)] - [InlineData(5, 100)] - [InlineData(100, 100)] - [InlineData(100, 200)] - public void UiaTextRange_private_MoveTo_SetValuesCorrectly(int start, int end) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, 0, 0); - - textRange.TestAccessor().MoveTo(start, end); - - Assert.Equal(start, textRange.Start); - Assert.Equal(end, textRange.End); - } - - [StaTheory] - [InlineData(-5, 0)] - [InlineData(0, -5)] - [InlineData(-10, -10)] - [InlineData(10, 5)] - public void UiaTextRange_private_MoveTo_ThrowsException_IfIncorrectParameters(int start, int end) - { - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - UiaTextProvider provider = new Mock(MockBehavior.Strict).Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, 0, 0); - - Assert.ThrowsAny(() => textRange.TestAccessor().MoveTo(start, end)); - } - - [StaTheory] - [InlineData(0, 0, 0, 0)] - [InlineData(0, 10, 0, 10)] - [InlineData(5, 10, 5, 10)] - [InlineData(5, 100, 5, 24)] - [InlineData(100, 100, 24, 24)] - [InlineData(100, 200, 24, 24)] - public void UiaTextRange_private_ValidateEndpoints_SetValuesCorrectly(int start, int end, int expectedStart, int expectedEnd) - { - string testText = "Some long long test text"; - IRawElementProviderSimple enclosingElement = new Mock(MockBehavior.Strict).Object; - Mock providerMock = new Mock(MockBehavior.Strict); - providerMock.Setup(m => m.TextLength).Returns(testText.Length); - UiaTextProvider provider = providerMock.Object; - UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start, end); - - textRange.TestAccessor().ValidateEndpoints(); - - Assert.Equal(expectedStart, textRange.Start); - Assert.Equal(expectedEnd, textRange.End); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ArrayTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ArrayTests.cs deleted file mode 100644 index 3fc0bd560e2..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ArrayTests.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Drawing; - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class ArrayTests -{ - [Theory] - [MemberData(nameof(ArrayInfo_ParseSuccessData))] - public void ArrayInfo_Parse_Success(MemoryStream stream, int expectedId, int expectedLength) - { - using BinaryReader reader = new(stream); - ArrayInfo info = ArrayInfo.Parse(reader, out Count length); - info.ObjectId.Should().Be(expectedId); - info.Length.Should().Be(expectedLength); - length.Should().Be(expectedLength); - } - - public static TheoryData ArrayInfo_ParseSuccessData => new() - { - { new MemoryStream(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }), 0, 0 }, - { new MemoryStream(new byte[] { 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }), 1, 1 }, - { new MemoryStream(new byte[] { 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }), 2, 1 }, - { new MemoryStream(new byte[] { 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F }), int.MaxValue, int.MaxValue } - }; - - [Theory] - [MemberData(nameof(ArrayInfo_ParseNegativeData))] - public void ArrayInfo_Parse_Negative(MemoryStream stream, Type expectedException) - { - using BinaryReader reader = new(stream); - Assert.Throws(expectedException, () => ArrayInfo.Parse(reader, out Count length)); - } - - public static TheoryData ArrayInfo_ParseNegativeData => new() - { - // Not enough data - { new MemoryStream(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }), typeof(EndOfStreamException) }, - { new MemoryStream(new byte[] { 0x00, 0x00, 0x00 }), typeof(EndOfStreamException) }, - // Negative numbers - { new MemoryStream(new byte[] { 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }), typeof(ArgumentOutOfRangeException) } - }; - - [Theory] - [MemberData(nameof(StringArray_Parse_Data))] - public void StringArray_Parse(string?[] strings) - { - BinaryFormattedObject format = strings.SerializeAndParse(); - format.RecordCount.Should().BeGreaterThanOrEqualTo(3); - ArraySingleString array = (ArraySingleString)format[1]; - format.GetStringValues(array, strings.Length).Should().BeEquivalentTo(strings); - } - - public static TheoryData StringArray_Parse_Data => new() - { - new string?[] { "one", "two" }, - new string?[] { "yes", "no", null }, - new string?[] { "same", "same", "same" } - }; - - [Theory] - [MemberData(nameof(PrimitiveArray_Parse_Data))] - public void PrimitiveArray_Parse(Array array) - { - BinaryFormattedObject format = array.SerializeAndParse(); - format.RecordCount.Should().BeGreaterThanOrEqualTo(3); - ArraySinglePrimitive arrayRecord = (ArraySinglePrimitive)format[1]; - ((IEnumerable)arrayRecord.ArrayObjects).Should().BeEquivalentTo((IEnumerable)array); - } - - public static TheoryData PrimitiveArray_Parse_Data => new() - { - new int[] { 1, 2, 3 }, - new int[] { 1, 2, 1 }, - new float[] { 1.0f, float.NaN, float.PositiveInfinity }, - new DateTime[] { DateTime.MaxValue } - }; - - public static IEnumerable Array_TestData => StringArray_Parse_Data.Concat(PrimitiveArray_Parse_Data); - - public static TheoryData Array_UnsupportedTestData => new() - { - new Point[] { new Point() }, - new object[] { new object() }, - }; -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/BinaryFormatWriterTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/BinaryFormatWriterTests.cs deleted file mode 100644 index 86207ab7391..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/BinaryFormatWriterTests.cs +++ /dev/null @@ -1,115 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Runtime.Serialization.Formatters.Binary; - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class BinaryFormatWriterTests -{ - [Theory] - [InlineData("Hello World.")] - [InlineData("")] - [InlineData("\0")] - [InlineData("Embedded\0 Null.")] - public void BinaryFormatWriter_WriteString(string testString) - { - using MemoryStream stream = new(); - BinaryFormatWriter.WriteString(stream, testString); - stream.Position = 0; - - using var formatterScope = new BinaryFormatterScope(enable: true); -#pragma warning disable SYSLIB0011 // Type or member is obsolete - BinaryFormatter formatter = new(); -#pragma warning restore - object deserialized = formatter.Deserialize(stream); - deserialized.Should().Be(testString); - } - - [Theory] - [MemberData(nameof(TryWriteObject_SupportedObjects_TestData))] - public void BinaryFormatWriter_TryWriteObject_SupportedObjects_BinaryFormatterRead(object value) - { - using MemoryStream stream = new(); - BinaryFormatWriter.TryWriteFrameworkObject(stream, value).Should().BeTrue(); - stream.Position = 0; - - using BinaryFormatterScope formaterScope = new(enable: true); -#pragma warning disable SYSLIB0011 // Type or member is obsolete - BinaryFormatter formatter = new(); -#pragma warning restore SYSLIB0011 // Type or member is obsolete - object deserialized = formatter.Deserialize(stream); - - if (value is Hashtable hashtable) - { - Hashtable deserializedHashtable = (Hashtable)deserialized; - deserializedHashtable.Count.Should().Be(hashtable.Count); - foreach (var key in hashtable.Keys) - { - deserializedHashtable[key].Should().Be(hashtable[key]); - } - } - else if (value is IEnumerable enumerable) - { - ((IEnumerable)deserialized).Should().BeEquivalentTo(enumerable); - } - else - { - deserialized.Should().Be(value); - } - } - - [Theory] - [MemberData(nameof(TryWriteObject_SupportedObjects_TestData))] - public void BinaryFormatWriter_TryWriteObject_SupportedObjects_RoundTrip(object value) - { - using MemoryStream stream = new(); - BinaryFormatWriter.TryWriteFrameworkObject(stream, value).Should().BeTrue(); - stream.Position = 0; - - BinaryFormattedObject format = new(stream); - format.TryGetFrameworkObject(out object? deserialized).Should().BeTrue(); - - if (value is Hashtable hashtable) - { - Hashtable deserializedHashtable = (Hashtable)deserialized!; - deserializedHashtable.Count.Should().Be(hashtable.Count); - foreach (var key in hashtable.Keys) - { - deserializedHashtable[key].Should().Be(hashtable[key]); - } - } - else if (value is IEnumerable enumerable) - { - ((IEnumerable)deserialized!).Should().BeEquivalentTo(enumerable); - } - else - { - deserialized.Should().Be(value); - } - } - - [Theory] - [MemberData(nameof(TryWriteObject_UnsupportedObjects_TestData))] - public void BinaryFormatWriter_TryWriteObject_UnsupportedObjects_RoundTrip(object value) - { - using MemoryStream stream = new(); - BinaryFormatWriter.TryWriteFrameworkObject(stream, value).Should().BeFalse(); - stream.Position.Should().Be(0); - } - - public static IEnumerable TryWriteObject_SupportedObjects_TestData => - HashtableTests.Hashtables_TestData.Concat( - ListTests.PrimitiveLists_TestData).Concat( - ListTests.ArrayLists_TestData).Concat( - PrimitiveTypeTests.Primitive_Data).Concat( - SystemDrawingTests.SystemDrawing_TestData).Concat( - ArrayTests.Array_TestData); - - public static IEnumerable TryWriteObject_UnsupportedObjects_TestData => - HashtableTests.Hashtables_UnsupportedTestData.Concat( - ListTests.Lists_UnsupportedTestData).Concat( - ListTests.ArrayLists_UnsupportedTestData).Concat( - ArrayTests.Array_UnsupportedTestData); -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/BinaryFormattedObjectTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/BinaryFormattedObjectTests.cs deleted file mode 100644 index 00d8b8655ad..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/BinaryFormattedObjectTests.cs +++ /dev/null @@ -1,413 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class BinaryFormattedObjectTests -{ - [Fact] - public void ReadHeader() - { - BinaryFormattedObject format = "Hello World.".SerializeAndParse(); - SerializationHeader header = (SerializationHeader)format[0]; - header.MajorVersion.Should().Be(1); - header.MinorVersion.Should().Be(0); - header.RootId.Should().Be(1); - header.HeaderId.Should().Be(-1); - } - - [Theory] - [InlineData("Hello there.")] - [InlineData("")] - [InlineData("Embedded\0 Null.")] - public void ReadBinaryObjectString(string testString) - { - BinaryFormattedObject format = testString.SerializeAndParse(); - BinaryObjectString stringRecord = (BinaryObjectString)format[1]; - stringRecord.ObjectId.Should().Be(1); - stringRecord.Value.Should().Be(testString); - } - - [Fact] - public void ReadEmptyHashTable() - { - BinaryFormattedObject format = new Hashtable().SerializeAndParse(); - - SystemClassWithMembersAndTypes systemClass = (SystemClassWithMembersAndTypes)format[1]; - systemClass.ObjectId.Should().Be(1); - systemClass.Name.Should().Be("System.Collections.Hashtable"); - systemClass.MemberNames.Should().BeEquivalentTo(new[] - { - "LoadFactor", - "Version", - "Comparer", - "HashCodeProvider", - "HashSize", - "Keys", - "Values" - }); - - systemClass.MemberTypeInfo.Should().BeEquivalentTo(new (BinaryType Type, object? Info)[] - { - (BinaryType.Primitive, PrimitiveType.Single), - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.SystemClass, "System.Collections.IComparer"), - (BinaryType.SystemClass, "System.Collections.IHashCodeProvider"), - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.ObjectArray, null), - (BinaryType.ObjectArray, null) - }); - - systemClass.MemberValues.Should().BeEquivalentTo(new object?[] - { - 0.72f, - 0, - ObjectNull.Instance, - ObjectNull.Instance, - 3, - new MemberReference(2), - new MemberReference(3) - }); - - ArraySingleObject array = (ArraySingleObject)format[2]; - array.ArrayInfo.ObjectId.Should().Be(2); - array.ArrayInfo.Length.Should().Be(0); - - array = (ArraySingleObject)format[3]; - array.ArrayInfo.ObjectId.Should().Be(3); - array.ArrayInfo.Length.Should().Be(0); - } - - [Fact] - public void ReadHashTableWithStringPair() - { - BinaryFormattedObject format = new Hashtable() - { - { "This", "That" } - }.SerializeAndParse(); - - SystemClassWithMembersAndTypes systemClass = (SystemClassWithMembersAndTypes)format[1]; - - systemClass.MemberTypeInfo.Should().BeEquivalentTo(new (BinaryType Type, object? Info)[] - { - (BinaryType.Primitive, PrimitiveType.Single), - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.SystemClass, "System.Collections.IComparer"), - (BinaryType.SystemClass, "System.Collections.IHashCodeProvider"), - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.ObjectArray, null), - (BinaryType.ObjectArray, null) - }); - - systemClass.MemberValues.Should().BeEquivalentTo(new object?[] - { - 0.72f, - 1, - ObjectNull.Instance, - ObjectNull.Instance, - 3, - new MemberReference(2), - new MemberReference(3) - }); - - ArraySingleObject array = (ArraySingleObject)format[2]; - array.ArrayInfo.ObjectId.Should().Be(2); - array.ArrayInfo.Length.Should().Be(1); - BinaryObjectString value = (BinaryObjectString)array.ArrayObjects[0]; - value.ObjectId.Should().Be(4); - value.Value.Should().Be("This"); - - array = (ArraySingleObject)format[3]; - array.ArrayInfo.ObjectId.Should().Be(3); - array.ArrayInfo.Length.Should().Be(1); - value = (BinaryObjectString)array.ArrayObjects[0]; - value.ObjectId.Should().Be(5); - value.Value.Should().Be("That"); - } - - [Fact] - public void ReadHashTableWithRepeatedStrings() - { - BinaryFormattedObject format = new Hashtable() - { - { "This", "That" }, - { "TheOther", "This" }, - { "That", "This" } - }.SerializeAndParse(); - - // The collections themselves get ids first before the strings do. - // Everything in the second array is a string reference. - ArraySingleObject array = (ArraySingleObject)format[3]; - array.ObjectId.Should().Be(3); - array[0].Should().BeOfType(); - array[1].Should().BeOfType(); - array[2].Should().BeOfType(); - } - - [Fact] - public void ReadHashTableWithNullValues() - { - BinaryFormattedObject format = new Hashtable() - { - { "Yowza", null }, - { "Youza", null }, - { "Meeza", null } - }.SerializeAndParse(); - - SystemClassWithMembersAndTypes systemClass = (SystemClassWithMembersAndTypes)format[1]; - - systemClass.MemberValues.Should().BeEquivalentTo(new object?[] - { - 0.72f, - 4, - ObjectNull.Instance, - ObjectNull.Instance, - 7, - new MemberReference(2), - new MemberReference(3) - }); - - ArrayRecord array = (ArrayRecord)format[(MemberReference)systemClass.MemberValues[5]]; - - array.ArrayInfo.ObjectId.Should().Be(2); - array.ArrayInfo.Length.Should().Be(3); - BinaryObjectString value = (BinaryObjectString)array.ArrayObjects[0]; - value.ObjectId.Should().Be(4); - value.Value.Should().BeOneOf("Yowza", "Youza", "Meeza"); - - array = (ArrayRecord)format[(MemberReference)systemClass["Values"]]; - array.ArrayInfo.ObjectId.Should().Be(3); - array.ArrayInfo.Length.Should().Be(3); - array.ArrayObjects[0].Should().BeOfType(); - } - - [Fact] - public void ReadObject() - { - BinaryFormattedObject format = new object().SerializeAndParse(); - format[1].Should().BeOfType(); - } - - [Fact] - public void ReadStruct() - { - ValueTuple tuple = new(355); - BinaryFormattedObject format = tuple.SerializeAndParse(); - format[1].Should().BeOfType(); - } - - [Fact] - public void ReadSimpleSerializableObject() - { - BinaryFormattedObject format = new SimpleSerializableObject().SerializeAndParse(); - - BinaryLibrary library = (BinaryLibrary)format[1]; - library.LibraryName.Should().Be(typeof(BinaryFormattedObjectTests).Assembly.FullName); - library.LibraryId.Should().Be(2); - - ClassWithMembersAndTypes @class = (ClassWithMembersAndTypes)format[2]; - @class.ObjectId.Should().Be(1); - @class.Name.Should().Be(typeof(SimpleSerializableObject).FullName); - @class.MemberNames.Should().BeEmpty(); - @class.LibraryId.Should().Be(2); - @class.MemberTypeInfo.Should().BeEmpty(); - - format[3].Should().BeOfType(); - } - - [Fact] - public void ReadNestedSerializableObject() - { - BinaryFormattedObject format = new NestedSerializableObject().SerializeAndParse(); - - BinaryLibrary library = (BinaryLibrary)format[1]; - library.LibraryName.Should().Be(typeof(BinaryFormattedObjectTests).Assembly.FullName); - library.LibraryId.Should().Be(2); - - ClassWithMembersAndTypes @class = (ClassWithMembersAndTypes)format[2]; - @class.ObjectId.Should().Be(1); - @class.Name.Should().Be(typeof(NestedSerializableObject).FullName); - @class.MemberNames.Should().BeEquivalentTo(new[] { "_object", "_meaning" }); - @class.LibraryId.Should().Be(2); - @class.MemberTypeInfo.Should().BeEquivalentTo(new (BinaryType Type, object? Info)[] - { - (BinaryType.Class, new ClassTypeInfo(typeof(SimpleSerializableObject).FullName!, 2)), - (BinaryType.Primitive, PrimitiveType.Int32) - }); - @class.MemberValues.Should().BeEquivalentTo(new object?[] - { - new MemberReference(3), - 42 - }); - - @class = (ClassWithMembersAndTypes)format[3]; - @class.ObjectId.Should().Be(3); - @class.Name.Should().Be(typeof(SimpleSerializableObject).FullName); - @class.MemberNames.Should().BeEmpty(); - @class.LibraryId.Should().Be(2); - @class.MemberTypeInfo.Should().BeEmpty(); - - format[4].Should().BeOfType(); - } - - [Fact] - public void ReadTwoIntObject() - { - BinaryFormattedObject format = new TwoIntSerializableObject().SerializeAndParse(); - - BinaryLibrary library = (BinaryLibrary)format[1]; - library.LibraryName.Should().Be(typeof(BinaryFormattedObjectTests).Assembly.FullName); - library.LibraryId.Should().Be(2); - - ClassWithMembersAndTypes @class = (ClassWithMembersAndTypes)format[2]; - @class.ObjectId.Should().Be(1); - @class.Name.Should().Be(typeof(TwoIntSerializableObject).FullName); - @class.MemberNames.Should().BeEquivalentTo(new[] { "_value", "_meaning" }); - @class.LibraryId.Should().Be(2); - @class.MemberTypeInfo.Should().BeEquivalentTo(new (BinaryType Type, object? Info)[] - { - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.Primitive, PrimitiveType.Int32) - }); - - @class.MemberValues.Should().BeEquivalentTo(new object?[] - { - 1970, - 42 - }); - - format[3].Should().BeOfType(); - } - - [Fact] - public void ReadRepeatedNestedObject() - { - BinaryFormattedObject format = new RepeatedNestedSerializableObject().SerializeAndParse(); - ClassWithMembersAndTypes firstClass = (ClassWithMembersAndTypes)format[3]; - ClassWithId classWithId = (ClassWithId)format[4]; - classWithId.MetadataId.Should().Be(firstClass.ObjectId); - classWithId.MemberValues.Should().BeEquivalentTo(new object[] { 1970, 42 }); - } - - [Fact] - public void ReadPrimitiveArray() - { - BinaryFormattedObject format = new int[] { 10, 9, 8, 7 }.SerializeAndParse(); - - ArraySinglePrimitive array = (ArraySinglePrimitive)format[1]; - array.ArrayInfo.Length.Should().Be(4); - array.PrimitiveType.Should().Be(PrimitiveType.Int32); - array.ArrayObjects.Should().BeEquivalentTo(new object[] { 10, 9, 8, 7 }); - } - - [Fact] - public void ReadStringArray() - { - BinaryFormattedObject format = new string[] { "Monday", "Tuesday", "Wednesday" }.SerializeAndParse(); - ArraySingleString array = (ArraySingleString)format[1]; - array.ArrayInfo.ObjectId.Should().Be(1); - array.ArrayInfo.Length.Should().Be(3); - BinaryObjectString value = (BinaryObjectString)array.ArrayObjects[0]; - } - - [Fact] - public void ReadStringArrayWithNulls() - { - BinaryFormattedObject format = new string?[] { "Monday", null, "Wednesday", null, null, null }.SerializeAndParse(); - ArraySingleString array = (ArraySingleString)format[1]; - array.ArrayInfo.ObjectId.Should().Be(1); - array.ArrayInfo.Length.Should().Be(6); - array.ArrayObjects.Should().BeEquivalentTo(new object?[] - { - new BinaryObjectString(2, "Monday"), - ObjectNull.Instance, - new BinaryObjectString(3, "Wednesday"), - ObjectNull.Instance, - ObjectNull.Instance, - ObjectNull.Instance - }); - BinaryObjectString value = (BinaryObjectString)array.ArrayObjects[0]; - } - - [Fact] - public void ReadDuplicatedStringArray() - { - BinaryFormattedObject format = new string[] { "Monday", "Tuesday", "Monday" }.SerializeAndParse(); - ArraySingleString array = (ArraySingleString)format[1]; - array.ArrayInfo.ObjectId.Should().Be(1); - array.ArrayInfo.Length.Should().Be(3); - BinaryObjectString value = (BinaryObjectString)array.ArrayObjects[0]; - MemberReference reference = (MemberReference)array.ArrayObjects[2]; - reference.IdRef.Should().Be(value.ObjectId); - } - - [Fact] - public void ReadObjectWithNullableObjects() - { - BinaryFormattedObject format = new ObjectWithNullableObjects().SerializeAndParse(); - ClassWithMembersAndTypes classRecord = (ClassWithMembersAndTypes)format[2]; - BinaryLibrary library = (BinaryLibrary)format[classRecord.LibraryId]; - } - - [Fact] - public void ReadNestedObjectWithNullableObjects() - { - BinaryFormattedObject format = new NestedObjectWithNullableObjects().SerializeAndParse(); - ClassWithMembersAndTypes classRecord = (ClassWithMembersAndTypes)format[2]; - BinaryLibrary library = (BinaryLibrary)format[classRecord.LibraryId]; - } - - [Serializable] - private class SimpleSerializableObject - { - } - -#pragma warning disable IDE0052 // Remove unread private members -#pragma warning disable IDE0051 // Remove unused private members -#pragma warning disable CS0414 // Field is assigned but its value is never used -#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value null -#pragma warning disable CA1823 // Avoid unused private fields - [Serializable] - private class ObjectWithNullableObjects - { - public object? First; - public object? Second; - public object? Third; - } - - [Serializable] - private class NestedObjectWithNullableObjects - { - public ObjectWithNullableObjects? First; - public ObjectWithNullableObjects? Second; - public ObjectWithNullableObjects? Third = new(); - } - - [Serializable] - private class NestedSerializableObject - { - private readonly SimpleSerializableObject _object = new(); - private readonly int _meaning = 42; - } - - [Serializable] - private class TwoIntSerializableObject - { - private readonly int _value = 1970; - private readonly int _meaning = 42; - } - - [Serializable] - private class RepeatedNestedSerializableObject - { - private readonly TwoIntSerializableObject _first = new(); - private readonly TwoIntSerializableObject _second = new(); - } -#pragma warning restore IDE0052 // Remove unread private members -#pragma warning restore IDE0051 // Remove unused private members -#pragma warning restore CS0414 // Field is assigned but its value is never used -#pragma warning restore CS0649 // Field is never assigned to, and will always have its default value null -#pragma warning restore CA1823 // Avoid unused private fields -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/BinaryFormattedTypes.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/BinaryFormattedTypes.cs deleted file mode 100644 index 746d6ce5f89..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/BinaryFormattedTypes.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.ComponentModel; -using System.Drawing; -using System.Runtime.Serialization; - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class BinaryFormattedTypes -{ - [Theory] - [MemberData(nameof(BinaryFormattedTypes_TestData))] - public void Types_UseBinaryFormatter(Type type) - { - bool iSerializable = type.IsAssignableTo(typeof(ISerializable)); -#pragma warning disable SYSLIB0050 // Type or member is obsolete - bool serializable = type.IsSerializable; -#pragma warning restore SYSLIB0050 - - Assert.True(iSerializable || serializable, "Type should either implement ISerializable or be marked as [Serializable]"); - - var converter = TypeDescriptor.GetConverter(type); - Assert.False( - converter.CanConvertFrom(typeof(string)) && converter.CanConvertTo(typeof(string)), - "Type should not be convertable back and forth to string."); - Assert.False( - converter.CanConvertFrom(typeof(byte[])) && converter.CanConvertTo(typeof(byte[])), - "Type should not be convertable back and forth to byte[]."); - } - - public static TheoryData BinaryFormattedTypes_TestData => new() - { - typeof(Hashtable), - typeof(ArrayList), - typeof(PointF), - typeof(RectangleF), - typeof(List), - }; - - [Theory] - [MemberData(nameof(NotBinaryFormattedTypes_TestData))] - public void Types_DoNotUseBinaryFormatter(Type type) - { - var converter = TypeDescriptor.GetConverter(type); - Assert.True( - (converter.CanConvertFrom(typeof(string)) && converter.CanConvertTo(typeof(string))) - || (converter.CanConvertFrom(typeof(byte[])) && converter.CanConvertTo(typeof(byte[]))), - "Type should be convertable back and forth to string or byte[]."); - } - - public static TheoryData NotBinaryFormattedTypes_TestData => new() - { - typeof(Point), - typeof(Size), - typeof(SizeF), - typeof(Rectangle), - typeof(Color) - }; -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ClassInfoTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ClassInfoTests.cs deleted file mode 100644 index 5f5250fdb8f..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ClassInfoTests.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class ClassInfoTests -{ - private static readonly byte[] s_hashtableClassInfo = new byte[] - { - 0x01, 0x00, 0x00, 0x00, 0x1c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x4c, 0x6f, 0x61, 0x64, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, - 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, - 0x72, 0x10, 0x48, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x08, 0x48, 0x61, 0x73, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x04, 0x4b, 0x65, 0x79, 0x73, - 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73 - }; - - [Fact] - public void ClassInfo_ReadHashtable() - { - using BinaryReader reader = new(new MemoryStream(s_hashtableClassInfo)); - ClassInfo info = ClassInfo.Parse(reader, out Count memberCount); - - memberCount.Should().Be(7); - info.ObjectId.Should().Be(1); - info.Name.Should().Be("System.Collections.Hashtable"); - info.MemberNames.Should().BeEquivalentTo(new[] - { - "LoadFactor", - "Version", - "Comparer", - "HashCodeProvider", - "HashSize", - "Keys", - "Values" - }); - } - - [Fact] - public void ClassInfo_Hashtable_RoundTrip() - { - using BinaryReader reader = new(new MemoryStream(s_hashtableClassInfo)); - ClassInfo info = ClassInfo.Parse(reader, out Count memberCount); - - MemoryStream stream = new(); - BinaryWriter writer = new(stream); - info.Write(writer); - stream.Position = 0; - - using BinaryReader reader2 = new(stream); - info = ClassInfo.Parse(reader2, out memberCount); - - memberCount.Should().Be(7); - info.ObjectId.Should().Be(1); - info.Name.Should().Be("System.Collections.Hashtable"); - info.MemberNames.Should().BeEquivalentTo(new[] - { - "LoadFactor", - "Version", - "Comparer", - "HashCodeProvider", - "HashSize", - "Keys", - "Values" - }); - } - - [Fact] - public void MemberTypeInfo_ReadHashtable_TooShort() - { - MemoryStream stream = new(s_hashtableClassInfo); - stream.SetLength(stream.Length - 1); - using BinaryReader reader = new(stream); - Action action = () => ClassInfo.Parse(reader, out _); - action.Should().Throw(); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/CountTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/CountTests.cs deleted file mode 100644 index 80bbd0c4eb0..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/CountTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class CountTests -{ - [Fact] - public void CountDoesNotAcceptNegativeValues() - { - Func func = () => (Count)(-1); - func.Should().Throw(); - } - - [Fact] - public void CountEqualsInt() - { - ((Count)4).Should().Be(4); - } - - [Fact] - public void CountEqualsCount() - { - ((Count)4).Should().Be((Count)4); - } - - [Fact] - public void CountToStringIsInt() - { - ((Count)5).ToString().Should().Be("5"); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ExceptionTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ExceptionTests.cs deleted file mode 100644 index 6c88318a557..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ExceptionTests.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class ExceptionTests -{ - [Fact] - public void NotSupportedException_Parse() - { - BinaryFormattedObject format = new NotSupportedException().SerializeAndParse(); - format.RecordCount.Should().Be(3); - var systemClass = (SystemClassWithMembersAndTypes)format[1]; - systemClass.Name.Should().Be(typeof(NotSupportedException).FullName); - systemClass.MemberNames.Should().BeEquivalentTo(new string[] - { - "ClassName", - "Message", - "Data", - "InnerException", - "HelpURL", - "StackTraceString", - "RemoteStackTraceString", - "RemoteStackIndex", - "ExceptionMethod", - "HResult", - "Source", - "WatsonBuckets" - }); - - systemClass.MemberTypeInfo.Should().BeEquivalentTo(new (BinaryType, object?)[] - { - (BinaryType.String, null), - (BinaryType.String, null), - (BinaryType.SystemClass, typeof(IDictionary).FullName), - (BinaryType.SystemClass, typeof(Exception).FullName), - (BinaryType.String, null), - (BinaryType.String, null), - (BinaryType.String, null), - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.String, null), - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.String, null), - (BinaryType.PrimitiveArray, PrimitiveType.Byte) - }); - - systemClass.MemberValues.Should().BeEquivalentTo(new object[] - { - new BinaryObjectString(2, "System.NotSupportedException"), - new BinaryObjectString(3, "Specified method is not supported."), - ObjectNull.Instance, - ObjectNull.Instance, - ObjectNull.Instance, - ObjectNull.Instance, - ObjectNull.Instance, - 0, - ObjectNull.Instance, - unchecked((int)0x80131515), - ObjectNull.Instance, - ObjectNull.Instance - }); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/HashTableTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/HashTableTests.cs deleted file mode 100644 index 6a5189966c6..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/HashTableTests.cs +++ /dev/null @@ -1,249 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Drawing; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class HashtableTests -{ - [Fact] - public void HashTable_GetObjectData() - { - Hashtable hashtable = new() - { - { "This", "That" } - }; - - // The converter isn't used for this scenario and can be a no-op. -#pragma warning disable SYSLIB0050 // Type or member is obsolete - SerializationInfo info = new(typeof(Hashtable), FormatterConverterStub.Instance); -#pragma warning restore SYSLIB0050 -#pragma warning disable SYSLIB0051 // Type or member is obsolete - hashtable.GetObjectData(info, default); -#pragma warning restore SYSLIB0051 - info.MemberCount.Should().Be(7); - - var enumerator = info.GetEnumerator(); - - enumerator.MoveNext().Should().BeTrue(); - enumerator.Current.Name.Should().Be("LoadFactor"); - enumerator.Current.Value.Should().Be(0.72f); - - enumerator.MoveNext().Should().BeTrue(); - enumerator.Current.Name.Should().Be("Version"); - enumerator.Current.Value.Should().Be(1); - - enumerator.MoveNext().Should().BeTrue(); - enumerator.Current.Name.Should().Be("Comparer"); - enumerator.Current.Value.Should().BeNull(); - - enumerator.MoveNext().Should().BeTrue(); - enumerator.Current.Name.Should().Be("HashCodeProvider"); - enumerator.Current.Value.Should().BeNull(); - - enumerator.MoveNext().Should().BeTrue(); - enumerator.Current.Name.Should().Be("HashSize"); - enumerator.Current.Value.Should().Be(3); - - enumerator.MoveNext().Should().BeTrue(); - enumerator.Current.Name.Should().Be("Keys"); - enumerator.Current.Value.Should().BeEquivalentTo(new object[] { "This" }); - - enumerator.MoveNext().Should().BeTrue(); - enumerator.Current.Name.Should().Be("Values"); - enumerator.Current.Value.Should().BeEquivalentTo(new object[] { "That" }); - } - - [Theory] - [MemberData(nameof(Hashtables_TestData))] - public void BinaryFormatWriter_WriteHashtables(Hashtable hashtable) - { - using MemoryStream stream = new(); - BinaryFormatWriter.WritePrimitiveHashtable(stream, hashtable); - stream.Position = 0; - - using var formatterScope = new BinaryFormatterScope(enable: true); -#pragma warning disable SYSLIB0011 // Type or member is obsolete - BinaryFormatter formatter = new(); - Hashtable deserialized = (Hashtable)formatter.Deserialize(stream); -#pragma warning restore SYSLIB0011 - - deserialized.Count.Should().Be(hashtable.Count); - foreach (var key in hashtable.Keys) - { - deserialized[key].Should().Be(hashtable[key]); - } - } - - [Theory] - [MemberData(nameof(Hashtables_UnsupportedTestData))] - public void BinaryFormatWriter_WriteUnsupportedHashtables(Hashtable hashtable) - { - using MemoryStream stream = new(); - Action action = () => BinaryFormatWriter.WritePrimitiveHashtable(stream, hashtable); - action.Should().Throw(); - } - - [Theory] - [MemberData(nameof(Hashtables_TestData))] - public void BinaryFormattedObjectExtensions_TryGetPrimitiveHashtable(Hashtable hashtable) - { - BinaryFormattedObject format = hashtable.SerializeAndParse(); - format.TryGetPrimitiveHashtable(out Hashtable? deserialized).Should().BeTrue(); - - deserialized!.Count.Should().Be(hashtable.Count); - foreach (var key in hashtable.Keys) - { - deserialized[key].Should().Be(hashtable[key]); - } - } - - [Theory] - [MemberData(nameof(Hashtables_TestData))] - public void RoundTripHashtables(Hashtable hashtable) - { - using MemoryStream stream = new(); - BinaryFormatWriter.WritePrimitiveHashtable(stream, hashtable); - stream.Position = 0; - - BinaryFormattedObject format = new(stream); - format.TryGetPrimitiveHashtable(out Hashtable? deserialized).Should().BeTrue(); - deserialized!.Count.Should().Be(hashtable.Count); - foreach (var key in hashtable.Keys) - { - deserialized[key].Should().Be(hashtable[key]); - } - } - - public static TheoryData Hashtables_TestData => new() - { - new Hashtable(), - new Hashtable() - { - { "This", "That" } - }, - new Hashtable() - { - { "Meaning", 42 } - }, - new Hashtable() - { - { 42, 42 } - }, - new Hashtable() - { - { 42, 42 }, - { 43, 42 } - }, - new Hashtable() - { - { "Hastings", new DateTime(1066, 10, 14) } - }, - new Hashtable() - { - { "Decimal", decimal.MaxValue } - }, - new Hashtable() - { - { "This", "That" }, - { "TheOther", "This" }, - { "That", "This" } - }, - new Hashtable() - { - { "Yowza", null }, - { "Youza", null }, - { "Meeza", null } - }, - new Hashtable() - { - { "Yowza", null }, - { "Youza", "Binks" }, - { "Meeza", null } - }, - new Hashtable() - { - { "Yowza", "Binks" }, - { "Youza", "Binks" }, - { "Meeza", null } - }, - new Hashtable() - { - { decimal.MinValue, decimal.MaxValue }, - { float.MinValue, float.MaxValue }, - { DateTime.MinValue, DateTime.MaxValue }, - { TimeSpan.MinValue, TimeSpan.MaxValue } - }, - // Stress the string interning - MakeRepeatedHashtable(50, "Ditto"), - MakeRepeatedHashtable(100, "..."), - // Cross over into ObjectNullMultiple - MakeRepeatedHashtable(255, null), - MakeRepeatedHashtable(256, null), - MakeRepeatedHashtable(257, null) - }; - - public static TheoryData Hashtables_UnsupportedTestData => new() - { - new Hashtable() - { - { new object(), new object() } - }, - new Hashtable() - { - { "Foo", new object() } - }, - new Hashtable() - { - { "Foo", new Point() } - }, - new Hashtable() - { - { "Foo", new PointF() } - }, - new Hashtable() - { - { "Foo", (nint)42 } - }, - }; - - private static Hashtable MakeRepeatedHashtable(int countOfEntries, object? value) - { - Hashtable result = new(countOfEntries); - for (int i = 1; i <= countOfEntries; i++) - { - result.Add($"Entry{i}", value); - } - - return result; - } - -#pragma warning disable SYSLIB0050 // Type or member is obsolete - private sealed class FormatterConverterStub : IFormatterConverter - { - public static IFormatterConverter Instance { get; } = new FormatterConverterStub(); -#pragma warning restore SYSLIB0050 - - public object Convert(object value, Type type) => throw new NotImplementedException(); - public object Convert(object value, TypeCode typeCode) => throw new NotImplementedException(); - public bool ToBoolean(object value) => throw new NotImplementedException(); - public byte ToByte(object value) => throw new NotImplementedException(); - public char ToChar(object value) => throw new NotImplementedException(); - public DateTime ToDateTime(object value) => throw new NotImplementedException(); - public decimal ToDecimal(object value) => throw new NotImplementedException(); - public double ToDouble(object value) => throw new NotImplementedException(); - public short ToInt16(object value) => throw new NotImplementedException(); - public int ToInt32(object value) => throw new NotImplementedException(); - public long ToInt64(object value) => throw new NotImplementedException(); - public sbyte ToSByte(object value) => throw new NotImplementedException(); - public float ToSingle(object value) => throw new NotImplementedException(); - public string? ToString(object value) => throw new NotImplementedException(); - public ushort ToUInt16(object value) => throw new NotImplementedException(); - public uint ToUInt32(object value) => throw new NotImplementedException(); - public ulong ToUInt64(object value) => throw new NotImplementedException(); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ListTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ListTests.cs deleted file mode 100644 index 230064ba22a..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/ListTests.cs +++ /dev/null @@ -1,221 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Drawing; -using System.Runtime.Serialization.Formatters.Binary; - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class ListTests -{ - [Fact] - public void BinaryFormattedObject_ParseEmptyArrayList() - { - BinaryFormattedObject format = new ArrayList().SerializeAndParse(); - SystemClassWithMembersAndTypes systemClass = (SystemClassWithMembersAndTypes)format[1]; - - systemClass.Name.Should().Be(typeof(ArrayList).FullName); - systemClass.MemberNames.Should().BeEquivalentTo(new string[] { "_items", "_size", "_version" }); - systemClass.MemberTypeInfo[0].Should().Be((BinaryType.ObjectArray, null)); - - format[2].Should().BeOfType(); - } - - [Theory] - [MemberData(nameof(ArrayList_Primitive_Data))] - public void BinaryFormattedObject_ParsePrimitivesArrayList(object value) - { - BinaryFormattedObject format = new ArrayList() - { - value - }.SerializeAndParse(); - - SystemClassWithMembersAndTypes systemClass = (SystemClassWithMembersAndTypes)format[1]; - - systemClass.Name.Should().Be(typeof(ArrayList).FullName); - systemClass.MemberNames.Should().BeEquivalentTo(new string[] { "_items", "_size", "_version" }); - systemClass.MemberTypeInfo[0].Should().Be((BinaryType.ObjectArray, null)); - - ArraySingleObject array = (ArraySingleObject)format[2]; - MemberPrimitiveTyped primitve = (MemberPrimitiveTyped)array[0]; - primitve.Value.Should().Be(value); - } - - [Fact] - public void BinaryFormattedObject_ParseStringArrayList() - { - BinaryFormattedObject format = new ArrayList() - { - "JarJar" - }.SerializeAndParse(); - - SystemClassWithMembersAndTypes systemClass = (SystemClassWithMembersAndTypes)format[1]; - - systemClass.Name.Should().Be(typeof(ArrayList).FullName); - systemClass.MemberNames.Should().BeEquivalentTo(new string[] { "_items", "_size", "_version" }); - systemClass.MemberTypeInfo[0].Should().Be((BinaryType.ObjectArray, null)); - - ArraySingleObject array = (ArraySingleObject)format[2]; - BinaryObjectString binaryString = (BinaryObjectString)array[0]; - binaryString.Value.Should().Be("JarJar"); - } - - public static TheoryData ArrayList_Primitive_Data => new() - { - int.MaxValue, - uint.MaxValue, - long.MaxValue, - ulong.MaxValue, - short.MaxValue, - ushort.MaxValue, - byte.MaxValue, - sbyte.MaxValue, - true, - float.MaxValue, - double.MaxValue, - char.MaxValue, - TimeSpan.MaxValue, - DateTime.MaxValue, - decimal.MaxValue, - }; - - public static TheoryData ArrayLists_TestData => new() - { - new ArrayList(), - new ArrayList() - { - int.MaxValue, - uint.MaxValue, - long.MaxValue, - ulong.MaxValue, - short.MaxValue, - ushort.MaxValue, - byte.MaxValue, - sbyte.MaxValue, - true, - float.MaxValue, - double.MaxValue, - char.MaxValue, - TimeSpan.MaxValue, - DateTime.MaxValue, - decimal.MaxValue, - "You betcha" - }, - new ArrayList() { "Same", "old", "same", "old" } - }; - - public static TheoryData ArrayLists_UnsupportedTestData => new() - { - new ArrayList() - { - new object(), - }, - new ArrayList() - { - int.MaxValue, - new Point() - } - }; - - [Fact] - public void BinaryFormattedObject_ParseEmptyIntList() - { - BinaryFormattedObject format = new List().SerializeAndParse(); - SystemClassWithMembersAndTypes classInfo = (SystemClassWithMembersAndTypes)format[1]; - - // Note that T types are serialized as the mscorlib type. - classInfo.Name.Should().Be( - "System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"); - - classInfo.ClassInfo.MemberNames.Should().BeEquivalentTo(new string[] - { - "_items", - // This is something that wouldn't be needed if List implemented ISerializable. If we format - // we can save any extra unused array spots. - "_size", - // It is a bit silly that _version gets serialized, it's only use is as a check to see if - // the collection is modified while it is being enumerated. - "_version" - }); - classInfo.MemberTypeInfo[0].Should().Be((BinaryType.PrimitiveArray, PrimitiveType.Int32)); - classInfo.MemberTypeInfo[1].Should().Be((BinaryType.Primitive, PrimitiveType.Int32)); - classInfo.MemberTypeInfo[2].Should().Be((BinaryType.Primitive, PrimitiveType.Int32)); - classInfo["_items"].Should().BeOfType(); - classInfo["_size"].Should().Be(0); - classInfo["_version"].Should().Be(0); - - ArraySinglePrimitive array = (ArraySinglePrimitive)format[2]; - array.Length.Should().Be(0); - } - - [Fact] - public void BinaryFormattedObject_ParseEmptyStringList() - { - BinaryFormattedObject format = new List().SerializeAndParse(); - SystemClassWithMembersAndTypes classInfo = (SystemClassWithMembersAndTypes)format[1]; - classInfo.ClassInfo.Name.Should().StartWith("System.Collections.Generic.List`1[[System.String,"); - classInfo.MemberTypeInfo[0].Should().Be((BinaryType.StringArray, null)); - classInfo["_items"].Should().BeOfType(); - - ArraySingleString array = (ArraySingleString)format[2]; - array.Length.Should().Be(0); - } - - [Theory] - [MemberData(nameof(PrimitiveLists_TestData))] - public void BinaryFormatWriter_TryWritePrimitiveList(IList list) - { - using MemoryStream stream = new(); - BinaryFormatWriter.TryWritePrimitiveList(stream, list).Should().BeTrue(); - stream.Position = 0; - - using var formatterScope = new BinaryFormatterScope(enable: true); -#pragma warning disable SYSLIB0011 // Type or member is obsolete - BinaryFormatter formatter = new(); - IList deserialized = (IList)formatter.Deserialize(stream); -#pragma warning restore SYSLIB0011 - - deserialized.Should().BeEquivalentTo(list); - } - - [Theory] - [MemberData(nameof(Lists_UnsupportedTestData))] - public void BinaryFormatWriter_TryWritePrimitiveList_Unsupported(IList list) - { - using MemoryStream stream = new(); - BinaryFormatWriter.TryWritePrimitiveList(stream, list).Should().BeFalse(); - stream.Position.Should().Be(0); - } - - [Theory] - [MemberData(nameof(PrimitiveLists_TestData))] - public void BinaryFormattedObjectExtensions_TryGetPrimitiveList(IList list) - { - BinaryFormattedObject format = list.SerializeAndParse(); - format.TryGetPrimitiveList(out object? deserialized).Should().BeTrue(); - deserialized.Should().BeEquivalentTo(list); - } - - public static TheoryData PrimitiveLists_TestData => new() - { - new List(), - new List() { 3.14f }, - new List() { float.NaN, float.PositiveInfinity, float.NegativeInfinity, float.NegativeZero }, - new List() { 1, 3, 4, 5, 6, 7 }, - new List() { 0xDE, 0xAD, 0xBE, 0xEF }, - new List() { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' }, - new List() { 'a', '\0', 'c' }, - new List() { "Believe", "it", "or", "not" }, - new List() { 42m }, - new List() { new(2000, 1, 1) }, - new List() { new(0, 0, 50) } - }; - - public static TheoryData Lists_UnsupportedTestData => new() - { - new List(), - new List(), - new List<(int, int)>() - }; -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/MemberTypeInfoTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/MemberTypeInfoTests.cs deleted file mode 100644 index fe4099e4745..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/MemberTypeInfoTests.cs +++ /dev/null @@ -1,69 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class MemberTypeInfoTests -{ - private static readonly byte[] s_hashtableMemberInfo = new byte[] - { - 0x00, 0x00, 0x03, 0x03, 0x00, 0x05, 0x05, 0x0b, 0x08, 0x1c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x49, 0x43, 0x6f, - 0x6d, 0x70, 0x61, 0x72, 0x65, 0x72, 0x24, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x43, 0x6f, - 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x49, 0x48, 0x61, 0x73, 0x68, 0x43, - 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x08 - }; - - [Fact] - public void MemberTypeInfo_ReadHashtable() - { - using BinaryReader reader = new(new MemoryStream(s_hashtableMemberInfo)); - MemberTypeInfo info = MemberTypeInfo.Parse(reader, 7); - - info.Should().BeEquivalentTo(new (BinaryType Type, object? Info)[] - { - (BinaryType.Primitive, PrimitiveType.Single), - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.SystemClass, "System.Collections.IComparer"), - (BinaryType.SystemClass, "System.Collections.IHashCodeProvider"), - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.ObjectArray, null), - (BinaryType.ObjectArray, null) - }); - } - - [Fact] - public void MemberTypeInfo_HashtableRoundTrip() - { - using BinaryReader reader = new(new MemoryStream(s_hashtableMemberInfo)); - MemberTypeInfo info = MemberTypeInfo.Parse(reader, 7); - - MemoryStream stream = new(); - BinaryWriter writer = new(stream); - info.Write(writer); - stream.Position = 0; - - using BinaryReader reader2 = new(stream); - info = MemberTypeInfo.Parse(reader2, 7); - info.Should().BeEquivalentTo(new (BinaryType Type, object? Info)[] - { - (BinaryType.Primitive, PrimitiveType.Single), - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.SystemClass, "System.Collections.IComparer"), - (BinaryType.SystemClass, "System.Collections.IHashCodeProvider"), - (BinaryType.Primitive, PrimitiveType.Int32), - (BinaryType.ObjectArray, null), - (BinaryType.ObjectArray, null) - }); - } - - [Fact] - public void MemberTypeInfo_ReadHashtable_TooShort() - { - MemoryStream stream = new(s_hashtableMemberInfo); - stream.SetLength(stream.Length - 1); - using BinaryReader reader = new(stream); - Action action = () => MemberTypeInfo.Parse(reader, 7); - action.Should().Throw(); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/NullTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/NullTests.cs deleted file mode 100644 index b57769c0bb1..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/NullTests.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class NullTests -{ - [Fact] - public void ObjectNullMultiple256_ThrowsOverflowOnWrite() - { - // We read a byte on the way in so there is nothing to check. - - NullRecord.ObjectNullMultiple256 objectNull = new(1000); - - using BinaryWriter writer = new(new MemoryStream()); - Action action = () => objectNull.Write(writer); - action.Should().Throw(); - } - - [Fact] - public void ObjectNullMultiple256_WritesCorrectly() - { - NullRecord.ObjectNullMultiple256 objectNull = new(0xCA); - - byte[] buffer = new byte[2]; - using BinaryWriter writer = new(new MemoryStream(buffer)); - objectNull.Write(writer); - buffer.Should().BeEquivalentTo(new byte[] { (byte)NullRecord.ObjectNullMultiple256.RecordType, 0xCA }); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/PointFTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/PointFTests.cs deleted file mode 100644 index ad1a7a42f7e..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/PointFTests.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class PointFTests -{ - [Fact] - public void PointF_Parse() - { - BinaryFormattedObject format = new PointF().SerializeAndParse(); - - BinaryLibrary binaryLibrary = (BinaryLibrary)format[1]; - binaryLibrary.LibraryId.Should().Be(2); - binaryLibrary.LibraryName.Should().Be("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); - - ClassWithMembersAndTypes classInfo = (ClassWithMembersAndTypes)format[2]; - classInfo.ObjectId.Should().Be(1); - classInfo.Name.Should().Be("System.Drawing.PointF"); - classInfo.MemberNames.Should().BeEquivalentTo(new string[] { "x", "y" }); - classInfo.MemberValues.Should().BeEquivalentTo(new object[] { 0.0f, 0.0f }); - classInfo.MemberTypeInfo.Should().BeEquivalentTo(new[] - { - (BinaryType.Primitive, PrimitiveType.Single), - (BinaryType.Primitive, PrimitiveType.Single) - }); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/PrimitiveTypeTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/PrimitiveTypeTests.cs deleted file mode 100644 index 2548a9c368f..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/PrimitiveTypeTests.cs +++ /dev/null @@ -1,158 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.Serialization.Formatters.Binary; -using System.Text; - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class PrimitiveTypeTests -{ - [Theory] - [MemberData(nameof(RoundTrip_Data))] - public void WriteReadPrimitiveValue_RoundTrip(byte type, object value) - { - MemoryStream stream = new(); - using (BinaryWriter writer = new(stream, Encoding.UTF8, leaveOpen: true)) - { - TestRecord.WritePrimitiveValue(writer, (PrimitiveType)type, value); - } - - stream.Position = 0; - - using BinaryReader reader = new(stream); - object result = TestRecord.ReadPrimitiveValue(reader, (PrimitiveType)type); - result.Should().Be(value); - } - - public static TheoryData RoundTrip_Data => new() - { - { (byte)PrimitiveType.Int64, 0L }, - { (byte)PrimitiveType.Int64, -1L }, - { (byte)PrimitiveType.Int64, 1L }, - { (byte)PrimitiveType.Int64, long.MaxValue }, - { (byte)PrimitiveType.Int64, long.MinValue }, - { (byte)PrimitiveType.UInt64, ulong.MaxValue }, - { (byte)PrimitiveType.UInt64, ulong.MinValue }, - { (byte)PrimitiveType.Int32, 0 }, - { (byte)PrimitiveType.Int32, -1 }, - { (byte)PrimitiveType.Int32, 1 }, - { (byte)PrimitiveType.Int32, int.MaxValue }, - { (byte)PrimitiveType.Int32, int.MinValue }, - { (byte)PrimitiveType.UInt32, uint.MaxValue }, - { (byte)PrimitiveType.UInt32, uint.MinValue }, - { (byte)PrimitiveType.Int16, (short)0 }, - { (byte)PrimitiveType.Int16, (short)-1 }, - { (byte)PrimitiveType.Int16, (short)1 }, - { (byte)PrimitiveType.Int16, short.MaxValue }, - { (byte)PrimitiveType.Int16, short.MinValue }, - { (byte)PrimitiveType.UInt16, ushort.MaxValue }, - { (byte)PrimitiveType.UInt16, ushort.MinValue }, - { (byte)PrimitiveType.SByte, (sbyte)0 }, - { (byte)PrimitiveType.SByte, (sbyte)-1 }, - { (byte)PrimitiveType.SByte, (sbyte)1 }, - { (byte)PrimitiveType.SByte, sbyte.MaxValue }, - { (byte)PrimitiveType.SByte, sbyte.MinValue }, - { (byte)PrimitiveType.Byte, byte.MinValue }, - { (byte)PrimitiveType.Byte, byte.MaxValue }, - { (byte)PrimitiveType.Boolean, true }, - { (byte)PrimitiveType.Boolean, false }, - { (byte)PrimitiveType.Single, 0.0f }, - { (byte)PrimitiveType.Single, -1.0f }, - { (byte)PrimitiveType.Single, 1.0f }, - { (byte)PrimitiveType.Single, float.MaxValue }, - { (byte)PrimitiveType.Single, float.MinValue }, - { (byte)PrimitiveType.Single, float.NegativeZero }, - { (byte)PrimitiveType.Single, float.NaN }, - { (byte)PrimitiveType.Single, float.NegativeInfinity }, - { (byte)PrimitiveType.Double, 0.0d }, - { (byte)PrimitiveType.Double, -1.0d }, - { (byte)PrimitiveType.Double, 1.0d }, - { (byte)PrimitiveType.Double, double.MaxValue }, - { (byte)PrimitiveType.Double, double.MinValue }, - { (byte)PrimitiveType.Double, double.NegativeZero }, - { (byte)PrimitiveType.Double, double.NaN }, - { (byte)PrimitiveType.Double, double.NegativeInfinity }, - { (byte)PrimitiveType.TimeSpan, TimeSpan.MinValue }, - { (byte)PrimitiveType.TimeSpan, TimeSpan.MaxValue }, - { (byte)PrimitiveType.DateTime, DateTime.MinValue }, - { (byte)PrimitiveType.DateTime, DateTime.MaxValue }, - }; - - [Theory] - [MemberData(nameof(Primitive_Data))] - public void PrimitiveTypeMemberName(object value) - { - BinaryFormattedObject format = value.SerializeAndParse(); - SystemClassWithMembersAndTypes systemClass = (SystemClassWithMembersAndTypes)format[1]; - systemClass.MemberNames[0].Should().Be("m_value"); - systemClass.MemberValues.Count.Should().Be(1); - } - - [Theory] - [MemberData(nameof(Primitive_Data))] - [MemberData(nameof(Primitive_ExtendedData))] - public void BinaryFormatWriter_WritePrimitive(object value) - { - MemoryStream stream = new(); - BinaryFormatWriter.WritePrimitive(stream, value); - stream.Position = 0; - - using BinaryFormatterScope formatterScope = new(enable: true); -#pragma warning disable SYSLIB0011 // Type or member is obsolete - BinaryFormatter formatter = new(); -#pragma warning restore SYSLIB0011 // Type or member is obsolete - object deserialized = formatter.Deserialize(stream); - deserialized.Should().Be(value); - } - - [Theory] - [MemberData(nameof(Primitive_Data))] - [MemberData(nameof(Primitive_ExtendedData))] - public void BinaryFormattedObject_ReadPrimitive(object value) - { - BinaryFormattedObject formattedObject = value.SerializeAndParse(); - formattedObject.TryGetPrimitiveType(out object? deserialized).Should().BeTrue(); - deserialized.Should().Be(value); - } - - public static TheoryData Primitive_Data => new() - { - int.MaxValue, - uint.MaxValue, - long.MaxValue, - ulong.MaxValue, - short.MaxValue, - ushort.MaxValue, - byte.MaxValue, - sbyte.MaxValue, - true, - float.MaxValue, - double.MaxValue, - char.MaxValue - }; - - public static TheoryData Primitive_ExtendedData => new() - { - TimeSpan.MaxValue, - DateTime.MaxValue, - decimal.MaxValue, - (nint)1918, - (nuint)2020, - "Roundabout" - }; - - internal class TestRecord : Record - { - public static void WritePrimitiveValue(BinaryWriter writer, PrimitiveType type, object value) - => WritePrimitiveType(writer, type, value); - - public static object ReadPrimitiveValue(BinaryReader reader, PrimitiveType type) - => ReadPrimitiveType(reader, type); - - public override void Write(BinaryWriter writer) - { - throw new NotImplementedException(); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/RecordMapTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/RecordMapTests.cs deleted file mode 100644 index 5a7e529b149..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/RecordMapTests.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class RecordMapTests -{ - private class Record : IRecord - { - void IBinaryWriteable.Write(BinaryWriter writer) { } - } - - [Fact] - public void RecordMap_CannotAddSameIndexTwice() - { - RecordMap map = new(); - Action action = () => map[1] = new Record(); - action(); - action.Should().Throw(); - } - - [Fact] - public void RecordMap_GetMissingThrowsKeyNotFound() - { - RecordMap map = new(); - Func func = () => map[0]; - func.Should().Throw(); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/StringRecordsCollectionTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/StringRecordsCollectionTests.cs deleted file mode 100644 index 36c83e59f39..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/StringRecordsCollectionTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class StringRecordsCollectionTests -{ - [Fact] - public void BasicFunctionality() - { - StringRecordsCollection collection = new(currentId: 1); - IRecord record = collection.GetStringRecord("Foo"); - collection.CurrentId.Should().Be(2); - record.Should().BeOfType(); - ((BinaryObjectString)record).ObjectId.Should().Be(1); - - record = collection.GetStringRecord("Foo"); - collection.CurrentId.Should().Be(2); - record.Should().BeOfType(); - ((MemberReference)record).IdRef.Should().Be(1); - - record = collection.GetStringRecord("Bar"); - collection.CurrentId.Should().Be(3); - record.Should().BeOfType(); - ((BinaryObjectString)record).ObjectId.Should().Be(2); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/SystemDrawingTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/SystemDrawingTests.cs deleted file mode 100644 index 3798293bfa0..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/BinaryFormat/SystemDrawingTests.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; - -namespace System.Windows.Forms.BinaryFormat.Tests; - -public class SystemDrawingTests -{ - [Fact] - public void PointF_Parse() - { - BinaryFormattedObject format = new PointF().SerializeAndParse(); - - BinaryLibrary binaryLibrary = (BinaryLibrary)format[1]; - binaryLibrary.LibraryId.Should().Be(2); - binaryLibrary.LibraryName.ToString().Should().Be("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); - - ClassWithMembersAndTypes classInfo = (ClassWithMembersAndTypes)format[2]; - classInfo.ObjectId.Should().Be(1); - classInfo.Name.Should().Be("System.Drawing.PointF"); - classInfo.MemberNames.Should().BeEquivalentTo(new string[] { "x", "y" }); - classInfo.MemberValues.Should().BeEquivalentTo(new object[] { 0.0f, 0.0f }); - classInfo.MemberTypeInfo.Should().BeEquivalentTo(new[] - { - (BinaryType.Primitive, PrimitiveType.Single), - (BinaryType.Primitive, PrimitiveType.Single) - }); - } - - [Fact] - public void RectangleF_Parse() - { - BinaryFormattedObject format = new RectangleF().SerializeAndParse(); - - BinaryLibrary binaryLibrary = (BinaryLibrary)format[1]; - binaryLibrary.LibraryId.Should().Be(2); - binaryLibrary.LibraryName.ToString().Should().Be("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); - - ClassWithMembersAndTypes classInfo = (ClassWithMembersAndTypes)format[2]; - classInfo.ObjectId.Should().Be(1); - classInfo.Name.Should().Be("System.Drawing.RectangleF"); - classInfo.MemberNames.Should().BeEquivalentTo(new string[] { "x", "y", "width", "height" }); - classInfo.MemberValues.Should().BeEquivalentTo(new object[] { 0.0f, 0.0f, 0.0f, 0.0f }); - classInfo.MemberTypeInfo.Should().BeEquivalentTo(new[] - { - (BinaryType.Primitive, PrimitiveType.Single), - (BinaryType.Primitive, PrimitiveType.Single), - (BinaryType.Primitive, PrimitiveType.Single), - (BinaryType.Primitive, PrimitiveType.Single) - }); - } - - public static TheoryData SystemDrawing_TestData => new() - { - new PointF(), - new RectangleF() - }; -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/DeviceContextHdcScopeTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/DeviceContextHdcScopeTests.cs deleted file mode 100644 index 9783097eec3..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/DeviceContextHdcScopeTests.cs +++ /dev/null @@ -1,341 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Drawing.Drawing2D; -using Moq; -using static Interop; - -namespace System.Windows.Forms.Tests; - -public class DeviceContextHdcScopeTests -{ - [Fact] - public unsafe void CreateWithGraphicsBasedOnImageAppliesRequestedParameters() - { - using Bitmap b = new Bitmap(10, 10); - using Graphics g = Graphics.FromImage(b); - - Rectangle clipRectangle = new Rectangle(1, 1, 5, 5); - using Region r = new Region(clipRectangle); - g.Clip = r; - - Matrix transform = new Matrix(); - transform.Translate(1.0f, 2.0f); - g.Transform = transform; - - // Just the translation transform - using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.TranslateTransform)) - { - Point origin = default; - PInvoke.GetViewportOrgEx(scope, &origin); - Assert.Equal(new Point(1, 2), origin); - - RECT clipRect = default; - RegionType regionType = (RegionType)PInvoke.GetClipBox(scope, &clipRect); - Assert.Equal(RegionType.SIMPLEREGION, regionType); - Assert.Equal(new Rectangle(-1, -2, 10, 10), (Rectangle)clipRect); - - Assert.Equal(g, scope.DeviceContext); - } - - // Just the clipping - using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.Clipping)) - { - Point origin = default; - PInvoke.GetViewportOrgEx(scope, &origin); - Assert.Equal(new Point(0, 0), origin); - - RECT clipRect = default; - RegionType regionType = (RegionType)PInvoke.GetClipBox(scope, &clipRect); - Assert.Equal(RegionType.SIMPLEREGION, regionType); - Assert.Equal(clipRectangle, (Rectangle)clipRect); - - Assert.Equal(g, scope.DeviceContext); - } - - // Both - using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.All)) - { - Point origin = default; - PInvoke.GetViewportOrgEx(scope, &origin); - Assert.Equal(new Point(1, 2), origin); - - RECT clipRect = default; - RegionType regionType = (RegionType)PInvoke.GetClipBox(scope, &clipRect); - Assert.Equal(RegionType.SIMPLEREGION, regionType); - Assert.Equal(new Rectangle(0, -1, 5, 5), (Rectangle)clipRect); - - Assert.Equal(g, scope.DeviceContext); - } - - // Nothing - using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.None)) - { - Point origin = default; - PInvoke.GetViewportOrgEx(scope, &origin); - Assert.Equal(new Point(0, 0), origin); - - RECT clipRect = default; - RegionType regionType = (RegionType)PInvoke.GetClipBox(scope, &clipRect); - Assert.Equal(RegionType.SIMPLEREGION, regionType); - Assert.Equal(new Rectangle(0, 0, 10, 10), (Rectangle)clipRect); - - Assert.Equal(g, scope.DeviceContext); - } - - // Validating we've unlocked the graphics object - g.DrawLine(Pens.DarkBlue, default, default); - } - - [Fact] - public unsafe void CreateWithGraphicsBasedOnHdcAppliesRequestedParameters() - { - using var hdc = GetDcScope.ScreenDC; - RECT originalClipRect = default; - RegionType originalRegionType = (RegionType)PInvoke.GetClipBox(hdc, &originalClipRect); - Point originalOrigin = default; - PInvoke.GetViewportOrgEx(hdc, &originalOrigin); - - using Graphics g = Graphics.FromHdcInternal(hdc); - - Rectangle clipRectangle = new Rectangle(1, 1, 5, 5); - using Region r = new Region(clipRectangle); - g.Clip = r; - - Matrix transform = new Matrix(); - transform.Translate(1.0f, 2.0f); - g.Transform = transform; - - // Just the translation transform - using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.TranslateTransform)) - { - Point origin = default; - PInvoke.GetViewportOrgEx(scope, &origin); - Assert.Equal(new Point(1, 2), origin); - - RECT clipRect = default; - RegionType regionType = (RegionType)PInvoke.GetClipBox(scope, &clipRect); - Assert.Equal(originalRegionType, regionType); - Rectangle expectedClipRect = originalClipRect; - expectedClipRect.X -= 1; - expectedClipRect.Y -= 2; - Assert.Equal(expectedClipRect, (Rectangle)clipRect); - - Assert.Equal(g, scope.DeviceContext); - Assert.Equal(hdc, scope.HDC); - } - - // Should be in original state - RECT currentClipRect = default; - PInvoke.GetClipBox(hdc, ¤tClipRect); - Point currentOrigin = default; - PInvoke.GetViewportOrgEx(hdc, ¤tOrigin); - Assert.Equal(originalClipRect, currentClipRect); - Assert.Equal(originalOrigin, currentOrigin); - - // Just the clipping - using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.Clipping)) - { - Point origin = default; - PInvoke.GetViewportOrgEx(scope, &origin); - Assert.Equal(new Point(0, 0), origin); - - RECT clipRect = default; - RegionType regionType = (RegionType)PInvoke.GetClipBox(scope, &clipRect); - Assert.Equal(RegionType.SIMPLEREGION, regionType); - Assert.Equal(clipRectangle, (Rectangle)clipRect); - - Assert.Equal(g, scope.DeviceContext); - Assert.Equal(hdc, scope.HDC); - } - - // Should be in original state - currentClipRect = default; - PInvoke.GetClipBox(hdc, ¤tClipRect); - PInvoke.GetViewportOrgEx(hdc, ¤tOrigin); - Assert.Equal(originalClipRect, currentClipRect); - Assert.Equal(originalOrigin, currentOrigin); - - // Both - using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.All)) - { - Point origin = default; - PInvoke.GetViewportOrgEx(scope, &origin); - Assert.Equal(new Point(1, 2), origin); - - RECT clipRect = default; - RegionType regionType = (RegionType)PInvoke.GetClipBox(scope, &clipRect); - Assert.Equal(RegionType.SIMPLEREGION, regionType); - Assert.Equal(new Rectangle(0, -1, 5, 5), (Rectangle)clipRect); - - Assert.Equal(g, scope.DeviceContext); - Assert.Equal(hdc, scope.HDC); - } - - // Should be in original state - currentClipRect = default; - PInvoke.GetClipBox(hdc, ¤tClipRect); - PInvoke.GetViewportOrgEx(hdc, ¤tOrigin); - Assert.Equal(originalClipRect, currentClipRect); - Assert.Equal(originalOrigin, currentOrigin); - - // Nothing - using (var scope = new DeviceContextHdcScope(g, ApplyGraphicsProperties.None)) - { - Point origin = default; - PInvoke.GetViewportOrgEx(scope, &origin); - Assert.Equal(new Point(0, 0), origin); - - RECT clipRect = default; - RegionType regionType = (RegionType)PInvoke.GetClipBox(scope, &clipRect); - Assert.Equal(originalRegionType, regionType); - Assert.Equal((Rectangle)originalClipRect, (Rectangle)clipRect); - - Assert.Equal(g, scope.DeviceContext); - Assert.Equal(hdc, scope.HDC); - } - - // Should be in original state - currentClipRect = default; - PInvoke.GetClipBox(hdc, ¤tClipRect); - PInvoke.GetViewportOrgEx(hdc, ¤tOrigin); - Assert.Equal(originalClipRect, currentClipRect); - Assert.Equal(originalOrigin, currentOrigin); - - // Validating we've unlocked the graphics object - g.DrawLine(Pens.DarkBlue, default, default); - } - - [Theory] - [InlineData((int)ApplyGraphicsProperties.TranslateTransform)] - [InlineData((int)ApplyGraphicsProperties.Clipping)] - [InlineData((int)ApplyGraphicsProperties.All)] - [InlineData((int)ApplyGraphicsProperties.None)] - public void CreateFromCleanIGraphicsHdcProviderDoesNotCreateGraphics(int apply) - { - using var hdc = GetDcScope.ScreenDC; - var mockHdcProvider = new Mock(); - var mockIDeviceContext = mockHdcProvider.As(); - mockHdcProvider - .Setup(p => p.IsGraphicsStateClean) - .Returns(true); - mockHdcProvider - .Setup(p => p.GetHDC()) - .Returns(hdc); - - using (var scope = new DeviceContextHdcScope(mockIDeviceContext.Object, (ApplyGraphicsProperties)apply)) - { - Assert.Equal(hdc, scope.HDC); - Assert.Equal(mockIDeviceContext.Object, scope.DeviceContext); - - mockHdcProvider.VerifyGet(p => p.IsGraphicsStateClean, Times.AtLeastOnce()); - mockHdcProvider.Verify(p => p.GetHDC(), Times.Once()); - mockHdcProvider.VerifyNoOtherCalls(); - mockIDeviceContext.VerifyNoOtherCalls(); - } - - // If we didn't create a graphics there is no need to release the HDC - mockHdcProvider.VerifyNoOtherCalls(); - mockIDeviceContext.VerifyNoOtherCalls(); - } - - [Theory] - [InlineData((int)ApplyGraphicsProperties.TranslateTransform)] - [InlineData((int)ApplyGraphicsProperties.Clipping)] - [InlineData((int)ApplyGraphicsProperties.All)] - public void CreateFromDirtyIGraphicsHdcProviderCreatesGraphics(int apply) - { - using Bitmap b = new Bitmap(10, 10); - using Graphics g = Graphics.FromImage(b); - - HDC mockHdc = new HDC((IntPtr)1234); - var mockHdcProvider = new Mock(); - var mockIDeviceContext = mockHdcProvider.As(); - mockHdcProvider - .Setup(p => p.IsGraphicsStateClean) - .Returns(false); - mockHdcProvider - .Setup(p => p.GetHDC()) - .Returns(mockHdc); - mockHdcProvider - .Setup(p => p.GetGraphics(true)) - .Returns(g); - - using (var scope = new DeviceContextHdcScope(mockIDeviceContext.Object, (ApplyGraphicsProperties)apply)) - { - Assert.NotEqual(mockHdc, scope.HDC); - Assert.Equal(g, scope.DeviceContext); - - mockHdcProvider.VerifyGet(p => p.IsGraphicsStateClean, Times.AtLeastOnce()); - mockHdcProvider.Verify(p => p.GetGraphics(true), Times.Once()); - mockHdcProvider.VerifyNoOtherCalls(); - mockIDeviceContext.VerifyNoOtherCalls(); - } - - // The graphics object itself will be called to release - mockHdcProvider.VerifyNoOtherCalls(); - mockIDeviceContext.VerifyNoOtherCalls(); - - // Validating we've unlocked the graphics object - g.DrawLine(Pens.DarkBlue, default, default); - } - - [Fact] - public void CreateFromDirtyIGraphicsHdcProviderDoesNotCreateGraphics() - { - // If we don't request to apply properties, there is no need to get the graphics. - - using var hdc = GetDcScope.ScreenDC; - var mockHdcProvider = new Mock(); - var mockIDeviceContext = mockHdcProvider.As(); - mockHdcProvider - .Setup(p => p.IsGraphicsStateClean) - .Returns(false); - mockHdcProvider - .Setup(p => p.GetHDC()) - .Returns(hdc); - - using (var scope = new DeviceContextHdcScope(mockIDeviceContext.Object, ApplyGraphicsProperties.None)) - { - Assert.Equal(hdc, scope.HDC); - Assert.Equal(mockIDeviceContext.Object, scope.DeviceContext); - - mockHdcProvider.VerifyGet(p => p.IsGraphicsStateClean, Times.AtLeastOnce()); - mockHdcProvider.Verify(p => p.GetHDC(), Times.Once()); - mockHdcProvider.VerifyNoOtherCalls(); - mockIDeviceContext.VerifyNoOtherCalls(); - } - - // We don't release anything as we haven't locked a Graphics object - mockHdcProvider.VerifyNoOtherCalls(); - mockIDeviceContext.VerifyNoOtherCalls(); - } - - [Theory] - [InlineData((int)ApplyGraphicsProperties.TranslateTransform)] - [InlineData((int)ApplyGraphicsProperties.Clipping)] - [InlineData((int)ApplyGraphicsProperties.All)] - [InlineData((int)ApplyGraphicsProperties.None)] - public void CreateFromIDeviceContext(int apply) - { - using var hdc = GetDcScope.ScreenDC; - var mockIDeviceContext = new Mock(); - mockIDeviceContext - .Setup(p => p.GetHdc()) - .Returns(hdc); - mockIDeviceContext - .Setup(p => p.ReleaseHdc()); - - using (var scope = new DeviceContextHdcScope(mockIDeviceContext.Object, (ApplyGraphicsProperties)apply)) - { - Assert.Equal(hdc, scope.HDC); - Assert.Equal(mockIDeviceContext.Object, scope.DeviceContext); - - mockIDeviceContext.Verify(p => p.GetHdc(), Times.Once); - mockIDeviceContext.VerifyNoOtherCalls(); - } - - mockIDeviceContext.Verify(p => p.ReleaseHdc(), Times.Once); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/DeviceContextScopeTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/DeviceContextScopeTests.cs deleted file mode 100644 index 2db959c4ef3..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/DeviceContextScopeTests.cs +++ /dev/null @@ -1,107 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Runtime.InteropServices; -using static Interop; - -namespace System.Windows.Forms.Tests; - -public class DeviceContextScopeTests -{ - [DllImport(Libraries.Gdi32, SetLastError = true, ExactSpelling = true)] - private static extern int GetRandomRgn(HDC hdc, HRGN hrgn, int i); - - [Fact] - public unsafe void Scope_ApplyGraphicsProperties() - { - // Create a bitmap using the screen's stats - using PInvoke.CreateDcScope dcScope = new(default); - using PInvoke.CreateBitmapScope bitmapScope = new(dcScope, 20, 20); - PInvoke.SelectObject(dcScope, bitmapScope); - - // Select a clipping region into the DC - using var dcRegion = new PInvoke.RegionScope(2, 1, 4, 7); - RegionType type = (RegionType)PInvoke.SelectClipRgn(dcScope, dcRegion); - Assert.Equal(RegionType.SIMPLEREGION, type); - - using var test = new PInvoke.RegionScope(0, 0, 0, 0); - int result = GetRandomRgn(dcScope, test, 1); - RECT rect2 = default; - type = (RegionType)PInvoke.GetRgnBox(test, &rect2); - - // Create a Graphics object and set it's clipping region - using Graphics graphics = dcScope.CreateGraphics(); - using Region oldRegion = graphics.Clip; - - // The existing region should be infinite (no clipping) - Assert.True(oldRegion.IsInfinite(graphics)); - - // Add a new region and transform - using Region region = new Region(new Rectangle(1, 1, 2, 3)); - graphics.Clip = region; - graphics.Transform = new Matrix(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f); - - using var hdcScope = new DeviceContextHdcScope(graphics); - using var regionScope = new PInvoke.RegionScope(hdcScope); - Assert.False(regionScope.IsNull); - RECT rect = default; - type = (RegionType)PInvoke.GetRgnBox(regionScope, &rect); - - // Our clipping region should be the intersection - Assert.Equal(new Rectangle(2, 1, 1, 3), (Rectangle)rect); - } - - [Fact] - public void Graphics_HdcStatePersistence() - { - // Create a bitmap using the screen's stats - using PInvoke.CreateDcScope dcScope = new(default); - using PInvoke.CreateBitmapScope bitmapScope = new(dcScope, 20, 20); - HDC_MAP_MODE originalMapMode = (HDC_MAP_MODE)PInvoke.SetMapMode(dcScope, HDC_MAP_MODE.MM_HIMETRIC); - PInvoke.SelectObject(dcScope, bitmapScope); - - using PInvoke.CreateBrushScope blueBrush = new(Color.Blue); - using PInvoke.CreateBrushScope redBrush = new(Color.Red); - PInvoke.SelectObject(dcScope, blueBrush); - - using Graphics graphics = dcScope.CreateGraphics(); - HGDIOBJ current = PInvoke.GetCurrentObject(dcScope, OBJ_TYPE.OBJ_BRUSH); - - HDC_MAP_MODE currentMode = (HDC_MAP_MODE)PInvoke.GetMapMode(dcScope); - Assert.Equal(HDC_MAP_MODE.MM_HIMETRIC, currentMode); - - IntPtr hdc = graphics.GetHdc(); - currentMode = (HDC_MAP_MODE)PInvoke.SetMapMode(dcScope, HDC_MAP_MODE.MM_TEXT); - Assert.Equal(HDC_MAP_MODE.MM_HIMETRIC, currentMode); - try - { - // We get the same HDC out - Assert.Equal(dcScope.HDC, (HDC)hdc); - current = PInvoke.GetCurrentObject(dcScope, OBJ_TYPE.OBJ_BRUSH); - Assert.Equal(blueBrush.HBRUSH, (HBRUSH)current); - PInvoke.SelectObject(dcScope, redBrush); - } - finally - { - graphics.ReleaseHdc(hdc); - currentMode = (HDC_MAP_MODE)PInvoke.GetMapMode(dcScope); - Assert.Equal(HDC_MAP_MODE.MM_TEXT, currentMode); - current = PInvoke.GetCurrentObject(dcScope, OBJ_TYPE.OBJ_BRUSH); - - graphics.GetHdc(); - try - { - currentMode = (HDC_MAP_MODE)PInvoke.GetMapMode(dcScope); - Assert.Equal(HDC_MAP_MODE.MM_TEXT, currentMode); - } - finally - { - graphics.ReleaseHdc(hdc); - } - } - - current = PInvoke.GetCurrentObject(dcScope, OBJ_TYPE.OBJ_BRUSH); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/FileDialogCustomPlaceTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/FileDialogCustomPlaceTests.cs deleted file mode 100644 index 515dab0b718..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/FileDialogCustomPlaceTests.cs +++ /dev/null @@ -1,93 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Tests; - -public class FileDialogCustomPlaceTests -{ - public static TheoryData GetStringWithNullTheoryData() - { - var data = new TheoryData - { - null, - string.Empty, - "reasonable" - }; - return data; - } - - [Theory] - [MemberData(nameof(GetStringWithNullTheoryData))] - public void FileDialogCustomPlace_Ctor_String(string? path) - { - var place = new FileDialogCustomPlace(path); - Assert.Equal(Guid.Empty, place.KnownFolderGuid); - Assert.Same(path ?? string.Empty, place.Path); - } - - public static TheoryData GetGuidTheoryData() - { - var data = new TheoryData - { - Guid.Empty, - Guid.NewGuid() - }; - return data; - } - - [Theory] - [MemberData(nameof(GetGuidTheoryData))] - public void FileDialogCustomPlace_Ctor_Guid(Guid knownFolderGuid) - { - var place = new FileDialogCustomPlace(knownFolderGuid); - Assert.Equal(knownFolderGuid, place.KnownFolderGuid); - Assert.Empty(place.Path); - } - - [Theory] - [MemberData(nameof(GetGuidTheoryData))] - public void FileDialogCustomPlace_KnownFolderGuid_Set_GetReturnsExpected(Guid value) - { - var place = new FileDialogCustomPlace("path") - { - KnownFolderGuid = value - }; - Assert.Equal(value, place.KnownFolderGuid); - Assert.Empty(place.Path); - - // Set same. - place.KnownFolderGuid = value; - Assert.Equal(value, place.KnownFolderGuid); - Assert.Empty(place.Path); - } - - [Theory] - [MemberData(nameof(GetStringWithNullTheoryData))] - public void FileDialogCustomPlace_Path_Set_GetReturnsExpected(string? value) - { - var place = new FileDialogCustomPlace(Guid.NewGuid()) - { - Path = value - }; - Assert.Same(value ?? string.Empty, place.Path); - Assert.Equal(Guid.Empty, place.KnownFolderGuid); - - // Set same. - place.Path = value; - Assert.Same(value ?? string.Empty, place.Path); - Assert.Equal(Guid.Empty, place.KnownFolderGuid); - } - - public static IEnumerable ToString_TestData() - { - yield return new object[] { new FileDialogCustomPlace("path"), "System.Windows.Forms.FileDialogCustomPlace Path: path KnownFolderGuid: 00000000-0000-0000-0000-000000000000" }; - yield return new object[] { new FileDialogCustomPlace(new Guid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)), "System.Windows.Forms.FileDialogCustomPlace Path: KnownFolderGuid: 00000001-0002-0003-0405-060708090a0b" }; - } - - [Theory] - [MemberData(nameof(ToString_TestData))] - public void FileDialogCustomPlace_ToString_Invoke_ReturnsExpected(FileDialogCustomPlace place, string expected) - { - Assert.Equal(expected, place.ToString()); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/FileDialogCustomPlacesCollectionTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/FileDialogCustomPlacesCollectionTests.cs deleted file mode 100644 index a02c26c501b..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/FileDialogCustomPlacesCollectionTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Tests; - -public class FileDialogCustomPlacesCollectionTests -{ - public static TheoryData GetStringWithNullTheoryData() - { - var data = new TheoryData - { - null, - string.Empty, - "reasonable" - }; - return data; - } - - [Theory] - [MemberData(nameof(GetStringWithNullTheoryData))] - public void FileDialogCustomPlacesCollection_Add_String_Success(string? path) - { - var collection = new FileDialogCustomPlacesCollection - { - path - }; - FileDialogCustomPlace place = Assert.Single(collection); - Assert.Equal(Guid.Empty, place.KnownFolderGuid); - Assert.Same(path ?? string.Empty, place.Path); - } - - public static TheoryData GetGuidTheoryData() - { - var data = new TheoryData - { - Guid.Empty, - Guid.NewGuid() - }; - return data; - } - - [Theory] - [MemberData(nameof(GetGuidTheoryData))] - public void FileDialogCustomPlacesCollection_Add_Guid_Success(Guid knownFolderGuid) - { - var collection = new FileDialogCustomPlacesCollection - { - knownFolderGuid - }; - FileDialogCustomPlace place = Assert.Single(collection); - Assert.Equal(knownFolderGuid, place.KnownFolderGuid); - Assert.Empty(place.Path); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/IdTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/IdTests.cs deleted file mode 100644 index 3dac040b44f..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/IdTests.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Tests; - -public class IdTests -{ - [Fact] - public void IdSignedAreEquivalent() - { - ((Id)1).Should().Be((Id)(-1)); - } - - [Fact] - public void IdEqualsInt() - { - ((Id)4).Should().Be(4); - } - - [Fact] - public void IdEqualsId() - { - ((Id)4).Should().Be((Id)4); - } - - [Fact] - public void IdToStringIsInt() - { - ((Id)5).ToString().Should().Be("5"); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Internals/ArgumentValidationTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Internals/ArgumentValidationTests.cs deleted file mode 100644 index 3550d3611e9..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/Internals/ArgumentValidationTests.cs +++ /dev/null @@ -1,262 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Tests; - -public class ArgumentValidationTests -{ - [Fact] - public void OrThrowIfNull_ParamIsNull() - { - object? param = null; - var exception = Assert.Throws(() => _ = param.OrThrowIfNull()); - Assert.Equal(nameof(param), exception.ParamName); - } - - [Fact] - public void OrThrowIfNull_ParamIsNull_DifferentParamName() - { - string paramName = "param2"; - object? param = null; - var exception = Assert.Throws(() => _ = param.OrThrowIfNull(paramName)); - Assert.Equal(paramName, exception.ParamName); - } - - [Fact] - public void OrThrowIfNull_ParamIsNotNull() - { - var param = new object(); - var variable = param.OrThrowIfNull(); - Assert.Equal(param, variable); - } - - [Fact] - public void OrThrowIfNullWithMessage_ParamIsNull() - { - object? param = null; - var message = "message"; - var exception = Assert.Throws(() => _ = param.OrThrowIfNullWithMessage(message)); - Assert.StartsWith(message, exception.Message); - Assert.Equal(nameof(param), exception.ParamName); - } - - [Fact] - public void OrThrowIfNullWithMessage_ParamIsNull_DifferentParamName() - { - var paramName = "param2"; - object? param = null; - var message = "message"; - var exception = Assert.Throws(() => _ = param.OrThrowIfNullWithMessage(message, paramName)); - Assert.StartsWith(message, exception.Message); - Assert.Equal(paramName, exception.ParamName); - } - - [Fact] - public void OrThrowIfNullWithMessage_ParamIsNotNull() - { - var param = new object(); - var message = "message"; - var variable = param.OrThrowIfNullWithMessage(message); - Assert.Equal(param, variable); - } - - [Fact] - public void OrThrowIfZero_ParamIsZero() - { - var param = IntPtr.Zero; - var exception = Assert.Throws(() => _ = param.OrThrowIfZero()); - Assert.Equal(nameof(param), exception.ParamName); - } - - [Fact] - public void OrThrowIfZero_ParamIsNull_DifferentParamName() - { - var paramName = "param2"; - var param = IntPtr.Zero; - var exception = Assert.Throws(() => _ = param.OrThrowIfZero(paramName)); - Assert.Equal(paramName, exception.ParamName); - } - - [Fact] - public void OrThrowIfZero_ParamIsNotZero() - { - var param = new IntPtr(24); - var variable = param.OrThrowIfZero(); - Assert.Equal(param, variable); - } - - [Fact] - public void ThrowIfNull_HDC_ParamIsNull() - { - var param = new HDC(IntPtr.Zero); - var exception = Assert.Throws(() => ArgumentValidation.ThrowIfNull(param)); - Assert.Equal(nameof(param), exception.ParamName); - } - - [Fact] - public void ThrowIfNull_HDC_ParamIsNotNull() - { - var param = new HDC(new IntPtr(24)); - ArgumentValidation.ThrowIfNull(param); - } - - [Fact] - public void ThrowIfNull_HDC_DifferentParamName() - { - var param = new HDC(IntPtr.Zero); - var exception = Assert.Throws(() => ArgumentValidation.ThrowIfNull(param, "paramName")); - Assert.Equal("paramName", exception.ParamName); - } - - [Fact] - public void ThrowIfNullOrEmpty_ParamIsValid() - { - var param = "valid"; - ArgumentValidation.ThrowIfNullOrEmpty(param); - } - - [Fact] - public void ThrowIfNullOrEmpty_ParamIsNull() - { - string? param = null; - var exception = Assert.Throws(() => param.ThrowIfNullOrEmpty()); - Assert.Equal(nameof(param), exception.ParamName); - } - - [Fact] - public void ThrowIfNullOrEmpty_ParamIsEmpty() - { - string param = string.Empty; - var exception = Assert.Throws(() => param.ThrowIfNullOrEmpty()); - Assert.Equal(nameof(param), exception.ParamName); - } - - [Fact] - public void ThrowIfNullOrEmpty_ParamIsValid_DifferentParamName() - { - string param = "valid"; - ArgumentValidation.ThrowIfNullOrEmpty(param, "paramName"); - } - - [Fact] - public void ThrowIfNullOrEmpty_ParamIsNull_DifferentParamName() - { - string? param = null; - var exception = Assert.Throws(() => param.ThrowIfNullOrEmpty("paramName")); - Assert.Equal("paramName", exception.ParamName); - } - - [Fact] - public void ThrowIfNullOrEmpty_ParamIsEmpty_DifferentParamName() - { - var param = string.Empty; - var exception = Assert.Throws(() => param.ThrowIfNullOrEmpty("paramName")); - Assert.Equal("paramName", exception.ParamName); - } - - [Fact] - public void ThrowIfNullOrEmptyWithMessage_ParamIsValid() - { - string param = "valid"; - param.ThrowIfNullOrEmptyWithMessage("message"); - } - - [Fact] - public void ThrowIfNullOrEmptyWithMessage_ParamIsNull() - { - string? param = null; - var message = "message"; - var exception = Assert.Throws(() => param.ThrowIfNullOrEmptyWithMessage(message)); - Assert.StartsWith(message, exception.Message); - Assert.Equal(nameof(param), exception.ParamName); - } - - [Fact] - public void ThrowIfNullOrEmptyWithMessage_ParamIsEmpty() - { - var param = string.Empty; - var message = "message"; - var exception = Assert.Throws(() => param.ThrowIfNullOrEmptyWithMessage(message)); - Assert.StartsWith(message, exception.Message); - Assert.Equal(nameof(param), exception.ParamName); - } - - [Fact] - public void ThrowIfNullOrEmptyWithMessage_ParamIsValid_DifferentParamName() - { - string param = "valid"; - param.ThrowIfNullOrEmptyWithMessage("message", "paramName"); - } - - [Fact] - public void ThrowIfNullOrEmptyWithMessage_ParamIsNull_DifferentParamName() - { - string? param = null; - var message = "message"; - var exception = Assert.Throws(() => param.ThrowIfNullOrEmptyWithMessage(message, "paramName")); - Assert.StartsWith(message, exception.Message); - Assert.Equal("paramName", exception.ParamName); - } - - [Fact] - public void ThrowIfNullOrEmptyWithMessage_ParamIsEmpty_DifferentParamName() - { - var param = string.Empty; - var message = "message"; - var exception = Assert.Throws(() => param.ThrowIfNullOrEmptyWithMessage(message, "paramName")); - Assert.StartsWith(message, exception.Message); - Assert.Equal("paramName", exception.ParamName); - } - - [Fact] - public void OrThrowIfNullOrEmpty_ParamIsValid() - { - var param = "valid"; - var value = param.OrThrowIfNullOrEmpty(); - Assert.Equal(param, value); - } - - [Fact] - public void OrThrowIfNullOrEmpty_ParamIsNull() - { - string? param = null; -#pragma warning disable CS8604 // Possible null reference argument. - var exception = Assert.Throws(() => _ = param.OrThrowIfNullOrEmpty()); -#pragma warning restore CS8604 // Possible null reference argument. - Assert.Equal(nameof(param), exception.ParamName); - } - - [Fact] - public void OrThrowIfNullOrEmpty_ParamIsEmpty() - { - var param = string.Empty; - var exception = Assert.Throws(() => _ = param.OrThrowIfNullOrEmpty()); - Assert.Equal(nameof(param), exception.ParamName); - } - - [Fact] - public void OrThrowIfNullOrEmpty_ParamIsValid_DifferentParamName() - { - var param = "valid"; - var value = param.OrThrowIfNullOrEmpty("paramName"); - Assert.Equal(param, value); - } - - [Fact] - public void OrThrowIfNullOrEmpty_ParamIsNull_DifferentParamName() - { - string? param = null; -#pragma warning disable CS8604 // Possible null reference argument. - var exception = Assert.Throws(() => _ = param.OrThrowIfNullOrEmpty("paramName")); -#pragma warning restore CS8604 // Possible null reference argument. - Assert.Equal("paramName", exception.ParamName); - } - - [Fact] - public void OrThrowIfNullOrEmpty_ParamIsEmpty_DifferentParamName() - { - var param = string.Empty; - var exception = Assert.Throws(() => _ = param.OrThrowIfNullOrEmpty("paramName")); - Assert.Equal("paramName", exception.ParamName); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/LocalAppContextSwitchesTest.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/LocalAppContextSwitchesTest.cs deleted file mode 100644 index 1fbae5a7a54..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/LocalAppContextSwitchesTest.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the.NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.Versioning; -using System.Windows.Forms.Primitives; - -namespace System.Windows.Forms.Tests; - -public class LocalAppContextSwitchesTest -{ - private void ResetLocalSwitches(dynamic testAccessor) - { - testAccessor.s_anchorLayoutV2 = 0; - testAccessor.s_scaleTopLevelFormMinMaxSizeForDpi = 0; - testAccessor.s_trackBarModernRendering = 0; - testAccessor.s_servicePointManagerCheckCrl = 0; - } - - [WinFormsTheory] - [InlineData(".NETCoreApp,Version=v8.0", true)] - [InlineData(".NETCoreApp,Version=v7.0", false)] - [InlineData(".NET Framework,Version=v4.8", false)] - public void Validate_Default_Switch_Values(string targetFrameworkName, bool expected) - { - FrameworkName? previousTestTargetFramework = LocalAppContextSwitches.TargetFrameworkName; - dynamic testAccessor = typeof(LocalAppContextSwitches).TestAccessor().Dynamic; - ResetLocalSwitches(testAccessor); - - try - { - testAccessor.s_targetFrameworkName = new FrameworkName(targetFrameworkName); - - Assert.Equal(expected, LocalAppContextSwitches.TrackBarModernRendering); - Assert.Equal(expected, LocalAppContextSwitches.ScaleTopLevelFormMinMaxSizeForDpi); - Assert.Equal(expected, LocalAppContextSwitches.ServicePointManagerCheckCrl); - } - finally - { - // Reset target framework name. - testAccessor.s_targetFrameworkName = previousTestTargetFramework; - ResetLocalSwitches(testAccessor); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/NonNullCollectionTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/NonNullCollectionTests.cs deleted file mode 100644 index 3bb39bb3586..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/NonNullCollectionTests.cs +++ /dev/null @@ -1,172 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; - -namespace System.Windows.Forms.Tests; - -public class NonNullCollectionTests -{ - [Fact] - public void NonNullCollection_Constructor_ThrowsWithNull() - { - Assert.Throws("items", () => new TestCollection(null!)); - } - - [Fact] - public void NonNullCollection_Constructor_ThrowsWithNullInCollection() - { - Assert.Throws("items", () => new TestCollection(new object[] { null! })); - } - - [Fact] - public void NonNullCollection_Add_ThrowsWithNull() - { - TestCollection collection = new(); - Assert.Throws("item", () => collection.Add(null!)); - } - - [Fact] - public void NonNullCollection_Add_CallsItemAdded() - { - TestCollection collection = new(); - object item = new(); - collection.Add(item); - Assert.Same(item, collection.LastAdded); - Assert.Equal(1, collection.AddCount); - } - - [Fact] - public void NonNullCollection_IListAdd_ThrowsWithNull() - { - TestCollection collection = new(); - Assert.Throws("value", () => ((IList)collection).Add(null)); - } - - [Fact] - public void NonNullCollection_IListAdd_CallsItemAdded() - { - TestCollection collection = new(); - object item = new(); - ((IList)collection).Add(item); - Assert.Same(item, collection.LastAdded); - Assert.Equal(1, collection.AddCount); - } - - [Fact] - public void NonNullCollection_Indexer_ThrowsWithNull() - { - TestCollection collection = new() { new() }; - Assert.Throws("value", () => collection[0] = null!); - } - - [Fact] - public void NonNullCollection_Indexer_CallsItemAdded() - { - TestCollection collection = new(new object[] { new() }); - object item = new(); - collection[0] = item; - Assert.Same(item, collection.LastAdded); - Assert.Equal(2, collection.AddCount); - } - - [Fact] - public void NonNullCollection_IListIndexer_ThrowsWithNull() - { - TestCollection collection = new() { new() }; - Assert.Throws("value", () => ((IList)collection)[0] = null); - } - - [Fact] - public void NonNullCollection_IListIndexer_CallsItemAdded() - { - TestCollection collection = new(new object[] { new() }); - object item = new(); - ((IList)collection)[0] = item; - Assert.Same(item, collection.LastAdded); - Assert.Equal(2, collection.AddCount); - } - - [Fact] - public void NonNullCollection_Insert_ThrowsWithNull() - { - TestCollection collection = new(); - Assert.Throws("item", () => collection.Insert(0, null!)); - } - - [Fact] - public void NonNullCollection_Insert_CallsItemAdded() - { - TestCollection collection = new(); - object item = new(); - collection.Insert(0, item); - Assert.Same(item, collection.LastAdded); - Assert.Equal(1, collection.AddCount); - } - - [Fact] - public void NonNullCollection_IListInsert_ThrowsWithNull() - { - TestCollection collection = new(); - Assert.Throws("value", () => ((IList)collection).Insert(0, null)); - } - - [Fact] - public void NonNullCollection_IListInsert_CallsItemAdded() - { - TestCollection collection = new(); - object item = new(); - ((IList)collection).Insert(0, item); - Assert.Same(item, collection.LastAdded); - Assert.Equal(1, collection.AddCount); - } - - [Fact] - public void NonNullCollection_AddRange_ThrowsWithNull() - { - TestCollection collection = new(); - Assert.Throws("items", () => collection.AddRange(null!)); - } - - [Fact] - public void NonNullCollection_AddRange_ThrowsWithNullInCollection() - { - TestCollection collection = new(); - Assert.Throws("items", () => collection.AddRange(new object[] { null! })); - } - - [Fact] - public void NonNullCollection_AddRange_CallsItemAdded() - { - TestCollection collection = new(); - object item = new(); - collection.AddRange(new object[] { item }); - Assert.Same(item, collection.LastAdded); - Assert.Equal(1, collection.AddCount); - - collection.AddRange(new object[] { new(), new(), new() }); - Assert.Equal(4, collection.AddCount); - } - - private class TestCollection : NonNullCollection - { - public object? LastAdded { get; set; } - - public int AddCount { get; set; } - - public TestCollection() - { - } - - public TestCollection(IEnumerable items) : base(items) - { - } - - protected override void ItemAdded(object item) - { - LastAdded = item; - AddCount++; - base.ItemAdded(item); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/RefCacheTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/RefCacheTests.cs deleted file mode 100644 index 23be0e958c4..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/RefCacheTests.cs +++ /dev/null @@ -1,115 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; - -namespace System.Windows.Forms.Tests; - -public class RefCacheTests -{ - [Fact] - public void RefCountTests() - { - var cache = new ObjectCache(5, 10); - var firstScope = cache.GetEntry(1); - Assert.Equal(1, firstScope.RefCount); - object first = firstScope.Object; - var secondScope = cache.GetEntry(1); - object second = secondScope.Object; - Assert.Equal(2, firstScope.RefCount); - Assert.Equal(2, secondScope.RefCount); - Assert.Same(first, second); - firstScope.Dispose(); - Assert.Equal(1, secondScope.RefCount); - secondScope.Dispose(); - Assert.Equal(0, secondScope.RefCount); - using var thirdScope = cache.GetEntry(1); - Assert.Equal(1, thirdScope.RefCount); - Assert.Same(first, thirdScope.Object); - } - - [Fact] - public void LimitTests() - { - var cache = new ObjectCache(2, 4); - - // Fill to the hard limit - var firstScope = cache.GetEntry(1); - var secondScope = cache.GetEntry(2); - var thirdScope = cache.GetEntry(3); - var fourthScope = cache.GetEntry(4); - Assert.Equal(0, firstScope.Object.DisposeCount); - Assert.Equal(0, secondScope.Object.DisposeCount); - Assert.Equal(0, thirdScope.Object.DisposeCount); - Assert.Equal(0, fourthScope.Object.DisposeCount); - - // New objects shouldn't be cached - var fifthScope = cache.GetEntry(5); - var sixthScope = cache.GetEntry(5); - - Assert.NotSame(fifthScope.Object, sixthScope.Object); - - // Dispose all scopes - firstScope.Dispose(); - secondScope.Dispose(); - thirdScope.Dispose(); - fourthScope.Dispose(); - fifthScope.Dispose(); - sixthScope.Dispose(); - - Assert.Equal(0, firstScope.Object.DisposeCount); - Assert.Equal(0, secondScope.Object.DisposeCount); - Assert.Equal(0, thirdScope.Object.DisposeCount); - Assert.Equal(0, fourthScope.Object.DisposeCount); - - // As these were never cached they should be disposed - Assert.Equal(1, fifthScope.Object.DisposeCount); - Assert.Equal(1, sixthScope.Object.DisposeCount); - - using var seventhScope = cache.GetEntry(7); - - // Now that the other scopes are closed, the earliest entries should have been cleaned - Assert.Equal(1, firstScope.Object.DisposeCount); - Assert.Equal(1, secondScope.Object.DisposeCount); - Assert.Equal(0, thirdScope.Object.DisposeCount); - Assert.Equal(0, fourthScope.Object.DisposeCount); - } - - // Example to show that the entry data can match the object type when it has enough context to match the key - internal sealed class IntColorCache : RefCountedCache - { - public IntColorCache(int softLimit, int hardLimit) : base(softLimit, hardLimit) { } - - protected override CacheEntry CreateEntry(int key, bool cached) - => new ColorCacheEntry(Color.FromArgb(key), cached); - - protected override bool IsMatch(int key, CacheEntry data) => key == data.Data.ToArgb(); - - private class ColorCacheEntry : CacheEntry - { - public ColorCacheEntry(Color color, bool cached) : base(color, cached) { } - public override Color Object => Data; - } - } - - public class DisposalCounter : IDisposable - { - public int DisposeCount; - public void Dispose() => DisposeCount++; - } - - internal class ObjectCache : RefCountedCache where T : class, new() - { - public ObjectCache(int softLimit = 40, int hardLimit = 60) : base(softLimit, hardLimit) { } - - protected override CacheEntry CreateEntry(int key, bool cached) => new ObjectCacheEntry(key, cached); - protected override bool IsMatch(int key, CacheEntry data) => key == data.Data; - - protected class ObjectCacheEntry : CacheEntry - { - private readonly T _object; - public ObjectCacheEntry(int value, bool cached) : base(value, cached) => _object = new T(); - public override T Object => _object; - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/SinglyLinkedListTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/SinglyLinkedListTests.cs deleted file mode 100644 index 8ea9d4d7185..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/System/Windows/Forms/SinglyLinkedListTests.cs +++ /dev/null @@ -1,199 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Windows.Forms.Tests; - -public class SinglyLinkedListTests -{ - [Fact] - public void AddFirst() - { - var list = new SinglyLinkedList(); - - Assert.Equal(0, list.Count); - Assert.Null(list.First); - Assert.Null(list.Last); - - list.AddFirst(1); - Assert.Equal(1, list.Count); - Assert.NotNull(list.First); - Assert.NotNull(list.Last); - Assert.Same(list.First, list.Last); - Assert.Null(list.First!.Next); - Assert.Equal(1, list.First); - - list.AddFirst(2); - Assert.Equal(2, list.Count); - Assert.NotNull(list.First); - Assert.NotNull(list.Last); - Assert.NotSame(list.First, list.Last); - Assert.Same(list.First.Next, list.Last); - Assert.Null(list.Last!.Next); - Assert.Equal(2, list.First); - Assert.Equal(1, list.Last); - } - - [Fact] - public void AddLast() - { - var list = new SinglyLinkedList(); - - Assert.Equal(0, list.Count); - Assert.Null(list.First); - Assert.Null(list.Last); - - list.AddLast(1); - Assert.Equal(1, list.Count); - Assert.NotNull(list.First); - Assert.NotNull(list.Last); - Assert.Same(list.First, list.Last); - Assert.Null(list.First!.Next); - Assert.Equal(1, list.First); - - list.AddLast(2); - Assert.Equal(2, list.Count); - Assert.NotNull(list.First); - Assert.NotNull(list.Last); - Assert.NotSame(list.First, list.Last); - Assert.Same(list.First.Next, list.Last); - Assert.Null(list.Last!.Next); - Assert.Equal(1, list.First); - Assert.Equal(2, list.Last); - } - - [Fact] - public void MoveToFront() - { - var list = new SinglyLinkedList(); - list.AddAll(1, 2, 3, 4, 5); - - var enumerator = list.GetEnumerator(); - Assert.True(enumerator.MoveNext()); - enumerator.MoveCurrentToFront(); - - // Should be moved back in front - Assert.Null(enumerator.Current); - Assert.Equal(5, list.Count); - Assert.True(enumerator.MoveNext()); - Assert.Equal(1, enumerator.Current); - - Assert.True(enumerator.MoveNext()); - Assert.Equal(2, enumerator.Current); - enumerator.MoveCurrentToFront(); - Assert.Equal(1, enumerator.Current); - - Assert.True(enumerator.MoveNext()); - Assert.Equal(3, enumerator.Current); - Assert.True(enumerator.MoveNext()); - Assert.Equal(4, enumerator.Current); - Assert.True(enumerator.MoveNext()); - Assert.Equal(5, enumerator.Current); - - enumerator.MoveCurrentToFront(); - Assert.Equal(4, enumerator.Current); - - Assert.False(enumerator.MoveNext()); - Assert.Null(enumerator.Current); - Assert.Equal(5, list!.First); - - Assert.Equal(new int[] { 5, 2, 1, 3, 4 }, list.WalkToList()); - Assert.Equal(new int[] { 5, 2, 1, 3, 4 }, list.EnumerateToList()); - } - - [Fact] - public void MoveToFront_InvalidOperations() - { - var list = new SinglyLinkedList(); - list.AddFirst(1); - - var enumerator = list.GetEnumerator(); - Assert.Throws(() => enumerator.MoveCurrentToFront()); - Assert.True(enumerator.MoveNext()); - enumerator.MoveCurrentToFront(); - Assert.Throws(() => enumerator.MoveCurrentToFront()); - } - - [Fact] - public void RemoveCurrent() - { - var list = new SinglyLinkedList(); - list.AddAll(1, 2, 3, 4, 5); - - var enumerator = list.GetEnumerator(); - Assert.True(enumerator.MoveNext()); - - enumerator.RemoveCurrent(); - Assert.Equal(4, list.Count); - Assert.Null(enumerator.Current); - - Assert.True(enumerator.MoveNext()); - Assert.Equal(2, enumerator.Current); - Assert.True(enumerator.MoveNext()); - Assert.Equal(3, enumerator.Current); - enumerator.RemoveCurrent(); - Assert.Equal(3, list.Count); - Assert.Equal(2, enumerator.Current); - - Assert.True(enumerator.MoveNext()); - Assert.True(enumerator.MoveNext()); - Assert.Equal(5, enumerator.Current); - enumerator.RemoveCurrent(); - Assert.Equal(2, list.Count); - Assert.Equal(4, enumerator.Current); - Assert.False(enumerator.MoveNext()); - Assert.Null(enumerator.Current); - - Assert.Equal(new int[] { 2, 4 }, list.WalkToList()); - Assert.Equal(new int[] { 2, 4 }, list.EnumerateToList()); - } - - [Fact] - public void RemoveCurrent_InvalidOperations() - { - var list = new SinglyLinkedList(); - list.AddFirst(1); - list.AddLast(2); - - var enumerator = list.GetEnumerator(); - Assert.Throws(() => enumerator.RemoveCurrent()); - Assert.True(enumerator.MoveNext()); - enumerator.RemoveCurrent(); - Assert.Throws(() => enumerator.RemoveCurrent()); - } -} - -internal static class ListExtensions -{ - public static void AddAll(this SinglyLinkedList linkedList, params T[] values) - { - foreach (T value in values) - { - linkedList.AddLast(value); - } - } - - public static List WalkToList(this SinglyLinkedList linkedList) - { - List list = new List(linkedList.Count); - var node = linkedList.First; - while (node is not null) - { - list.Add(node); - node = node.Next; - } - - return list; - } - - public static List EnumerateToList(this SinglyLinkedList linkedList) - { - List list = new List(linkedList.Count); - var enumerator = linkedList.GetEnumerator(); - while (enumerator.MoveNext()) - { - list.Add(enumerator.Current); - } - - return list; - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/AgileComPointerTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/AgileComPointerTests.cs deleted file mode 100644 index a2d8604c64c..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/AgileComPointerTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Windows.Win32.System.Com; - -namespace System.Windows.Forms.Primitives.Tests.Windows.Win32; - -public unsafe class AgileComPointerTests -{ - [Fact] - public void AgileComPointer_CheckRefCounts() - { - IStream* stream = ComHelpers.GetComPointer(new GlobalInterfaceTableTests.MyStream()); - - uint count; - - using (var agileStream = new AgileComPointer(stream, takeOwnership: true)) - { - count = stream->AddRef(); - Assert.Equal(2u, count); - using var astream = agileStream.GetInterface(); - } - - count = stream->Release(); - Assert.Equal(0u, count); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/GlobalInterfaceTableTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/GlobalInterfaceTableTests.cs deleted file mode 100644 index ff3fd1b83aa..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/GlobalInterfaceTableTests.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using Windows.Win32.System.Com; - -namespace System.Windows.Forms.Primitives.Tests.Windows.Win32; - -public unsafe class GlobalInterfaceTableTests -{ - [Fact] - public void GlobalInterfaceTable_CheckRefCounts() - { - using var stream = ComHelpers.TryGetComScope(new MyStream(), out HRESULT hr); - Assert.True(hr.Succeeded); - - uint count = stream.Value->AddRef(); - Assert.Equal(2u, count); - - count = stream.Value->Release(); - Assert.Equal(1u, count); - - uint cookie = GlobalInterfaceTable.RegisterInterface(stream.Value); - count = stream.Value->AddRef(); - // +1 for the AddRef, and +1 for the git registration - Assert.Equal(3u, count); - - count = stream.Value->Release(); - Assert.Equal(2u, count); - - GlobalInterfaceTable.RevokeInterface(cookie); - count = stream.Value->AddRef(); - Assert.Equal(2u, count); - stream.Value->Release(); - } - - internal class MyStream : IStream.Interface, IManagedWrapper - { - public unsafe HRESULT Read(void* pv, uint cb, [Optional] uint* pcbRead) => throw new NotImplementedException(); - public unsafe HRESULT Write(void* pv, uint cb, [Optional] uint* pcbWritten) => throw new NotImplementedException(); - public unsafe HRESULT Seek(long dlibMove, SeekOrigin dwOrigin, [Optional] ulong* plibNewPosition) => throw new NotImplementedException(); - public HRESULT SetSize(ulong libNewSize) => throw new NotImplementedException(); - public unsafe HRESULT CopyTo(IStream* pstm, ulong cb, [Optional] ulong* pcbRead, [Optional] ulong* pcbWritten) => throw new NotImplementedException(); - public HRESULT Commit(uint grfCommitFlags) => throw new NotImplementedException(); - public HRESULT Revert() => throw new NotImplementedException(); - public HRESULT LockRegion(ulong libOffset, ulong cb, uint dwLockType) => throw new NotImplementedException(); - public HRESULT UnlockRegion(ulong libOffset, ulong cb, uint dwLockType) => throw new NotImplementedException(); - public unsafe HRESULT Stat(STATSTG* pstatstg, uint grfStatFlag) => throw new NotImplementedException(); - public unsafe HRESULT Clone(IStream** ppstm) => throw new NotImplementedException(); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/RegionTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/RegionTests.cs deleted file mode 100644 index c3f3763e10a..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/RegionTests.cs +++ /dev/null @@ -1,113 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using static Interop; - -namespace System.Windows.Forms.Primitives.Tests.Windows.Win32; - -public class RegionTests -{ - [Fact] - public void GetClipRgn_NoRegion() - { - // Create a bitmap using the screen's stats - HDC hdc = PInvoke.CreateCompatibleDC((HDC)default); - Assert.False(hdc.IsNull); - - try - { - HBITMAP hbitmap = PInvoke.CreateCompatibleBitmap(hdc, 20, 20); - Assert.False(hdc.IsNull); - - try - { - PInvoke.SelectObject(hdc, hbitmap); - HRGN hregion = PInvoke.CreateRectRgn(0, 0, 0, 0); - - Assert.False(hregion.IsNull); - try - { - int result = PInvoke.GetClipRgn(hdc, hregion); - - // We should have no clipping region - Assert.Equal(0, result); - } - finally - { - PInvoke.DeleteObject(hregion); - } - } - finally - { - PInvoke.DeleteObject(hbitmap); - } - } - finally - { - PInvoke.DeleteDC(hdc); - } - } - - [Fact] - public void RegionScope_NullWithNoClippingRegion() - { - // Create a bitmap using the screen's stats - HDC hdc = PInvoke.CreateCompatibleDC((HDC)default); - Assert.False(hdc.IsNull); - - try - { - HBITMAP hbitmap = PInvoke.CreateCompatibleBitmap(hdc, 20, 20); - Assert.False(hdc.IsNull); - - try - { - using var hregion = new PInvoke.RegionScope(hdc); - Assert.True(hregion.IsNull); - } - finally - { - PInvoke.DeleteObject(hbitmap); - } - } - finally - { - PInvoke.DeleteDC(hdc); - } - } - - [Fact] - public unsafe void RegionScope_GetRegion() - { - // Create a bitmap using the screen's stats - HDC hdc = PInvoke.CreateCompatibleDC((HDC)default); - Assert.False(hdc.IsNull); - - try - { - HBITMAP hbitmap = PInvoke.CreateCompatibleBitmap(hdc, 20, 20); - Assert.False(hdc.IsNull); - - try - { - Rectangle rectangle = new(1, 2, 3, 4); - using PInvoke.RegionScope originalRegion = new(rectangle); - PInvoke.SelectClipRgn(hdc, originalRegion); - using PInvoke.RegionScope retrievedRegion = new(hdc); - RECT rect = default; - RegionType type = (RegionType)PInvoke.GetRgnBox(retrievedRegion, &rect); - Assert.Equal(RegionType.SIMPLEREGION, type); - Assert.Equal(rectangle, (Rectangle)rect); - } - finally - { - PInvoke.DeleteObject(hbitmap); - } - } - finally - { - PInvoke.DeleteDC(hdc); - } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/System/Com/IDispatchTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/System/Com/IDispatchTests.cs deleted file mode 100644 index 101f6ea00c1..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/System/Com/IDispatchTests.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using Windows.Win32.System.Ole; -using Windows.Win32.System.Variant; - -namespace Windows.Win32.System.Com.Tests; - -[Collection("Sequential")] -public partial class IDispatchTests -{ - [StaFact] - public unsafe void IDispatch_GetIDsOfNames_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var picture = IPictureDisp.CreateFromImage(image); - Assert.False(picture.IsNull); - - Guid riid = Guid.Empty; - fixed (char* width = "Width") - fixed (char* other = "Other") - { - var rgszNames = new PWSTR[] { width, other }; - var rgDispId = new int[rgszNames.Length]; - fixed (int* pRgDispId = rgDispId) - fixed (PWSTR* pRgszNames = rgszNames) - { - picture.Value->GetIDsOfNames(&riid, pRgszNames, (uint)rgszNames.Length, PInvoke.GetThreadLocale(), pRgDispId); - Assert.Equal(new PWSTR[] { width, other }, rgszNames); - - Assert.Equal(new int[] { (int)PInvoke.DISPID_PICT_WIDTH, PInvoke.DISPID_UNKNOWN }, rgDispId); - } - } - } - - [StaFact] - public unsafe void IDispatch_GetTypeInfo_Invoke_Success() - { - using var image = new Bitmap(16, 16); - using var picture = IPictureDisp.CreateFromImage(image); - Assert.False(picture.IsNull); - - using ComScope typeInfo = new(null); - picture.Value->GetTypeInfo(0, PInvoke.GetThreadLocale(), typeInfo); - } - - [StaFact] - public unsafe void IDispatch_GetTypeInfoCount_Invoke_Success() - { - using var image = new Bitmap(16, 16); - using var picture = IPictureDisp.CreateFromImage(image); - Assert.False(picture.IsNull); - - uint ctInfo = uint.MaxValue; - picture.Value->GetTypeInfoCount(&ctInfo); - Assert.Equal(1u, ctInfo); - } - - [StaFact] - public unsafe void IDispatch_Invoke_Invoke_Success() - { - using var image = new Bitmap(16, 32); - using var picture = IPictureDisp.CreateFromImage(image); - Assert.False(picture.IsNull); - - using VARIANT varResult = default; - HRESULT hr = ((IDispatch*)picture.Value)->TryGetProperty( - PInvoke.DISPID_PICT_WIDTH, - &varResult, - PInvoke.GetThreadLocale()); - Assert.Equal(HRESULT.S_OK, hr); - Assert.Equal(VARENUM.VT_I4, varResult.vt); - Assert.Equal(16, GdiHelper.HimetricToPixelY(varResult.data.intVal)); - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/System/Ole/ClassPropertyDispatchAdapterTests.cs b/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/System/Ole/ClassPropertyDispatchAdapterTests.cs deleted file mode 100644 index c1a4a3494cc..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/Windows/Win32/System/Ole/ClassPropertyDispatchAdapterTests.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using Windows.Win32.System.Variant; -using static Windows.Win32.System.Ole.FDEX_PROP_FLAGS; - -namespace Windows.Win32.System.Ole.Tests; - -public unsafe class ClassPropertyDispatchAdapterTests -{ - [Fact] - public void ClassPropertyDispatchAdapter_SingleClass() - { - TestClass testClass = new(); - ClassPropertyDispatchAdapter adapter = new(testClass); - - adapter.TryGetNextDispId(PInvoke.DISPID_STARTENUM, out int result).Should().BeTrue(); - result.Should().Be(0x10000); - adapter.TryGetMemberName(result, out string? name).Should().BeTrue(); - name.Should().Be("Value"); - adapter.TryGetMemberProperties(result, out var flags).Should().BeTrue(); - flags.Should().Be(fdexPropCanGet | fdexPropCanPut | fdexPropCannotPutRef | fdexPropCannotCall | fdexPropCannotConstruct | fdexPropCannotSourceEvents); - - VARIANT parameter = (VARIANT)42; - Com.DISPPARAMS dispParams = new() - { - cArgs = 1, - rgvarg = ¶meter - }; - - HRESULT hr = adapter.Invoke(result, 0, Com.DISPATCH_FLAGS.DISPATCH_PROPERTYPUT, &dispParams, null); - hr.Succeeded.Should().BeTrue(); - testClass.Value.Should().Be(42); - VARIANT returnValue = default; - hr = adapter.Invoke(result, 0, Com.DISPATCH_FLAGS.DISPATCH_PROPERTYGET, &dispParams, &returnValue); - hr.Succeeded.Should().BeTrue(); - ((int)returnValue).Should().Be(42); - - adapter.TryGetNextDispId(result, out result).Should().BeTrue(); - result.Should().Be(0x10001); - adapter.TryGetMemberName(result, out name).Should().BeTrue(); - name.Should().Be("Name"); - adapter.TryGetMemberProperties(result, out flags).Should().BeTrue(); - flags.Should().Be(fdexPropCanGet | fdexPropCannotPut | fdexPropCannotPutRef | fdexPropCannotCall | fdexPropCannotConstruct | fdexPropCannotSourceEvents); - hr = adapter.Invoke(result, 0, Com.DISPATCH_FLAGS.DISPATCH_PROPERTYGET, &dispParams, &returnValue); - hr.Succeeded.Should().BeTrue(); - ((BSTR)returnValue).ToStringAndFree().Should().Be("Q"); - - adapter.TryGetNextDispId(result, out result).Should().BeTrue(); - result.Should().Be(0x1); - adapter.TryGetMemberName(result, out name).Should().BeTrue(); - name.Should().Be("Percent"); - } - - [Fact] - public void ClassPropertyDispatchAdapter_ConflictingDispID() - { - TestClass testClass = new(); - TestClass2 testClass2 = new(); - - ClassPropertyDispatchAdapter adapter = new(testClass, new(testClass2)); - adapter.TryGetDispID("Percent", out int dispId).Should().BeTrue(); - dispId.Should().Be(0x10002); - adapter.TryGetDispID("CollidingDispId", out dispId).Should().BeTrue(); - dispId.Should().Be(0x1); - - adapter = new(testClass2, new(testClass)); - adapter.TryGetDispID("Percent", out dispId).Should().BeTrue(); - dispId.Should().Be(0x1); - adapter.TryGetDispID("CollidingDispId", out dispId).Should().BeTrue(); - dispId.Should().Be(0x10002); - } - - public class TestClass - { - public int Value { get; set; } - public string Name { get; } = "Q"; - - [DispId(1)] - public float Percent { get; set; } - } - - public class TestClass2 - { - [DispId(1)] - public int CollidingDispId { get; set; } - } -} diff --git a/src/System.Windows.Forms.Primitives/tests/UnitTests/runtimeconfig.template.json b/src/System.Windows.Forms.Primitives/tests/UnitTests/runtimeconfig.template.json deleted file mode 100644 index e460762026c..00000000000 --- a/src/System.Windows.Forms.Primitives/tests/UnitTests/runtimeconfig.template.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "configProperties": { - "TestSwitch.LocalAppContext.DisableCaching": "true", - "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": "false" - } -} \ No newline at end of file diff --git a/src/System.Windows.Forms.PrivateSourceGenerators/tests/UnitTests/EnumValidationTests.cs b/src/System.Windows.Forms.PrivateSourceGenerators/tests/UnitTests/EnumValidationTests.cs deleted file mode 100644 index d164c03e558..00000000000 --- a/src/System.Windows.Forms.PrivateSourceGenerators/tests/UnitTests/EnumValidationTests.cs +++ /dev/null @@ -1,344 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using System.Reflection; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Xunit; - -namespace System.Windows.Forms.PrivateSourceGenerators.Tests; - -public class EnumValidationTests -{ - [Fact] - public void SequentialEnum() - { - string source = @" -namespace People -{ - enum Names - { - David, - Igor, - Jeremy, - Hugh, - Tobias, - Olia, - Merrie - } - - class C - { - void M(Names value) - { - SourceGenerated.EnumValidator.Validate(value); - } - } -}"; - string expected = -@"if (intValue >= 0 && intValue <= 6) return;"; - - VerifyGeneratedMethodLines(source, "People.Names", expected); - } - - [Fact] - public void MultipleCalls_OneValidateMethod() - { - string source = @" -namespace People -{ - enum Names - { - David, - Igor, - Jeremy, - Hugh, - Tobias, - Olia, - Merrie - } - - class C - { - void M(Names value) - { - SourceGenerated.EnumValidator.Validate(value); - } - - void N(Names input) - { - SourceGenerated.EnumValidator.Validate(input, nameof(input)); - } - - C(Names name) - { - SourceGenerated.EnumValidator.Validate(name, nameof(name)); - SourceGenerated.EnumValidator.Validate(name); - } - } -}"; - string expected = -@"if (intValue >= 0 && intValue <= 6) return;"; - - VerifyGeneratedMethodLines(source, "People.Names", expected); - } - - [Fact] - public void DuplicateValues() - { - string source = @" -namespace People -{ - enum Names - { - David = 1, - Igor = 2, - Jeremy = 2, - Hugh = 4, - Tobias = 4 - } - - class C - { - void M(Names value) - { - SourceGenerated.EnumValidator.Validate(value); - } - } -}"; - string expected = -@"if (intValue >= 1 && intValue <= 2) return; -if (intValue == 4) return;"; - - VerifyGeneratedMethodLines(source, "People.Names", expected); - } - - [Fact] - public void ValuesFromConstants() - { - string source = @" -namespace People -{ - static class Win32 - { - public const int HResult = 2; - public const int E_FAIL = 4; - } - - enum Names - { - David = Win32.HResult, - Igor = Win32.E_FAIL, - Jeremy = Win32.HResult - 1, - Hugh = Win32.E_FAIL + Win32.HResult, - Tobias = Hugh - } - - class C - { - void M(Names value) - { - SourceGenerated.EnumValidator.Validate(value); - } - } -}"; - string expected = -@"if (intValue >= 1 && intValue <= 2) return; -if (intValue == 4) return; -if (intValue == 6) return;"; - - VerifyGeneratedMethodLines(source, "People.Names", expected); - } - - [Fact] - public void NonSequentialEnum() - { - string source = @" -namespace People -{ - enum Names - { - David = 1, - Igor = 7, - Jeremy = 6, - Hugh = 9, - Tobias = 2, - Olia = 15, - Merrie = 3 - } - - class C - { - void M(Names value) - { - SourceGenerated.EnumValidator.Validate(value); - } - } -}"; - string expected = -@"if (intValue >= 1 && intValue <= 3) return; -if (intValue >= 6 && intValue <= 7) return; -if (intValue == 9) return; -if (intValue == 15) return;"; - - VerifyGeneratedMethodLines(source, "People.Names", expected); - } - - [Fact] - public void SequentialEnumWithPowersOf2() - { - string source = @" -namespace People -{ - enum Names - { - David = 1, - Igor = 2, - Jeremy = 4, - Hugh = 8, - Tobias = 16, - Olia = 32, - Merrie = 64 - } - - class C - { - void M(Names value) - { - SourceGenerated.EnumValidator.Validate(value); - } - } -}"; - string expected = -@"if (intValue >= 1 && intValue <= 2) return; -if (intValue == 4) return; -if (intValue == 8) return; -if (intValue == 16) return; -if (intValue == 32) return; -if (intValue == 64) return;"; - - VerifyGeneratedMethodLines(source, "People.Names", expected); - } - - [Fact] - public void SequentialEnumWithPowersOf2_BinaryNotation() - { - string source = @" -namespace People -{ - enum Names - { - David = 0b0000001, - Igor = 0b0000010, - Jeremy = 0b0000100, - Hugh = 0b0001000, - Tobias = 0b0010000, - Olia = 0b0100000, - Merrie = 0b1000000 - } - - class C - { - void M(Names value) - { - SourceGenerated.EnumValidator.Validate(value); - } - } -}"; - string expected = -@"if (intValue >= 1 && intValue <= 2) return; -if (intValue == 4) return; -if (intValue == 8) return; -if (intValue == 16) return; -if (intValue == 32) return; -if (intValue == 64) return;"; - - VerifyGeneratedMethodLines(source, "People.Names", expected); - } - - [Fact] - public void FlagsEnum() - { - string source = @" -namespace Paint -{ - [System.Flags] - enum Colours - { - Red = 1, - Green = 2, - Blue = 4, - Purple = 8 - } - - class C - { - void M(Colours value) - { - SourceGenerated.EnumValidator.Validate(value); - } - } -}"; - string expected = -@"if ((intValue & 15) == intValue) return;"; - - VerifyGeneratedMethodLines(source, "Paint.Colours", expected); - } - - private void VerifyGeneratedMethodLines(string source, string expectedEnumName, string expectedBody) - { - SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(source); - - List references = new List(); - Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (Assembly assembly in assemblies) - { - if (!assembly.IsDynamic) - { - references.Add(MetadataReference.CreateFromFile(assembly.Location)); - } - } - - CSharpCompilation compilation = CSharpCompilation.Create("original", new SyntaxTree[] { syntaxTree }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - - ISourceGenerator generator = new EnumValidationGenerator().AsSourceGenerator(); - - CSharpGeneratorDriver driver = CSharpGeneratorDriver.Create(generator); - driver.RunGeneratorsAndUpdateCompilation(compilation, out Compilation outputCompilation, out ImmutableArray diagnostics); - Assert.False(diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error), $"Failed: {diagnostics.FirstOrDefault()?.GetMessage()}"); - - string output = outputCompilation.SyntaxTrees.Skip(2).First().ToString(); - - List lines = output.Split("\r\n").ToList(); - - AssertFirstLineAndRemove(lines, "// "); - AssertFirstLineAndRemove(lines, "namespace SourceGenerated"); - AssertFirstLineAndRemove(lines, "{"); - AssertFirstLineAndRemove(lines, "internal static partial class EnumValidator"); - AssertFirstLineAndRemove(lines, "{"); - - AssertFirstLineAndRemove(lines, "/// Validates that the enum value passed in is valid for the enum type."); - AssertFirstLineAndRemove(lines, $"public static void Validate({expectedEnumName} enumToValidate, string parameterName = \"value\")"); - AssertFirstLineAndRemove(lines, "{"); - AssertFirstLineAndRemove(lines, "int intValue = (int)enumToValidate;"); - - foreach (string line in expectedBody.Split("\r\n")) - { - AssertFirstLineAndRemove(lines, line.Trim()); - } - - AssertFirstLineAndRemove(lines, $"ReportEnumValidationError(parameterName, intValue, typeof({expectedEnumName}));"); - - AssertFirstLineAndRemove(lines, "}"); - - static void AssertFirstLineAndRemove(List lines, string expected) - { - Assert.True(lines.Count > 0); - - var line = lines[0].Trim(); - lines.RemoveAt(0); - Assert.Equal(expected, line); - } - } -} diff --git a/src/System.Windows.Forms.PrivateSourceGenerators/tests/UnitTests/System.Windows.Forms.PrivateSourceGenerators.Tests.csproj b/src/System.Windows.Forms.PrivateSourceGenerators/tests/UnitTests/System.Windows.Forms.PrivateSourceGenerators.Tests.csproj deleted file mode 100644 index 208a5519844..00000000000 --- a/src/System.Windows.Forms.PrivateSourceGenerators/tests/UnitTests/System.Windows.Forms.PrivateSourceGenerators.Tests.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - diff --git a/src/System.Windows.Forms/src/AssemblyRef.cs b/src/System.Windows.Forms/src/AssemblyRef.cs index ab3e532e150..20bcd5297e0 100644 --- a/src/System.Windows.Forms/src/AssemblyRef.cs +++ b/src/System.Windows.Forms/src/AssemblyRef.cs @@ -5,7 +5,7 @@ internal static class FXAssembly { // NB: this must never-ever change to facilitate type-forwarding from // .NET Framework, if those are referenced in .NET project. - internal const string Version = "4.0.0.0"; + internal const string Version = "8.0.0.0"; } internal static class AssemblyRef diff --git a/src/System.Windows.Forms/src/Properties/AssemblyInfo.cs b/src/System.Windows.Forms/src/Properties/AssemblyInfo.cs index 45c3e6510a3..672a3721bdf 100644 --- a/src/System.Windows.Forms/src/Properties/AssemblyInfo.cs +++ b/src/System.Windows.Forms/src/Properties/AssemblyInfo.cs @@ -5,6 +5,7 @@ [assembly: System.Runtime.InteropServices.ComVisible(false)] +[assembly: InternalsVisibleTo("WTG.System.Windows.Forms.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")] [assembly: InternalsVisibleTo("System.Windows.Forms.Tests, PublicKey=00000000000000000400000000000000")] [assembly: InternalsVisibleTo("System.Windows.Forms.TestUtilities, PublicKey=00000000000000000400000000000000")] [assembly: InternalsVisibleTo("System.Windows.Forms.Primitives.TestUtilities, PublicKey=00000000000000000400000000000000")] diff --git a/src/System.Windows.Forms/src/Resources/SR.resx b/src/System.Windows.Forms/src/Resources/SR.resx index 87500f3321f..b09c8690821 100644 --- a/src/System.Windows.Forms/src/Resources/SR.resx +++ b/src/System.Windows.Forms/src/Resources/SR.resx @@ -5583,6 +5583,84 @@ Stack trace where the illegal operation occurred was: Occurs whenever the specified interval time elapses. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + + + Controls whether the ToolBar will automatically size itself based on Button size. + + + Parameter must be of type ToolBarButton. + + + Controls what type of border the ToolBar control will have. + + + Occurs whenever a button in the ToolBar is clicked by the user. + + + Occurs whenever a button with the DropDownButton style is pressed. + + + Controls whether this button responds to user input. + + + Identifies the image displayed on the button. + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + + + References that a non-existent ToolBarButton has been received. + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + + + The collection of ToolBarButtons that make up this ToolBar. + + + The size of the buttons on the control if the button contents do not require a larger size. + + + Indicates what style of ToolBarButton this will be. + + + The caption to be displayed for this button. + + + The ToolTip text to be displayed for this button. + + + Indicates whether this button should be visible. + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + + + The ImageList from which this ToolBar will get all of the button images. + + + The size of the images within the ToolBar's ImageList. + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + + + Controls how the text is positioned relative to the Image in each button. + + + Indicates if more than one row of buttons is allowed. + AllowItemReorder and AllowDrop cannot both be true. @@ -6128,52 +6206,52 @@ Stack trace where the illegal operation occurred was: Alt - {Locked="Alt"} + {Locked="Alt"} Back Ctrl - {Locked=!de; "Ctrl"} + {Locked=!de; "Ctrl"} (default) Del - {Locked=!fr,de,it,es; "Del"} + {Locked=!fr,de,it,es; "Del"} End - {Locked=!fr,de,it,es; "End"} + {Locked=!fr,de,it,es; "End"} Enter - {Locked=!fr,de,it,es; "Enter"} + {Locked=!fr,de,it,es; "Enter"} Home - {Locked=!fr,de,es; "Home"} + {Locked=!fr,de,es; "Home"} Insert - {Locked=!fr,de,it,es,zh-Hant; "Insert"} + {Locked=!fr,de,it,es,zh-Hant; "Insert"} (none) PgDn - {Locked=!fr,de,it,es; "PgDn"} + {Locked=!fr,de,it,es; "PgDn"} PgUp - {Locked=!fr,de,it,es; "PgUp"} + {Locked=!fr,de,it,es; "PgUp"} Shift - {Locked=!fr,de,it,es; "Shift"} + {Locked=!fr,de,it,es; "Shift"} Indicates whether the control will resize itself automatically based on a computation of the default scroll bar dimensions. @@ -6979,4 +7057,418 @@ Stack trace where the illegal operation occurred was: The resource value '{0}' was not found. + + Indicates whether the grid can be re-sorted by clicking a column header. + + + Indicates the background color of alternating rows for a ledger appearance. + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + Indicates the color of the DataGrid background. + + + BeginInit() has already been called without an EndInit(). + + + Specifies whether the DataGridBoolColumn allows null values. + + + Indicates the border style for the DataGrid. + + + Navigates back to the parent rows. + + + Indicates the background color of the top caption. + + + Shows/Hides the parent rows for the current set of child rows. + + + Indicates the font of the top caption. + + + Indicates the color of text that appears in the top caption. + + + Indicates the text displayed in the top caption. + + + Indicates whether the top caption is visible. + + + DataGridColumn instance does not exist in the collection. + + + Indicates whether the column headers are visible. + + + Position of ListManager must be equal to 'rowNum'. + + + PropertyDescriptor has not been set on this DataGridColumn. + + + Data grid column styles collection already contains a column style with the same mapping name. + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + ColumnWidth must be greater than or equal to 0. + + + The currently selected cell in the DataGrid. + + + Indicates a sub-list of the DataSource to show in the DataGrid. + + + Indicates the source of data for the DataGrid. + + + User cannot change the contents of the default GridColumnStylesCollection. + + + Value of this property cannot be changed on the default DataGridTableStyle. + + + Occurs when the user clicks the "show/hide parent rows" icon. + + + Value '{0}' cannot be set to an empty value. + + + Committing the row to the original data store has caused an error. + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + Program cannot get information about the painting and scrolling region. + + + Indicates the index of the column that is first shown. + + + Indicates whether the grid has a flat appearance. + + + Indicates the color of the grid lines. + + + Indicates the style of the grid lines. + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + Indicates the background color of the column and row headers. + + + Indicates the font of the text in the column and row headers. + + + Indicates the color of the text in the column and row headers. + + + Returns the horizontal scroll bar used by the grid. + + + Indicates the color of the text that appears inside the child links. + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + The CurrencyManager that the DataGrid uses to get data from the data source. + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + Indicates whether links to child tables are shown. + + + Occurs when the user clicks on the expansion glyph on the row header. + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + Event raised when the value of the DataSource property is changed on DataGrid. + + + Event raised when the value of the FlatMode property is changed on DataGrid. + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + Indicates the background color of the parent rows. + + + Indicates the color of the text in the parent rows. + + + Indicates whether the parent rows show labels for the table and for the columns. + + + Indicates whether the parent rows area is visible. + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + Indicates the preferred height of the rows. + + + Value {0} Do you want to correct this value? + + + Indicates whether rows in the grid can be edited, added, or deleted. + + + Indicates whether the row headers are visible. + + + Indicates the width of the row headers. + + + DataGridRow.Height cannot be negative. + + + DataGridRow cannot have a negative row number. + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + Indicates the index of the current row. + + + Indicates the background color of any selected cells or rows. + + + Indicates the color of the text in any selected cells or rows. + + + ListManager can be set using the DataSource and DataMember properties. + + + Position on a null ListManager cannot be set. + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + DataGridTable instance does not exist in the collection. + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + Data grid table styles collection already contains a table style with the same mapping name. + + + DataGridTableStyle does not support transparent AlternatingBackColor. + + + DataGridTableStyle does not support transparent BackColor. + + + DataGridTableStyle does not support transparent HeaderBackColor. + + + DataGridTableStyle does not support transparent SelectionBackColor. + + + null rectangle for icon bounds when adding tool tip. + + + DataGrid control does not support transparent AlternatingBackColor. + + + DataGrid control does not support transparent BackColor. + + + DataGrid control does not support transparent CaptionBackColor. + + + DataGrid control does not support transparent HeaderBackColor. + + + DataGrid control does not support transparent ParentRowsBackColor. + + + DataGrid control does not support transparent SelectionBackColor. + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + Returns the vertical scroll bar used by the grid. + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + Raised when the context menu collapses. + + + Gets or sets the ImageList associated with this context menu. + + + ContextMenu cannot be shown on an invisible control. + + + Gets or sets a value indicating whether the menu has an image margin. + + + The last control that caused this context menu to be displayed. + + + The main menu of the form. This must be set to a component of type MainMenu. + + + Occurs when the main menu collapses. + + + Parameter must be of type MenuItem. + + + Indicates if this menu contains any child items. + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + Indicates whether the item is checked. + + + Indicates whether the item is the default item. + + + Indicates whether the item is enabled. + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + Determines whether the MDI child window list is appended to this item. + + + Determines the merge order of the item. + + + Determines how the item is handled when menus are merged. + + + Occurs when the menu item is selected. + + + Occurs before the containing menu is displayed. + + + Occurs when the menu item is selected. + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + If the item is checked, this value will determine whether the check style is a radio button. + + + The caption displayed by the item. + + + Indicates whether the item is visible. + + + Retrieves the menu item that contains a list of MDI child windows. + + + The menu items for the menu. + + + Cannot merge a menu with itself. + + + Indicates if this menu should display right to left + + + The merged menu of this form, which is used when displaying a single merged MDI menu. + + + Adding the panel to the native status bar control has not succeeded. + + + Parameter must be of type StatusBarPanel. + + + Occurs whenever a panel in the StatusBar needs to be painted. + + + Occurs when a panel within the status bar is clicked. + + + The alignment of the panel's text. + + + Determines how a panel will resize when the parent changes size. + + + Determines what type of border a panel has. + + + Determines what icon is displayed in the panel. + + + The minimum width of the panel. + + + The name of the panel. + + + The panels in the status bar. + + + The style of the panel. + + + The text displayed in the panel. + + + The panel's ToolTip text. + + + The width of the panel. + + + Determines if a status bar displays panels, or if it displays a single line of text. + + + Determines whether a status bar has a sizing grip. + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf index 213a79130f2..3ec782e754d 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf @@ -1312,6 +1312,31 @@ Nadřazený formulář tohoto ovládacího prvku kontejneru. + + Raised when the context menu collapses. + Vyvolá se při sbalení místní nabídky. + + + + Gets or sets the ImageList associated with this context menu. + Získá nebo nastaví ovládací prvek ImageList spojený s touto místní nabídkou. + + + + ContextMenu cannot be shown on an invisible control. + Nabídku ContextMenu nelze zobrazit v neviditelném ovládacím prvku. + + + + Gets or sets a value indicating whether the menu has an image margin. + Získá nebo nastaví hodnotu označující, zda má nabídka okraj pro obrázek. + + + + The last control that caused this context menu to be displayed. + Poslední ovládací prvek, který způsobil zobrazení této kontextové nabídky. + + The last control that caused this context menu strip to be displayed. Poslední ovládací prvek, který způsobil zobrazení této místní nabídky @@ -2192,6 +2217,466 @@ Funkce RemoveAt není pro vazby mezi vlastnostmi podporována. + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. Vyvolá se při změně hodnoty vlastnosti AlternatingRowsDefaultCellStyle. @@ -5375,11 +5860,21 @@ Chcete jej nahradit? Získá nebo nastaví ukotvení pro minimalizované podřízené položky MDI. + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. Určuje primární hodnotu MenuStrip pro formulář. Tato vlastnost se používá k aktivování klávesnice a automatickému sloučení v MDI. + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. Určuje, zda formulář má v pravém horním rohu záhlaví minimalizační pole. @@ -6929,6 +7424,11 @@ Trasování zásobníku, kde došlo k neplatné operaci: Formulář, který byl určen jako nadřazený objekt MdiParent pro tento formulář, není typu MdiContainer. + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. Označuje, zda je znak příkazového řádku platný jako vstup. @@ -7064,6 +7564,81 @@ Trasování zásobníku, kde došlo k neplatné operaci: Určuje typ objektu, který se má použít k analýze vstupního textu v případě, že ovládací prvek ztratí fokus. + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. Klávesová zkratka přiřazená položce nabídky @@ -7074,6 +7649,36 @@ Trasování zásobníku, kde došlo k neplatné operaci: Určuje, zda bude v položce nabídky zobrazena klávesová zkratka pro tuto položku. + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. Určuje položku, jejíž seznam DropDown se zobrazí v seznamu oken MDI. @@ -9129,6 +9734,91 @@ Trasování zásobníku, kde došlo k neplatné operaci: Získání zařazovacího modulu pro IID {0} se nezdařilo. + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. Určuje strany panelu, na kterých by se měla zobrazovat ohraničení. @@ -9714,6 +10404,136 @@ Trasování zásobníku, kde došlo k neplatné operaci: Příliš mnoho volání ResumeUpdateMenuHandles. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + Určuje vzhled ovládacího prvku ToolBar a využívá hodnoty výčtu ToolBarAppearance. + + + + Controls whether the ToolBar will automatically size itself based on Button size. + Určuje, zda ovládací prvek ToolBar automaticky změní velikost na základě velikosti prvku Button. + + + + Parameter must be of type ToolBarButton. + Parametr musí být typu ToolBarButton. + + + + Controls what type of border the ToolBar control will have. + Určuje typ ohraničení ovládacího prvku ToolBar. + + + + Occurs whenever a button in the ToolBar is clicked by the user. + Vyvolá se vždy, když uživatel klikne na tlačítko na panelu nástrojů (ToolBar). + + + + Occurs whenever a button with the DropDownButton style is pressed. + Vyvolá se při každém stisknutí tlačítka se stylem DropDownButton. + + + + Controls whether this button responds to user input. + Určuje, zda toto tlačítko bude reagovat na vstup uživatele. + + + + Identifies the image displayed on the button. + Určuje obrázek zobrazovaný na tlačítku. + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + Rozevírací nabídka pro ovládací prvek ToolBarButton musí být typu ContextMenu. + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + Místní nabídka, která bude zobrazena, pokud bude styl tohoto tlačítka nastaven na hodnotu DropDownButton. + + + + References that a non-existent ToolBarButton has been received. + Označuje, že byl přijat neexistující objekt ToolBarButton. + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + Určuje, zda by tlačítko mělo být zobrazeno jako částečně stisknuté, ale pouze v případě, že je styl tlačítka nastaven na hodnotu ToggleButton. + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + Určuje, zda tlačítko je nebo není stisknuto. Nejčastěji se používá pro tlačítka se stylem TOGGLEBUTTON. + + + + The size of the buttons on the control if the button contents do not require a larger size. + Velikost tlačítek v ovládacím prvku, pokud obsah tlačítek nevyžaduje větší velikost + + + + Indicates what style of ToolBarButton this will be. + Určuje styl ovládacího prvku ToolBarButton. + + + + The caption to be displayed for this button. + Titulek, který bude zobrazen pro toto tlačítko. + + + + The ToolTip text to be displayed for this button. + Text popisu tlačítka, který bude zobrazen pro toto tlačítko. + + + + Indicates whether this button should be visible. + Určuje, zda toto tlačítko bude viditelné. + + + + The collection of ToolBarButtons that make up this ToolBar. + Kolekce objektů ToolBarButtons, které vytvářejí tento ovládací prvek ToolBar. + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + Určuje, zda ovládací prvek ToolBar zobrazí v horní části klientské oblasti prostorovou čáru. + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + Určuje, zda ovládací prvek ToolBar zobrazí vedle rozevíracích tlačítek šipku. + + + + The ImageList from which this ToolBar will get all of the button images. + Seznam ImageList, z něhož tento ovládací prvek ToolBar získá všechny obrázky tlačítek. + + + + The size of the images within the ToolBar's ImageList. + Velikost obrázků v rámci seznamu ImageList tohoto ovládacího prvku ToolBar. + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + Určuje, zda budou pro jednotlivá tlačítka zobrazeny popisy tlačítek, jsou-li k dispozici. + + + + Controls how the text is positioned relative to the Image in each button. + Určuje pozici textu vzhledem k obrázku v jednotlivých tlačítkách. + + + + Indicates if more than one row of buttons is allowed. + Určuje, zda je povolen více než jeden řádek tlačítek. + + AllowItemReorder and AllowDrop cannot both be true. Vlastnosti AllowItemReorder a AllowDrop nemohou být současně nastaveny na hodnotu True. @@ -11431,4 +12251,4 @@ Trasování zásobníku, kde došlo k neplatné operaci: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf index 34359e0070b..734f0513d07 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf @@ -1312,6 +1312,31 @@ Das übergeordnete Formular des Containersteuerelements. + + Raised when the context menu collapses. + Wird ausgelöst, wenn das Kontextmenü ausgeblendet wird. + + + + Gets or sets the ImageList associated with this context menu. + Ruft die mit diesem Kontextmenü verknüpfte ImageList ab oder legt sie fest. + + + + ContextMenu cannot be shown on an invisible control. + ContextMenu kann nicht auf einem unsichtbarem Steuerelement angezeigt werden. + + + + Gets or sets a value indicating whether the menu has an image margin. + Ruft einen Wert ab oder legt einen Wert fest, der anzeigt, ob das Menü einen Bildrand hat. + + + + The last control that caused this context menu to be displayed. + Das letzte Steuerelement, dass die Anzeige des Kontextmenüs verursacht hat. + + The last control that caused this context menu strip to be displayed. Das letzte Steuerelement, das die Anzeige dieser Kontextmenüleiste verursacht hat. @@ -2192,6 +2217,466 @@ RemoveAt wird für die Eigenschaftenbindung nicht unterstützt. + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. Tritt auf, wenn sich der Wert der AlternatingRowsDefaultCellStyle-Eigenschaft ändert. @@ -5375,11 +5860,21 @@ Möchten Sie sie ersetzen? Ruft die Verankerung für minimierte untergeordnete MDI-Elemente ab oder legt sie fest. + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. Gibt den primären MenuStrip für das Formular an. Diese Eigenschaft wird für die Tastaturaktivierung und das automatische Zusammenführen in MDI verwendet. + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. Bestimmt, ob ein Formular ein Minimieren-Feld in der oberen rechten Ecke seiner Titelleiste hat. @@ -6929,6 +7424,11 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat: Das Formular, das als MdiParent für dieses Formular angegeben wurde, ist kein MdiContainer. + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. Zeigt an, ob das Eingabeaufforderungszeichen eine gültige Eingabe ist. @@ -7064,6 +7564,81 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat: Gibt den Typ des für die Analyse des Eingabetexts zu verwendenden Objekts an, wenn das Steuerelement den Fokus verliert. + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. Die dem Menüelement zugeordnete Tastenkombination. @@ -7074,6 +7649,36 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat: Gibt an, ob die Tastenkombination für das Menüelement in dem Element angezeigt wird. + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. Gibt das Element an, dessen DropDown die Liste der MDI-Fenster anzeigt. @@ -9129,6 +9734,91 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat: Fehler beim Abrufen des Marshallers für IID {0}. + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. Gibt die Seiten des Bereichs an, die Rahmen anzeigen sollen. @@ -9714,6 +10404,136 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat: Zu viele Aufrufe an ResumeUpdateMenuHandles. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + Steuert die Darstellung des ToolBar-Steuerelements mit Werten aus der ToolBarAppearance-Enumeration. + + + + Controls whether the ToolBar will automatically size itself based on Button size. + Steuert, ob die Größe der ToolBar automatisch basierend auf der Schaltflächengröße geändert wird. + + + + Parameter must be of type ToolBarButton. + Der Parameter muss den Typ ToolBarButton haben. + + + + Controls what type of border the ToolBar control will have. + Steuert den Rahmentyp des ToolBar-Steuerelements. + + + + Occurs whenever a button in the ToolBar is clicked by the user. + Tritt ein, wenn der Benutzer auf eine ToolBar-Schaltfläche klickt. + + + + Occurs whenever a button with the DropDownButton style is pressed. + Tritt ein, wenn auf eine Schaltfläche mit dem Stil DropDownButton geklickt wird. + + + + Controls whether this button responds to user input. + Steuert, ob die Schaltfläche auf Benutzereingaben reagiert. + + + + Identifies the image displayed on the button. + Gibt das auf der Schaltfläche angezeigte Bild an. + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + Das DropdownmMenü für einen ToolBarButton muss den Typ ContextMenu haben. + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + Das Kontextmenü, das angezeigt wird, wenn der Stil der Schaltfläche auf DropDownButton festgelegt ist. + + + + References that a non-existent ToolBarButton has been received. + Gibt an, dass ein nicht vorhandener ToolBarButton empfangen wurde. + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + Steuert, ob die Schaltfläche als partiell gedrückt angezeigt wird (nur wenn der Stil der Schaltfläche auf ToggleButton festgelegt ist). + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + Gibt an, ob auf die Schaltfläche geklickt wurde (wird häufig für Schaltflächen mit dem TOGGLEBUTTON-Stil verwendet). + + + + The size of the buttons on the control if the button contents do not require a larger size. + Die Größe der Schaltflächen in dem Steuerelement, wenn für den Inhalt der Schaltfläche keine größere Größe erforderlich ist. + + + + Indicates what style of ToolBarButton this will be. + Gibt den Stil für ToolBarButton an. + + + + The caption to be displayed for this button. + Die Beschriftung, die für diese Schaltfläche angezeigt wird. + + + + The ToolTip text to be displayed for this button. + Die QuickInfo, die für diese Schaltfläche angezeigt wird. + + + + Indicates whether this button should be visible. + Zeigt an, ob diese Schaltfläche sichtbar sein soll. + + + + The collection of ToolBarButtons that make up this ToolBar. + Die ToolBarButtons-Sammlung, die diese ToolBar bildet. + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + Steuert, ob in der ToolBar eine 3D-Zeile am oberen Rand des Clientbereichs angezeigt wird. + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + Steuert, ob in der ToolBar ein Pfeil neben den Dropdown-Schaltflächen angezeigt wird. + + + + The ImageList from which this ToolBar will get all of the button images. + Die ImageList, aus der die ToolBar alle Schaltflächenbilder abruft. + + + + The size of the images within the ToolBar's ImageList. + Die Größe der Bilder in der ImageList der Toolbar. + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + Gibt an, ob QuickInfos für jede Schaltfläche angezeigt werden, sofern verfügbar. + + + + Controls how the text is positioned relative to the Image in each button. + Steuert, wie der Text relativ zum Bild in jeder Schaltfläche positioniert wird. + + + + Indicates if more than one row of buttons is allowed. + Zeigt an, ob mehr als eine Schaltflächenzeile zulässig ist. + + AllowItemReorder and AllowDrop cannot both be true. AllowItemReorder und AllowDrop können nicht beide "true" sein. @@ -11431,4 +12251,4 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf index 9a903f8da2e..f4073f4ba60 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf @@ -1312,6 +1312,31 @@ Formulario primario de este control contenedor. + + Raised when the context menu collapses. + Se desencadena cuando se contrae el menú contextual. + + + + Gets or sets the ImageList associated with this context menu. + Obtiene o establece ImageList asociado con este menú contextual. + + + + ContextMenu cannot be shown on an invisible control. + No se puede mostrar ContextMenu en un control invisible. + + + + Gets or sets a value indicating whether the menu has an image margin. + Obtiene o establece un valor que indica si el menú tiene un margen de imagen. + + + + The last control that caused this context menu to be displayed. + Último control que hizo que se mostrara el menú contextual. + + The last control that caused this context menu strip to be displayed. Último control que hizo que se mostrara la franja de menús contextuales. @@ -2192,6 +2217,466 @@ El enlace propiedad a propiedad no admite RemoveAt. + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. Tiene lugar cuando el valor de la propiedad AlternatingRowsDefaultCellStyle cambia. @@ -5375,11 +5860,21 @@ Do you want to replace it? Obtiene o establece la delimitación para elementos secundarios MDI minimizados. + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. Especifica el MenuStrip principal para el formulario. Esta propiedad se utiliza para la activación del teclado y la combinación automática en MDI. + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. Determina si el formulario tiene un cuadro para minimizar en la esquina superior derecha de la barra de título. @@ -6929,6 +7424,11 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue: El formulario especificado como MdiParent para este formulario no es un contenedor MdiContainer. + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. Indica si el carácter de petición de datos es válido como entrada. @@ -7064,6 +7564,81 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue: Especifica el tipo del objeto que se va a utilizar para analizar el texto de entrada cuando el control pierde el foco. + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. Tecla de método abreviado asociada al elemento de menú. @@ -7074,6 +7649,36 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue: Indica si la tecla de método abreviado del elemento de menú se muestra en el elemento. + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. Especifica el elemento cuyo DropDown mostrará la lista de ventanas MDI. @@ -9129,6 +9734,91 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue: No se pudo obtener el cálculo de referencias para IID {0}. + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. Especifica los lados del panel que deberían mostrar bordes. @@ -9714,6 +10404,136 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue: Demasiadas llamadas a ResumeUpdateMenuHandles. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + Controla la apariencia del control ToolBar, usando los valores de la enumeración ToolBarAppearance. + + + + Controls whether the ToolBar will automatically size itself based on Button size. + Controla si la barra de herramientas debe cambiar automáticamente de tamaño basándose en el tamaño de los botones. + + + + Parameter must be of type ToolBarButton. + El parámetro debe ser de tipo ToolBarButton. + + + + Controls what type of border the ToolBar control will have. + Controla qué tipo de borde tiene el control de la barra de herramientas. + + + + Occurs whenever a button in the ToolBar is clicked by the user. + Tiene lugar cuando el usuario hace clic en un botón de la barra de herramientas. + + + + Occurs whenever a button with the DropDownButton style is pressed. + Tiene lugar cuando se presiona un botón con estilo DropDownButton. + + + + Controls whether this button responds to user input. + Controla si este botón responde a la entrada del usuario. + + + + Identifies the image displayed on the button. + Identifica la imagen que aparece en el botón. + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + El menú desplegable de la colección ToolBarButton debe ser de tipo ContextMenu. + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + Menú contextual que aparecerá si el estilo de este botón se establece en DropDownButton. + + + + References that a non-existent ToolBarButton has been received. + Se han recibido referencias a un ToolBarButton que no existe. + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + Controla si el botón se debe mostrar como parcialmente presionado, pero sólo si el estilo del botón es ToggleButton. + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + Indica si el botón está presionado o no. Lo más normal es encontrarlo en los botones que tienen el estilo TOGGLEBUTTON. + + + + The size of the buttons on the control if the button contents do not require a larger size. + Tamaño de los botones del control si el contenido de los botones no requiere un tamaño mayor. + + + + Indicates what style of ToolBarButton this will be. + Indica qué estilo tendrá ToolBarButton. + + + + The caption to be displayed for this button. + Título que se muestra para este botón. + + + + The ToolTip text to be displayed for this button. + El texto de información sobre herramientas que se va a mostrar para este botón. + + + + Indicates whether this button should be visible. + Indica si este botón debe ser visible. + + + + The collection of ToolBarButtons that make up this ToolBar. + Colección de botones ToolBarButtons que forman esta barra de herramientas. + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + Controla si la barra de herramientas mostrará una línea en 3D en la parte superior de su área cliente. + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + Controla si la barra de herramientas mostrará una flecha junto a los botones de lista desplegable. + + + + The ImageList from which this ToolBar will get all of the button images. + ImageList de la que esta barra de herramientas obtendrá todas las imágenes de los botones. + + + + The size of the images within the ToolBar's ImageList. + Tamaño de las imágenes de ImageList de la barra de herramientas. + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + Indica si se debe mostrar la información sobre herramientas para cada uno de los botones, si está disponible. + + + + Controls how the text is positioned relative to the Image in each button. + Controla cómo se sitúa el texto en relación con la imagen en cada botón. + + + + Indicates if more than one row of buttons is allowed. + Indica si se permite más de una fila de botones. + + AllowItemReorder and AllowDrop cannot both be true. AllowItemReorder y AllowDrop no pueden ser ambos true. @@ -11431,4 +12251,4 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf index c32040002c0..6a32fd7fa83 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf @@ -1312,9 +1312,34 @@ Le formulaire parent de ce contrôle conteneur. + + Raised when the context menu collapses. + Déclenché lorsque le menu contextuel est réduit. + + + + Gets or sets the ImageList associated with this context menu. + Obtient ou définit le ImageList associé à ce menu contextuel. + + + + ContextMenu cannot be shown on an invisible control. + ContextMenu ne peut pas être affiché sur un contrôle invisible. + + + + Gets or sets a value indicating whether the menu has an image margin. + Obtient ou définit une valeur indiquant si le menu dispose d'une marge d'image. + + + + The last control that caused this context menu to be displayed. + Dernier contrôle ayant provoqué l'affichage de ce menu contextuel. + + The last control that caused this context menu strip to be displayed. - Dernier contrôle ayant provoqué l'affichage de cette bande de menus contextuels. + The last control that caused this context menu strip to be displayed. @@ -2192,6 +2217,466 @@ RemoveAt n'est pas pris en charge pour la liaison de propriété à propriété. + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. Se produit lorsque la valeur de la propriété AlternatingRowsDefaultCellStyle change. @@ -5375,11 +5860,21 @@ Voulez-vous le remplacer ? Obtient ou définit l’ancrage pour les enfants MDI réduits. + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. Spécifie le MenuStrip principal du formulaire. Cette propriété est utilisée pour l'activation clavier et la fusion automatique en MDI. + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. Détermine si un formulaire dispose d'un bouton de réduction dans le coin supérieur droit de sa barre de légende. @@ -6929,6 +7424,11 @@ Cette opération non conforme s'est produite sur la trace de la pile : Le formulaire qui a été spécifié comme étant le MdiParent pour ce formulaire n'est pas un MdiContainer. + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. Indique si le caractère d'invite est valide en tant qu'entrée. @@ -7064,6 +7564,81 @@ Cette opération non conforme s'est produite sur la trace de la pile : Spécifie le Type de l'objet à utiliser pour l'analyse du texte d'entrée lorsque le contrôle perd le focus. + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. La touche de raccourci associée à l'élément de menu. @@ -7074,6 +7649,36 @@ Cette opération non conforme s'est produite sur la trace de la pile : Indique si la touche de raccourci pour l'élément de menu est affichée sur l'élément. + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. Spécifie l'élément dont le DropDown affichera la liste des fenêtres MDI. @@ -9129,6 +9734,91 @@ Cette opération non conforme s'est produite sur la trace de la pile : Impossible d'obtenir le marshaleur pour IID {0}. + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. Spécifie les côtés du panneau qui doivent afficher des bordures. @@ -9714,6 +10404,136 @@ Cette opération non conforme s'est produite sur la trace de la pile : Trop d'appels vers ResumeUpdateMenuHandles. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + Contrôle l'apparence du contrôle ToolBar, en utilisant les valeurs de l'énumération ToolBarAppearance. + + + + Controls whether the ToolBar will automatically size itself based on Button size. + Contrôle si la barre d'outils est automatiquement redimensionnée en fonction de la taille des boutons. + + + + Parameter must be of type ToolBarButton. + Le paramètre doit être de type ToolBarButton. + + + + Controls what type of border the ToolBar control will have. + Contrôle le type de bordure du contrôle ToolBar. + + + + Occurs whenever a button in the ToolBar is clicked by the user. + Se produit lorsqu'un utilisateur clique sur un bouton du ToolBar. + + + + Occurs whenever a button with the DropDownButton style is pressed. + Se produit lorsqu'un bouton de style DropDownButton est enfoncé. + + + + Controls whether this button responds to user input. + Contrôle si ce bouton répond aux entrées d'utilisateur. + + + + Identifies the image displayed on the button. + Identifie l'image affichée sur ce bouton. + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + Le type d'un menu déroulant d'un ToolBarButton doit être ContextMenu. + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + Le menu contextuel qui s'affiche si le style du bouton a la valeur DropDownButton. + + + + References that a non-existent ToolBarButton has been received. + Indique qu'un ToolBarButton inexistant a été reçu. + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + Contrôle si le bouton doit être affiché comme étant partiellement enfoncé, mais uniquement si le style du bouton est ToggleButton. + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + Indique si le bouton est ou non enfoncé. Utilisé pour les boutons avec le style TOGGLEBUTTON. + + + + The size of the buttons on the control if the button contents do not require a larger size. + La taille des boutons du contrôle, si le contenu du bouton ne nécessite pas une taille plus grande. + + + + Indicates what style of ToolBarButton this will be. + Indique le style du ToolBarButton. + + + + The caption to be displayed for this button. + La légende à afficher pour ce bouton. + + + + The ToolTip text to be displayed for this button. + Le texte ToolTip à afficher pour ce bouton. + + + + Indicates whether this button should be visible. + Indique si ce bouton doit être visible. + + + + The collection of ToolBarButtons that make up this ToolBar. + La collection de ToolBarButtons qui composent ce ToolBar. + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + Contrôle si le ToolBar affiche une ligne 3D en haut de la zone cliente. + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + Contrôle si le ToolBar affiche une flèche sur le côté des boutons déroulants. + + + + The ImageList from which this ToolBar will get all of the button images. + Le ImageList à partir duquel ce ToolBar obtient toutes les images de boutons. + + + + The size of the images within the ToolBar's ImageList. + La taille des images dans le ImageList du ToolBar. + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + Indique si des info-bulles sont affichées pour chaque bouton, si elles sont disponibles. + + + + Controls how the text is positioned relative to the Image in each button. + Contrôle la façon dont le texte est positionné par rapport à l'image dans chaque bouton. + + + + Indicates if more than one row of buttons is allowed. + Indique si plusieurs lignes de boutons sont autorisées. + + AllowItemReorder and AllowDrop cannot both be true. AllowItemReorder et AllowDrop ne peuvent pas être true en même temps. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf index 2252ee790ef..aa60c568cbd 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf @@ -1312,6 +1312,31 @@ Form padre di questo controllo contenitore. + + Raised when the context menu collapses. + Generato quando si comprime il menu di scelta rapida. + + + + Gets or sets the ImageList associated with this context menu. + Ottiene o imposta il componente ImageList associato a questo menu di scelta rapida. + + + + ContextMenu cannot be shown on an invisible control. + Impossibile visualizzare il menu di scelta rapida su un controllo invisibile. + + + + Gets or sets a value indicating whether the menu has an image margin. + Ottiene o imposta un valore che indica se è presente un margine nell'immagine del menu. + + + + The last control that caused this context menu to be displayed. + Ultimo controllo che ha comportato la visualizzazione di questo menu di scelta rapida. + + The last control that caused this context menu strip to be displayed. Ultimo controllo che ha causato la visualizzazione di questo elenco di menu di scelta rapida. @@ -2192,6 +2217,466 @@ RemoveAt non è supportato per l'associazione da proprietà a proprietà. + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. Generato quando il valore della proprietà AlternatingRowsDefaultCellStyle cambia. @@ -5375,11 +5860,21 @@ Sostituirlo? Ottiene o imposta l'ancoraggio per gli elementi figlio MDI ridotti a icona. + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. Specifica il MenuStrip principale per il form. Questa proprietà consente l'attivazione della tastiera e il merge automatico in MDI. + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. Determina se un form dispone di un pulsante di riduzione a icona nella parte superiore destra della barra del titolo. @@ -6929,6 +7424,11 @@ Traccia dello stack da cui si è verificata l'operazione non valida: Il form specificato come MdiParent per questo form non è un MdiContainer. + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. Indica se il carattere di prompt è valido come input. @@ -7064,6 +7564,81 @@ Traccia dello stack da cui si è verificata l'operazione non valida: Specifica il tipo di oggetto da utilizzare per l'analisi del testo di input quando il controllo perde lo stato attivo. + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. Il tasto di scelta rapida associato alla voce di menu. @@ -7074,6 +7649,36 @@ Traccia dello stack da cui si è verificata l'operazione non valida: Indica se il tasto di scelta rapida della voce di menu viene visualizzato sulla voce. + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. Specifica per quale elemento l'oggetto DropDown visualizzerà l'elenco delle finestre MDI. @@ -9129,6 +9734,91 @@ Traccia dello stack da cui si è verificata l'operazione non valida: Impossibile ottenere il gestore di marshalling per IID {0}. + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. Specifica i lati del riquadro per i quali devono essere visualizzati i bordi. @@ -9714,6 +10404,136 @@ Traccia dello stack da cui si è verificata l'operazione non valida: Troppe chiamate a ResumeUpdateMenuHandles. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + Determina l'aspetto del controllo ToolBar utilizzando i valori dell'enumerazione ToolBarAppearance. + + + + Controls whether the ToolBar will automatically size itself based on Button size. + Determina se viene effettuato il ridimensionamento automatico del controllo ToolBar in base alla dimensione del controllo Button. + + + + Parameter must be of type ToolBarButton. + Il parametro deve essere di tipo ToolBarButton. + + + + Controls what type of border the ToolBar control will have. + Determina il tipo di bordo del controllo ToolBar. + + + + Occurs whenever a button in the ToolBar is clicked by the user. + Generato quando l'utente fa clic su un pulsante del controllo ToolBar. + + + + Occurs whenever a button with the DropDownButton style is pressed. + Generato quando si fa clic su un pulsante con lo stile DropDownButton. + + + + Controls whether this button responds to user input. + Determina se questo pulsante risponde all'input dell'utente. + + + + Identifies the image displayed on the button. + Identifica l'immagine visualizzata sul pulsante. + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + Il menu a discesa di ToolBarButton deve essere di tipo ContextMenu. + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + Il menu di scelta rapida che verrà visualizzato se lo stile di questo pulsante è DropDownButton. + + + + References that a non-existent ToolBarButton has been received. + Ricevuto ToolBarButton inesistente. + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + Se lo stile del pulsante è ToggleButton, determina se il pulsante deve essere visualizzato come parzialmente premuto. + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + Indica se il pulsante è premuto. Normalmente si utilizza con pulsanti con lo stile TOGGLEBUTTON. + + + + The size of the buttons on the control if the button contents do not require a larger size. + La dimensione dei pulsanti del controllo se il contenuto dei pulsanti non richiede una dimensione maggiore. + + + + Indicates what style of ToolBarButton this will be. + Indica lo stile del controllo ToolBarButton. + + + + The caption to be displayed for this button. + La didascalia da visualizzare per questo pulsante. + + + + The ToolTip text to be displayed for this button. + Il testo di ToolTip da visualizzare per questo pulsante. + + + + Indicates whether this button should be visible. + Indica se questo pulsante deve essere visibile. + + + + The collection of ToolBarButtons that make up this ToolBar. + La raccolta di controlli ToolBarButton che appartengono a questo controllo ToolBar. + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + Determina se la barra degli strumenti visualizzerà una riga 3D nella parte superiore della propria area client. + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + Determina se nel controllo ToolBar verrà visualizzata una freccia accanto ai pulsanti a discesa. + + + + The ImageList from which this ToolBar will get all of the button images. + ImageList da cui questo controllo ToolBar recupera tutte le immagini dei pulsanti. + + + + The size of the images within the ToolBar's ImageList. + La dimensione delle immagini in ImageList di ToolBar. + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + Indica se visualizzare componenti ToolTip per ciascun pulsante, se disponibili. + + + + Controls how the text is positioned relative to the Image in each button. + Determina in che modo verrà posizionato il testo dei pulsanti rispetto all'immagine. + + + + Indicates if more than one row of buttons is allowed. + Indica se è consentita più di una riga di pulsanti. + + AllowItemReorder and AllowDrop cannot both be true. Le proprietà AllowItemReorder e AllowDrop non possono avere entrambe valore true. @@ -11431,4 +12251,4 @@ Traccia dello stack da cui si è verificata l'operazione non valida: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf index 525f32e234d..f8195b90ee1 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf @@ -1312,6 +1312,31 @@ このコンテナー コントロールの親フォームです。 + + Raised when the context menu collapses. + コンテキスト メニューが縮小するときに発生します。 + + + + Gets or sets the ImageList associated with this context menu. + このコンテキスト メニューに関連付けられた ImageList を取得および設定します。 + + + + ContextMenu cannot be shown on an invisible control. + 非表示のコントロールでは、ContextMenu を表示できません。 + + + + Gets or sets a value indicating whether the menu has an image margin. + メニューがイメージの余白を持つかどうかを示す値を取得または設定します。 + + + + The last control that caused this context menu to be displayed. + このコンテキスト メニューを最後に表示させたコントロールです。 + + The last control that caused this context menu strip to be displayed. このコンテキスト メニュー ストリップを最後に表示させたコントロールです。 @@ -2192,6 +2217,466 @@ RemoveAt は、プロパティからプロパティへの バインドに対してサポートされていません。 + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. AlternatingRowsDefaultCellStyle プロパティの値が変更したときに発生します。 @@ -5375,11 +5860,21 @@ Do you want to replace it? 最小化された MDI 子要素の固定を取得または設定します。 + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. フォームの主要な MenuStrip を指定します。このプロパティは、キーボードのアクティブ化および MDI での自動マージのために使用されます。 + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. フォームがキャプション バーの右上に最小化ボタンを指定するかどうかを決定します。 @@ -6929,6 +7424,11 @@ Stack trace where the illegal operation occurred was: このフォームの MdiParent として指定されたフォームは MdiContainer ではありません。 + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. プロンプト文字が入力として有効であるかどうかを示します。 @@ -7064,6 +7564,81 @@ Stack trace where the illegal operation occurred was: コントロールがフォーカスを失ったときに、入力テキストを解析するために使用されるオブジェクトの型を指定します。 + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. メニュー項目に関連付けられたショートカット キーです。 @@ -7074,6 +7649,36 @@ Stack trace where the illegal operation occurred was: メニュー項目のショートカット キーをアイテムに表示するかどうかを示します。 + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. DropDown が MDI ウィンドウの一覧を表示するアイテムを指定します。 @@ -9129,6 +9734,91 @@ Stack trace where the illegal operation occurred was: IID {0} のマーシャラーを取得できませんでした。 + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. 境界線を表示するパネルの側面を指定します。 @@ -9714,6 +10404,136 @@ Stack trace where the illegal operation occurred was: ResumeUpdateMenuHandles への呼び出しが多すぎます。 + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + ToolBarAppearance 列挙 からの値を用いて、ToolBar コントロールの外観を制御します。 + + + + Controls whether the ToolBar will automatically size itself based on Button size. + ボタンのサイズに基づいて、ツール バーのサイズを自動的に変更するかどうかを制御します。 + + + + Parameter must be of type ToolBarButton. + パラメーターは型 ToolBarButton でなければなりません。 + + + + Controls what type of border the ToolBar control will have. + ツール バー コントロールの境界線の種類を設定します。 + + + + Occurs whenever a button in the ToolBar is clicked by the user. + ユーザーがツール バーのボタンをクリックしたときに発生します。 + + + + Occurs whenever a button with the DropDownButton style is pressed. + DropDownButton スタイルのボタンがクリックされたときに発生します。 + + + + Controls whether this button responds to user input. + このボタンがユーザーの入力に応答するかどうかを制御します。 + + + + Identifies the image displayed on the button. + ボタンに表示されたイメージを識別します。 + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + ToolBarButton のドロップダウン メニューは ContextMenu 型でなければなりません。 + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + このボタンのスタイルが DropDownButton に設定されている場合に表示されるショートカット メニューです。 + + + + References that a non-existent ToolBarButton has been received. + 存在しない ToolBarButton を受け取ったことを示します。 + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + ボタンの種類が ToggleButton の場合のみ、ボタンが部分的にクリックされたとして表示するかどうかを制御します。 + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + ボタンをクリックしたかどうかを示します。TOGGLEBUTTON スタイルのボタンによく使われます。 + + + + The size of the buttons on the control if the button contents do not require a larger size. + ボタンの内容により大きなサイズが必要でない場合の、コントロール上のボタンのサイズです。 + + + + Indicates what style of ToolBarButton this will be. + ToolBarButton のスタイルを示します。 + + + + The caption to be displayed for this button. + このボタンに表示されるキャプションです。 + + + + The ToolTip text to be displayed for this button. + このボタンに表示されるツールヒント テキストです。 + + + + Indicates whether this button should be visible. + このボタンを表示するかどうかを示します。 + + + + The collection of ToolBarButtons that make up this ToolBar. + このツール バーを構成する ToolBarButtons のコレクションです。 + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + ツール バーがこのクライアント領域の上に 3D の線を表示するかどうかを設定します。 + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + ツール バーがドロップダウン ボタンの横に矢印を表示するかどうかを制御します。 + + + + The ImageList from which this ToolBar will get all of the button images. + ツール バーがすべてボタンのイメージを取得する ImageList です。 + + + + The size of the images within the ToolBar's ImageList. + ツール バーの ImageList 内にある、イメージのサイズです。 + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + ツールヒントがある場合に、それぞれのボタンでそれを表示するかどうかを示します。 + + + + Controls how the text is positioned relative to the Image in each button. + 各ボタンのイメージに対して、テキストがどのように表示されるか制御します。 + + + + Indicates if more than one row of buttons is allowed. + 複数行のボタンを許可するかどうかを示します。 + + AllowItemReorder and AllowDrop cannot both be true. AllowItemReorder と AllowDrop の両方を true にすることはできません。 @@ -11431,4 +12251,4 @@ Stack trace where the illegal operation occurred was: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf index d712fad67d0..f12f017d237 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf @@ -1312,6 +1312,31 @@ 이 컨테이너 컨트롤의 부모 폼입니다. + + Raised when the context menu collapses. + 상황에 맞는 메뉴가 축소될 때 발생합니다. + + + + Gets or sets the ImageList associated with this context menu. + 이 상황에 맞는 메뉴에 연결된 ImageList를 가져오거나 설정합니다. + + + + ContextMenu cannot be shown on an invisible control. + 보이지 않는 컨트롤에 ContextMenu를 표시할 수 없습니다. + + + + Gets or sets a value indicating whether the menu has an image margin. + 메뉴에 이미지 여백이 있는지 여부를 나타내는 값을 가져오거나 설정합니다. + + + + The last control that caused this context menu to be displayed. + 상황에 맞는 메뉴를 표시한 마지막 컨트롤입니다. + + The last control that caused this context menu strip to be displayed. 상황에 맞는 메뉴 스트립을 표시한 마지막 컨트롤입니다. @@ -2192,6 +2217,466 @@ RemoveAt은 속성에 대하여 속성 바인딩을 지원하지 않습니다. + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. AlternatingRowsDefaultCellStyle 속성 값이 변경될 때 발생합니다. @@ -5375,11 +5860,21 @@ Do you want to replace it? 최소화된 MDI 자식에 대한 앵커링을 가져오거나 설정합니다. + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. 폼의 주 MenuStrip을 지정합니다. 이 속성은 MDI에서 자동 병합 및 키보드 활성화에 사용됩니다. + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. 폼의 캡션 표시줄 오른쪽 위 모퉁이에 최소화 상자를 포함할지 여부를 결정합니다. @@ -6929,6 +7424,11 @@ Stack trace where the illegal operation occurred was: 이 폼의 MdiParent로 지정한 폼이 MdiContainer가 아닙니다. + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. 프롬프트 문자가 입력으로 올바른지 여부를 나타냅니다. @@ -7064,6 +7564,81 @@ Stack trace where the illegal operation occurred was: 컨트롤이 포커스를 잃을 때 입력 텍스트를 구문 분석하는 데 사용할 개체의 형식을 지정합니다. + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. 메뉴 항목에 연결된 바로 가기 키입니다. @@ -7074,6 +7649,36 @@ Stack trace where the illegal operation occurred was: 메뉴 항목의 바로 가기 키가 항목에 표시되는지 여부를 나타냅니다. + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. DropDown에 MDI 창의 목록이 표시되는 항목을 지정합니다. @@ -9129,6 +9734,91 @@ Stack trace where the illegal operation occurred was: IID {0}의 마샬러를 가져오지 못했습니다. + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. 테두리를 표시할 패널 면을 지정합니다. @@ -9714,6 +10404,136 @@ Stack trace where the illegal operation occurred was: ResumeUpdateMenuHandles에 대한 호출이 너무 많습니다. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + ToolBarAppearance 열거형의 값을 사용하여 ToolBar 컨트롤의 모양을 제어합니다. + + + + Controls whether the ToolBar will automatically size itself based on Button size. + 단추 크기에 따라 도구 모음의 크기를 자동으로 조정할지 여부를 제어합니다. + + + + Parameter must be of type ToolBarButton. + 매개 변수는 ToolBarButton 형식이어야 합니다. + + + + Controls what type of border the ToolBar control will have. + ToolBar 컨트롤의 테두리 형식을 제어합니다. + + + + Occurs whenever a button in the ToolBar is clicked by the user. + 사용자가 ToolBar의 단추를 클릭할 때마다 발생합니다. + + + + Occurs whenever a button with the DropDownButton style is pressed. + DropDownButton 스타일의 단추를 누를 때마다 발생합니다. + + + + Controls whether this button responds to user input. + 이 단추가 사용자 입력에 응답하는지 여부를 제어합니다. + + + + Identifies the image displayed on the button. + 단추에 표시되는 이미지를 식별합니다. + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + ToolBarButton의 드롭다운 메뉴는 ContextMenu 형식이어야 합니다. + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + 이 단추의 스타일을 DropDownButton으로 설정하면 표시되는 바로 가기 메뉴입니다. + + + + References that a non-existent ToolBarButton has been received. + 존재하지 않는 ToolBarButton에 대한 참조를 받았습니다. + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + 단추 스타일이 ToggleButton인 경우에 한하여 단추를 부분적으로 눌린 상태로 표시할지 여부를 제어합니다. + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + 단추의 누름 상태를 나타내며, 대개 TOGGLEBUTTON 스타일의 단추에서 볼 수 있습니다. + + + + The size of the buttons on the control if the button contents do not require a larger size. + 단추 크기가 단추 내용에 적합한 경우 컨트롤에 표시될 단추의 크기입니다. + + + + Indicates what style of ToolBarButton this will be. + 구현될 ToolBarButton 스타일을 나타냅니다. + + + + The caption to be displayed for this button. + 이 단추에 표시할 캡션입니다. + + + + The ToolTip text to be displayed for this button. + 이 단추에 표시할 ToolTip 텍스트입니다. + + + + Indicates whether this button should be visible. + 이 단추를 표시할지 여부를 나타냅니다. + + + + The collection of ToolBarButtons that make up this ToolBar. + 이 ToolBar를 구성하는 ToolBarButtons 컬렉션입니다. + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + 도구 모음에서 클라이언트 영역의 맨 위에 3D 선을 표시할지 여부를 제어합니다. + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + 도구 모음에서 드롭다운 단추 옆에 화살표를 표시할지 여부를 제어합니다. + + + + The ImageList from which this ToolBar will get all of the button images. + 이 ToolBar에서 모든 단추 이미지를 가져올 ImageList입니다. + + + + The size of the images within the ToolBar's ImageList. + 도구 모음의 ImageList에 있는 이미지의 크기입니다. + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + 도구 설명을 사용할 수 있는 경우 각 단추의 도구 설명을 표시할지 여부를 나타냅니다. + + + + Controls how the text is positioned relative to the Image in each button. + 각 단추에서 이미지를 기준으로 하여 텍스트를 배치하는 방법을 제어합니다. + + + + Indicates if more than one row of buttons is allowed. + 두 행 이상의 단추를 사용할 수 있는지 여부를 나타냅니다. + + AllowItemReorder and AllowDrop cannot both be true. AllowItemReorder 및 AllowDrop이 모두 true일 수 없습니다. @@ -11431,4 +12251,4 @@ Stack trace where the illegal operation occurred was: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf index 2bc82e65006..d47bbd4f725 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf @@ -1312,6 +1312,31 @@ Formularz nadrzędny tego formantu kontenera. + + Raised when the context menu collapses. + Występuje po zwinięciu menu kontekstowego. + + + + Gets or sets the ImageList associated with this context menu. + Pobiera lub ustawia listę ImageList skojarzoną z tym menu kontekstowym. + + + + ContextMenu cannot be shown on an invisible control. + Nie można pokazać elementu ContextMenu w niewidocznym formancie. + + + + Gets or sets a value indicating whether the menu has an image margin. + Pobiera lub ustawia wartość wskazującą, czy menu ma margines obrazu. + + + + The last control that caused this context menu to be displayed. + Ostatni formant, który spowodował wyświetlenie tego menu kontekstowego. + + The last control that caused this context menu strip to be displayed. Ostatni formant, który spowodował wyświetlenie tego paska menu kontekstowego. @@ -2192,6 +2217,466 @@ Element RemoveAt nie jest obsługiwany dla powiązań właściwości z właściwością + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. Występuje, gdy wartość właściwości AlternatingRowsDefaultCellStyle zostanie zmieniona. @@ -5375,11 +5860,21 @@ Czy chcesz go zamienić? Pobiera lub ustawia kotwiczenie dla zminimalizowanych elementów podrzędnych MDI. + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. Określa podstawowy element MenuStrip dla elementu Form. Ta właściwość jest używana do aktywacji klawiatury i automatycznego scalania w interfejsie MDI. + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. Określa, czy w prawym górnym rogu paska podpisu formularza znajduje się pole minimalizacji. @@ -6929,6 +7424,11 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja: Formularz, który został określony jako MdiParent dla tego formularza, nie jest elementem MdiContainer. + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. Wskazuje, czy znak monitu jest prawidłowym wprowadzanym znakiem. @@ -7064,6 +7564,81 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja: Określa typ obiektu używanego do analizowania tekstu wejściowego, gdy formant utraci fokus. + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. Klawisz skrótu skojarzony z elementem menu. @@ -7074,6 +7649,36 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja: Wskazuje, czy skrót do elementu menu będzie wyświetlany. + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. Określa element, którego element DropDown pokazuje listę okien interfejsu MDI. @@ -9129,6 +9734,91 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja: Nie można uzyskać modułu serializacji dla identyfikatora IID {0}. + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. Określa strony panelu, które mają wyświetlać obramowanie. @@ -9714,6 +10404,136 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja: Zbyt wiele odwołań do elementu ResumeUpdateMenuHandles. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + Steruje wyglądem formantu ToolBar przy użyciu wartości z wyliczenia ToolBarAppearance. + + + + Controls whether the ToolBar will automatically size itself based on Button size. + Określa, czy rozmiar formantu ToolBar będzie zmieniał się automatycznie na podstawie rozmiaru elementu Button. + + + + Parameter must be of type ToolBarButton. + Parametr musi być typu ToolBarButton. + + + + Controls what type of border the ToolBar control will have. + Określa typ obramowania formantu ToolBar. + + + + Occurs whenever a button in the ToolBar is clicked by the user. + Występuje za każdym razem, gdy użytkownik kliknie przycisk w formancie ToolBar. + + + + Occurs whenever a button with the DropDownButton style is pressed. + Występuje zawsze, gdy zostanie naciśnięty przycisk o stylu DropDownButton. + + + + Controls whether this button responds to user input. + Określa, czy przycisk odpowiada na działania użytkownika. + + + + Identifies the image displayed on the button. + Identyfikuje obraz wyświetlany na przycisku. + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + Menu rozwijane elementu ToolBarButton musi być typu ContextMenu. + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + Menu kontekstowe pojawiające się, jeśli styl przycisku jest ustawiony na DropDownButton. + + + + References that a non-existent ToolBarButton has been received. + Odebrano odwołania do nieistniejącego elementu ToolBarButton. + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + Określa, czy przycisk powinien być wyświetlany jako częściowo naciśnięty, czy nie, ale tylko wtedy, gdy stylem przycisku jest ToggleButton. + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + Wskazuje, czy przycisk jest naciśnięty, czy nie. Najczęściej występuje w przyciskach ze stylem TOGGLEBUTTON. + + + + The size of the buttons on the control if the button contents do not require a larger size. + Rozmiar przycisków w formancie, gdy zawartość formantu nie wymaga większego rozmiaru. + + + + Indicates what style of ToolBarButton this will be. + Wskazuje styl elementu ToolBarButton. + + + + The caption to be displayed for this button. + Podpis wyświetlany dla przycisku. + + + + The ToolTip text to be displayed for this button. + Tekst elementu ToolTip wyświetlany na tym przycisku. + + + + Indicates whether this button should be visible. + Wskazuje, czy przycisk powinien być widoczny. + + + + The collection of ToolBarButtons that make up this ToolBar. + Kolekcja elementów ToolBarButton, które tworzą ten element ToolBar. + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + Określa, czy u góry obszaru klienckiego elementu ToolBar ma być wyświetlana linia 3W. + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + Określa, czy obok przycisków rozwijanych w elemencie ToolBar będą wyświetlane strzałki. + + + + The ImageList from which this ToolBar will get all of the button images. + Element ImageList, z którego element ToolBar pobierze wszystkie obrazy dla przycisków. + + + + The size of the images within the ToolBar's ImageList. + Rozmiary obrazów w elemencie ImageList elementu ToolBar. + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + Wskazuje, czy elementy ToolTip mają być pokazywane na każdym przycisku, jeśli są dostępne. + + + + Controls how the text is positioned relative to the Image in each button. + Określa, jak rozmieszczany jest tekst względem obrazu na każdym przycisku. + + + + Indicates if more than one row of buttons is allowed. + Wskazuje, czy dopuszczalny jest więcej niż jeden wiersz przycisków. + + AllowItemReorder and AllowDrop cannot both be true. Wartości AllowItemReorder i AllowDrop nie mogą być jednocześnie prawdziwe. @@ -11431,4 +12251,4 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf index eb4505e49be..65317b308e5 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf @@ -1312,6 +1312,31 @@ O formulário pai deste controle de recipiente. + + Raised when the context menu collapses. + Gerado quando o menu contextual é recolhido. + + + + Gets or sets the ImageList associated with this context menu. + Obtém ou define a ImageList associada ao menu contextual. + + + + ContextMenu cannot be shown on an invisible control. + ContextMenu não pode ser mostrado em um controle invisível. + + + + Gets or sets a value indicating whether the menu has an image margin. + Obtém ou define um valor indicando se o menu tem uma margem de imagem. + + + + The last control that caused this context menu to be displayed. + O último controle que exibiu este menu contextual. + + The last control that caused this context menu strip to be displayed. O último controle que fez esta faixa de menus contextuais ser exibida. @@ -2192,6 +2217,466 @@ RemoveAt não oferece suporte para associação de propriedade a propriedade. + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. Ocorre quando o valor da propriedade AlternatingRowsDefaultCellStyle é alterado. @@ -5375,11 +5860,21 @@ Deseja substituí-lo? Obtém ou define a ancoragem para filhos MDI minimizados. + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. Especifica a MenuStrip primário do formulário. Essa propriedade é usada para ativação do teclado e mesclagem automática em MDI. + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. Determina se um formulário tem uma caixa de minimização no canto superior direito de sua barra de legenda. @@ -6929,6 +7424,11 @@ Rastreamento de pilha em que a operação ilegal ocorreu: O formulário especificado para ser o MdiParent deste formulário não é um MdiContainer. + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. Indica se o caractere de prompt é válido como entrada. @@ -7064,6 +7564,81 @@ Rastreamento de pilha em que a operação ilegal ocorreu: Especifica o Tipo de objeto a ser usado para análise do texto de entrada quando o controle perde o foco. + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. A tecla de atalho associada ao item de menu. @@ -7074,6 +7649,36 @@ Rastreamento de pilha em que a operação ilegal ocorreu: Indica se a tecla de atalho para o item de menu é exibida no item. + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. Especifica o item cujo DropDown mostrará a lista de janelas MDI. @@ -9129,6 +9734,91 @@ Rastreamento de pilha em que a operação ilegal ocorreu: Falha ao obter marshaler para IID {0}. + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. Especifica os lados do painel que deverão exibir bordas. @@ -9714,6 +10404,136 @@ Rastreamento de pilha em que a operação ilegal ocorreu: Número excessivo de chamadas para ResumeUpdateMenuHandles. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + Controla a aparência do controle ToolBar, usando os valores de enumeração ToolBarAppearance. + + + + Controls whether the ToolBar will automatically size itself based on Button size. + Controla se ToolBar será dimensionado automaticamente com base no tamanho do botão. + + + + Parameter must be of type ToolBarButton. + O parâmetro deve ser do tipo ToolBarButton. + + + + Controls what type of border the ToolBar control will have. + Controla o tipo de borda que o controle ToolBar terá. + + + + Occurs whenever a button in the ToolBar is clicked by the user. + Ocorre sempre que um botão em ToolBar é clicado pelo usuário. + + + + Occurs whenever a button with the DropDownButton style is pressed. + Ocorre sempre que um botão com o estilo DropDownButton é pressionado. + + + + Controls whether this button responds to user input. + Controla se este botão responde à entrada do usuário. + + + + Identifies the image displayed on the button. + Identifica a imagem exibida no botão. + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + O menu suspenso para um ToolBarButton deve ser do tipo ContextMenu. + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + O menu de atalho a ser exibido se o estilo deste botão for definido como DropDownButton. + + + + References that a non-existent ToolBarButton has been received. + Referências de que um ToolBarButton inexistente foi recebido. + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + Controla se o botão deve ser exibido como parcialmente pressionado ou não, mas somente se o estilo do botão for ToggleButton. + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + Indica se o botão está pressionado ou não. Isso é mais comum para botões com estilo TOGGLEBUTTON. + + + + The size of the buttons on the control if the button contents do not require a larger size. + O tamanho dos botões no controle se o conteúdo do botão não exigir um tamanho maior. + + + + Indicates what style of ToolBarButton this will be. + Indica o estilo de ToolBarButton a ser usado. + + + + The caption to be displayed for this button. + A legenda a ser exibida para este botão. + + + + The ToolTip text to be displayed for this button. + O texto de dica de ferramenta a ser exibido para este botão. + + + + Indicates whether this button should be visible. + Indica se este botão deve estar visível. + + + + The collection of ToolBarButtons that make up this ToolBar. + A coleção de ToolBarButtons que compõe este ToolBar. + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + Controla se ToolBar exibirá uma linha em 3D na parte superior de sua área cliente. + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + Controla se ToolBar exibirá uma seta na lateral dos botões suspensos. + + + + The ImageList from which this ToolBar will get all of the button images. + ImageList do qual este ToolBar obterá todas as imagens de botões. + + + + The size of the images within the ToolBar's ImageList. + O tamanho das imagens dentro de ImageList de ToolBar. + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + Indica se dicas de ferramenta serão mostradas para cada um dos botões, se disponíveis. + + + + Controls how the text is positioned relative to the Image in each button. + Controla como o texto é posicionado em relação à imagem em cada botão. + + + + Indicates if more than one row of buttons is allowed. + Indica se é permitida mais de uma linha de botões. + + AllowItemReorder and AllowDrop cannot both be true. AllowItemReorder e AllowDrop não podem ser verdadeiros. @@ -11431,4 +12251,4 @@ Rastreamento de pilha em que a operação ilegal ocorreu: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf index bcfb7b33f8e..3bfd91f3b5e 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf @@ -1312,6 +1312,31 @@ Родительская форма данного вмещающего элемента управления. + + Raised when the context menu collapses. + Вызывается при сворачивании контекстного меню. + + + + Gets or sets the ImageList associated with this context menu. + Получает или устанавливает ImageList для данного контекстного меню. + + + + ContextMenu cannot be shown on an invisible control. + Невозможно отобразить ContextMenu в невидимом элементе управления. + + + + Gets or sets a value indicating whether the menu has an image margin. + Получает или задает значение, определяющее наличие в меню полей изображения. + + + + The last control that caused this context menu to be displayed. + Последний элемент управления, вызывавший отображение этого контекстного меню. + + The last control that caused this context menu strip to be displayed. Последний элемент управления, вызвавший отображение полосы данного контекстного меню. @@ -2192,6 +2217,466 @@ Метод RemoveAt не поддерживается для привязки свойства к другому свойству. + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. Возникает при изменении значения свойства AlternatingRowsDefaultCellStyle. @@ -5376,11 +5861,21 @@ Do you want to replace it? Получает или задает привязку для свернутых дочерних форм MDI. + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. Определяет для Form первичный MenuStrip. Данное свойство используется для активации клавиатуры и автоматического слияния в MDI. + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. Определяет, содержит ли форма в правом верхнем углу строки заголовка значок свертывания. @@ -6930,6 +7425,11 @@ Stack trace where the illegal operation occurred was: Форма, указанная как MdiParent для данной формы, не является MdiContainer. + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. Указывает, является ли символ, введенный в окне приглашения, допустимым. @@ -7065,6 +7565,81 @@ Stack trace where the illegal operation occurred was: Указывает Type для объекта, который будет использоваться для разбора вводимого текста при потере фокуса элементом управления. + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. Указывает клавиши быстрого доступа к данному меню. @@ -7075,6 +7650,36 @@ Stack trace where the illegal operation occurred was: Определяет, будут ли отображаться клавиши быстрого доступа для данного элемента меню. + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. Указывает пункт, чья функция DropDown будет отображать список окон MDI. @@ -9130,6 +9735,91 @@ Stack trace where the illegal operation occurred was: Не удалось получить упаковщик ("маршалер") для IID {0}. + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. Задает стороны панели, на которых должны отображаться границы. @@ -9715,6 +10405,136 @@ Stack trace where the illegal operation occurred was: Недопустимо большое число вызовов ResumeUpdateMenuHandles. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + Задает внешний вид элемента управления ToolBar с помощью значений из перечисления ToolBarAppearance. + + + + Controls whether the ToolBar will automatically size itself based on Button size. + Указывает, будет ли ToolBar автоматически изменять размер в соответствии с размером кнопок. + + + + Parameter must be of type ToolBarButton. + Параметр должен быть типа ToolBarButton. + + + + Controls what type of border the ToolBar control will have. + Определяет тип границы для элемента управления ToolBar. + + + + Occurs whenever a button in the ToolBar is clicked by the user. + Происходит при каждом нажатии кнопки на ToolBar с помощью мыши. + + + + Occurs whenever a button with the DropDownButton style is pressed. + Происходит при каждом нажатии кнопки, имеющей стиль DropDownButton. + + + + Controls whether this button responds to user input. + Указывает, воспринимает ли эта кнопка действия пользователя. + + + + Identifies the image displayed on the button. + Указывает индекс изображения в ImageList для родительского ToolBar, который используется при получении изображения для этой кнопки. + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + Раскрывающееся меню для ToolBarButton должно иметь тип ContextMenu. + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + Контекстное меню, отображаемое в том случае, если кнопке назначен стиль DropDownButton. + + + + References that a non-existent ToolBarButton has been received. + Сообщает о том, что получен несуществующий ToolBarButton. + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + Задает, должна ли кнопка отображаться нажатой (только для кнопок, имеющих стиль ToggleButton). + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + Указывает, находится ли кнопка в нажатом положении. Обычно этот признак используется для кнопок, имеющих стиль TOGGLEBUTTON. + + + + The size of the buttons on the control if the button contents do not require a larger size. + Предлагает размер кнопок на ToolBar. Размеры отдельных кнопок могут отличаться от данного размера в зависимости от длины текста, наличия стрелок раскрывающегося списка и др. + + + + Indicates what style of ToolBarButton this will be. + Указывает, какой стиль ToolBarButton будет использоваться. + + + + The caption to be displayed for this button. + Надпись, отображаемая на этой кнопке. + + + + The ToolTip text to be displayed for this button. + Текст подсказки, отображаемый для этой кнопки. + + + + Indicates whether this button should be visible. + Указывает, должна ли эта кнопка быть видимой. + + + + The collection of ToolBarButtons that make up this ToolBar. + Коллекция ToolBarButton, из которых состоит эта панель ToolBar. + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + Задает, должна ли в верхней части клиентской области панели ToolBar отображаться объемная линия. + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + Задает, отображаются ли на ToolBar стрелки рядом с кнопками, имеющими раскрывающиеся списки. + + + + The ImageList from which this ToolBar will get all of the button images. + ImageList, из которого эта панель ToolBar будет извлекать изображения всех кнопок. + + + + The size of the images within the ToolBar's ImageList. + Размер изображений в списке изображений для ToolBar. + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + Указывает, должна ли отображаться подсказка (если доступна) для каждой кнопки. + + + + Controls how the text is positioned relative to the Image in each button. + Задает расположение текста относительно изображения на каждой кнопке. + + + + Indicates if more than one row of buttons is allowed. + Указывает, разрешено ли несколько рядов кнопок. + + AllowItemReorder and AllowDrop cannot both be true. AllowItemReorder и AllowDrop не могут одновременно иметь значение true. @@ -11432,4 +12252,4 @@ Stack trace where the illegal operation occurred was: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf index e41d54bf92f..8fca0bb8407 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf @@ -1312,6 +1312,31 @@ Bu kapsayıcı denetiminin üst formu. + + Raised when the context menu collapses. + İçerik menüsü daraltıldığında harekete geçirilir. + + + + Gets or sets the ImageList associated with this context menu. + Bu içerik menüsüyle ilişkili ImageList'i alır veya ayarlar. + + + + ContextMenu cannot be shown on an invisible control. + ContextMenu, görünmeyen bir denetimde gösterilemiyor. + + + + Gets or sets a value indicating whether the menu has an image margin. + Menüde resim kenar boşluğu olup olmadığını gösteren değeri alır veya ayarlar. + + + + The last control that caused this context menu to be displayed. + Bu bağlam menüsünün görüntülenmesine neden olan en son denetim. + + The last control that caused this context menu strip to be displayed. Bu içerik menüsü şeridinin görüntülenmesine neden olan en son denetim. @@ -2192,6 +2217,466 @@ RemoveAt, özellikler arası bağlama için desteklenmiyor. + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. AlternatingRowsDefaultCellStyle özelliğinin değeri değiştiğinde gerçekleşir. @@ -5375,11 +5860,21 @@ Bunu değiştirmek istiyor musunuz? Simge durumuna küçültülmüş MDI alt öğeleri için bağlamayı alır veya ayarlar. + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. Form için birincil MenuStrip'i belirtir. Bu özellik MDI'da klavye etkinleştirme ve otomatik birleştirme için kullanılır. + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. Formda başlık çubuğunun sağ üst köşesinde simge durumuna küçültme kutusunun bulunup bulunmadığını belirler. @@ -6929,6 +7424,11 @@ Geçersiz işlemin gerçekleştiği yığın izi: Bu form için MdiParent olarak belirtilen form, bir MdiContainer değil. + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. İstem karakterinin giriş olarak geçerli olup olmadığını gösterir. @@ -7064,6 +7564,81 @@ Geçersiz işlemin gerçekleştiği yığın izi: Denetim odağı kaybettiğinde giriş metnini ayrıştırmak için kullanılacak nesnenin türünü belirtir. + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. Menü öğesiyle ilişkili kısayol tuşu. @@ -7074,6 +7649,36 @@ Geçersiz işlemin gerçekleştiği yığın izi: Menü öğesinin kısayolunun öğede görüntülenip görüntülenmeyeceğini gösterir. + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. DropDown'ı MDI pencereleri listesini gösterecek öğeyi belirtir. @@ -9129,6 +9734,91 @@ Geçersiz işlemin gerçekleştiği yığın izi: {0} IID için sıralayıcı alınamadı. + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. Bölmenin kenarlıkları görüntüleyecek taraflarını belirtir. @@ -9714,6 +10404,136 @@ Geçersiz işlemin gerçekleştiği yığın izi: Çok fazla sayıda ResumeUpdateMenuHandles çağrısı. + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + ToolBarAppearance numaralandırmasındaki değerleri kullanarak ToolBar denetiminin görünümünü denetler. + + + + Controls whether the ToolBar will automatically size itself based on Button size. + Araç Çubuğu'nun Düğme boyutuna bağlı olarak kendi kendini otomatik olarak boyutlandırıp boyutlandıramayacağını denetler. + + + + Parameter must be of type ToolBarButton. + Parametrenin ToolBarButton türünde olması gerekir. + + + + Controls what type of border the ToolBar control will have. + ToolBar denetiminin ne tür kenarlığı olacağını denetler. + + + + Occurs whenever a button in the ToolBar is clicked by the user. + Araç Çubuğu'ndaki bir düğme kullanıcı tarafından her tıklatıldığında gerçekleşir. + + + + Occurs whenever a button with the DropDownButton style is pressed. + DropDownButton stilindeki bir düğmeye her basıldığında gerçekleşir. + + + + Controls whether this button responds to user input. + Bu düğmenin kullanıcı girişini yanıtlayıp yanıtlayamayacağını denetler. + + + + Identifies the image displayed on the button. + Düğmede görüntülenen resmi tanımlar. + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + ToolBarButton'ın açılan menüsü ContextMenu türünde olmalı. + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + Bu düğmenin stili DropDownButton olarak ayarlandığında görünecek olan kısayol menüsü. + + + + References that a non-existent ToolBarButton has been received. + Varolmayan bir ToolBarButton alındığını gösterir. + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + Düğmenin kısmen basılı olarak görüntülenip görüntülenmeyeceğini denetler, ancak yalnızca düğme stili ToggleButton ise uygulanabilir. + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + Düğmenin basılı olup olmadığını gösterir. Bu, genellikle stili TOGGLEBUTTON olan düğmelerde görülür. + + + + The size of the buttons on the control if the button contents do not require a larger size. + Düğme içerikleri daha büyük bir boyut gerektirmezse düğmelerin boyutu. + + + + Indicates what style of ToolBarButton this will be. + Bu ToolBarButton'ın hangi stilde olacağını gösterir. + + + + The caption to be displayed for this button. + Bu düğme için görüntülenecek başlık. + + + + The ToolTip text to be displayed for this button. + Bu düğme için görüntülenecek ToolTip metni. + + + + Indicates whether this button should be visible. + Bu düğmenin görünür olup olmayacağını gösterir. + + + + The collection of ToolBarButtons that make up this ToolBar. + Bu ToolBar'ı oluşturan ToolBarButton koleksiyonu. + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + ToolBar'ın istemci alanının üstünde 3 boyutlu çizgi görüntülenip görüntülenmeyeceğini denetler. + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + ToolBar'ın açılır düğmelerinin yanında ok görüntülenip görüntülenmeyeceğini denetler. + + + + The ImageList from which this ToolBar will get all of the button images. + Bu ToolBar'ın tüm düğme resimlerini alacağı ImageList. + + + + The size of the images within the ToolBar's ImageList. + ToolBar'ın ImageList'indeki resimlerin boyutu. + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + Her bir düğme için ToolTip'lerin (varsa) gösterilip gösterilmeyeceğini belirler. + + + + Controls how the text is positioned relative to the Image in each button. + Metnin her düğmedeki Resme göre nasıl yerleştirileceğini denetler. + + + + Indicates if more than one row of buttons is allowed. + Birden fazla düğme satırına izin verilip verilmeyeceğini gösterir. + + AllowItemReorder and AllowDrop cannot both be true. Hem AllowItemReorder hem de AllowDrop True olamaz. @@ -11431,4 +12251,4 @@ Geçersiz işlemin gerçekleştiği yığın izi: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf index 4956e80123c..31990b71af4 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf @@ -1312,6 +1312,31 @@ 此容器控件的父窗体。 + + Raised when the context menu collapses. + 在上下文菜单折叠时引发。 + + + + Gets or sets the ImageList associated with this context menu. + 获取或设置与此上下文菜单关联的 ImageList。 + + + + ContextMenu cannot be shown on an invisible control. + ContextMenu 无法在不可见的控件上显示。 + + + + Gets or sets a value indicating whether the menu has an image margin. + 获取或设置指示菜单是否有图像边距的值。 + + + + The last control that caused this context menu to be displayed. + 使此上下文菜单显示的最后一个控件。 + + The last control that caused this context menu strip to be displayed. 使该上下文菜单条显示的最后一个控件。 @@ -2192,6 +2217,466 @@ 属性到属性的绑定不支持 RemoveAt。 + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. AlternatingRowsDefaultCellStyle 属性值更改时发生。 @@ -5375,11 +5860,21 @@ Do you want to replace it? 获取或设置最小化 MDI 子级的定位点。 + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. 为窗体指定主 MenuStrip。此属性用于键盘激活和 MDI 中的自动合并。 + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. 确定窗体标题栏的右上角是否有最小化框。 @@ -6929,6 +7424,11 @@ Stack trace where the illegal operation occurred was: 被指定为此窗体的 MdiParent 的窗体不是 MdiContainer。 + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. 指示提示字符是否为有效输入。 @@ -7064,6 +7564,81 @@ Stack trace where the illegal operation occurred was: 指定当控件失去焦点时用于分析输入文本的对象的类型。 + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. 与菜单项关联的快捷键。 @@ -7074,6 +7649,36 @@ Stack trace where the illegal operation occurred was: 指示是否在该项上显示菜单项的快捷键。 + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. 指定其 DropDown 将显示 MDI 窗口列表的项。 @@ -9129,6 +9734,91 @@ Stack trace where the illegal operation occurred was: 未能获取 IID {0} 的封送处理程序。 + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. 指定应显示边框的面板的边。 @@ -9714,6 +10404,136 @@ Stack trace where the illegal operation occurred was: 对 ResumeUpdateMenuHandles 的调用过多。 + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + 使用 ToolBarAppearance 枚举中的值来控制 ToolBar 控件的外观。 + + + + Controls whether the ToolBar will automatically size itself based on Button size. + 控制工具栏是否根据按钮大小自动调整自身的大小。 + + + + Parameter must be of type ToolBarButton. + 参数必须是 ToolBarButton 类型。 + + + + Controls what type of border the ToolBar control will have. + 控制工具栏控件将具有的边框类型。 + + + + Occurs whenever a button in the ToolBar is clicked by the user. + 每当用户单击 ToolBar 中的按钮时发生。 + + + + Occurs whenever a button with the DropDownButton style is pressed. + 每当按下具有 DropDownButton 样式的按钮时发生。 + + + + Controls whether this button responds to user input. + 控制此按钮是否响应用户输入。 + + + + Identifies the image displayed on the button. + 标识按钮上显示的图像。 + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + ToolBarButton 的下拉菜单的类型必须为 ContextMenu。 + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + 当此按钮的样式设置为 DropDownButton 时将显示的快捷菜单。 + + + + References that a non-existent ToolBarButton has been received. + 接收到对不存在的 ToolBarButton 的引用。 + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + 控制该按钮是否应显示为部分下压,但这仅适用于样式为 ToggleButton 的按钮。 + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + 指示按钮是否是下压的。这常见于样式为 TOGGLEBUTTON 的按钮。 + + + + The size of the buttons on the control if the button contents do not require a larger size. + 按钮内容不需要更大大小时控件上的按钮的大小。 + + + + Indicates what style of ToolBarButton this will be. + 指示它将成为何种样式的 ToolBarButton。 + + + + The caption to be displayed for this button. + 此按钮将要显示的标题。 + + + + The ToolTip text to be displayed for this button. + 要为此按钮显示的 ToolTip 文本。 + + + + Indicates whether this button should be visible. + 指示此按钮是否应为可见。 + + + + The collection of ToolBarButtons that make up this ToolBar. + 组成此 ToolBar 的 ToolBarButtons 集合。 + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + 控制工具栏是否在其工作区的顶部显示三维线。 + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + 控制工具栏是否在下拉按钮旁边显示一个箭头。 + + + + The ImageList from which this ToolBar will get all of the button images. + 此 ToolBar 将从中获取所有按钮图像的 ImageList。 + + + + The size of the images within the ToolBar's ImageList. + 工具栏的 ImageList 内的图像的大小。 + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + 指示是否为每个按钮显示工具提示(如果有的话)。 + + + + Controls how the text is positioned relative to the Image in each button. + 控制如何相对于每一按钮中的图像来定位文本。 + + + + Indicates if more than one row of buttons is allowed. + 指示是否允许多行按钮。 + + AllowItemReorder and AllowDrop cannot both be true. AllowItemReorder 和 AllowDrop 不能同时为 True。 @@ -11431,4 +12251,4 @@ Stack trace where the illegal operation occurred was: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf index c2d9b1065e9..8358ed3de3b 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf @@ -1312,6 +1312,31 @@ 此容器控制項的父表單。 + + Raised when the context menu collapses. + 在內容功能表摺疊時引發。 + + + + Gets or sets the ImageList associated with this context menu. + 取得或設定與此內容功能表相關的 ImageList。 + + + + ContextMenu cannot be shown on an invisible control. + 無法在不可見的控制項上顯示 ContextMenu。 + + + + Gets or sets a value indicating whether the menu has an image margin. + 取得或設定用來指示功能表是否有影像邊界的值。 + + + + The last control that caused this context menu to be displayed. + 造成顯示此內容功能表的最後控制項。 + + The last control that caused this context menu strip to be displayed. 造成顯示此內容功能表區域的最後控制項。 @@ -2192,6 +2217,466 @@ 屬性間的繫結不支援 RemoveAt。 + + Indicates whether the grid can be re-sorted by clicking a column header. + Indicates whether the grid can be re-sorted by clicking a column header. + + + + Indicates the background color of alternating rows for a ledger appearance. + Indicates the background color of alternating rows for a ledger appearance. + + + + Occurs when the user clicks the Back button on a child table to return to the parent table. + Occurs when the user clicks the Back button on a child table to return to the parent table. + + + + Indicates the color of the DataGrid background. + Indicates the color of the DataGrid background. + + + + BeginInit() has already been called without an EndInit(). + BeginInit() has already been called without an EndInit(). + + + + Specifies whether the DataGridBoolColumn allows null values. + Specifies whether the DataGridBoolColumn allows null values. + + + + Indicates the border style for the DataGrid. + Indicates the border style for the DataGrid. + + + + Navigates back to the parent rows. + Navigates back to the parent rows. + + + + Indicates the background color of the top caption. + Indicates the background color of the top caption. + + + + Shows/Hides the parent rows for the current set of child rows. + Shows/Hides the parent rows for the current set of child rows. + + + + Indicates the font of the top caption. + Indicates the font of the top caption. + + + + Indicates the color of text that appears in the top caption. + Indicates the color of text that appears in the top caption. + + + + Indicates the text displayed in the top caption. + Indicates the text displayed in the top caption. + + + + Indicates whether the top caption is visible. + Indicates whether the top caption is visible. + + + + DataGridColumn instance does not exist in the collection. + DataGridColumn instance does not exist in the collection. + + + + Indicates whether the column headers are visible. + Indicates whether the column headers are visible. + + + + Position of ListManager must be equal to 'rowNum'. + Position of ListManager must be equal to 'rowNum'. + + + + PropertyDescriptor has not been set on this DataGridColumn. + PropertyDescriptor has not been set on this DataGridColumn. + + + + Data grid column styles collection already contains a column style with the same mapping name. + Data grid column styles collection already contains a column style with the same mapping name. + + + + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + DataGridColumnStyle of '{0}' cannot be used because it is not associated with a Property or Column in the DataSource. + + + + ColumnWidth must be greater than or equal to 0. + ColumnWidth must be greater than or equal to 0. + + + + The currently selected cell in the DataGrid. + The currently selected cell in the DataGrid. + + + + Indicates a sub-list of the DataSource to show in the DataGrid. + Indicates a sub-list of the DataSource to show in the DataGrid. + + + + Indicates the source of data for the DataGrid. + Indicates the source of data for the DataGrid. + + + + User cannot change the contents of the default GridColumnStylesCollection. + User cannot change the contents of the default GridColumnStylesCollection. + + + + Value of this property cannot be changed on the default DataGridTableStyle. + Value of this property cannot be changed on the default DataGridTableStyle. + + + + Occurs when the user clicks the "show/hide parent rows" icon. + Occurs when the user clicks the "show/hide parent rows" icon. + + + + Value '{0}' cannot be set to an empty value. + Value '{0}' cannot be set to an empty value. + + + + Committing the row to the original data store has caused an error. + Committing the row to the original data store has caused an error. + + + + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + DataGrid received an exception at design time. Reset the DataSource and DataMember property on the grid. + + + + Program cannot get information about the painting and scrolling region. + Program cannot get information about the painting and scrolling region. + + + + Indicates the index of the column that is first shown. + Indicates the index of the column that is first shown. + + + + Indicates whether the grid has a flat appearance. + Indicates whether the grid has a flat appearance. + + + + Indicates the color of the grid lines. + Indicates the color of the grid lines. + + + + Indicates the style of the grid lines. + Indicates the style of the grid lines. + + + + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + The collection of DataGridTableStyle objects that the DataGrid can render its data with. + + + + Indicates the background color of the column and row headers. + Indicates the background color of the column and row headers. + + + + Indicates the font of the text in the column and row headers. + Indicates the font of the text in the column and row headers. + + + + Indicates the color of the text in the column and row headers. + Indicates the color of the text in the column and row headers. + + + + Returns the horizontal scroll bar used by the grid. + Returns the horizontal scroll bar used by the grid. + + + + Indicates the color of the text that appears inside the child links. + Indicates the color of the text that appears inside the child links. + + + + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + Indicates the color of the text that appears inside a child link when the mouse pointer moves over it. + + + + The CurrencyManager that the DataGrid uses to get data from the data source. + The CurrencyManager that the DataGrid uses to get data from the data source. + + + + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + Occurs when the user navigates to the child rows or when the user navigates back to the parent rows. + + + + Indicates whether links to child tables are shown. + Indicates whether links to child tables are shown. + + + + Occurs when the user clicks on the expansion glyph on the row header. + Occurs when the user clicks on the expansion glyph on the row header. + + + + Event raised when the value of the BackgroundColor property is changed on DataGrid. + Event raised when the value of the BackgroundColor property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the BorderStyle property is changed on DataGrid. + Event raised when the value of the BorderStyle property is changed on DataGrid. + + + + Event raised when the value of the CaptionVisible property is changed on DataGrid. + Event raised when the value of the CaptionVisible property is changed on DataGrid. + + + + Event raised when the value of the CurrentCell property is changed on DataGrid. + Event raised when the value of the CurrentCell property is changed on DataGrid. + + + + Event raised when the value of the DataSource property is changed on DataGrid. + Event raised when the value of the DataSource property is changed on DataGrid. + + + + Event raised when the value of the FlatMode property is changed on DataGrid. + Event raised when the value of the FlatMode property is changed on DataGrid. + + + + Event raised when the value of the NavigationMode property is changed on DataGrid. + Event raised when the value of the NavigationMode property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + Event raised when the value of the ParentRowsLabelStyle property is changed on DataGrid. + + + + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + Event raised when the value of the ParentRowsVisible property is changed on DataGrid. + + + + Event raised when the value of the ReadOnly property is changed on DataGrid. + Event raised when the value of the ReadOnly property is changed on DataGrid. + + + + Indicates the background color of the parent rows. + Indicates the background color of the parent rows. + + + + Indicates the color of the text in the parent rows. + Indicates the color of the text in the parent rows. + + + + Indicates whether the parent rows show labels for the table and for the columns. + Indicates whether the parent rows show labels for the table and for the columns. + + + + Indicates whether the parent rows area is visible. + Indicates whether the parent rows area is visible. + + + + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + Specifies what the default pixel widths of the grid columns are. The default value for PreferredColumnWidth is 75. + + + + Indicates the preferred height of the rows. + Indicates the preferred height of the rows. + + + + Value {0} Do you want to correct this value? + Value {0} Do you want to correct this value? + + + + Indicates whether rows in the grid can be edited, added, or deleted. + Indicates whether rows in the grid can be edited, added, or deleted. + + + + Indicates the width of the row headers. + Indicates the width of the row headers. + + + + Indicates whether the row headers are visible. + Indicates whether the row headers are visible. + + + + DataGridRow.Height cannot be negative. + DataGridRow.Height cannot be negative. + + + + DataGridRow cannot have a negative row number. + DataGridRow cannot have a negative row number. + + + + Occurs when the user scrolls either the horizontal or vertical scroll bar. + Occurs when the user scrolls either the horizontal or vertical scroll bar. + + + + Indicates the index of the current row. + Indicates the index of the current row. + + + + Indicates the background color of any selected cells or rows. + Indicates the background color of any selected cells or rows. + + + + Indicates the color of the text in any selected cells or rows. + Indicates the color of the text in any selected cells or rows. + + + + ListManager can be set using the DataSource and DataMember properties. + ListManager can be set using the DataSource and DataMember properties. + + + + Position on a null ListManager cannot be set. + Position on a null ListManager cannot be set. + + + + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + CurrentCell cannot be set at this time. Moving your code to the Form.Load event should solve this problem. + + + + DataGridTable instance does not exist in the collection. + DataGridTable instance does not exist in the collection. + + + + DataGridTableStyle that is already parented to another DataGrid cannot be added. + DataGridTableStyle that is already parented to another DataGrid cannot be added. + + + + Data grid table styles collection already contains a table style with the same mapping name. + Data grid table styles collection already contains a table style with the same mapping name. + + + + DataGridTableStyle does not support transparent AlternatingBackColor. + DataGridTableStyle does not support transparent AlternatingBackColor. + + + + DataGridTableStyle does not support transparent BackColor. + DataGridTableStyle does not support transparent BackColor. + + + + DataGridTableStyle does not support transparent HeaderBackColor. + DataGridTableStyle does not support transparent HeaderBackColor. + + + + DataGridTableStyle does not support transparent SelectionBackColor. + DataGridTableStyle does not support transparent SelectionBackColor. + + + + null rectangle for icon bounds when adding tool tip. + null rectangle for icon bounds when adding tool tip. + + + + DataGrid control does not support transparent AlternatingBackColor. + DataGrid control does not support transparent AlternatingBackColor. + + + + DataGrid control does not support transparent BackColor. + DataGrid control does not support transparent BackColor. + + + + DataGrid control does not support transparent CaptionBackColor. + DataGrid control does not support transparent CaptionBackColor. + + + + DataGrid control does not support transparent HeaderBackColor. + DataGrid control does not support transparent HeaderBackColor. + + + + DataGrid control does not support transparent ParentRowsBackColor. + DataGrid control does not support transparent ParentRowsBackColor. + + + + DataGrid control does not support transparent SelectionBackColor. + DataGrid control does not support transparent SelectionBackColor. + + + + Data cannot be read from a DataGrid which is not bound to a DataTable. + Data cannot be read from a DataGrid which is not bound to a DataTable. + + + + Returns the vertical scroll bar used by the grid. + Returns the vertical scroll bar used by the grid. + + Occurs when the value of the AlternatingRowsDefaultCellStyle property changes. AlternatingRowsDefaultCellStyle 屬性的值變更時發生。 @@ -5375,11 +5860,21 @@ Do you want to replace it? 為最小化的 MDI 子項目獲得或設定錨定。 + + The main menu of the form. This must be set to a component of type MainMenu. + The main menu of the form. This must be set to a component of type MainMenu. + + Specifies the primary MenuStrip for the Form. This property is used for keyboard activation and automatic merging in MDI. 指定表單的主要 MenuStrip。此屬性可用於鍵盤啟用,以及 MDI 中的自動合併。 + + The merged menu of this form, which is used when displaying a single merged MDI menu. + The merged menu of this form, which is used when displaying a single merged MDI menu. + + Determines whether a form has a minimize box in the upper-right corner of its caption bar. 決定表單在其標題列的右上角是否有最小化的方塊。 @@ -6929,6 +7424,11 @@ Stack trace where the illegal operation occurred was: 指定了不是 MdiContainer 的表單當做是該表單的 MdiParent 的表單。 + + Occurs when the main menu collapses. + Occurs when the main menu collapses. + + Indicates whether the prompt character is valid as input. 表示提示字元是否可以當做有效輸入。 @@ -7064,6 +7564,81 @@ Stack trace where the illegal operation occurred was: 指定當控制項遺失焦點時,用來剖析輸入文字的物件類型。 + + Parameter must be of type MenuItem. + Parameter must be of type MenuItem. + + + + Indicates if this menu contains any child items. + Indicates if this menu contains any child items. + + + + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + Cannot add MenuItem '{0}'. It already exists as a parent of the current menu item. + + + + Indicates whether the item is checked. + Indicates whether the item is checked. + + + + Indicates whether the item is the default item. + Indicates whether the item is the default item. + + + + Indicates whether the item is enabled. + Indicates whether the item is enabled. + + + + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + True is not a valid value for the Checked property. This is only valid for MenuItems that have no children and are not top-level. + + + + Determines whether the MDI child window list is appended to this item. + Determines whether the MDI child window list is appended to this item. + + + + Determines the merge order of the item. + Determines the merge order of the item. + + + + Determines how the item is handled when menus are merged. + Determines how the item is handled when menus are merged. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Occurs before the containing menu is displayed. + Occurs before the containing menu is displayed. + + + + Occurs when the menu item is selected. + Occurs when the menu item is selected. + + + + Indicates if Windows will draw the menu item or if the user will handle the painting. + Indicates if Windows will draw the menu item or if the user will handle the painting. + + + + If the item is checked, this value will determine whether the check style is a radio button. + If the item is checked, this value will determine whether the check style is a radio button. + + The shortcut key associated with the menu item. 與功能表項目相關的快速鍵。 @@ -7074,6 +7649,36 @@ Stack trace where the illegal operation occurred was: 表示是否將功能表項目的快速鍵顯示在該項目上。 + + The caption displayed by the item. + The caption displayed by the item. + + + + Indicates whether the item is visible. + Indicates whether the item is visible. + + + + Retrieves the menu item that contains a list of MDI child windows. + Retrieves the menu item that contains a list of MDI child windows. + + + + The menu items for the menu. + The menu items for the menu. + + + + Cannot merge a menu with itself. + Cannot merge a menu with itself. + + + + Indicates if this menu should display right to left + Indicates if this menu should display right to left + + Specifies the item whose DropDown will show the list of MDI windows. 指定其 DropDown 將顯示 MDI 視窗清單的項目。 @@ -9129,6 +9734,91 @@ Stack trace where the illegal operation occurred was: 無法取得 IID {0} 的封送處理器。 + + Adding the panel to the native status bar control has not succeeded. + Adding the panel to the native status bar control has not succeeded. + + + + Parameter must be of type StatusBarPanel. + Parameter must be of type StatusBarPanel. + + + + Occurs whenever a panel in the StatusBar needs to be painted. + Occurs whenever a panel in the StatusBar needs to be painted. + + + + Occurs when a panel within the status bar is clicked. + Occurs when a panel within the status bar is clicked. + + + + The alignment of the panel's text. + The alignment of the panel's text. + + + + Determines how a panel will resize when the parent changes size. + Determines how a panel will resize when the parent changes size. + + + + Determines what type of border a panel has. + Determines what type of border a panel has. + + + + Determines what icon is displayed in the panel. + Determines what icon is displayed in the panel. + + + + The minimum width of the panel. + The minimum width of the panel. + + + + The name of the panel. + The name of the panel. + + + + The style of the panel. + The style of the panel. + + + + The text displayed in the panel. + The text displayed in the panel. + + + + The panel's ToolTip text. + The panel's ToolTip text. + + + + The width of the panel. + The width of the panel. + + + + The panels in the status bar. + The panels in the status bar. + + + + Determines if a status bar displays panels, or if it displays a single line of text. + Determines if a status bar displays panels, or if it displays a single line of text. + + + + Determines whether a status bar has a sizing grip. + Determines whether a status bar has a sizing grip. + + Specifies the sides of the panel that should display borders. 指定面板中應該顯示框線的邊。 @@ -9714,6 +10404,136 @@ Stack trace where the illegal operation occurred was: 太多的 ResumeUpdateMenuHandles 呼叫。 + + Controls the appearance of the ToolBar control, using values from the ToolBarAppearance enumeration. + 控制 ToolBar 控制項的外觀,使用來自 ToolBarAppearance 列舉型別的值。 + + + + Controls whether the ToolBar will automatically size itself based on Button size. + 控制工具列 (ToolBar) 是否會依照按鈕大小自動調整其大小。 + + + + Parameter must be of type ToolBarButton. + 參數必須屬於 ToolBarButton 類型。 + + + + Controls what type of border the ToolBar control will have. + 控制 ToolBar 控制項擁有的框線類型。 + + + + Occurs whenever a button in the ToolBar is clicked by the user. + 當使用者按下 ToolBar 中的按鈕時發生。 + + + + Occurs whenever a button with the DropDownButton style is pressed. + 當按住有 DropDownButton 樣式的按鈕時發生。 + + + + Controls whether this button responds to user input. + 控制此按鈕是否回應使用者的輸入。 + + + + Identifies the image displayed on the button. + 識別按鈕上顯示的影像。 + + + + The drop-down menu for a ToolBarButton must be of type ContextMenu. + ToolBarButton 的下拉式功能表必須屬於 ContextMenu 類型。 + + + + The shortcut menu that will appear if this button's style is set to DropDownButton. + 將此按鈕的樣式設為 DropDownButton 時會顯示的捷徑功能表。 + + + + References that a non-existent ToolBarButton has been received. + 參考已收到的非現存 ToolBarButton。 + + + + Controls whether the button should be displayed as partially pushed or not, but only if the style of the button is ToggleButton. + 控制按鈕是否應顯示為部分壓下,但僅適用於按鈕的樣式為 ToggleButton。 + + + + Indicates whether the button is pushed or not. This is most commonly seen for buttons with the TOGGLEBUTTON style. + 表示是否按下按鈕。這些按鈕最常見的樣式為 TOGGLEBUTTON。 + + + + The size of the buttons on the control if the button contents do not require a larger size. + 按鈕內容不需要更大的大小時,控制項上按鈕的大小。 + + + + Indicates what style of ToolBarButton this will be. + 表示將會是何種 ToolBarButton 樣式。 + + + + The caption to be displayed for this button. + 此按鈕所顯示的標題。 + + + + The ToolTip text to be displayed for this button. + 此按鈕所顯示的 ToolTip 文字。 + + + + Indicates whether this button should be visible. + 表示此按鈕是否可見。 + + + + The collection of ToolBarButtons that make up this ToolBar. + 組成這個 ToolBar 的 ToolBarButtons 集合物件。 + + + + Controls whether the ToolBar will display a 3-D line at the top of its client area. + 控制工具列是否要在其工作區的頂端顯示立體線段。 + + + + Controls whether the ToolBar will display an arrow on the side of drop-down buttons. + 控制工具列是否要在下拉按鈕旁顯示箭頭。 + + + + The ImageList from which this ToolBar will get all of the button images. + 這個 ToolBar 用來取得所有按鈕影像的 ImageList。 + + + + The size of the images within the ToolBar's ImageList. + 工具列的 ImageList 中的影像大小。 + + + + Indicates whether ToolTips will be shown for each of the buttons, if available. + 表示是否顯示每個按鈕的工具提示 (如果有)。 + + + + Controls how the text is positioned relative to the Image in each button. + 控制每個按鈕中與影像相關的文字位置。 + + + + Indicates if more than one row of buttons is allowed. + 表示是否允許一列以上的按鈕。 + + AllowItemReorder and AllowDrop cannot both be true. AllowItemReorder 和 AllowDrop 不能同時為 true。 @@ -11431,4 +12251,4 @@ Stack trace where the illegal operation occurred was: - \ No newline at end of file + diff --git a/src/System.Windows.Forms/src/System.Windows.Forms.csproj b/src/System.Windows.Forms/src/System.Windows.Forms.csproj index ed4abdf9d1e..32d4ce94633 100644 --- a/src/System.Windows.Forms/src/System.Windows.Forms.csproj +++ b/src/System.Windows.Forms/src/System.Windows.Forms.csproj @@ -1,7 +1,8 @@ - + System.Windows.Forms + 8.0.0.0 true true enable @@ -11,11 +12,39 @@ IL Trim warnings which should be removed in order to make WinForms trimmable See https://github.com/dotnet/winforms/issues/4649 --> - $(NoWarn);IL2026;IL2050;IL2057;IL2062;IL2067;IL2070;IL2072;IL2075;IL2077;IL2080;IL2092;IL2093;IL2094;IL2096;IL2111 + + $(NoWarn);CS8605;CA1052;CS0114;CS0108;CS8765;CS8622;CS0184;CS0169;CS0414;SA1507;IL2026;IL2050;IL2057;IL2062;IL2067;IL2070;IL2072;IL2075;IL2077;IL2080;IL2092;IL2093;IL2094;IL2096;IL2111;CSIsNull001;CSIsNull002;SA1129;WFDEV001;CA1822;CA1823;SA1518;SA1400;CA1066;CS8769;CS8625;CS8600;CS8603;CS8618;CS8601;CS8602;SA1508;SA1505;CA1507;CS8604;CS0649;CA1805;SA1131; Resources\System\Windows\Forms\XPThemes.manifest true true - true + + + $([System.IO.Path]::GetFullPath('$(RepoRoot)Bin\$(OutDirName)\')) + + + + + true + true + WTG.System.Windows.Forms + WiseTech Global forked version of System.Windows.Forms that includes controls that were deprecated in .NET Core 3.1 and .NET 5, like DataGrid, Menu, ToolBar and StatusBar. + WiseTech Global + © WiseTech Global Limited. All rights reserved. + @@ -23,17 +52,15 @@ - - - - - + + + @@ -83,4 +110,5 @@ PreserveNewest + \ No newline at end of file diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/AxHost.cs b/src/System.Windows.Forms/src/System/Windows/Forms/AxHost.cs index e26b328228a..756bd881f6d 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/AxHost.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/AxHost.cs @@ -464,6 +464,20 @@ private void OnContainerVisibleChanged(object? sender, EventArgs e) } } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override ContextMenu ContextMenu + { + get + { + return base.ContextMenu; + } + + set + { + base.ContextMenu = value; + } + } + /// /// Determines if the control is in edit mode. /// diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/BindingContext.cs b/src/System.Windows.Forms/src/System/Windows/Forms/BindingContext.cs index 04ae1e3a8fd..636461b5635 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/BindingContext.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/BindingContext.cs @@ -13,7 +13,7 @@ namespace System.Windows.Forms; [DefaultEvent(nameof(CollectionChanged))] public partial class BindingContext : ICollection { - private readonly Dictionary _listManagers; + private readonly Hashtable _listManagers; /// /// Initializes a new instance of the System.Windows.Forms.BindingContext class. @@ -42,7 +42,7 @@ int ICollection.Count void ICollection.CopyTo(Array ar, int index) { ScrubWeakRefs(); - _listManagers.HashtableCopyTo(ar, index); + _listManagers.CopyTo(ar, index); } /// @@ -213,6 +213,7 @@ protected virtual void RemoveCore(object dataSource) private BindingManagerBase EnsureListManager(object dataSource, string? dataMember) { BindingManagerBase? bindingManagerBase = null; + WeakReference? wRef = null; dataMember ??= string.Empty; @@ -229,8 +230,9 @@ private BindingManagerBase EnsureListManager(object dataSource, string? dataMemb // Check for previously created binding manager HashKey key = GetKey(dataSource, dataMember); - if (_listManagers.TryGetValue(key, out WeakReference? wRef) && wRef is not null) + if (_listManagers.ContainsKey(key)) { + wRef = (WeakReference)_listManagers[key]; bindingManagerBase = (BindingManagerBase?)wRef.Target; } @@ -320,13 +322,13 @@ private static void CheckPropertyBindingCycles(BindingContext newBindingContext, private void ScrubWeakRefs() { List? cleanupList = null; - foreach (KeyValuePair de in _listManagers) + foreach (System.Collections.DictionaryEntry de in _listManagers) { - if (de.Value.Target is null) + if (((WeakReference)de.Value).Target is null) { cleanupList ??= new(); - cleanupList.Add(de.Key); + cleanupList.Add((HashKey)de.Key); } } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ComboBox.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ComboBox.cs index 5c9d98ed684..e959b7d1297 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ComboBox.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ComboBox.cs @@ -1832,7 +1832,7 @@ private void ChildWndProc(ref Message m) _mousePressed = true; _mouseEvents = true; - if (ContextMenuStrip is not null) + if (ContextMenuStrip is not null || ContextMenu is not null) { // Set the mouse capture as this is the child Wndproc. Capture = true; @@ -1858,6 +1858,11 @@ private void ChildWndProc(ref Message m) _mousePressed = false; _mouseEvents = false; + if (ContextMenu is not null) + { + Capture = false; + } + DefChildWndProc(ref m); // The message gets fired from Combo-box's WndPrc - convert to Combobox coordinates @@ -1868,7 +1873,7 @@ private void ChildWndProc(ref Message m) case PInvoke.WM_CONTEXTMENU: // Forward context menu messages to the parent control - if (ContextMenuStrip is not null) + if (ContextMenuStrip is not null || ContextMenu is not null) { PInvoke.SendMessage(this, PInvoke.WM_CONTEXTMENU, m.WParamInternal, m.LParamInternal); } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ContextMenu.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ContextMenu.cs new file mode 100644 index 00000000000..5593d3e04a0 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ContextMenu.cs @@ -0,0 +1,227 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace System.Windows.Forms +{ + /// + /// This class is used to put context menus on your form and show them for + /// controls at runtime. It basically acts like a regular Menu control, + /// but can be set for the ContextMenu property that most controls have. + /// + [DefaultEvent(nameof(Popup))] + public class ContextMenu : Menu + { + private EventHandler onPopup; + private EventHandler onCollapse; + internal Control? sourceControl; + + private RightToLeft rightToLeft = System.Windows.Forms.RightToLeft.Inherit; + + /// + /// Creates a new ContextMenu object with no items in it by default. + /// + public ContextMenu() + : base(null) + { + } + + /// + /// Creates a ContextMenu object with the given MenuItems. + /// + public ContextMenu(MenuItem[] menuItems) + : base(menuItems) + { + } + + /// + /// The last control that was acted upon that resulted in this context + /// menu being displayed. + /// + [ + Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SRDescription(nameof(SR.ContextMenuSourceControlDescr)) + ] + public Control SourceControl + { + get + { + return sourceControl; + } + } + + [SRDescription(nameof(SR.MenuItemOnInitDescr))] + public event EventHandler Popup + { + add => onPopup += value; + remove => onPopup -= value; + } + + /// + /// Fires when the context menu collapses. + /// + [SRDescription(nameof(SR.ContextMenuCollapseDescr))] + public event EventHandler Collapse + { + add => onCollapse += value; + remove => onCollapse -= value; + } + + /// + /// This is used for international applications where the language + /// is written from RightToLeft. When this property is true, + /// text alignment and reading order will be from right to left. + /// + // Add a DefaultValue attribute so that the Reset context menu becomes + // available in the Property Grid but the default value remains No. + [ + Localizable(true), + DefaultValue(RightToLeft.No), + SRDescription(nameof(SR.MenuRightToLeftDescr)) + ] + public virtual RightToLeft RightToLeft + { + get + { + if (System.Windows.Forms.RightToLeft.Inherit == rightToLeft) + { + if (sourceControl is not null) + { + return ((Control)sourceControl).RightToLeft; + } + else + { + return RightToLeft.No; + } + } + else + { + return rightToLeft; + } + } + set + { + + //valid values are 0x0 to 0x2. + if (!ClientUtils.IsEnumValid(value, (int)value, (int)RightToLeft.No, (int)RightToLeft.Inherit)) + { + throw new InvalidEnumArgumentException(nameof(RightToLeft), (int)value, typeof(RightToLeft)); + } + + if (RightToLeft != value) + { + rightToLeft = value; + UpdateRtl((value == System.Windows.Forms.RightToLeft.Yes)); + } + + } + } + + internal override bool RenderIsRightToLeft + { + get + { + return (rightToLeft == System.Windows.Forms.RightToLeft.Yes); + } + } + + /// + /// Fires the popup event + /// + protected internal virtual void OnPopup(EventArgs e) + { + onPopup?.Invoke(this, e); + } + + /// + /// Fires the collapse event + /// + protected internal virtual void OnCollapse(EventArgs e) + { + onCollapse?.Invoke(this, e); + } + + protected internal virtual bool ProcessCmdKey(ref Message msg, Keys keyData, Control control) + { + sourceControl = control; + return ProcessCmdKey(ref msg, keyData); + } + + private void ResetRightToLeft() + { + RightToLeft = RightToLeft.No; + } + + /// + /// Returns true if the RightToLeft should be persisted in code gen. + /// + internal virtual bool ShouldSerializeRightToLeft() + { + if (System.Windows.Forms.RightToLeft.Inherit == rightToLeft) + { + return false; + } + + return true; + } + + /// + /// Displays the context menu at the specified position. This method + /// doesn't return until the menu is dismissed. + /// + public void Show(Control control, Point pos) + { + Show(control, pos, NativeMethods.TPM_VERTICAL | NativeMethods.TPM_RIGHTBUTTON); + } + + /// + /// Displays the context menu at the specified position. This method + /// doesn't return until the menu is dismissed. + /// + public void Show(Control control, Point pos, LeftRightAlignment alignment) + { + // This code below looks wrong but it's correct. + // WinForms Left alignment means we want the menu to show up left of the point it is invoked from. + // We specify TPM_RIGHTALIGN which tells win32 to align the right side of this + // menu with the point (which aligns it Left visually) + if (alignment == LeftRightAlignment.Left) + { + Show(control, pos, NativeMethods.TPM_VERTICAL | NativeMethods.TPM_RIGHTBUTTON | NativeMethods.TPM_RIGHTALIGN); + } + else + { + Show(control, pos, NativeMethods.TPM_VERTICAL | NativeMethods.TPM_RIGHTBUTTON | NativeMethods.TPM_LEFTALIGN); + } + } + + private void Show(Control control, Point pos, int flags) + { + if (control == null) + { + throw new ArgumentNullException(nameof(control)); + } + + if (!control.IsHandleCreated || !control.Visible) + { + throw new ArgumentException(SR.ContextMenuInvalidParent, "control"); + } + + sourceControl = control; + + OnPopup(EventArgs.Empty); + pos = control.PointToScreen(pos); + SafeNativeMethods.TrackPopupMenuEx(new HandleRef(this, Handle), + flags, + pos.X, + pos.Y, + new HandleRef(control, control.Handle), + null); + } + + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs index d90366ec2bc..7183f6e20be 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs @@ -199,6 +199,164 @@ private protected void TraceCanProcessMnemonic() private static MessageId s_threadCallbackMessage; private static ContextCallback? s_invokeMarshaledCallbackHelperDelegate; + internal static IntPtr SetUpPalette(IntPtr dc, bool force, bool realizePalette) + { + Debug.WriteLineIf(s_paletteTracing.TraceVerbose, "SetUpPalette(force:=" + force + ", ralizePalette:=" + realizePalette + ")"); + + IntPtr halftonePalette = Graphics.GetHalftonePalette(); + + Debug.WriteLineIf(s_paletteTracing.TraceVerbose, "select palette " + !force); + IntPtr result = Gdi32.SelectPalette(dc, halftonePalette, force ? BOOL.FALSE : BOOL.TRUE); + if (result != IntPtr.Zero && realizePalette) + { + Gdi32.RealizePalette(dc); + } + + return result; + } + + /// + /// Handles the WM_MENUSELECT message + /// + private void WmMenuSelect(ref Message m) + { + int item = NativeMethods.Util.LOWORD(m.WParam); + User32.MF flags = (User32.MF)NativeMethods.Util.HIWORD(m.WParam); + IntPtr hmenu = m.LParam; + MenuItem mi = null; + + if ((flags & User32.MF.SYSMENU) != 0) + { + // nothing + } + else if ((flags & User32.MF.POPUP) == 0) + { + Command cmd = Command.GetCommandFromID(item); + if (cmd != null) + { + object reference = cmd.Target; + if (reference != null && reference is MenuItem.MenuItemData) + { + mi = ((MenuItem.MenuItemData)reference).baseItem; + } + } + } + else + { + mi = GetMenuItemFromHandleId(hmenu, item); + } + + if (mi != null) + { + mi.PerformSelect(); + } + + DefWndProc(ref m); + } + + /// + /// WM_DRAWITEM handler + /// + private void WmDrawItem(ref Message m) + { + // If the wparam is zero, then the message was sent by a menu. + // See WM_DRAWITEM in MSDN. + if (m.WParamInternal == 0u) + { + WmDrawItemMenuItem(ref m); + } + else + { + WmOwnerDraw(ref m); + } + } + + private unsafe void WmDrawItemMenuItem(ref Message m) + { + // Obtain the menu item object + User32.DRAWITEMSTRUCT* dis = (User32.DRAWITEMSTRUCT*)m.LParam; + + // A pointer to the correct MenuItem is stored in the draw item + // information sent with the message. + // (See MenuItem.CreateMenuItemInfo) + MenuItem menuItem = MenuItem.GetMenuItemFromItemData(dis->itemData); + + // Delegate this message to the menu item + menuItem?.WmDrawItem(ref m); + } + + /// + /// WM_MEASUREITEM handler + /// + private unsafe void WmMeasureItem(ref Message m) + { + // If the wparam is zero, then the message was sent by a menu. + // See WM_MEASUREITEM in MSDN. + if (m.WParamInternal == 0u) + { + // Obtain the menu item object + Debug.Assert(m.LParam != IntPtr.Zero, "m.lparam is null"); + User32.MEASUREITEMSTRUCT* mis = (User32.MEASUREITEMSTRUCT*)m.LParam; + + // A pointer to the correct MenuItem is stored in the measure item + // information sent with the message. + // (See MenuItem.CreateMenuItemInfo) + MenuItem menuItem = MenuItem.GetMenuItemFromItemData(mis->itemData); + Debug.Assert(menuItem != null, "UniqueID is not associated with a menu item"); + + // Delegate this message to the menu item + menuItem?.WmMeasureItem(ref m); + } + else + { + WmOwnerDraw(ref m); + } + } + + private MenuItem GetMenuItemFromHandleId(IntPtr hmenu, int item) + { + MenuItem mi = null; + int id = User32.GetMenuItemID(hmenu, item); + if (id == unchecked((int)0xFFFFFFFF)) + { + IntPtr childMenu = IntPtr.Zero; + childMenu = User32.GetSubMenu(hmenu, item); + int count = User32.GetMenuItemCount(childMenu); + MenuItem found = null; + for (int i = 0; i < count; i++) + { + found = GetMenuItemFromHandleId(childMenu, i); + if (found != null) + { + Menu parent = found.Parent; + if (parent != null && parent is MenuItem) + { + found = (MenuItem)parent; + break; + } + + found = null; + } + } + + mi = found; + } + else + { + Command cmd = Command.GetCommandFromID(id); + if (cmd != null) + { + object reference = cmd.Target; + if (reference != null && reference is MenuItem.MenuItemData) + { + mi = ((MenuItem.MenuItemData)reference).baseItem; + } + } + } + + return mi; + } + #pragma warning disable IDE1006 // Naming Styles [ThreadStatic] private static bool t_inCrossThreadSafeCall; @@ -1377,6 +1535,90 @@ public bool ContainsFocus } } + private static readonly int s_contextMenuProperty = PropertyStore.CreateKey(); + + private void DetachContextMenu(object sender, EventArgs e) => ContextMenu = null; + + private static readonly object s_contextMenuEvent = new object(); + + [EditorBrowsable(EditorBrowsableState.Advanced)] + protected virtual void OnContextMenuChanged(EventArgs e) + { + if (Events[s_contextMenuEvent] is EventHandler eh) + { + eh(this, e); + } + } + + /// + /// Handles the WM_MENUCHAR message + /// + private void WmMenuChar(ref Message m) + { + Menu menu = ContextMenu; + if (menu != null) + { + menu.WmMenuChar(ref m); + if (m.Result != IntPtr.Zero) + { + // This char is a mnemonic on our menu. + return; + } + } + } + + /// + /// The contextMenu associated with this control. The contextMenu + /// will be shown when the user right clicks the mouse on the control. + /// + /// Whidbey: ContextMenu is browsable false. In all cases where both a context menu + /// and a context menu strip are assigned, context menu will be shown instead of context menu strip. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(null), + SRDescription(nameof(SR.ControlContextMenuDescr)), + Browsable(false) + ] + public virtual ContextMenu? ContextMenu + { + get => (ContextMenu)Properties.GetObject(s_contextMenuProperty); + set + { + ContextMenu oldValue = (ContextMenu)Properties.GetObject(s_contextMenuProperty); + + if (oldValue != value) + { + EventHandler disposedHandler = new EventHandler(DetachContextMenu); + + if (oldValue != null) + { + oldValue.Disposed -= disposedHandler; + } + + Properties.SetObject(s_contextMenuProperty, value); + + if (value != null) + { + value.Disposed += disposedHandler; + } + + OnContextMenuChanged(EventArgs.Empty); + } + } + } + + [ + SRCategory(nameof(SR.CatPropertyChanged)), + SRDescription(nameof(SR.ControlOnContextMenuChangedDescr)), + Browsable(false) + ] + public event EventHandler ContextMenuChanged + { + add => Events.AddHandler(s_contextMenuEvent, value); + remove => Events.RemoveHandler(s_contextMenuEvent, value); + } + /// /// The contextMenuStrip associated with this control. The contextMenuStrip /// will be shown when the user right clicks the mouse on the control. @@ -1421,6 +1663,31 @@ public event EventHandler? ContextMenuStripChanged remove => Events.RemoveHandler(s_contextMenuStripEvent, value); } + /// + /// Sends a Win32 message to this control. If the control does not yet + /// have a handle, it will be created. + /// + internal IntPtr SendMessage(int msg, int wparam, int lparam) + { + return UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), msg, wparam, lparam); + } + + /// + /// Sends a Win32 message to this control. If the control does not yet + /// have a handle, it will be created. + /// + internal IntPtr SendMessage(int msg, int wparam, string lparam) + { + Debug.Assert(IsHandleCreated, "Performance alert! Calling Control::SendMessage and forcing handle creation. Re-work control so handle creation is not required to set properties. If there is no work around, wrap the call in an IsHandleCreated check."); + return UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), msg, wparam, lparam); + } + + internal IntPtr SendMessage(int msg, IntPtr wparam, IntPtr lparam) + { + Debug.Assert(IsHandleCreated, "Performance alert! Calling Control::SendMessage and forcing handle creation. Re-work control so handle creation is not required to set properties. If there is no work around, wrap the call in an IsHandleCreated check."); + return UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), msg, wparam, lparam); + } + /// /// Collection of child controls. /// @@ -2459,6 +2726,8 @@ public bool HasChildren } } + internal virtual bool HasMenu => false; + /// /// The height of this control /// @@ -5097,6 +5366,12 @@ protected override void Dispose(bool disposing) DisposeAxControls(); ((ActiveXImpl?)Properties.GetObject(s_activeXImplProperty))?.Dispose(); + ContextMenu contextMenu = (ContextMenu)Properties.GetObject(s_contextMenuProperty); + if (contextMenu != null) + { + contextMenu.Disposed -= new EventHandler(DetachContextMenu); + } + ResetBindings(); if (IsHandleCreated) @@ -5706,11 +5981,11 @@ protected virtual Rectangle GetScaledBounds(Rectangle bounds, SizeF factor, Boun CreateParams cp = CreateParams; // We would need to get adornments metrics for both (old and new) Dpi in case application is in PerMonitorV2 mode and Dpi changed. - AdjustWindowRectExForControlDpi(ref adornmentsAfterDpiChange, (WINDOW_STYLE)cp.Style, bMenu: false, (WINDOW_EX_STYLE)cp.ExStyle); + AdjustWindowRectExForControlDpi(ref adornmentsAfterDpiChange, (WINDOW_STYLE)cp.Style, bMenu: HasMenu, (WINDOW_EX_STYLE)cp.ExStyle); if (_oldDeviceDpi != _deviceDpi && OsVersion.IsWindows10_1703OrGreater()) { - AdjustWindowRectExForDpi(ref adornmentsBeforeDpiChange, (WINDOW_STYLE)cp.Style, bMenu: false, (WINDOW_EX_STYLE)cp.ExStyle, _oldDeviceDpi); + AdjustWindowRectExForDpi(ref adornmentsBeforeDpiChange, (WINDOW_STYLE)cp.Style, bMenu: HasMenu, (WINDOW_EX_STYLE)cp.ExStyle, _oldDeviceDpi); } else { @@ -9231,6 +9506,12 @@ protected virtual bool ProcessCmdKey(ref Message msg, Keys keyData) { s_controlKeyboardRouting.TraceVerbose($"Control.ProcessCmdKey {msg}"); + ContextMenu contextMenu = (ContextMenu)Properties.GetObject(s_contextMenuProperty); + if (contextMenu != null && contextMenu.ProcessCmdKey(ref msg, keyData, this)) + { + return true; + } + if (_parent is not null) { return _parent.ProcessCmdKey(ref msg, keyData); @@ -10347,7 +10628,7 @@ protected virtual void ScaleControl(SizeF factor, BoundsSpecified specified) { CreateParams cp = CreateParams; RECT adornments = default; - AdjustWindowRectExForControlDpi(ref adornments, (WINDOW_STYLE)cp.Style, false, (WINDOW_EX_STYLE)cp.ExStyle); + AdjustWindowRectExForControlDpi(ref adornments, (WINDOW_STYLE)cp.Style, HasMenu, (WINDOW_EX_STYLE)cp.ExStyle); Size minSize = MinimumSize; Size maxSize = MaximumSize; @@ -10829,7 +11110,7 @@ internal Size SizeFromClientSizeInternal(Size size) { RECT rect = new(size); CreateParams cp = CreateParams; - AdjustWindowRectExForControlDpi(ref rect, (WINDOW_STYLE)cp.Style, false, (WINDOW_EX_STYLE)cp.ExStyle); + AdjustWindowRectExForControlDpi(ref rect, (WINDOW_STYLE)cp.Style, HasMenu, (WINDOW_EX_STYLE)cp.ExStyle); return rect.Size; } @@ -11836,8 +12117,9 @@ internal virtual void WmContextMenu(ref Message m) /// internal void WmContextMenu(ref Message m, Control sourceControl) { + var contextMenu = Properties.GetObject(s_contextMenuProperty) as ContextMenu; var contextMenuStrip = (ContextMenuStrip?)Properties.GetObject(s_contextMenuStripProperty); - if (contextMenuStrip is not null) + if (contextMenu != null || contextMenuStrip != null) { int x = PARAM.SignedLOWORD(m.LParamInternal); int y = PARAM.SignedHIWORD(m.LParamInternal); @@ -11855,9 +12137,22 @@ internal void WmContextMenu(ref Message m, Control sourceControl) client = PointToClient(new Point(x, y)); } + // VisualStudio7 # 156, only show the context menu when clicked in the client area if (ClientRectangle.Contains(client)) { - contextMenuStrip.ShowInternal(sourceControl, client, keyboardActivated); + if (contextMenu != null) + { + contextMenu.Show(sourceControl, client); + } + else if (contextMenuStrip != null) + { + contextMenuStrip.ShowInternal(sourceControl, client, keyboardActivated); + } + else + { + Debug.Fail("contextmenu and contextmenustrip are both null... hmm how did we get here?"); + DefWndProc(ref m); + } } else { @@ -11928,6 +12223,26 @@ private void WmEraseBkgnd(ref Message m) } } + /// + /// Handles the WM_EXITMENULOOP message. If this control has a context menu, its + /// Collapse event is raised. + /// + private void WmExitMenuLoop(ref Message m) + { + bool isContextMenu = (unchecked((int)(long)m.WParam) == 0) ? false : true; + + if (isContextMenu) + { + ContextMenu contextMenu = (ContextMenu)Properties.GetObject(s_contextMenuProperty); + if (contextMenu != null) + { + contextMenu.OnCollapse(EventArgs.Empty); + } + } + + DefWndProc(ref m); + } + /// /// Handles the WM_GETCONTROLNAME message. Returns the name of the control. /// @@ -12037,6 +12352,24 @@ private unsafe void WmHelp(ref Message m) } } + /// + /// Handles the WM_INITMENUPOPUP message + /// + private void WmInitMenuPopup(ref Message m) + { + ContextMenu contextMenu = (ContextMenu)Properties.GetObject(s_contextMenuProperty); + if (contextMenu != null) + { + + if (contextMenu.ProcessInitMenuPopup(m.WParam)) + { + return; + } + } + + DefWndProc(ref m); + } + /// /// Handles the WM_CREATE message /// @@ -12955,17 +13288,17 @@ protected virtual void WndProc(ref Message m) break; case PInvoke.WM_DRAWITEM: - if (m.WParamInternal != 0u) - { - WmOwnerDraw(ref m); - } - + WmDrawItem(ref m); break; case PInvoke.WM_ERASEBKGND: WmEraseBkgnd(ref m); break; + case PInvoke.WM_EXITMENULOOP: + WmExitMenuLoop(ref m); + break; + case PInvoke.WM_HELP: WmHelp(ref m); break; @@ -12994,6 +13327,10 @@ protected virtual void WndProc(ref Message m) break; + case WindowMessages.WM_INITMENUPOPUP: + WmInitMenuPopup(ref m); + break; + case PInvoke.WM_SYSCOMMAND: if ((m.WParamInternal & 0xFFF0) == PInvoke.SC_KEYMENU) { @@ -13020,11 +13357,7 @@ protected virtual void WndProc(ref Message m) break; case PInvoke.WM_MEASUREITEM: - if (m.WParamInternal != 0u) - { - WmOwnerDraw(ref m); - } - + WmMeasureItem(ref m); break; case PInvoke.WM_SETCURSOR: @@ -13242,9 +13575,9 @@ protected virtual void WndProc(ref Message m) WmParentNotify(ref m); break; - case PInvoke.WM_EXITMENULOOP: - case PInvoke.WM_INITMENUPOPUP: case PInvoke.WM_MENUSELECT: + WmMenuSelect(ref m); + break; default: // If we received a thread execute message, then execute it. diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ControlPaint.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ControlPaint.cs index e920050cc25..54869817352 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ControlPaint.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ControlPaint.cs @@ -6,6 +6,7 @@ using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Runtime.InteropServices; +using static Interop; namespace System.Windows.Forms; @@ -352,6 +353,26 @@ internal static unsafe HBRUSH CreateHalftoneHBRUSH() return PInvoke.CreateBrushIndirect(&lb); } + internal static unsafe Interop.Gdi32.HBRUSH CreateHalftoneHBRUSH2() + { + short* grayPattern = stackalloc short[8]; + for (int i = 0; i < 8; i++) + { + grayPattern[i] = (short)(0x5555 << (i & 1)); + } + + using PInvoke.CreateBitmapScope hBitmap = new(8, 8, 1, 1, grayPattern); + + LOGBRUSH lb = new() + { + lbStyle = BRUSH_STYLE.BS_PATTERN, + lbColor = default, // color is ignored since style is BS.PATTERN + lbHatch = (nuint)(IntPtr)hBitmap + }; + + return Gdi32.CreateBrushIndirect(ref lb); + } + /// /// Draws a border of the specified style and color to the given graphics. /// diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGrid.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGrid.cs new file mode 100644 index 00000000000..dc519cab57e --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGrid.cs @@ -0,0 +1,10766 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; +using static System.Windows.Forms.Triangle; +using static Interop; + +namespace System.Windows.Forms +{ + /// + /// Displays ADO.NET data in a scrollable grid. + /// + [ + ComVisible(true), + ClassInterface(ClassInterfaceType.AutoDispatch), + Designer("System.Windows.Forms.Design.DataGridDesigner, " + AssemblyRef.SystemDesign), + DefaultProperty(nameof(DataSource)), + DefaultEvent(nameof(Navigate)), + ComplexBindingProperties(nameof(DataSource), nameof(DataMember)), + ] + public class DataGrid : Control, ISupportInitialize, IDataGridEditingService + { +#if DEBUG + internal TraceSwitch DataGridAcc = new TraceSwitch("DataGridAcc", "Trace Windows Forms DataGrid Accessibility"); +#else + internal TraceSwitch DataGridAcc = null; +#endif + + private const int GRIDSTATE_allowSorting = 0x00000001; + private const int GRIDSTATE_columnHeadersVisible = 0x00000002; + private const int GRIDSTATE_rowHeadersVisible = 0x00000004; + private const int GRIDSTATE_trackColResize = 0x00000008; + private const int GRIDSTATE_trackRowResize = 0x00000010; + private const int GRIDSTATE_isLedgerStyle = 0x00000020; + private const int GRIDSTATE_isFlatMode = 0x00000040; + private const int GRIDSTATE_listHasErrors = 0x00000080; + private const int GRIDSTATE_dragging = 0x00000100; + private const int GRIDSTATE_inListAddNew = 0x00000200; + private const int GRIDSTATE_inDeleteRow = 0x00000400; + private const int GRIDSTATE_canFocus = 0x00000800; + private const int GRIDSTATE_readOnlyMode = 0x00001000; + private const int GRIDSTATE_allowNavigation = 0x00002000; + private const int GRIDSTATE_isNavigating = 0x00004000; + private const int GRIDSTATE_isEditing = 0x00008000; + private const int GRIDSTATE_editControlChanging = 0x00010000; + private const int GRIDSTATE_isScrolling = 0x00020000; + private const int GRIDSTATE_overCaption = 0x00040000; + private const int GRIDSTATE_childLinkFocused = 0x00080000; + private const int GRIDSTATE_inAddNewRow = 0x00100000; + private const int GRIDSTATE_inSetListManager = 0x00200000; + private const int GRIDSTATE_metaDataChanged = 0x00400000; + private const int GRIDSTATE_exceptionInPaint = 0x00800000; + private const int GRIDSTATE_layoutSuspended = 0x01000000; + + // PERF: take all the bools and put them into a state variable + private Collections.Specialized.BitVector32 gridState; // see GRIDSTATE_ consts above + + // for column widths + private const int NumRowsForAutoResize = 10; + + private const int errorRowBitmapWidth = 15; + + private const DataGridParentRowsLabelStyle defaultParentRowsLabelStyle = DataGridParentRowsLabelStyle.Both; + + private const BorderStyle defaultBorderStyle = BorderStyle.Fixed3D; + + private const bool defaultCaptionVisible = true; + + private const bool defaultParentRowsVisible = true; + + private readonly DataGridTableStyle defaultTableStyle = new DataGridTableStyle(true); + + // private bool allowSorting = true; + + private SolidBrush alternatingBackBrush = DefaultAlternatingBackBrush; + + // private bool columnHeadersVisible = true; + + private SolidBrush gridLineBrush = DefaultGridLineBrush; + + private const DataGridLineStyle defaultGridLineStyle = DataGridLineStyle.Solid; + private DataGridLineStyle gridLineStyle = defaultGridLineStyle; + + private SolidBrush headerBackBrush = DefaultHeaderBackBrush; + + private Font headerFont; // this is ambient property to Font value + + private SolidBrush headerForeBrush = DefaultHeaderForeBrush; + private Pen headerForePen = DefaultHeaderForePen; + + private SolidBrush linkBrush = DefaultLinkBrush; + + private const int defaultPreferredColumnWidth = 75; + private int preferredColumnWidth = defaultPreferredColumnWidth; + + private static readonly int defaultFontHeight = Control.DefaultFont.Height; + private int preferredRowHeight = defaultFontHeight + 3; + + // private bool rowHeadersVisible = true; + private const int defaultRowHeaderWidth = 35; + private int rowHeaderWidth = defaultRowHeaderWidth; + private int minRowHeaderWidth; + + private SolidBrush selectionBackBrush = DefaultSelectionBackBrush; + private SolidBrush selectionForeBrush = DefaultSelectionForeBrush; + + // parent rows + // + private readonly DataGridParentRows parentRows; + // Set_ListManager uses the originalState to determine + // if the grid should disconnect from all the MetaDataChangedEvents + // keep "originalState != null" when navigating back and forth in the grid + // and use Add/RemoveMetaDataChanged methods. + private DataGridState originalState; + + // ui state + // + // Don't use dataGridRows, use the accessor!!! + private DataGridRow[] dataGridRows = Array.Empty(); + private int dataGridRowsLength; + + // for toolTip + private int toolTipId; + private DataGridToolTip toolTipProvider; + + private DataGridAddNewRow addNewRow; + private LayoutData layout = new LayoutData(); + private RECT[] cachedScrollableRegion; + + // header namespace goo + // + + // these are actually get/set by ColumnBehavior + internal bool allowColumnResize = true; + + internal bool allowRowResize = true; + + internal DataGridParentRowsLabelStyle parentRowsLabels = defaultParentRowsLabelStyle; + + // information for col/row resizing + // private bool trackColResize = false; + private int trackColAnchor; + private int trackColumn; + // private bool trackRowResize = false; + private int trackRowAnchor; + private int trackRow; + private PropertyDescriptor trackColumnHeader; + private MouseEventArgs lastSplitBar; + + // private bool isLedgerStyle = true; + // private bool isFlatMode = false; + private Font linkFont; + + private SolidBrush backBrush = DefaultBackBrush; + private SolidBrush foreBrush = DefaultForeBrush; + private SolidBrush backgroundBrush = DefaultBackgroundBrush; + + // font cacheing info + private int fontHeight = -1; + private int linkFontHeight = -1; + private int captionFontHeight = -1; + private int headerFontHeight = -1; + + // the preffered height of the row. + + // if the list has items with errors + + // private bool listHasErrors = false; + + // caption + private readonly DataGridCaption caption; + + // Border + // + private BorderStyle borderStyle; + + // data binding + // + private object dataSource; + private string dataMember = string.Empty; + private CurrencyManager listManager; + + // currently focused control + // we want to unparent it either when rebinding the grid or when the grid is disposed + Control toBeDisposedEditingControl; + + // persistent data state + // + internal GridTableStylesCollection dataGridTables; + // SET myGridTable in SetDataGridTable ONLY + internal DataGridTableStyle myGridTable; + internal bool checkHierarchy = true; + internal bool inInit; + + // Selection + internal int currentRow; + internal int currentCol; + private int numSelectedRows; + private int lastRowSelected = -1; + + // dragging: + // private bool dragging = false; + + // addNewRow + // private bool inAddNewRow = false; + // delete Row + // private bool inDeleteRow = false; + + // when we leave, we call CommitEdit + // if we leave, then do not focus the dataGrid. + // so we can't focus the grid at the following moments: + // 1. while processing the OnLayout event + // 2. while processing the OnLeave event + // private bool canFocus = true; + + // for CurrentCell +#if DEBUG + private bool inDataSource_PositionChanged; +#endif // DEBUG + + // Policy + // private bool readOnlyMode = false; + private readonly Policy policy = new Policy(); + // private bool allowNavigation = true; + + // editing + // private bool isNavigating = false; + // private bool isEditing = false; + // private bool editControlChanging = false; + private DataGridColumnStyle editColumn; + private DataGridRow editRow; + + // scrolling + // + private readonly ScrollBar horizScrollBar = new HScrollBar(); + private readonly ScrollBar vertScrollBar = new VScrollBar(); + + // the sum of the widths of the columns preceding the firstVisibleColumn + // + private int horizontalOffset; + + // the number of pixels of the firstVisibleColumn which are not visible + // + private int negOffset; + + private int wheelDelta; + // private bool isScrolling = false; + + // Visibility + // + internal int firstVisibleRow; + internal int firstVisibleCol; + private int numVisibleRows; + // the number of columns which are visible + private int numVisibleCols; + private int numTotallyVisibleRows; + // lastTotallyVisibleCol == -1 means that the data grid does not show any column in its entirety + private int lastTotallyVisibleCol; + + // mouse move hot-tracking + // + private int oldRow = -1; + // private bool overCaption = true; + + // child relationships focused + // + // private bool childLinkFocused = false; + + // private static readonly object EVENT_COLUMNHEADERCLICK = new object(); + private static readonly object EVENT_CURRENTCELLCHANGED = new object(); + // private static readonly object EVENT_COLUMNRESIZE = new object(); + // private static readonly object EVENT_LINKCLICKED = new object(); + private static readonly object EVENT_NODECLICKED = new object(); + // private static readonly object EVENT_ROWRESIZE = new object(); + private static readonly object EVENT_SCROLL = new object(); + private static readonly object EVENT_BACKBUTTONCLICK = new object(); + private static readonly object EVENT_DOWNBUTTONCLICK = new object(); + + // event handlers + // + private readonly ItemChangedEventHandler itemChangedHandler; + private readonly EventHandler positionChangedHandler; + private readonly EventHandler currentChangedHandler; + private readonly EventHandler metaDataChangedHandler; + + // we have to know when the collection of dataGridTableStyles changes + private readonly CollectionChangeEventHandler dataGridTableStylesCollectionChanged; + + private readonly EventHandler backButtonHandler; + private readonly EventHandler downButtonHandler; + + private NavigateEventHandler onNavigate; + + private EventHandler onRowHeaderClick; + + // forDebug + // + // private int forDebug = 0; + + // =----------------------------------------------------------------- + + /// + /// Initializes a new instance of the + /// class. + /// + public DataGrid() : base() + { + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.Opaque, false); + SetStyle(ControlStyles.SupportsTransparentBackColor, false); + SetStyle(ControlStyles.UserMouse, true); + gridState = new Collections.Specialized.BitVector32(0x00042827); + + dataGridTables = new GridTableStylesCollection(this); + layout = CreateInitialLayoutState(); + parentRows = new DataGridParentRows(this); + + horizScrollBar.Top = ClientRectangle.Height - horizScrollBar.Height; + horizScrollBar.Left = 0; + horizScrollBar.Visible = false; + horizScrollBar.Scroll += new ScrollEventHandler(GridHScrolled); + Controls.Add(horizScrollBar); + + vertScrollBar.Top = 0; + vertScrollBar.Left = ClientRectangle.Width - vertScrollBar.Width; + vertScrollBar.Visible = false; + vertScrollBar.Scroll += new ScrollEventHandler(GridVScrolled); + Controls.Add(vertScrollBar); + + BackColor = DefaultBackBrush.Color; + ForeColor = DefaultForeBrush.Color; + borderStyle = defaultBorderStyle; + + // create the event handlers + // + currentChangedHandler = new EventHandler(DataSource_RowChanged); + positionChangedHandler = new EventHandler(DataSource_PositionChanged); + itemChangedHandler = new ItemChangedEventHandler(DataSource_ItemChanged); + metaDataChangedHandler = new EventHandler(DataSource_MetaDataChanged); + dataGridTableStylesCollectionChanged = new CollectionChangeEventHandler(TableStylesCollectionChanged); + dataGridTables.CollectionChanged += dataGridTableStylesCollectionChanged; + + SetDataGridTable(defaultTableStyle, true); + + backButtonHandler = new EventHandler(OnBackButtonClicked); + downButtonHandler = new EventHandler(OnShowParentDetailsButtonClicked); + + caption = new DataGridCaption(this); + caption.BackwardClicked += backButtonHandler; + caption.DownClicked += downButtonHandler; + + RecalculateFonts(); + Size = new Size(130, 80); + Invalidate(); + PerformLayout(); + } + + // =------------------------------------------------------------------ + // = Properties + // =------------------------------------------------------------------ + + /// + /// Gets or sets a value indicating whether the grid can be resorted by clicking on + /// a column header. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(true), + SRDescription(nameof(SR.DataGridAllowSortingDescr)) + ] + public bool AllowSorting + { + get + { + return gridState[GRIDSTATE_allowSorting]; + } + set + { + if (AllowSorting != value) + { + gridState[GRIDSTATE_allowSorting] = value; + if (!value && listManager != null) + { + IList list = listManager.List; + if (list is IBindingList) + { + ((IBindingList)list).RemoveSort(); + } + } + } + } + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridAlternatingBackColorDescr)) + ] + public Color AlternatingBackColor + { + get + { + return alternatingBackBrush.Color; + } + set + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, + "AlternatingBackColor")); + } + + if (IsTransparentColor(value)) + { + throw new ArgumentException(SR.DataGridTransparentAlternatingBackColorNotAllowed); + } + + if (!alternatingBackBrush.Color.Equals(value)) + { + alternatingBackBrush = new SolidBrush(value); + InvalidateInside(); + } + } + } + + public void ResetAlternatingBackColor() + { + if (ShouldSerializeAlternatingBackColor()) + { + AlternatingBackColor = DefaultAlternatingBackBrush.Color; + InvalidateInside(); + } + } + + protected virtual bool ShouldSerializeAlternatingBackColor() + { + return !AlternatingBackBrush.Equals(DefaultAlternatingBackBrush); + } + + internal Brush AlternatingBackBrush + { + get + { + return alternatingBackBrush; + } + } + + // overrode those properties just to move the BackColor and the ForeColor + // from the Appearance group onto the Color Group + /// + /// Gets or sets the background color of the grid. + /// + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.ControlBackColorDescr)) + ] + public override Color BackColor + { + // overrode those properties just to move the BackColor and the ForeColor + // from the Appearance group onto the Color Group + get + { + return base.BackColor; + } + set + { + if (IsTransparentColor(value)) + { + throw new ArgumentException(SR.DataGridTransparentBackColorNotAllowed); + } + + base.BackColor = value; + } + } + + public override void ResetBackColor() + { + if (!BackColor.Equals(DefaultBackBrush.Color)) + { + BackColor = DefaultBackBrush.Color; + } + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.ControlForeColorDescr)) + ] + public override Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + + public override void ResetForeColor() + { + if (!ForeColor.Equals(DefaultForeBrush.Color)) + { + ForeColor = DefaultForeBrush.Color; + } + } + + /// + /// Gets a value + /// indicating whether the property should be + /// persisted. + /// + internal SolidBrush BackBrush + { + get + { + return backBrush; + } + } + + internal SolidBrush ForeBrush + { + get + { + return foreBrush; + } + } + + /// + /// Gets or sets the border style. + /// + [SRCategory(nameof(SR.CatAppearance))] + [DefaultValue(defaultBorderStyle)] + [DispId((int)Ole32.DispatchID.BORDERSTYLE)] + [SRDescription(nameof(SR.DataGridBorderStyleDescr))] + public BorderStyle BorderStyle + { + get => borderStyle; + set + { + if (!ClientUtils.IsEnumValid(value, (int)value, (int)BorderStyle.None, (int)BorderStyle.Fixed3D)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(BorderStyle)); + } + + if (borderStyle != value) + { + borderStyle = value; + PerformLayout(); + Invalidate(); + OnBorderStyleChanged(EventArgs.Empty); + } + } + } + + private static readonly object EVENT_BORDERSTYLECHANGED = new object(); + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.DataGridOnBorderStyleChangedDescr))] + public event EventHandler BorderStyleChanged + { + add => Events.AddHandler(EVENT_BORDERSTYLECHANGED, value); + remove => Events.RemoveHandler(EVENT_BORDERSTYLECHANGED, value); + } + + private int BorderWidth + { + get + { + if (BorderStyle == BorderStyle.Fixed3D) + { + return SystemInformation.Border3DSize.Width; + } + else if (BorderStyle == BorderStyle.FixedSingle) + { + return 2; + } + else + { + return 0; + } + } + } + + protected override Size DefaultSize + { + get + { + return new Size(130, 80); + } + } + + private static SolidBrush DefaultSelectionBackBrush + { + get + { + return (SolidBrush)SystemBrushes.ActiveCaption; + } + } + + private static SolidBrush DefaultSelectionForeBrush + { + get + { + return (SolidBrush)SystemBrushes.ActiveCaptionText; + } + } + + internal static SolidBrush DefaultBackBrush + { + get + { + return (SolidBrush)SystemBrushes.Window; + } + } + + internal static SolidBrush DefaultForeBrush + { + get + { + return (SolidBrush)SystemBrushes.WindowText; + } + } + + private static SolidBrush DefaultBackgroundBrush + { + get + { + return (SolidBrush)SystemBrushes.AppWorkspace; + } + } + + internal static SolidBrush DefaultParentRowsForeBrush + { + get + { + return (SolidBrush)SystemBrushes.WindowText; + } + } + + internal static SolidBrush DefaultParentRowsBackBrush + { + get + { + return (SolidBrush)SystemBrushes.Control; + } + } + + internal static SolidBrush DefaultAlternatingBackBrush + { + get + { + return (SolidBrush)SystemBrushes.Window; + } + } + + private static SolidBrush DefaultGridLineBrush + { + get + { + return (SolidBrush)SystemBrushes.Control; + } + } + + private static SolidBrush DefaultHeaderBackBrush + { + get + { + return (SolidBrush)SystemBrushes.Control; + } + } + + private static SolidBrush DefaultHeaderForeBrush + { + get + { + return (SolidBrush)SystemBrushes.ControlText; + } + } + + private static Pen DefaultHeaderForePen + { + get + { + return new Pen(SystemColors.ControlText); + } + } + + private static SolidBrush DefaultLinkBrush + { + get + { + return (SolidBrush)SystemBrushes.HotTrack; + } + } + + private bool ListHasErrors + { + get + { + return gridState[GRIDSTATE_listHasErrors]; + } + set + { + if (ListHasErrors != value) + { + gridState[GRIDSTATE_listHasErrors] = value; + ComputeMinimumRowHeaderWidth(); + if (!layout.RowHeadersVisible) + { + return; + } + + if (value) + { + if (myGridTable.IsDefault) + { + RowHeaderWidth += errorRowBitmapWidth; + } + else + { + myGridTable.RowHeaderWidth += errorRowBitmapWidth; + } + } + else + { + if (myGridTable.IsDefault) + { + RowHeaderWidth -= errorRowBitmapWidth; + } + else + { + myGridTable.RowHeaderWidth -= errorRowBitmapWidth; + } + } + } + } + } + + private bool Bound + { + get + { + return !(listManager == null || myGridTable == null); + } + } + + internal DataGridCaption Caption + { + get + { + return caption; + } + } + + /// + /// Gets or sets the background color of the caption area. + /// + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridCaptionBackColorDescr)) + ] + public Color CaptionBackColor + { + get + { + return Caption.BackColor; + } + set + { + if (IsTransparentColor(value)) + { + throw new ArgumentException(SR.DataGridTransparentCaptionBackColorNotAllowed); + } + + Caption.BackColor = value; + } + } + + private void ResetCaptionBackColor() + { + Caption.ResetBackColor(); + } + + /// + /// Gets a value + /// indicating whether the property should be + /// persisted. + /// + protected virtual bool ShouldSerializeCaptionBackColor() + { + return Caption.ShouldSerializeBackColor(); + } + + /// + /// Gets + /// or sets the foreground color + /// of the caption area. + /// + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridCaptionForeColorDescr)) + ] + public Color CaptionForeColor + { + get + { + return Caption.ForeColor; + } + set + { + Caption.ForeColor = value; + } + } + + private void ResetCaptionForeColor() + { + Caption.ResetForeColor(); + } + + /// + /// Gets a value + /// indicating whether the property should be + /// persisted. + /// + protected virtual bool ShouldSerializeCaptionForeColor() + { + return Caption.ShouldSerializeForeColor(); + } + + /// + /// Gets or sets the font of the grid's caption. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + Localizable(true), + AmbientValue(null), + SRDescription(nameof(SR.DataGridCaptionFontDescr)) + ] + public Font CaptionFont + { + get + { + return Caption.Font; + } + set + { + Caption.Font = value; + } + } + + /// + /// Gets a value indicating whether the + /// caption's font is persisted. + /// + private bool ShouldSerializeCaptionFont() + { + return Caption.ShouldSerializeFont(); + } + + private void ResetCaptionFont() + { + Caption.ResetFont(); + } + + /// + /// Gets or sets the text of the grid's caption. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(""), + Localizable(true), + SRDescription(nameof(SR.DataGridCaptionTextDescr)) + ] + public string CaptionText + { + get + { + return Caption.Text; + } + set + { + Caption.Text = value; + } + } + + /// + /// Gets or sets a value that indicates + /// whether the grid's caption is visible. + /// + [ + DefaultValue(true), + SRCategory(nameof(SR.CatDisplay)), + SRDescription(nameof(SR.DataGridCaptionVisibleDescr)) + ] + public bool CaptionVisible + { + get + { + return layout.CaptionVisible; + } + set + { + if (layout.CaptionVisible != value) + { + layout.CaptionVisible = value; + PerformLayout(); + Invalidate(); + OnCaptionVisibleChanged(EventArgs.Empty); + } + } + } + + private static readonly object EVENT_CAPTIONVISIBLECHANGED = new object(); + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.DataGridOnCaptionVisibleChangedDescr))] + public event EventHandler CaptionVisibleChanged + { + add => Events.AddHandler(EVENT_CAPTIONVISIBLECHANGED, value); + remove => Events.RemoveHandler(EVENT_CAPTIONVISIBLECHANGED, value); + } + + /// + /// Gets or sets which cell has the focus. Not available at design time. + /// + [ + Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SRDescription(nameof(SR.DataGridCurrentCellDescr)) + ] + public DataGridCell CurrentCell + { + get + { + return new DataGridCell(currentRow, currentCol); + } + set + { + // if the OnLayout event was not set in the grid, then we can't + // reliably set the currentCell on the grid. + if (layout.dirty) + { + throw new ArgumentException(SR.DataGridSettingCurrentCellNotGood); + } + + if (value.RowNumber == currentRow && value.ColumnNumber == currentCol) + { + return; + } + + // should we throw an exception, maybe? + if (DataGridRowsLength == 0 || myGridTable.GridColumnStyles == null || myGridTable.GridColumnStyles.Count == 0) + { + return; + } + + EnsureBound(); + + int currentRowSaved = currentRow; + int currentColSaved = currentCol; + bool wasEditing = gridState[GRIDSTATE_isEditing]; + bool cellChanged = false; + + // if the position in the listManager changed under the DataGrid, + // then do not edit after setting the current cell + bool doNotEdit = false; + + int newCol = value.ColumnNumber; + int newRow = value.RowNumber; + + string errorMessage = null; + + try + { + int columnCount = myGridTable.GridColumnStyles.Count; + if (newCol < 0) + { + newCol = 0; + } + + if (newCol >= columnCount) + { + newCol = columnCount - 1; + } + + int localGridRowsLength = DataGridRowsLength; + DataGridRow[] localGridRows = DataGridRows; + + if (newRow < 0) + { + newRow = 0; + } + + if (newRow >= localGridRowsLength) + { + newRow = localGridRowsLength - 1; + } + + // Current Column changing + // + if (currentCol != newCol) + { + cellChanged = true; + int currentListManagerPosition = ListManager.Position; + int currentListManagerCount = ListManager.List.Count; + + EndEdit(); + + if (ListManager.Position != currentListManagerPosition || + currentListManagerCount != ListManager.List.Count) + { + // EndEdit changed the list. + // Reset the data grid rows and the current row inside the datagrid. + // And then exit the method. + RecreateDataGridRows(); + if (ListManager.List.Count > 0) + { + currentRow = ListManager.Position; + Edit(); + } + else + { + currentRow = -1; + } + + return; + } + + currentCol = newCol; + InvalidateRow(currentRow); + } + + // Current Row changing + // + if (currentRow != newRow) + { + cellChanged = true; + int currentListManagerPosition = ListManager.Position; + int currentListManagerCount = ListManager.List.Count; + + EndEdit(); + + if (ListManager.Position != currentListManagerPosition || + currentListManagerCount != ListManager.List.Count) + { + // EndEdit changed the list. + // Reset the data grid rows and the current row inside the datagrid. + // And then exit the method. + RecreateDataGridRows(); + if (ListManager.List.Count > 0) + { + currentRow = ListManager.Position; + Edit(); + } + else + { + currentRow = -1; + } + + return; + } + + if (currentRow < localGridRowsLength) + { + localGridRows[currentRow].OnRowLeave(); + } + + localGridRows[newRow].OnRowEnter(); + currentRow = newRow; + if (currentRowSaved < localGridRowsLength) + { + InvalidateRow(currentRowSaved); + } + + InvalidateRow(currentRow); + + if (currentRowSaved != listManager.Position) + { + // not in sync +#if DEBUG + Debug.Assert(inDataSource_PositionChanged, "currentRow and listManager.Position can be out of sync only when the listManager changes its position under the DataGrid or when navigating back"); + Debug.Assert(ListManager.Position == currentRow || listManager.Position == -1, "DataSource_PositionChanged changes the position in the grid to the position in the listManager"); +#endif //DEBUG + doNotEdit = true; + if (gridState[GRIDSTATE_isEditing]) + { + AbortEdit(); + } + } + else if (gridState[GRIDSTATE_inAddNewRow]) + { +#if DEBUG + int currentRowCount = DataGridRowsLength; +#endif // debug + // cancelCurrentEdit will change the position in the list + // to the last element in the list. and the grid will get an on position changed + // event, and will set the current cell to the last element in the dataSource. + // so unhook the PositionChanged event from the listManager; + ListManager.PositionChanged -= positionChangedHandler; + ListManager.CancelCurrentEdit(); + ListManager.Position = currentRow; + ListManager.PositionChanged += positionChangedHandler; +#if DEBUG + + Debug.Assert(currentRowSaved > currentRow, "we can only go up when we are inAddNewRow"); + Debug.Assert(currentRowCount == DataGridRowsLength, "the number of rows in the dataGrid should not change"); + Debug.Assert(currentRowCount == ListManager.Count + 1, "the listManager should have one less record"); +#endif // debug + localGridRows[DataGridRowsLength - 1] = new DataGridAddNewRow(this, myGridTable, DataGridRowsLength - 1); + SetDataGridRows(localGridRows, DataGridRowsLength); + gridState[GRIDSTATE_inAddNewRow] = false; + } + else + { + ListManager.EndCurrentEdit(); + // some special care must be given when setting the + // position in the listManager. + // if EndCurrentEdit() deleted the current row + // ( because of some filtering problem, say ) + // then we cannot go over the last row + // + if (localGridRowsLength != DataGridRowsLength) + { + Debug.Assert(localGridRowsLength == DataGridRowsLength + 1, "this is the only change that could have happened"); + currentRow = (currentRow == localGridRowsLength - 1) ? DataGridRowsLength - 1 : currentRow; + } + + if (currentRow == dataGridRowsLength - 1 && policy.AllowAdd) + { + // it may be case ( see previous comment ) + // that listManager.EndCurrentEdit changed the number of rows + // in the grid. in this case, we should not be using the old + // localGridRows in our assertion, cause they are outdated now + // + Debug.Assert(DataGridRows[currentRow] is DataGridAddNewRow, "the last row is the DataGridAddNewRow"); + AddNewRow(); + Debug.Assert(ListManager.Position == currentRow || listManager.Position == -1, "the listManager should be positioned at the last row"); + } + else + { + ListManager.Position = currentRow; + } + } + } + } + catch (Exception e) + { + errorMessage = e.Message; + } + + if (errorMessage != null) + { + DialogResult result = RTLAwareMessageBox.Show(null, + string.Format(SR.DataGridPushedIncorrectValueIntoColumn, errorMessage), + SR.DataGridErrorMessageBoxCaption, MessageBoxButtons.YesNo, + MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0); + + if (result == DialogResult.Yes) + { + currentRow = currentRowSaved; + currentCol = currentColSaved; + Debug.Assert(currentRow == ListManager.Position || listManager.Position == -1, "the position in the list manager (" + ListManager.Position + ") is out of sync with the currentRow (" + currentRow + ")" + " and the exception is '" + errorMessage + "'"); + // this will make sure the newRow will not paint the + // row selector. + InvalidateRowHeader(newRow); + // also, make sure that we get the row selector on the currentrow, too + InvalidateRowHeader(currentRow); + if (wasEditing) + { + Edit(); + } + } + else + { + // if the user committed a row that used to be addNewRow and the backEnd rejects it, + // and then it tries to navigate down then we should stay in the addNewRow + // in this particular scenario, CancelCurrentEdit will cause the last row to be deleted, + // and this will ultimately call InvalidateRow w/ a row number larger than the number of rows + // so set the currentRow here: + if (currentRow == DataGridRowsLength - 1 && currentRowSaved == DataGridRowsLength - 2 && DataGridRows[currentRow] is DataGridAddNewRow) + { + newRow = currentRowSaved; + } + + currentRow = newRow; + Debug.Assert(result == DialogResult.No, "we only put cancel and ok on the error message box"); + listManager.PositionChanged -= positionChangedHandler; + listManager.CancelCurrentEdit(); + listManager.Position = newRow; + listManager.PositionChanged += positionChangedHandler; + currentRow = newRow; + currentCol = newCol; + if (wasEditing) + { + Edit(); + } + } + } + + if (cellChanged) + { + EnsureVisible(currentRow, currentCol); + OnCurrentCellChanged(EventArgs.Empty); + + // if the user changed the current cell using the UI, edit the new cell + // but if the user changed the current cell by changing the position in the + // listManager, then do not continue the edit + // + if (!doNotEdit) + { +#if DEBUG + Debug.Assert(!inDataSource_PositionChanged, "if the user changed the current cell using the UI, then do not edit"); +#endif // debug + Edit(); + } + + AccessibilityNotifyClients(AccessibleEvents.Focus, CurrentCellAccIndex); + AccessibilityNotifyClients(AccessibleEvents.Selection, CurrentCellAccIndex); + } + + Debug.Assert(currentRow == ListManager.Position || listManager.Position == -1, "the position in the list manager is out of sync with the currentRow"); + } + } + + internal int CurrentCellAccIndex + { + get + { + int currentCellAccIndex = 0; + currentCellAccIndex++; // ParentRowsAccessibleObject + currentCellAccIndex += myGridTable.GridColumnStyles.Count; // ColumnHeaderAccessibleObject + currentCellAccIndex += DataGridRows.Length; // DataGridRowAccessibleObject + if (horizScrollBar.Visible) // Horizontal Scroll Bar Accessible Object + { + currentCellAccIndex++; + } + + if (vertScrollBar.Visible) // Vertical Scroll Bar Accessible Object + { + currentCellAccIndex++; + } + + currentCellAccIndex += (currentRow * myGridTable.GridColumnStyles.Count) + currentCol; + return currentCellAccIndex; + } + } + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.DataGridOnCurrentCellChangedDescr))] + public event EventHandler CurrentCellChanged + { + add => Events.AddHandler(EVENT_CURRENTCELLCHANGED, value); + remove => Events.RemoveHandler(EVENT_CURRENTCELLCHANGED, value); + } + + private int CurrentColumn + { + get + { + return CurrentCell.ColumnNumber; + } + set + { + CurrentCell = new DataGridCell(currentRow, value); + } + } + + private int CurrentRow + { + get + { + return CurrentCell.RowNumber; + } + set + { + CurrentCell = new DataGridCell(value, currentCol); + } + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridSelectionBackColorDescr)) + ] + public Color SelectionBackColor + { + get + { + return selectionBackBrush.Color; + } + set + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "SelectionBackColor")); + } + + if (IsTransparentColor(value)) + { + throw new ArgumentException(SR.DataGridTransparentSelectionBackColorNotAllowed); + } + + if (!value.Equals(selectionBackBrush.Color)) + { + selectionBackBrush = new SolidBrush(value); + + InvalidateInside(); + } + } + } + + internal SolidBrush SelectionBackBrush + { + get + { + return selectionBackBrush; + } + } + + internal SolidBrush SelectionForeBrush + { + get + { + return selectionForeBrush; + } + } + + protected bool ShouldSerializeSelectionBackColor() + { + return !DefaultSelectionBackBrush.Equals(selectionBackBrush); + } + + public void ResetSelectionBackColor() + { + if (ShouldSerializeSelectionBackColor()) + { + SelectionBackColor = DefaultSelectionBackBrush.Color; + } + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridSelectionForeColorDescr)) + ] + public Color SelectionForeColor + { + get + { + return selectionForeBrush.Color; + } + set + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "SelectionForeColor")); + } + + if (!value.Equals(selectionForeBrush.Color)) + { + selectionForeBrush = new SolidBrush(value); + + InvalidateInside(); + } + } + } + + protected virtual bool ShouldSerializeSelectionForeColor() + { + return !SelectionForeBrush.Equals(DefaultSelectionForeBrush); + } + + public void ResetSelectionForeColor() + { + if (ShouldSerializeSelectionForeColor()) + { + SelectionForeColor = DefaultSelectionForeBrush.Color; + } + } + + internal override bool ShouldSerializeForeColor() + { + return !DefaultForeBrush.Color.Equals(ForeColor); + } + + /// + /// Indicates whether the property should be + /// persisted. + /// + internal override bool ShouldSerializeBackColor() + { + return !DefaultBackBrush.Color.Equals(BackColor); + } + + // Don't use dataGridRows, use the accessor!!! + internal DataGridRow[] DataGridRows + { + get + { + if (dataGridRows == null) + { + CreateDataGridRows(); + } + + return dataGridRows; + } + } + + // ToolTipping + internal DataGridToolTip ToolTipProvider + { + get + { + return toolTipProvider; + } + } + + internal int ToolTipId + { + get + { + return toolTipId; + } + set + { + toolTipId = value; + } + } + + private void ResetToolTip() + { + // remove all the tool tips which are stored + for (int i = 0; i < ToolTipId; i++) + { + ToolTipProvider.RemoveToolTip(new IntPtr(i)); + } + + // add toolTips for the backButton and + // details button on the caption. + if (!parentRows.IsEmpty()) + { + bool alignRight = isRightToLeft(); + int detailsButtonWidth = Caption.GetDetailsButtonWidth(); + Rectangle backButton = Caption.GetBackButtonRect(layout.Caption, alignRight, detailsButtonWidth); + Rectangle detailsButton = Caption.GetDetailsButtonRect(layout.Caption, alignRight); + + // mirror the buttons wrt RTL property + backButton.X = MirrorRectangle(backButton, layout.Inside, isRightToLeft()); + detailsButton.X = MirrorRectangle(detailsButton, layout.Inside, isRightToLeft()); + + ToolTipProvider.AddToolTip(SR.DataGridCaptionBackButtonToolTip, new IntPtr(0), backButton); + ToolTipProvider.AddToolTip(SR.DataGridCaptionDetailsButtonToolTip, new IntPtr(1), detailsButton); + ToolTipId = 2; + } + else + { + ToolTipId = 0; + } + } + + /// + /// Given a cursor, this will Create the right DataGridRows + /// + private void CreateDataGridRows() + { + CurrencyManager listManager = ListManager; + DataGridTableStyle dgt = myGridTable; + InitializeColumnWidths(); + + if (listManager == null) + { + SetDataGridRows(Array.Empty(), 0); + return; + } + + int nDataGridRows = listManager.Count; + if (policy.AllowAdd) + { + nDataGridRows++; + } + + DataGridRow[] rows = new DataGridRow[nDataGridRows]; + for (int r = 0; r < listManager.Count; r++) + { + rows[r] = new DataGridRelationshipRow(this, dgt, r); + } + + if (policy.AllowAdd) + { + addNewRow = new DataGridAddNewRow(this, dgt, nDataGridRows - 1); + rows[nDataGridRows - 1] = addNewRow; + } + else + { + addNewRow = null; + } + + // SetDataGridRows(rows, rows.Length); + SetDataGridRows(rows, nDataGridRows); + } + + private void RecreateDataGridRows() + { + int nDataGridRows = 0; + CurrencyManager listManager = ListManager; + + if (listManager != null) + { + nDataGridRows = listManager.Count; + if (policy.AllowAdd) + { + nDataGridRows++; + } + } + + SetDataGridRows(null, nDataGridRows); + } + + /// + /// Sets the array of DataGridRow objects used for + /// all row-related logic in the DataGrid. + /// + internal void SetDataGridRows(DataGridRow[] newRows, int newRowsLength) + { + dataGridRows = newRows; + dataGridRowsLength = newRowsLength; + + // update the vertical scroll bar + vertScrollBar.Maximum = Math.Max(0, DataGridRowsLength - 1); + if (firstVisibleRow > newRowsLength) + { + vertScrollBar.Value = 0; + firstVisibleRow = 0; + } + + ResetUIState(); +#if DEBUG + // sanity check: all the rows should have the same + // dataGridTable + if (newRows != null && newRowsLength > 0) + { + DataGridTableStyle dgTable = newRows[0].DataGridTableStyle; + for (int i = 0; i < newRowsLength; i++) + { + Debug.Assert(dgTable == newRows[i].DataGridTableStyle, "how can two rows have different tableStyles?"); + } + } +#endif // DEBUG + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: There are now " + DataGridRowsLength.ToString(CultureInfo.InvariantCulture) + " rows."); + } + + internal int DataGridRowsLength + { + get + { + return dataGridRowsLength; + } + } + + /// + /// Gets or sets the data source that the grid is displaying data for. + /// + [ + DefaultValue(null), + SRCategory(nameof(SR.CatData)), + RefreshProperties(RefreshProperties.Repaint), + AttributeProvider(typeof(IListSource)), + SRDescription(nameof(SR.DataGridDataSourceDescr)) + ] + public object DataSource + { + get + { + return dataSource; + } + + set + { + if (value != null && !(value is IList || value is IListSource)) + { + throw new ArgumentException(SR.BadDataSourceForComplexBinding); + } + + if (dataSource != null && dataSource.Equals(value)) + { + return; + } + + // when the designer resets the dataSource to null, set the dataMember to null, too + if ((value == null || value == Convert.DBNull) && DataMember != null && DataMember.Length != 0) + { + dataSource = null; + DataMember = string.Empty; + return; + } + + // if we are setting the dataSource and the dataMember is not a part + // of the properties in the dataSource, then set the dataMember to "" + // + if (value != null) + { + EnforceValidDataMember(value); + } + + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: DataSource being set to " + ((value == null) ? "null" : value.ToString())); + + // when we change the dataSource, we need to clear the parent rows. + // the same goes for all the caption UI: reset it when the datasource changes. + // + ResetParentRows(); + Set_ListManager(value, DataMember, false); + } + } + + private static readonly object EVENT_DATASOURCECHANGED = new object(); + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.DataGridOnDataSourceChangedDescr))] + public event EventHandler DataSourceChanged + { + add => Events.AddHandler(EVENT_DATASOURCECHANGED, value); + remove => Events.RemoveHandler(EVENT_DATASOURCECHANGED, value); + } + + /// + /// Gets or sets the specific table in a DataSource for the control. + /// + [ + DefaultValue(null), + SRCategory(nameof(SR.CatData)), + Editor("System.Windows.Forms.Design.DataMemberListEditor, " + AssemblyRef.SystemDesign, typeof(Drawing.Design.UITypeEditor)), + SRDescription(nameof(SR.DataGridDataMemberDescr)) + ] + public string DataMember + { + get + { + return dataMember; + } + set + { + if (dataMember != null && dataMember.Equals(value)) + { + return; + } + + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: DataSource being set to " + ((value == null) ? "null" : value.ToString())); + // when we change the dataMember, we need to clear the parent rows. + // the same goes for all the caption UI: reset it when the datamember changes. + // + ResetParentRows(); + Set_ListManager(DataSource, value, false); + } + } + + public void SetDataBinding(object dataSource, string dataMember) + { + parentRows.Clear(); + originalState = null; + caption.BackButtonActive = caption.DownButtonActive = caption.BackButtonVisible = false; + caption.SetDownButtonDirection(!layout.ParentRowsVisible); + + Set_ListManager(dataSource, dataMember, false); + } + + [ + Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), + SRDescription(nameof(SR.DataGridListManagerDescr)) + ] + internal protected CurrencyManager ListManager + { + get + { + //try to return something useful: + if (listManager == null && BindingContext != null && DataSource != null) + { + return (CurrencyManager)BindingContext[DataSource, DataMember]; + } + else + { + return listManager; + } + } + set + { + throw new NotSupportedException(SR.DataGridSetListManager); + } + } + + internal void Set_ListManager(object newDataSource, string newDataMember, bool force) + { + Set_ListManager(newDataSource, newDataMember, force, true); // true for forcing column creation + } + + // + // prerequisite: the dataMember and the dataSource should be set to the new values + // + // will do the following: + // call EndEdit on the current listManager, will unWire the listManager events, will set the listManager to the new + // reality, will wire the new listManager, will update the policy, will set the dataGridTable, will reset the ui state. + // + internal void Set_ListManager(object newDataSource, string newDataMember, bool force, bool forceColumnCreation) + { + bool dataSourceChanged = DataSource != newDataSource; + bool dataMemberChanged = DataMember != newDataMember; + + // if nothing happened, then why do any work? + if (!force && !dataSourceChanged && !dataMemberChanged && gridState[GRIDSTATE_inSetListManager]) + { + return; + } + + gridState[GRIDSTATE_inSetListManager] = true; + if (toBeDisposedEditingControl != null) + { + Debug.Assert(Controls.Contains(toBeDisposedEditingControl)); + Controls.Remove(toBeDisposedEditingControl); + toBeDisposedEditingControl = null; + } + + bool beginUpdateInternal = true; + try + { + // will endEdit on the current listManager + UpdateListManager(); + + // unwire the events: + if (listManager != null) + { + UnWireDataSource(); + } + + CurrencyManager oldListManager = listManager; + bool listManagerChanged = false; + // set up the new listManager + // CAUTION: we need to set up the listManager in the grid before setting the dataSource/dataMember props + // in the grid. the reason is that if the BindingContext was not yet requested, and it is created in the BindingContext prop + // then the grid will call Set_ListManager again, and eventually that means that the dataGrid::listManager will + // be hooked up twice to all the events (PositionChanged, ItemChanged, CurrentChanged) + if (newDataSource != null && BindingContext != null && !(newDataSource == Convert.DBNull)) + { + listManager = (CurrencyManager)BindingContext[newDataSource, newDataMember]; + } + else + { + listManager = null; + } + + // update the dataSource and the dateMember + dataSource = newDataSource; + dataMember = newDataMember ?? ""; + + listManagerChanged = (listManager != oldListManager); + + // wire the events + if (listManager != null) + { + WireDataSource(); + // update the policy + policy.UpdatePolicy(listManager, ReadOnly); + } + + if (!Initializing) + { + if (listManager == null) + { + if (ContainsFocus && ParentInternal == null) + { + Debug.Assert(toBeDisposedEditingControl == null, "we should have removed the toBeDisposedEditingControl already"); + // if we unparent the active control then the form won't close + for (int i = 0; i < Controls.Count; i++) + { + if (Controls[i].Focused) + { + toBeDisposedEditingControl = Controls[i]; + break; + } + } + + if (toBeDisposedEditingControl == horizScrollBar || toBeDisposedEditingControl == vertScrollBar) + { + toBeDisposedEditingControl = null; + } + +#if DEBUG + else + { + Debug.Assert(toBeDisposedEditingControl != null, "if the grid contains the focus, then the active control should be in the children of data grid control"); + Debug.Assert(editColumn != null, "if we have an editing control should be a control in the data grid column"); + if (editColumn is DataGridTextBoxColumn) + { + Debug.Assert(((DataGridTextBoxColumn)editColumn).TextBox == toBeDisposedEditingControl, "if we have an editing control should be a control in the data grid column"); + } + } +#endif // debug; + + } + + SetDataGridRows(null, 0); + defaultTableStyle.GridColumnStyles.Clear(); + SetDataGridTable(defaultTableStyle, forceColumnCreation); + + if (toBeDisposedEditingControl != null) + { + Controls.Add(toBeDisposedEditingControl); + } + } + } + + // PERF: if the listManager did not change, then do not: + // 1. create new rows + // 2. create new columns + // 3. compute the errors in the list + // + // when the metaDataChanges, we need to recreate + // the rows and the columns + // + if (listManagerChanged || gridState[GRIDSTATE_metaDataChanged]) + { + if (Visible) + { + BeginUpdateInternal(); + } + + if (listManager != null) + { + // get rid of the old gridColumns + // we need to clear the old column collection even when navigating to + // a list that has a table style associated w/ it. Why? because the + // old column collection will be used by the parent rows to paint + defaultTableStyle.GridColumnStyles.ResetDefaultColumnCollection(); + + DataGridTableStyle newGridTable = dataGridTables[listManager.GetListName()]; + if (newGridTable == null) + { + SetDataGridTable(defaultTableStyle, forceColumnCreation); + } + else + { + SetDataGridTable(newGridTable, forceColumnCreation); + } + + // set the currentRow in ssync w/ the position in the listManager + currentRow = listManager.Position == -1 ? 0 : listManager.Position; + } + + // when we create the rows we need to use the current dataGridTable + // + RecreateDataGridRows(); + if (Visible) + { + EndUpdateInternal(); + } + + beginUpdateInternal = false; + + ComputeMinimumRowHeaderWidth(); + if (myGridTable.IsDefault) + { + RowHeaderWidth = Math.Max(minRowHeaderWidth, RowHeaderWidth); + } + else + { + myGridTable.RowHeaderWidth = Math.Max(minRowHeaderWidth, RowHeaderWidth); + } + + ListHasErrors = DataGridSourceHasErrors(); + + // build the list of columns and relationships + // wipe out the now invalid states + //ResetMouseState(); + + ResetUIState(); + + //layout.CaptionVisible = dataCursor == null ? false : true; + + OnDataSourceChanged(EventArgs.Empty); + } + } + finally + { + gridState[GRIDSTATE_inSetListManager] = false; + // start painting again + if (beginUpdateInternal && Visible) + { + EndUpdateInternal(); + } + } + } + + /// + /// Gets or sets index of the selected row. + /// + // will set the position in the ListManager + // + [ + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + Browsable(false), + SRDescription(nameof(SR.DataGridSelectedIndexDescr)) + ] + public int CurrentRowIndex + { + get + { + if (originalState == null) + { + return listManager == null ? -1 : listManager.Position; + } + else + { + if (BindingContext == null) + { + return -1; + } + + CurrencyManager originalListManager = (CurrencyManager)BindingContext[originalState.DataSource, originalState.DataMember]; + return originalListManager.Position; + } + } + set + { + if (listManager == null) + { + throw new InvalidOperationException(SR.DataGridSetSelectIndex); + } + + if (originalState == null) + { + listManager.Position = value; + currentRow = value; + return; + } + + // if we have a this.ListManager, then this.BindingManager cannot be null + // + CurrencyManager originalListManager = (CurrencyManager)BindingContext[originalState.DataSource, originalState.DataMember]; + originalListManager.Position = value; + + // this is for parent rows + originalState.LinkingRow = originalState.DataGridRows[value]; + + // Invalidate everything + Invalidate(); + } + } + + /// + /// Gets the collection of tables for the grid. + /// + [ + SRCategory(nameof(SR.CatData)), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), + Localizable(true), + SRDescription(nameof(SR.DataGridGridTablesDescr)) + ] + public GridTableStylesCollection TableStyles + { + get + { + return dataGridTables; + } + } + + internal new int FontHeight + { + get + { + return fontHeight; + } + } + + internal AccessibleObject ParentRowsAccessibleObject + { + get + { + return parentRows.AccessibleObject; + } + } + + internal Rectangle ParentRowsBounds + { + get + { + return layout.ParentRows; + } + } + + /// + /// Gets or sets the color of the grid lines. + /// + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridGridLineColorDescr)) + ] + public Color GridLineColor + { + get + { + return gridLineBrush.Color; + } + set + { + if (gridLineBrush.Color != value) + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "GridLineColor")); + } + + gridLineBrush = new SolidBrush(value); + + Invalidate(layout.Data); + } + } + } + + protected virtual bool ShouldSerializeGridLineColor() + { + return !GridLineBrush.Equals(DefaultGridLineBrush); + } + + public void ResetGridLineColor() + { + if (ShouldSerializeGridLineColor()) + { + GridLineColor = DefaultGridLineBrush.Color; + } + } + + internal SolidBrush GridLineBrush + { + get + { + return gridLineBrush; + } + } + + /// + /// Gets or sets the line style of the grid. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(defaultGridLineStyle), + SRDescription(nameof(SR.DataGridGridLineStyleDescr)) + ] + public DataGridLineStyle GridLineStyle + { + get + { + return gridLineStyle; + } + set + { + //valid values are 0x0 to 0x1. + if (!ClientUtils.IsEnumValid(value, (int)value, (int)DataGridLineStyle.None, (int)DataGridLineStyle.Solid)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(DataGridLineStyle)); + } + + if (gridLineStyle != value) + { + gridLineStyle = value; + myGridTable.ResetRelationsUI(); + Invalidate(layout.Data); + } + } + } + + internal int GridLineWidth + { + get + { + Debug.Assert(GridLineStyle == DataGridLineStyle.Solid || GridLineStyle == DataGridLineStyle.None, "are there any other styles?"); + return GridLineStyle == DataGridLineStyle.Solid ? 1 : 0; + } + } + + /// + /// Gets or + /// sets the + /// way parent row labels are displayed. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + DefaultValue(defaultParentRowsLabelStyle), + SRCategory(nameof(SR.CatDisplay)), + SRDescription(nameof(SR.DataGridParentRowsLabelStyleDescr)) + ] + public DataGridParentRowsLabelStyle ParentRowsLabelStyle + { + get + { + return parentRowsLabels; + } + + set + { + //valid values are 0x0 to 0x3 + if (!ClientUtils.IsEnumValid(value, (int)value, (int)DataGridParentRowsLabelStyle.None, (int)DataGridParentRowsLabelStyle.Both)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(DataGridParentRowsLabelStyle)); + } + + if (parentRowsLabels != value) + { + parentRowsLabels = value; + Invalidate(layout.ParentRows); + OnParentRowsLabelStyleChanged(EventArgs.Empty); + } + } + } + + private static readonly object EVENT_PARENTROWSLABELSTYLECHANGED = new object(); + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.DataGridOnParentRowsLabelStyleChangedDescr))] + public event EventHandler ParentRowsLabelStyleChanged + { + add => Events.AddHandler(EVENT_PARENTROWSLABELSTYLECHANGED, value); + remove => Events.RemoveHandler(EVENT_PARENTROWSLABELSTYLECHANGED, value); + } + + internal bool Initializing + { + get + { + return inInit; + } + } + + /// + /// Gets the index of the first visible column in a grid. + /// + [ + Browsable(false), + SRDescription(nameof(SR.DataGridFirstVisibleColumnDescr)) + ] + public int FirstVisibleColumn + { + get + { + return firstVisibleCol; + } + } + + /// + /// Gets or sets a value indicating whether the grid displays in flat mode. + /// + [ + DefaultValue(false), + SRCategory(nameof(SR.CatAppearance)), + SRDescription(nameof(SR.DataGridFlatModeDescr)) + ] + public bool FlatMode + { + get + { + return gridState[GRIDSTATE_isFlatMode]; + } + set + { + if (value != FlatMode) + { + gridState[GRIDSTATE_isFlatMode] = value; + Invalidate(layout.Inside); + OnFlatModeChanged(EventArgs.Empty); + } + } + } + + private static readonly object EVENT_FLATMODECHANGED = new object(); + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.DataGridOnFlatModeChangedDescr))] + public event EventHandler FlatModeChanged + { + add => Events.AddHandler(EVENT_FLATMODECHANGED, value); + remove => Events.RemoveHandler(EVENT_FLATMODECHANGED, value); + } + + /// + /// Gets or + /// sets the background color of all row and column headers. + /// + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridHeaderBackColorDescr)) + ] + public Color HeaderBackColor + { + get + { + return headerBackBrush.Color; + } + set + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "HeaderBackColor")); + } + + if (IsTransparentColor(value)) + { + throw new ArgumentException(SR.DataGridTransparentHeaderBackColorNotAllowed); + } + + if (!value.Equals(headerBackBrush.Color)) + { + headerBackBrush = new SolidBrush(value); + + if (layout.RowHeadersVisible) + { + Invalidate(layout.RowHeaders); + } + + if (layout.ColumnHeadersVisible) + { + Invalidate(layout.ColumnHeaders); + } + + Invalidate(layout.TopLeftHeader); + } + } + } + + internal SolidBrush HeaderBackBrush + { + get + { + return headerBackBrush; + } + } + + protected virtual bool ShouldSerializeHeaderBackColor() + { + return !HeaderBackBrush.Equals(DefaultHeaderBackBrush); + } + + public void ResetHeaderBackColor() + { + if (ShouldSerializeHeaderBackColor()) + { + HeaderBackColor = DefaultHeaderBackBrush.Color; + } + } + + internal SolidBrush BackgroundBrush + { + get + { + return backgroundBrush; + } + } + + private void ResetBackgroundColor() + { + if (backgroundBrush != null && BackgroundBrush != DefaultBackgroundBrush) + { + backgroundBrush.Dispose(); + backgroundBrush = null; + } + + backgroundBrush = DefaultBackgroundBrush; + } + + protected virtual bool ShouldSerializeBackgroundColor() + { + return !BackgroundBrush.Equals(DefaultBackgroundBrush); + } + + // using this property, the user can set the backGround color + /// + /// Gets or sets the background color of the grid. + /// + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridBackgroundColorDescr)) + ] + public Color BackgroundColor + { + get + { + return backgroundBrush.Color; + } + set + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "BackgroundColor")); + } + + if (!value.Equals(backgroundBrush.Color)) + { + if (backgroundBrush != null && BackgroundBrush != DefaultBackgroundBrush) + { + backgroundBrush.Dispose(); + backgroundBrush = null; + } + + backgroundBrush = new SolidBrush(value); + + Invalidate(layout.Inside); + OnBackgroundColorChanged(EventArgs.Empty); + } + } + } + + private static readonly object EVENT_BACKGROUNDCOLORCHANGED = new object(); + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.DataGridOnBackgroundColorChangedDescr))] + public event EventHandler BackgroundColorChanged + { + add => Events.AddHandler(EVENT_BACKGROUNDCOLORCHANGED, value); + remove => Events.RemoveHandler(EVENT_BACKGROUNDCOLORCHANGED, value); + } + + /// + /// Indicates whether the property should be persisted. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + SRDescription(nameof(SR.DataGridHeaderFontDescr)) + ] + public Font HeaderFont + { + get + { + return (headerFont ?? Font); + } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(HeaderFont)); + } + + if (!value.Equals(headerFont)) + { + headerFont = value; + RecalculateFonts(); + PerformLayout(); + Invalidate(layout.Inside); + } + } + } + + protected bool ShouldSerializeHeaderFont() + { + return (headerFont != null); + } + + public void ResetHeaderFont() + { + if (headerFont != null) + { + headerFont = null; + RecalculateFonts(); + PerformLayout(); + Invalidate(layout.Inside); + } + } + + /// + /// Resets the property to its default value. + /// + /// + /// Gets or sets the foreground color of the grid's headers. + /// + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridHeaderForeColorDescr)) + ] + public Color HeaderForeColor + { + get + { + return headerForePen.Color; + } + set + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "HeaderForeColor")); + } + + if (!value.Equals(headerForePen.Color)) + { + headerForePen = new Pen(value); + headerForeBrush = new SolidBrush(value); + + if (layout.RowHeadersVisible) + { + Invalidate(layout.RowHeaders); + } + + if (layout.ColumnHeadersVisible) + { + Invalidate(layout.ColumnHeaders); + } + + Invalidate(layout.TopLeftHeader); + } + } + } + + protected virtual bool ShouldSerializeHeaderForeColor() + { + return !HeaderForePen.Equals(DefaultHeaderForePen); + } + + public void ResetHeaderForeColor() + { + if (ShouldSerializeHeaderForeColor()) + { + HeaderForeColor = DefaultHeaderForeBrush.Color; + } + } + + internal SolidBrush HeaderForeBrush + { + get + { + return headerForeBrush; + } + } + + internal Pen HeaderForePen + { + get + { + return headerForePen; + } + } + + private void ResetHorizontalOffset() + { + horizontalOffset = 0; + negOffset = 0; + firstVisibleCol = 0; + numVisibleCols = 0; + lastTotallyVisibleCol = -1; + } + + internal int HorizontalOffset + { + get + { + return horizontalOffset; + } + set + { + //if (CompModSwitches.DataGridScrolling.TraceVerbose) Debug.WriteLine("DataGridScrolling: Set_HorizontalOffset, value = " + value.ToString()); + if (value < 0) + { + value = 0; + } + + // + // if the dataGrid is not bound ( listManager == null || gridTable == null) + // then use ResetHorizontalOffset(); + // + + int totalWidth = GetColumnWidthSum(); + int widthNotVisible = totalWidth - layout.Data.Width; + if (value > widthNotVisible && widthNotVisible > 0) + { + value = widthNotVisible; + } + + if (value == horizontalOffset) + { + return; + } + + int change = horizontalOffset - value; + horizScrollBar.Value = value; + Rectangle scroll = layout.Data; + if (layout.ColumnHeadersVisible) + { + scroll = Rectangle.Union(scroll, layout.ColumnHeaders); + } + + horizontalOffset = value; + + firstVisibleCol = ComputeFirstVisibleColumn(); + // update the lastTotallyVisibleCol + ComputeVisibleColumns(); + + if (gridState[GRIDSTATE_isScrolling]) + { + // if the user did not click on the grid yet, then do not put the edit + // control when scrolling + if (currentCol >= firstVisibleCol && currentCol < firstVisibleCol + numVisibleCols - 1 && (gridState[GRIDSTATE_isEditing] || gridState[GRIDSTATE_isNavigating])) + { + Edit(); + } + else + { + EndEdit(); + } + + // isScrolling is set to TRUE when the user scrolls. + // once we move the edit box, we finished processing the scroll event, so set isScrolling to FALSE + // to set isScrolling to TRUE, we need another scroll event. + gridState[GRIDSTATE_isScrolling] = false; + } + else + { + EndEdit(); + } + + RECT[] rects = CreateScrollableRegion(scroll); + ScrollRectangles(rects, change); + OnScroll(EventArgs.Empty); + } + } + + private void ScrollRectangles(RECT[] rects, int change) + { + if (rects != null) + { + RECT scroll; + if (isRightToLeft()) + { + change = -change; + } + + for (int r = 0; r < rects.Length; r++) + { + scroll = rects[r]; + User32.ScrollWindow(this, + change, + 0, + ref scroll, + ref scroll); + } + } + } + + [ + SRDescription(nameof(SR.DataGridHorizScrollBarDescr)) + ] + protected ScrollBar HorizScrollBar + { + get + { + return horizScrollBar; + } + } + + /// + /// Retrieves a value indicating whether odd and even + /// rows are painted using a different background color. + /// + // Cleanup eventually to be static. + internal bool LedgerStyle + { + get + { + return gridState[GRIDSTATE_isLedgerStyle]; + } + + /* + set { + if (isLedgerStyle != value) { + isLedgerStyle = value; + InvalidateInside(); + } + } + */ + } + + /// + /// Indicates whether the property should be persisted. + /// + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridLinkColorDescr)) + ] + public Color LinkColor + { + get + { + return linkBrush.Color; + } + set + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "LinkColor")); + } + + if (!linkBrush.Color.Equals(value)) + { + linkBrush = new SolidBrush(value); + Invalidate(layout.Data); + } + } + } + + internal virtual bool ShouldSerializeLinkColor() + { + return !LinkBrush.Equals(DefaultLinkBrush); + } + + public void ResetLinkColor() + { + if (ShouldSerializeLinkColor()) + { + LinkColor = DefaultLinkBrush.Color; + } + } + + internal Brush LinkBrush + { + get + { + return linkBrush; + } + } + + /// + /// Gets + /// or sets the color a link changes to when + /// the mouse pointer moves over it. + /// + [ + SRDescription(nameof(SR.DataGridLinkHoverColorDescr)), + SRCategory(nameof(SR.CatColors)), + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never) + + ] + public Color LinkHoverColor + { + get + { + return LinkColor; + } + set + { + } + } + + protected virtual bool ShouldSerializeLinkHoverColor() + { + return false; + // return !LinkHoverBrush.Equals(defaultLinkHoverBrush); + } + + public void ResetLinkHoverColor() + { + /* + if (ShouldSerializeLinkHoverColor()) + LinkHoverColor = defaultLinkHoverBrush.Color;*/ + } + + /// + /// Indicates whether the property should be + /// persisted. + /// + internal Font LinkFont + { + get + { + return linkFont; + } + } + + internal int LinkFontHeight + { + get + { + return linkFontHeight; + } + } + + /// + /// Gets or sets a value + /// that specifies which links are shown and in what context. + /// + [ + DefaultValue(true), + SRDescription(nameof(SR.DataGridNavigationModeDescr)), + SRCategory(nameof(SR.CatBehavior)) + ] + public bool AllowNavigation + { + get + { + return gridState[GRIDSTATE_allowNavigation]; + } + set + { + if (AllowNavigation != value) + { + gridState[GRIDSTATE_allowNavigation] = value; + // let the Caption know about this: + Caption.BackButtonActive = !parentRows.IsEmpty() && (value); + Caption.BackButtonVisible = Caption.BackButtonActive; + RecreateDataGridRows(); + + OnAllowNavigationChanged(EventArgs.Empty); + } + } + } + + private static readonly object EVENT_ALLOWNAVIGATIONCHANGED = new object(); + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.DataGridOnNavigationModeChangedDescr))] + public event EventHandler AllowNavigationChanged + { + add => Events.AddHandler(EVENT_ALLOWNAVIGATIONCHANGED, value); + remove => Events.RemoveHandler(EVENT_ALLOWNAVIGATIONCHANGED, value); + } + + [ + Browsable(false), EditorBrowsable(EditorBrowsableState.Never) + ] + public override Cursor Cursor + { + // get the cursor out of the propertyGrid. + get + { + return base.Cursor; + } + + set + { + base.Cursor = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler CursorChanged + { + add => base.CursorChanged += value; + remove => base.CursorChanged -= value; + } + + [ + Browsable(false), EditorBrowsable(EditorBrowsableState.Never) + ] + public override Image BackgroundImage + { + // get the BackgroundImage out of the propertyGrid. + get + { + return base.BackgroundImage; + } + + set + { + base.BackgroundImage = value; + } + } + + [ + Browsable(false), EditorBrowsable(EditorBrowsableState.Never) + ] + public override ImageLayout BackgroundImageLayout + { + // get the BackgroundImage out of the propertyGrid. + get + { + return base.BackgroundImageLayout; + } + + set + { + base.BackgroundImageLayout = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler BackgroundImageChanged + { + add => base.BackgroundImageChanged += value; + remove => base.BackgroundImageChanged -= value; + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler BackgroundImageLayoutChanged + { + add => base.BackgroundImageLayoutChanged += value; + remove => base.BackgroundImageLayoutChanged -= value; + } + + /// + /// Gets or sets the background color of parent rows. + /// + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridParentRowsBackColorDescr)) + ] + public Color ParentRowsBackColor + { + get + { + return parentRows.BackColor; + } + set + { + if (IsTransparentColor(value)) + { + throw new ArgumentException(SR.DataGridTransparentParentRowsBackColorNotAllowed); + } + + parentRows.BackColor = value; + } + } + + internal SolidBrush ParentRowsBackBrush + { + get + { + return parentRows.BackBrush; + } + } + + /// + /// Indicates whether the property should be + /// persisted. + /// + protected virtual bool ShouldSerializeParentRowsBackColor() + { + return !ParentRowsBackBrush.Equals(DefaultParentRowsBackBrush); + } + + private void ResetParentRowsBackColor() + { + if (ShouldSerializeParentRowsBackColor()) + { + parentRows.BackBrush = DefaultParentRowsBackBrush; + } + } + + /// + /// Gets or sets the foreground color of parent rows. + /// + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridParentRowsForeColorDescr)) + ] + public Color ParentRowsForeColor + { + get + { + return parentRows.ForeColor; + } + set + { + parentRows.ForeColor = value; + } + } + + internal SolidBrush ParentRowsForeBrush + { + get + { + return parentRows.ForeBrush; + } + } + + /// + /// Indicates whether the property should be + /// persisted. + /// + protected virtual bool ShouldSerializeParentRowsForeColor() + { + return !ParentRowsForeBrush.Equals(DefaultParentRowsForeBrush); + } + + private void ResetParentRowsForeColor() + { + if (ShouldSerializeParentRowsForeColor()) + { + parentRows.ForeBrush = DefaultParentRowsForeBrush; + } + } + + /// + /// Gets + /// or sets the default width of the grid columns in + /// pixels. + /// + [ + DefaultValue(defaultPreferredColumnWidth), + SRCategory(nameof(SR.CatLayout)), + SRDescription(nameof(SR.DataGridPreferredColumnWidthDescr)), + TypeConverter(typeof(DataGridPreferredColumnWidthTypeConverter)) + ] + public int PreferredColumnWidth + { + get + { + return preferredColumnWidth; + } + set + { + if (value < 0) + { + throw new ArgumentException(SR.DataGridColumnWidth, "PreferredColumnWidth"); + } + + if (preferredColumnWidth != value) + { + preferredColumnWidth = value; + } + } + } + + /// + /// Gets or sets the preferred row height for the control. + /// + [ + SRCategory(nameof(SR.CatLayout)), + SRDescription(nameof(SR.DataGridPreferredRowHeightDescr)) + ] + public int PreferredRowHeight + { + get + { + return preferredRowHeight; + } + set + { + if (value < 0) + { + throw new ArgumentException(SR.DataGridRowRowHeight); + } + + preferredRowHeight = value; + } + } + + private void ResetPreferredRowHeight() + { + preferredRowHeight = defaultFontHeight + 3; + } + + protected bool ShouldSerializePreferredRowHeight() + { + return preferredRowHeight != defaultFontHeight + 3; + } + + /// + /// Gets or sets a value indicating whether the grid + /// is in read-only mode. + /// + [ + DefaultValue(false), + SRCategory(nameof(SR.CatBehavior)), + SRDescription(nameof(SR.DataGridReadOnlyDescr)) + ] + public bool ReadOnly + { + get + { + return gridState[GRIDSTATE_readOnlyMode]; + } + set + { + if (ReadOnly != value) + { + bool recreateRows = false; + if (value) + { + // AllowAdd happens to have the same boolean value as whether we need to recreate rows. + recreateRows = policy.AllowAdd; + + policy.AllowRemove = false; + policy.AllowEdit = false; + policy.AllowAdd = false; + } + else + { + recreateRows |= policy.UpdatePolicy(listManager, value); + } + + gridState[GRIDSTATE_readOnlyMode] = value; + DataGridRow[] dataGridRows = DataGridRows; + if (recreateRows) + { + RecreateDataGridRows(); + + // keep the selected rows + DataGridRow[] currentDataGridRows = DataGridRows; + int rowCount = Math.Min(currentDataGridRows.Length, dataGridRows.Length); + for (int i = 0; i < rowCount; i++) + { + if (dataGridRows[i].Selected) + { + currentDataGridRows[i].Selected = true; + } + } + } + + // the addnew row needs to be updated. + PerformLayout(); + InvalidateInside(); + OnReadOnlyChanged(EventArgs.Empty); + } + } + } + + private static readonly object EVENT_READONLYCHANGED = new object(); + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.DataGridOnReadOnlyChangedDescr))] + public event EventHandler ReadOnlyChanged + { + add => Events.AddHandler(EVENT_READONLYCHANGED, value); + remove => Events.RemoveHandler(EVENT_READONLYCHANGED, value); + } + + /// + /// Gets + /// or sets a value indicating if the grid's column headers are visible. + /// + [ + SRCategory(nameof(SR.CatDisplay)), + DefaultValue(true), + SRDescription(nameof(SR.DataGridColumnHeadersVisibleDescr)) + ] + public bool ColumnHeadersVisible + { + get + { + return gridState[GRIDSTATE_columnHeadersVisible]; + } + set + { + if (ColumnHeadersVisible != value) + { + gridState[GRIDSTATE_columnHeadersVisible] = value; + layout.ColumnHeadersVisible = value; + PerformLayout(); + InvalidateInside(); + } + } + } + + /// + /// Gets or sets a value indicating whether the parent rows of a table are + /// visible. + /// + [ + SRCategory(nameof(SR.CatDisplay)), + DefaultValue(true), + SRDescription(nameof(SR.DataGridParentRowsVisibleDescr)) + ] + public bool ParentRowsVisible + { + get + { + return layout.ParentRowsVisible; + } + set + { + if (layout.ParentRowsVisible != value) + { + SetParentRowsVisibility(value); + + // update the caption: parentDownVisible == false corresponds to DownButtonDown == true; + // + caption.SetDownButtonDirection(!value); + + OnParentRowsVisibleChanged(EventArgs.Empty); + } + } + } + + private static readonly object EVENT_PARENTROWSVISIBLECHANGED = new object(); + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.DataGridOnParentRowsVisibleChangedDescr))] + public event EventHandler ParentRowsVisibleChanged + { + add => Events.AddHandler(EVENT_PARENTROWSVISIBLECHANGED, value); + remove => Events.RemoveHandler(EVENT_PARENTROWSVISIBLECHANGED, value); + } + + internal bool ParentRowsIsEmpty() + { + return parentRows.IsEmpty(); + } + + /// + /// Gets or sets a value indicating whether the data grid's row headers are + /// visible. + /// + [ + SRCategory(nameof(SR.CatDisplay)), + DefaultValue(true), + SRDescription(nameof(SR.DataGridRowHeadersVisibleDescr)) + ] + public bool RowHeadersVisible + { + get + { + return gridState[GRIDSTATE_rowHeadersVisible]; + } + set + { + if (RowHeadersVisible != value) + { + gridState[GRIDSTATE_rowHeadersVisible] = value; + PerformLayout(); + InvalidateInside(); + } + } + } + + [ + SRCategory(nameof(SR.CatLayout)), + DefaultValue(defaultRowHeaderWidth), + SRDescription(nameof(SR.DataGridRowHeaderWidthDescr)) + ] + public int RowHeaderWidth + { + get + { + return rowHeaderWidth; + } + set + { + value = Math.Max(minRowHeaderWidth, value); + if (rowHeaderWidth != value) + { + rowHeaderWidth = value; + if (layout.RowHeadersVisible) + { + PerformLayout(); + InvalidateInside(); + } + } + } + } + + /// + /// Gets or sets the width of headers. + /// + [ + Browsable(false), EditorBrowsable(EditorBrowsableState.Never), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + Bindable(false) + ] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler TextChanged + { + add => base.TextChanged += value; + remove => base.TextChanged -= value; + } + + /// + /// Gets the vertical scroll bar of the control. + /// + [ + Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), + SRDescription(nameof(SR.DataGridVertScrollBarDescr)) + ] + protected ScrollBar VertScrollBar + { + get + { + return vertScrollBar; + } + } + + /// + /// Gets the number of visible columns. + /// + [ + Browsable(false), + SRDescription(nameof(SR.DataGridVisibleColumnCountDescr)) + ] + public int VisibleColumnCount + { + get + { + return Math.Min(numVisibleCols, myGridTable == null ? 0 : myGridTable.GridColumnStyles.Count); + } + } + + /// + /// Gets the number of rows visible. + /// + [ + Browsable(false), + SRDescription(nameof(SR.DataGridVisibleRowCountDescr)) + ] + public int VisibleRowCount + { + get + { + return numVisibleRows; + } + } + + /// + /// Gets or sets the value of the cell at + /// the specified the row and column. + /// + public object this[int rowIndex, int columnIndex] + { + get + { + EnsureBound(); + if (rowIndex < 0 || rowIndex >= DataGridRowsLength) + { + throw new ArgumentOutOfRangeException(nameof(rowIndex)); + } + + if (columnIndex < 0 || columnIndex >= myGridTable.GridColumnStyles.Count) + { + throw new ArgumentOutOfRangeException(nameof(columnIndex)); + } + + CurrencyManager listManager = this.listManager; + DataGridColumnStyle column = myGridTable.GridColumnStyles[columnIndex]; + return column.GetColumnValueAtRow(listManager, rowIndex); + } + set + { + EnsureBound(); + if (rowIndex < 0 || rowIndex >= DataGridRowsLength) + { + throw new ArgumentOutOfRangeException(nameof(rowIndex)); + } + + if (columnIndex < 0 || columnIndex >= myGridTable.GridColumnStyles.Count) + { + throw new ArgumentOutOfRangeException(nameof(columnIndex)); + } + + CurrencyManager listManager = this.listManager; + if (listManager.Position != rowIndex) + { + listManager.Position = rowIndex; + } + + DataGridColumnStyle column = myGridTable.GridColumnStyles[columnIndex]; + column.SetColumnValueAtRow(listManager, rowIndex, value); + + // invalidate the bounds of the cell only if the cell is visible + if (columnIndex >= firstVisibleCol && columnIndex <= firstVisibleCol + numVisibleCols - 1 && + rowIndex >= firstVisibleRow && rowIndex <= firstVisibleRow + numVisibleRows) + { + Rectangle bounds = GetCellBounds(rowIndex, columnIndex); + Invalidate(bounds); + } + } + } + + /// + /// Gets or sets the value of a specified . + /// + public object this[DataGridCell cell] + { + get + { + return this[cell.RowNumber, cell.ColumnNumber]; + } + set + { + this[cell.RowNumber, cell.ColumnNumber] = value; + } + } + + private void WireTableStylePropChanged(DataGridTableStyle gridTable) + { + gridTable.GridLineColorChanged += new EventHandler(GridLineColorChanged); + gridTable.GridLineStyleChanged += new EventHandler(GridLineStyleChanged); + gridTable.HeaderBackColorChanged += new EventHandler(HeaderBackColorChanged); + gridTable.HeaderFontChanged += new EventHandler(HeaderFontChanged); + gridTable.HeaderForeColorChanged += new EventHandler(HeaderForeColorChanged); + gridTable.LinkColorChanged += new EventHandler(LinkColorChanged); + gridTable.LinkHoverColorChanged += new EventHandler(LinkHoverColorChanged); + gridTable.PreferredColumnWidthChanged += new EventHandler(PreferredColumnWidthChanged); + gridTable.RowHeadersVisibleChanged += new EventHandler(RowHeadersVisibleChanged); + gridTable.ColumnHeadersVisibleChanged += new EventHandler(ColumnHeadersVisibleChanged); + gridTable.RowHeaderWidthChanged += new EventHandler(RowHeaderWidthChanged); + gridTable.AllowSortingChanged += new EventHandler(AllowSortingChanged); + } + + private void UnWireTableStylePropChanged(DataGridTableStyle gridTable) + { + gridTable.GridLineColorChanged -= new EventHandler(GridLineColorChanged); + gridTable.GridLineStyleChanged -= new EventHandler(GridLineStyleChanged); + gridTable.HeaderBackColorChanged -= new EventHandler(HeaderBackColorChanged); + gridTable.HeaderFontChanged -= new EventHandler(HeaderFontChanged); + gridTable.HeaderForeColorChanged -= new EventHandler(HeaderForeColorChanged); + gridTable.LinkColorChanged -= new EventHandler(LinkColorChanged); + gridTable.LinkHoverColorChanged -= new EventHandler(LinkHoverColorChanged); + gridTable.PreferredColumnWidthChanged -= new EventHandler(PreferredColumnWidthChanged); + gridTable.RowHeadersVisibleChanged -= new EventHandler(RowHeadersVisibleChanged); + gridTable.ColumnHeadersVisibleChanged -= new EventHandler(ColumnHeadersVisibleChanged); + gridTable.RowHeaderWidthChanged -= new EventHandler(RowHeaderWidthChanged); + gridTable.AllowSortingChanged -= new EventHandler(AllowSortingChanged); + } + + /// + /// DataSource events are handled + /// + private void WireDataSource() + { + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: WireDataSource"); + Debug.Assert(listManager != null, "Can't wire up to a null DataSource"); + listManager.CurrentChanged += currentChangedHandler; + listManager.PositionChanged += positionChangedHandler; + listManager.ItemChanged += itemChangedHandler; + listManager.MetaDataChanged += metaDataChangedHandler; + } + + private void UnWireDataSource() + { + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: UnWireDataSource"); + Debug.Assert(listManager != null, "Can't un wire from a null DataSource"); + listManager.CurrentChanged -= currentChangedHandler; + listManager.PositionChanged -= positionChangedHandler; + listManager.ItemChanged -= itemChangedHandler; + listManager.MetaDataChanged -= metaDataChangedHandler; + } + + // This is called after a row has been added. And I think whenever + // a row gets deleted, etc. + // We recreate our datagrid rows at this point. + private void DataSource_Changed(object sender, EventArgs ea) + { + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: DataSource_Changed"); + + // the grid will receive the dataSource_Changed event when + // allowAdd changes on the dataView. + policy.UpdatePolicy(ListManager, ReadOnly); + if (gridState[GRIDSTATE_inListAddNew]) + { + // we are adding a new row + // keep the old rows, w/ their height, expanded/collapsed information + // + Debug.Assert(policy.AllowAdd, "how can we add a new row if the policy does not allow this?"); + Debug.Assert(DataGridRowsLength == DataGridRows.Length, "how can this fail?"); + + DataGridRow[] gridRows = DataGridRows; + int currentRowCount = DataGridRowsLength; + // put the added row: + // + gridRows[currentRowCount - 1] = new DataGridRelationshipRow(this, myGridTable, currentRowCount - 1); + SetDataGridRows(gridRows, currentRowCount); + } + else if (gridState[GRIDSTATE_inAddNewRow] && !gridState[GRIDSTATE_inDeleteRow]) + { + // when the backEnd adds a row and we are still inAddNewRow + listManager.CancelCurrentEdit(); + gridState[GRIDSTATE_inAddNewRow] = false; + RecreateDataGridRows(); + } + else if (!gridState[GRIDSTATE_inDeleteRow]) + { + RecreateDataGridRows(); + currentRow = Math.Min(currentRow, listManager.Count); + } + + bool oldListHasErrors = ListHasErrors; + ListHasErrors = DataGridSourceHasErrors(); + // if we changed the ListHasErrors, then the grid is already invalidated + if (oldListHasErrors == ListHasErrors) + { + InvalidateInside(); + } + } + + private void GridLineColorChanged(object sender, EventArgs e) + { + Invalidate(layout.Data); + } + + private void GridLineStyleChanged(object sender, EventArgs e) + { + myGridTable.ResetRelationsUI(); + Invalidate(layout.Data); + } + + private void HeaderBackColorChanged(object sender, EventArgs e) + { + if (layout.RowHeadersVisible) + { + Invalidate(layout.RowHeaders); + } + + if (layout.ColumnHeadersVisible) + { + Invalidate(layout.ColumnHeaders); + } + + Invalidate(layout.TopLeftHeader); + } + + private void HeaderFontChanged(object sender, EventArgs e) + { + RecalculateFonts(); + PerformLayout(); + Invalidate(layout.Inside); + } + + private void HeaderForeColorChanged(object sender, EventArgs e) + { + if (layout.RowHeadersVisible) + { + Invalidate(layout.RowHeaders); + } + + if (layout.ColumnHeadersVisible) + { + Invalidate(layout.ColumnHeaders); + } + + Invalidate(layout.TopLeftHeader); + } + + private void LinkColorChanged(object sender, EventArgs e) + { + Invalidate(layout.Data); + } + + private void LinkHoverColorChanged(object sender, EventArgs e) + { + Invalidate(layout.Data); + } + + private void PreferredColumnWidthChanged(object sender, EventArgs e) + { + // reset the dataGridRows + SetDataGridRows(null, DataGridRowsLength); + // layout the horizontal scroll bar + PerformLayout(); + // invalidate everything + Invalidate(); + } + + private void RowHeadersVisibleChanged(object sender, EventArgs e) + { + layout.RowHeadersVisible = myGridTable == null ? false : myGridTable.RowHeadersVisible; + PerformLayout(); + InvalidateInside(); + } + + private void ColumnHeadersVisibleChanged(object sender, EventArgs e) + { + layout.ColumnHeadersVisible = myGridTable == null ? false : myGridTable.ColumnHeadersVisible; + PerformLayout(); + InvalidateInside(); + } + + private void RowHeaderWidthChanged(object sender, EventArgs e) + { + if (layout.RowHeadersVisible) + { + PerformLayout(); + InvalidateInside(); + } + } + + private void AllowSortingChanged(object sender, EventArgs e) + { + if (!myGridTable.AllowSorting && listManager != null) + { + IList list = listManager.List; + if (list is IBindingList) + { + ((IBindingList)list).RemoveSort(); + } + } + } + + private void DataSource_RowChanged(object sender, EventArgs ea) + { + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: DataSource_RowChanged"); + // it may be the case that our cache was not updated + // to the latest changes in the list : CurrentChanged is fired before + // ListChanged. + // So invalidate the row if there is something to invalidate + DataGridRow[] rows = DataGridRows; + if (currentRow < DataGridRowsLength) + { + InvalidateRow(currentRow); + } + } + + /// + /// Fired by the DataSource when row position moves. + /// + private void DataSource_PositionChanged(object sender, EventArgs ea) + { +#if DEBUG + inDataSource_PositionChanged = true; +#endif + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: DataSource_PositionChanged to " + listManager.Position.ToString(CultureInfo.InvariantCulture)); + // the grid will get the PositionChanged event + // before the OnItemChanged event when a row will be deleted in the backEnd; + // we still want to keep the old rows when the user deletes the rows using the grid + // and we do not want to do the same work twice when the user adds a row via the grid + if (DataGridRowsLength > listManager.Count + (policy.AllowAdd ? 1 : 0) && !gridState[GRIDSTATE_inDeleteRow]) + { + Debug.Assert(!gridState[GRIDSTATE_inAddNewRow] && !gridState[GRIDSTATE_inListAddNew], "how can the list decrease when we are adding a row?"); + RecreateDataGridRows(); + } + + if (ListManager.Position != currentRow) + { + CurrentCell = new DataGridCell(listManager.Position, currentCol); + } +#if DEBUG + inDataSource_PositionChanged = false; +#endif + } + + internal void DataSource_MetaDataChanged(object sender, EventArgs e) + { + MetaDataChanged(); + } + + private bool DataGridSourceHasErrors() + { + if (listManager == null) + { + return false; + } + + for (int i = 0; i < listManager.Count; i++) + { + object errObj = listManager[i]; + if (errObj is IDataErrorInfo) + { + string errString = ((IDataErrorInfo)errObj).Error; + if (errString != null && errString.Length != 0) + { + return true; + } + } + } + + return false; + } + + private void TableStylesCollectionChanged(object sender, CollectionChangeEventArgs ccea) + { + // if the users changed the collection of tableStyles + if (sender != dataGridTables) + { + return; + } + + if (listManager == null) + { + return; + } + + if (ccea.Action == CollectionChangeAction.Add) + { + DataGridTableStyle tableStyle = (DataGridTableStyle)ccea.Element; + if (listManager.GetListName().Equals(tableStyle.MappingName)) + { + Debug.Assert(myGridTable.IsDefault, "if the table is not default, then it had a name. how can one add another table to the collection w/ the same name and not throw an exception"); + SetDataGridTable(tableStyle, true); // true for forcing column creation + SetDataGridRows(null, 0); + } + } + else if (ccea.Action == CollectionChangeAction.Remove) + { + DataGridTableStyle tableStyle = (DataGridTableStyle)ccea.Element; + if (myGridTable.MappingName.Equals(tableStyle.MappingName)) + { + Debug.Assert(myGridTable.IsDefault, "if the table is not default, then it had a name. how can one add another table to the collection w/ the same name and not throw an exception"); + defaultTableStyle.GridColumnStyles.ResetDefaultColumnCollection(); + SetDataGridTable(defaultTableStyle, true); // true for forcing column creation + SetDataGridRows(null, 0); + } + } + else + { + Debug.Assert(ccea.Action == CollectionChangeAction.Refresh, "what else is possible?"); + // we have to search to see if the collection of table styles contains one + // w/ the same name as the list in the dataGrid + + DataGridTableStyle newGridTable = dataGridTables[listManager.GetListName()]; + if (newGridTable == null) + { + if (!myGridTable.IsDefault) + { + // get rid of the old gridColumns + defaultTableStyle.GridColumnStyles.ResetDefaultColumnCollection(); + SetDataGridTable(defaultTableStyle, true); // true for forcing column creation + SetDataGridRows(null, 0); + } + } + else + { + SetDataGridTable(newGridTable, true); // true for forcing column creation + SetDataGridRows(null, 0); + } + } + } + + private void DataSource_ItemChanged(object sender, ItemChangedEventArgs ea) + { + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: DataSource_ItemChanged at index " + ea.Index.ToString(CultureInfo.InvariantCulture)); + + // if ea.Index == -1, then we invalidate all rows. + if (ea.Index == -1) + { + DataSource_Changed(sender, EventArgs.Empty); + /* + // if there are rows which are invisible, it is more efficient to invalidata layout.Data + if (numVisibleRows <= dataGridRowsLength) + Invalidate(layout.Data); + else + { + Debug.Assert(firstVisibleRow == 0, "if all rows are visible, then how come that first row is not visible?"); + for (int i = 0; i < numVisibleRows; i++) + InvalidateRow(firstVisibleRow + numVisibleRows); + } + */ + } + else + { + // let's see how we are doing w/ the errors + object errObj = listManager[ea.Index]; + bool oldListHasErrors = ListHasErrors; + if (errObj is IDataErrorInfo) + { + if (((IDataErrorInfo)errObj).Error.Length != 0) + { + ListHasErrors = true; + } + else if (ListHasErrors) + { + // maybe there was an error that now is fixed + ListHasErrors = DataGridSourceHasErrors(); + } + } + + // Invalidate the row only if we did not change the ListHasErrors + if (oldListHasErrors == ListHasErrors) + { + InvalidateRow(ea.Index); + } + + // we need to update the edit box: + // we update the text in the edit box only when the currentRow + // equals the ea.Index + if (editColumn != null && ea.Index == currentRow) + { + editColumn.UpdateUI(ListManager, ea.Index, null); + } + } + } + + protected virtual void OnBorderStyleChanged(EventArgs e) + { + if (Events[EVENT_BORDERSTYLECHANGED] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnCaptionVisibleChanged(EventArgs e) + { + if (Events[EVENT_CAPTIONVISIBLECHANGED] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnCurrentCellChanged(EventArgs e) + { + if (Events[EVENT_CURRENTCELLCHANGED] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnFlatModeChanged(EventArgs e) + { + if (Events[EVENT_FLATMODECHANGED] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnBackgroundColorChanged(EventArgs e) + { + if (Events[EVENT_BACKGROUNDCOLORCHANGED] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnAllowNavigationChanged(EventArgs e) + { + if (Events[EVENT_ALLOWNAVIGATIONCHANGED] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnParentRowsVisibleChanged(EventArgs e) + { + if (Events[EVENT_PARENTROWSVISIBLECHANGED] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnParentRowsLabelStyleChanged(EventArgs e) + { + if (Events[EVENT_PARENTROWSLABELSTYLECHANGED] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnReadOnlyChanged(EventArgs e) + { + if (Events[EVENT_READONLYCHANGED] is EventHandler eh) + { + eh(this, e); + } + } + + /// + /// Raises the + /// event. + /// + protected void OnNavigate(NavigateEventArgs e) + { + onNavigate?.Invoke(this, e); + } + + /* + /// + /// Raises the event. + /// + protected void OnColumnResize(EventArgs e) { + RaiseEvent(EVENT_COLUMNRESIZE, e); + } + + internal void OnLinkClick(EventArgs e) { + RaiseEvent(EVENT_LINKCLICKED, e); + } + */ + + internal void OnNodeClick(EventArgs e) + { + // if we expanded/collapsed the RelationshipRow + // then we need to layout the vertical scroll bar + // + PerformLayout(); + + // also, we need to let the hosted edit control that its + // boundaries possibly changed. do this with a call to Edit() + // do this only if the firstVisibleColumn is the editColumn + // + GridColumnStylesCollection columns = myGridTable.GridColumnStyles; + if (firstVisibleCol > -1 && firstVisibleCol < columns.Count && columns[firstVisibleCol] == editColumn) + { + Edit(); + } + + // Raise the event for the event listeners + ((EventHandler)Events[EVENT_NODECLICKED])?.Invoke(this, e); + } + + /// + /// Raises the event. + /// + protected void OnRowHeaderClick(EventArgs e) + { + onRowHeaderClick?.Invoke(this, e); + } + + /// + /// Raises the event. + /// + protected void OnScroll(EventArgs e) + { + // reset the toolTip information + if (ToolTipProvider != null) + { + ResetToolTip(); + } + +((EventHandler)Events[EVENT_SCROLL])?.Invoke(this, e); + } + + /// + /// Listens + /// for the horizontal scrollbar's scroll + /// event. + /// + protected virtual void GridHScrolled(object sender, ScrollEventArgs se) + { + if (!Enabled) + { + return; + } + + if (DataSource == null) + { + Debug.Fail("Horizontal Scrollbar should be disabled without a DataSource."); + return; + } + + gridState[GRIDSTATE_isScrolling] = true; + +#if DEBUG + + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "DataGridScrolling: in GridHScrolled: the scroll event type:"); + switch (se.Type) + { + case ScrollEventType.SmallIncrement: + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "small increment"); + break; + case ScrollEventType.SmallDecrement: + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "small decrement"); + break; + case ScrollEventType.LargeIncrement: + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "Large decrement"); + break; + case ScrollEventType.LargeDecrement: + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "small decrement"); + break; + case ScrollEventType.ThumbPosition: + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "Thumb Position"); + break; + case ScrollEventType.ThumbTrack: + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "Thumb Track"); + break; + case ScrollEventType.First: + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "First"); + break; + case ScrollEventType.Last: + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "Last"); + break; + case ScrollEventType.EndScroll: + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "EndScroll"); + break; + } + +#endif // DEBUG + + if (se.Type == ScrollEventType.SmallIncrement || + se.Type == ScrollEventType.SmallDecrement) + { + int dCols = (se.Type == ScrollEventType.SmallIncrement) ? 1 : -1; + if (se.Type == ScrollEventType.SmallDecrement && negOffset == 0) + { + GridColumnStylesCollection cols = myGridTable.GridColumnStyles; + // if the column before the first visible column has width == 0 then skip it + for (int i = firstVisibleCol - 1; i >= 0 && cols[i].Width == 0; i--) + { + dCols--; + } + } + + if (se.Type == ScrollEventType.SmallIncrement && negOffset == 0) + { + GridColumnStylesCollection cols = myGridTable.GridColumnStyles; + for (int i = firstVisibleCol; i > -1 && i < cols.Count && cols[i].Width == 0; i++) + { + dCols++; + } + } + + ScrollRight(dCols); + se.NewValue = HorizontalOffset; + } + else if (se.Type != ScrollEventType.EndScroll) + { + HorizontalOffset = se.NewValue; + } + + gridState[GRIDSTATE_isScrolling] = false; + } + + /// + /// Listens + /// for the vertical scrollbar's scroll event. + /// + protected virtual void GridVScrolled(object sender, ScrollEventArgs se) + { + if (!Enabled) + { + return; + } + + if (DataSource == null) + { + Debug.Fail("Vertical Scrollbar should be disabled without a DataSource."); + return; + } + + gridState[GRIDSTATE_isScrolling] = true; + + try + { + se.NewValue = Math.Min(se.NewValue, DataGridRowsLength - numTotallyVisibleRows); + int dRows = se.NewValue - firstVisibleRow; + ScrollDown(dRows); + } + finally + { + gridState[GRIDSTATE_isScrolling] = false; + } + } + + private void HandleEndCurrentEdit() + { + int currentRowSaved = currentRow; + int currentColSaved = currentCol; + + string errorMessage = null; + + try + { + listManager.EndCurrentEdit(); + } + catch (Exception e) + { + errorMessage = e.Message; + } + + if (errorMessage != null) + { + DialogResult result = RTLAwareMessageBox.Show(null, string.Format(SR.DataGridPushedIncorrectValueIntoColumn, + errorMessage), SR.DataGridErrorMessageBoxCaption, MessageBoxButtons.YesNo, + MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0); + + if (result == DialogResult.Yes) + { + currentRow = currentRowSaved; + currentCol = currentColSaved; + Debug.Assert(currentRow == ListManager.Position || listManager.Position == -1, "the position in the list manager (" + ListManager.Position + ") is out of sync with the currentRow (" + currentRow + ")" + " and the exception is '" + errorMessage + "'"); + // also, make sure that we get the row selector on the currentrow, too + InvalidateRowHeader(currentRow); + Edit(); + } + else + { + // if the user committed a row that used to be addNewRow and the backEnd rejects it, + // and then it tries to navigate down then we should stay in the addNewRow + // in this particular scenario, CancelCurrentEdit will cause the last row to be deleted, + // and this will ultimately call InvalidateRow w/ a row number larger than the number of rows + // so set the currentRow here: + Debug.Assert(result == DialogResult.No, "we only put cancel and ok on the error message box"); + listManager.PositionChanged -= positionChangedHandler; + listManager.CancelCurrentEdit(); + listManager.Position = currentRow; + listManager.PositionChanged += positionChangedHandler; + } + } + } + + /// + /// Listens + /// for the caption's back button clicked event. + /// + protected void OnBackButtonClicked(object sender, EventArgs e) + { + NavigateBack(); + + ((EventHandler)Events[EVENT_BACKBUTTONCLICK])?.Invoke(this, e); + } + + protected override void OnBackColorChanged(EventArgs e) + { + backBrush = new SolidBrush(BackColor); + Invalidate(); + + base.OnBackColorChanged(e); + } + + protected override void OnBindingContextChanged(EventArgs e) + { + if (DataSource != null && !gridState[GRIDSTATE_inSetListManager]) + { + try + { + Set_ListManager(DataSource, DataMember, true, false); // we do not want to create columns + // if the columns are already created + // the grid should not rely on OnBindingContextChanged + // to create columns. + } + catch + { + // at runtime we will rethrow the exception + if (Site == null || !Site.DesignMode) + { + throw; + } + + RTLAwareMessageBox.Show(null, SR.DataGridExceptionInPaint, null, + MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0); + + if (Visible) + { + BeginUpdateInternal(); + } + + ResetParentRows(); + + Set_ListManager(null, string.Empty, true); + if (Visible) + { + EndUpdateInternal(); + } + } + } + + base.OnBindingContextChanged(e); + } + + protected virtual void OnDataSourceChanged(EventArgs e) + { + if (Events[EVENT_DATASOURCECHANGED] is EventHandler eh) + { + eh(this, e); + } + } + + /// + /// Listens for + /// the caption's down button clicked event. + /// + protected void OnShowParentDetailsButtonClicked(object sender, EventArgs e) + { + // we need to fire the ParentRowsVisibleChanged event + // and the ParentRowsVisible property just calls SetParentRowsVisibility and + // then fires the event. + ParentRowsVisible = !caption.ToggleDownButtonDirection(); + + ((EventHandler)Events[EVENT_DOWNBUTTONCLICK])?.Invoke(this, e); + } + + protected override void OnForeColorChanged(EventArgs e) + { + foreBrush = new SolidBrush(ForeColor); + Invalidate(); + + base.OnForeColorChanged(e); + } + + protected override void OnFontChanged(EventArgs e) + { + // let the caption know about the event changed + // + Caption.OnGridFontChanged(); + RecalculateFonts(); + RecreateDataGridRows(); + // get all the rows in the parentRows stack, and modify their height + if (originalState != null) + { + Debug.Assert(!parentRows.IsEmpty(), "if the originalState is not null, then parentRows contains at least one row"); + Stack parentStack = new Stack(); + // this is a huge performance hit: + // everytime we get/put something from/to + // the parentRows, the buttons in the dataGridCaption + // are invalidated + while (!parentRows.IsEmpty()) + { + DataGridState dgs = parentRows.PopTop(); + int rowCount = dgs.DataGridRowsLength; + + for (int i = 0; i < rowCount; i++) + { + // performance hit: this will cause to invalidate a bunch of + // stuff + + dgs.DataGridRows[i].Height = dgs.DataGridRows[i].MinimumRowHeight(dgs.GridColumnStyles); + } + + parentStack.Push(dgs); + } + + while (parentStack.Count != 0) + { + parentRows.AddParent((DataGridState)parentStack.Pop()); + } + } + + base.OnFontChanged(e); + } + +#pragma warning disable CS0419 // Ambiguous reference in cref attribute + /// + /// Raises the + /// event. + /// + protected override void OnPaintBackground(PaintEventArgs ebe) +#pragma warning restore CS0419 // Ambiguous reference in cref attribute + { + // null body + } + + /// + /// Raises the event which + /// repositions controls + /// and updates scroll bars. + /// + protected override void OnLayout(LayoutEventArgs levent) + { + // if we get a OnLayout event while the editControl changes, then just + // ignore it + // + if (gridState[GRIDSTATE_editControlChanging]) + { + return; + } + + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: OnLayout"); + base.OnLayout(levent); + + if (gridState[GRIDSTATE_layoutSuspended]) + { + return; + } + + gridState[GRIDSTATE_canFocus] = false; + try + { + if (IsHandleCreated) + { + if (layout.ParentRowsVisible) + { + parentRows.OnLayout(); + } + + // reset the toolTip information + if (ToolTipProvider != null) + { + ResetToolTip(); + } + + ComputeLayout(); + } + } + finally + { + gridState[GRIDSTATE_canFocus] = true; + } + } + + /// + /// Raises the + /// event. + /// + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + + // toolTipping + toolTipProvider = new DataGridToolTip(this); + toolTipProvider.CreateToolTipHandle(); + toolTipId = 0; + + PerformLayout(); + } + + /// + /// Raises the + /// event. + /// + protected override void OnHandleDestroyed(EventArgs e) + { + base.OnHandleDestroyed(e); + + // toolTipping + if (toolTipProvider != null) + { + toolTipProvider.Destroy(); + toolTipProvider = null; + } + + toolTipId = 0; + } + + /// + /// Raises the + /// event. + /// + protected override void OnEnter(EventArgs e) + { + if (gridState[GRIDSTATE_canFocus] && !gridState[GRIDSTATE_editControlChanging]) + { + if (Bound) + { + Edit(); + } + + base.OnEnter(e); + } + } + + /// + /// Raises the + /// event. + /// + protected override void OnLeave(EventArgs e) + { + OnLeave_Grid(); + base.OnLeave(e); + } + + private void OnLeave_Grid() + { + gridState[GRIDSTATE_canFocus] = false; + try + { + EndEdit(); + if (listManager != null && !gridState[GRIDSTATE_editControlChanging]) + { + if (gridState[GRIDSTATE_inAddNewRow]) + { + // if the user did not type anything + // in the addNewRow, then cancel the currentedit + listManager.CancelCurrentEdit(); + // set the addNewRow back + DataGridRow[] localGridRows = DataGridRows; + localGridRows[DataGridRowsLength - 1] = new DataGridAddNewRow(this, myGridTable, DataGridRowsLength - 1); + SetDataGridRows(localGridRows, DataGridRowsLength); + } + else + { + // this.listManager.EndCurrentEdit(); + HandleEndCurrentEdit(); + } + } + } + finally + { + gridState[GRIDSTATE_canFocus] = true; + // inAddNewRow should be set to false if the control was + // not changing + if (!gridState[GRIDSTATE_editControlChanging]) + { + gridState[GRIDSTATE_inAddNewRow] = false; + } + } + } + + /// + /// Raises the + /// event. + /// + protected override void OnKeyDown(KeyEventArgs ke) + { + Debug.WriteLineIf(CompModSwitches.DataGridKeys.TraceVerbose, "DataGridKeys: OnKeyDown "); + base.OnKeyDown(ke); + ProcessGridKey(ke); + } + + /// + /// Raises the event. + /// + protected override void OnKeyPress(KeyPressEventArgs kpe) + { + Debug.WriteLineIf(CompModSwitches.DataGridKeys.TraceVerbose, "DataGridKeys: OnKeyPress " + TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString(kpe.KeyChar)); + + base.OnKeyPress(kpe); + GridColumnStylesCollection coll = myGridTable.GridColumnStyles; + if (coll != null && currentCol > 0 && currentCol < coll.Count) + { + if (!coll[currentCol].ReadOnly) + { + if (kpe.KeyChar > 32) + { + Edit(new string(new char[] { (char)kpe.KeyChar })); + } + } + } + } + + /// + /// Raises the event. + /// + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + gridState[GRIDSTATE_childLinkFocused] = false; + gridState[GRIDSTATE_dragging] = false; + if (listManager == null) + { + return; + } + + HitTestInfo location = HitTest(e.X, e.Y); + Keys nModifier = ModifierKeys; + bool isControlDown = (nModifier & Keys.Control) == Keys.Control && (nModifier & Keys.Alt) == 0; + bool isShiftDown = (nModifier & Keys.Shift) == Keys.Shift; + + // Only left clicks for now + if (e.Button != MouseButtons.Left) + { + return; + } + + // Check column resize + if (location.type == HitTestType.ColumnResize) + { + if (e.Clicks > 1) + { + ColAutoResize(location.col); + } + else + { + ColResizeBegin(e, location.col); + } + + return; + } + + // Check row resize + if (location.type == HitTestType.RowResize) + { + if (e.Clicks > 1) + { + RowAutoResize(location.row); + } + else + { + RowResizeBegin(e, location.row); + } + + return; + } + + // Check column headers + if (location.type == HitTestType.ColumnHeader) + { + trackColumnHeader = myGridTable.GridColumnStyles[location.col].PropertyDescriptor; + return; + } + + if (location.type == HitTestType.Caption) + { + Rectangle captionRect = layout.Caption; + caption.MouseDown(e.X - captionRect.X, e.Y - captionRect.Y); + return; + } + + if (layout.Data.Contains(e.X, e.Y) || layout.RowHeaders.Contains(e.X, e.Y)) + { + // Check with the row underneath the mouse + int row = GetRowFromY(e.Y); + if (row > -1) + { + Point p = NormalizeToRow(e.X, e.Y, row); + DataGridRow[] localGridRows = DataGridRows; + if (localGridRows[row].OnMouseDown(p.X, p.Y, + layout.RowHeaders, + isRightToLeft())) + { + CommitEdit(); + + // possibly this was the last row, so then the link may not + // be visible. make it visible, by making the row visible. + // how can we be sure that the user did not click + // on a relationship and navigated to the child rows? + // check if the row is expanded: if the row is expanded, then the user clicked + // on the node. when we navigate to child rows the rows are recreated + // and are initially collapsed + localGridRows = DataGridRows; + if (row < DataGridRowsLength && (localGridRows[row] is DataGridRelationshipRow) && ((DataGridRelationshipRow)localGridRows[row]).Expanded) + { + EnsureVisible(row, 0); + } + + // show the edit box + // + Edit(); + return; + } + } + } + + // Check row headers + // + if (location.type == HitTestType.RowHeader) + { + EndEdit(); + if (!(DataGridRows[location.row] is DataGridAddNewRow)) + { + int savedCurrentRow = currentRow; + CurrentCell = new DataGridCell(location.row, currentCol); + if (location.row != savedCurrentRow && + currentRow != location.row && + currentRow == savedCurrentRow) + { + // The data grid was not able to move away from its previous current row. + // Be defensive and don't select the row. + return; + } + } + + if (isControlDown) + { + if (IsSelected(location.row)) + { + UnSelect(location.row); + } + else + { + Select(location.row); + } + } + else + { + if (lastRowSelected == -1 || !isShiftDown) + { + ResetSelection(); + Select(location.row); + } + else + { + int lowerRow = Math.Min(lastRowSelected, location.row); + int upperRow = Math.Max(lastRowSelected, location.row); + + // we need to reset the old SelectedRows. + // ResetSelection() will also reset lastRowSelected, so we + // need to save it + int saveLastRowSelected = lastRowSelected; + ResetSelection(); + lastRowSelected = saveLastRowSelected; + + DataGridRow[] rows = DataGridRows; + for (int i = lowerRow; i <= upperRow; i++) + { + rows[i].Selected = true; + numSelectedRows++; + } + + // hide the edit box: + // + EndEdit(); + return; + } + } + + lastRowSelected = location.row; + // OnRowHeaderClick(EventArgs.Empty); + return; + } + + // Check parentRows + // + if (location.type == HitTestType.ParentRows) + { + EndEdit(); + parentRows.OnMouseDown(e.X, e.Y, isRightToLeft()); + } + + // Check cell clicks + // + if (location.type == HitTestType.Cell) + { + if (myGridTable.GridColumnStyles[location.col].MouseDown(location.row, e.X, e.Y)) + { + return; + } + + DataGridCell target = new DataGridCell(location.row, location.col); + if (policy.AllowEdit && CurrentCell.Equals(target)) + { + ResetSelection(); + // + // what if only a part of the current cell is visible? + // + EnsureVisible(currentRow, currentCol); + Edit(); + } + else + { + ResetSelection(); + CurrentCell = target; + } + } + } + + /// + /// Creates the + /// event. + /// + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + if (oldRow != -1) + { + DataGridRow[] localGridRows = DataGridRows; + localGridRows[oldRow].OnMouseLeft(layout.RowHeaders, isRightToLeft()); + } + + if (gridState[GRIDSTATE_overCaption]) + { + caption.MouseLeft(); + } + + // when the mouse leaves the grid control, reset the cursor to arrow + Cursor = null; + } + + internal void TextBoxOnMouseWheel(MouseEventArgs e) + { + OnMouseWheel(e); + } + + /// + /// Raises the + /// event. + /// + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + if (listManager == null) + { + return; + } + + HitTestInfo location = HitTest(e.X, e.Y); + + bool alignToRight = isRightToLeft(); + + // We need to give UI feedback when the user is resizing a column + if (gridState[GRIDSTATE_trackColResize]) + { + ColResizeMove(e); + } + + if (gridState[GRIDSTATE_trackRowResize]) + { + RowResizeMove(e); + } + + if (gridState[GRIDSTATE_trackColResize] || location.type == HitTestType.ColumnResize) + { + Cursor = Cursors.SizeWE; + return; + } + else if (gridState[GRIDSTATE_trackRowResize] || location.type == HitTestType.RowResize) + { + Cursor = Cursors.SizeNS; + return; + } + else + { + Cursor = null; + } + + if ((layout.Data.Contains(e.X, e.Y) + || (layout.RowHeadersVisible && layout.RowHeaders.Contains(e.X, e.Y)))) + { + // && (isNavigating || isEditing)) { + DataGridRow[] localGridRows = DataGridRows; + // If we are over a row, let it know about the mouse move. + int rowOver = GetRowFromY(e.Y); + // set the dragging bit: + if (lastRowSelected != -1 && !gridState[GRIDSTATE_dragging]) + { + int topRow = GetRowTop(lastRowSelected); + int bottomRow = topRow + localGridRows[lastRowSelected].Height; + int dragHeight = SystemInformation.DragSize.Height; + gridState[GRIDSTATE_dragging] = ((e.Y - topRow < dragHeight && topRow - e.Y < dragHeight) || (e.Y - bottomRow < dragHeight && bottomRow - e.Y < dragHeight)); + } + + if (rowOver > -1) + { + Point p = NormalizeToRow(e.X, e.Y, rowOver); + if (!localGridRows[rowOver].OnMouseMove(p.X, p.Y, layout.RowHeaders, alignToRight) && gridState[GRIDSTATE_dragging]) + { + // if the row did not use this, see if selection can use it + MouseButtons mouse = MouseButtons; + if (lastRowSelected != -1 && (mouse & MouseButtons.Left) == MouseButtons.Left + && !(((Control.ModifierKeys & Keys.Control) == Keys.Control) && (Control.ModifierKeys & Keys.Alt) == 0)) + { + // ResetSelection() will reset the lastRowSelected too + // + int saveLastRowSelected = lastRowSelected; + ResetSelection(); + lastRowSelected = saveLastRowSelected; + + int lowerRow = Math.Min(lastRowSelected, rowOver); + int upperRow = Math.Max(lastRowSelected, rowOver); + + DataGridRow[] rows = DataGridRows; + for (int i = lowerRow; i <= upperRow; i++) + { + rows[i].Selected = true; + numSelectedRows++; + } + } + } + } + + if (oldRow != rowOver && oldRow != -1) + { + localGridRows[oldRow].OnMouseLeft(layout.RowHeaders, alignToRight); + } + + oldRow = rowOver; + } + + // check parentRows + // + if (location.type == HitTestType.ParentRows) + { + if (parentRows != null) + { + parentRows.OnMouseMove(e.X, e.Y); + } + } + + if (location.type == HitTestType.Caption) + { + gridState[GRIDSTATE_overCaption] = true; + Rectangle captionRect = layout.Caption; + caption.MouseOver(e.X - captionRect.X, e.Y - captionRect.Y); + return; + } + else + { + if (gridState[GRIDSTATE_overCaption]) + { + gridState[GRIDSTATE_overCaption] = false; + caption.MouseLeft(); + } + } + } + + /// + /// Raises the event. + /// + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + gridState[GRIDSTATE_dragging] = false; + if (listManager == null || myGridTable == null) + { + return; + } + + if (gridState[GRIDSTATE_trackColResize]) + { + ColResizeEnd(e); + } + + if (gridState[GRIDSTATE_trackRowResize]) + { + RowResizeEnd(e); + } + + gridState[GRIDSTATE_trackColResize] = false; + gridState[GRIDSTATE_trackRowResize] = false; + + HitTestInfo ci = HitTest(e.X, e.Y); + if ((ci.type & HitTestType.Caption) == HitTestType.Caption) + { + caption.MouseUp(e.X, e.Y); + } + + // Check column headers + if (ci.type == HitTestType.ColumnHeader) + { + PropertyDescriptor prop = myGridTable.GridColumnStyles[ci.col].PropertyDescriptor; + if (prop == trackColumnHeader) + { + ColumnHeaderClicked(trackColumnHeader); + } + } + + trackColumnHeader = null; + } + + /// + /// Raises the event. + /// + protected override void OnMouseWheel(MouseEventArgs e) + { + base.OnMouseWheel(e); + + if (e is HandledMouseEventArgs) + { + if (((HandledMouseEventArgs)e).Handled) + { + // The application event handler handled the scrolling - don't do anything more. + return; + } + + ((HandledMouseEventArgs)e).Handled = true; + } + + bool wheelingDown = true; + if ((ModifierKeys & Keys.Control) != 0) + { + wheelingDown = false; + } + + if (listManager == null || myGridTable == null) + { + return; + } + + ScrollBar sb = wheelingDown ? vertScrollBar : horizScrollBar; + if (!sb.Visible) + { + return; + } + + // so we scroll. we have to know this, cause otherwise we will call EndEdit + // and that would be wrong. + gridState[GRIDSTATE_isScrolling] = true; + wheelDelta += e.Delta; + float movePerc = (float)wheelDelta / (float)NativeMethods.WHEEL_DELTA; + int move = (int)((float)SystemInformation.MouseWheelScrollLines * movePerc); + if (move != 0) + { + wheelDelta = 0; + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: OnMouseWheel move=" + move.ToString(CultureInfo.InvariantCulture)); + if (wheelingDown) + { + int newRow = firstVisibleRow - move; + newRow = Math.Max(0, Math.Min(newRow, DataGridRowsLength - numTotallyVisibleRows)); + ScrollDown(newRow - firstVisibleRow); + } + else + { + int newValue = horizScrollBar.Value + (move < 0 ? 1 : -1) * horizScrollBar.LargeChange; + HorizontalOffset = newValue; + } + } + + gridState[GRIDSTATE_isScrolling] = false; + } + + /// + /// Raises the + /// event. + /// + protected override void OnPaint(PaintEventArgs pe) + { + try + { + CheckHierarchyState(); + + if (layout.dirty) + { + ComputeLayout(); + } + + Graphics g = pe.Graphics; + + Region clipRegion = g.Clip; + if (layout.CaptionVisible) + { + caption.Paint(g, layout.Caption, isRightToLeft()); + } + + if (layout.ParentRowsVisible) + { + Debug.WriteLineIf(CompModSwitches.DataGridParents.TraceVerbose, "DataGridParents: Painting ParentRows " + layout.ParentRows.ToString()); + g.FillRectangle(SystemBrushes.AppWorkspace, layout.ParentRows); + parentRows.Paint(g, layout.ParentRows, isRightToLeft()); + } + + Rectangle gridRect = layout.Data; + if (layout.RowHeadersVisible) + { + gridRect = Rectangle.Union(gridRect, layout.RowHeaders); + } + + if (layout.ColumnHeadersVisible) + { + gridRect = Rectangle.Union(gridRect, layout.ColumnHeaders); + } + + g.SetClip(gridRect); + PaintGrid(g, gridRect); + g.Clip = clipRegion; + clipRegion.Dispose(); + PaintBorder(g, layout.ClientRectangle); + + g.FillRectangle(DefaultHeaderBackBrush, layout.ResizeBoxRect); + + base.OnPaint(pe); // raise paint event + } + catch + { + // at runtime we will rethrow the exception + if (Site == null || !Site.DesignMode) + { + throw; + } + + gridState[GRIDSTATE_exceptionInPaint] = true; + try + { + RTLAwareMessageBox.Show(null, SR.DataGridExceptionInPaint, null, MessageBoxButtons.OK, + MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0); + + if (Visible) + { + BeginUpdateInternal(); + } + + ResetParentRows(); + + Set_ListManager(null, string.Empty, true); + } + finally + { + gridState[GRIDSTATE_exceptionInPaint] = false; + if (Visible) + { + EndUpdateInternal(); + } + } + } + } + + // Since Win32 only invalidates the area that gets uncovered, + // we have to manually invalidate the old border area + /// + /// Raises the event. + /// + protected override void OnResize(EventArgs e) + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: OnResize"); + + if (layout.CaptionVisible) + { + Invalidate(layout.Caption); + } + + if (layout.ParentRowsVisible) + { + parentRows.OnResize(layout.ParentRows); + } + + int borderWidth = BorderWidth; + Rectangle right; + Rectangle bottom; + Rectangle oldClientRectangle = layout.ClientRectangle; + + right = new Rectangle(oldClientRectangle.X + oldClientRectangle.Width - borderWidth, + oldClientRectangle.Y, + borderWidth, + oldClientRectangle.Height); + bottom = new Rectangle(oldClientRectangle.X, + oldClientRectangle.Y + oldClientRectangle.Height - borderWidth, + oldClientRectangle.Width, + borderWidth); + + Rectangle newClientRectangle = ClientRectangle; + if (newClientRectangle.Width != oldClientRectangle.Width) + { + Invalidate(right); + right = new Rectangle(newClientRectangle.X + newClientRectangle.Width - borderWidth, + newClientRectangle.Y, + borderWidth, + newClientRectangle.Height); + Invalidate(right); + } + + if (newClientRectangle.Height != oldClientRectangle.Height) + { + Invalidate(bottom); + bottom = new Rectangle(newClientRectangle.X, + newClientRectangle.Y + newClientRectangle.Height - borderWidth, + newClientRectangle.Width, + borderWidth); + Invalidate(bottom); + } + + //also, invalidate the ResizeBoxRect + if (!layout.ResizeBoxRect.IsEmpty) + { + Invalidate(layout.ResizeBoxRect); + } + + layout.ClientRectangle = newClientRectangle; + + int oldFirstVisibleRow = firstVisibleRow; + base.OnResize(e); + if (isRightToLeft() || oldFirstVisibleRow != firstVisibleRow) + { + Invalidate(); + } + } + + internal void OnRowHeightChanged(DataGridRow row) + { + ClearRegionCache(); + int cy = GetRowTop(row.RowNumber); + if (cy > 0) + { + Rectangle refresh = new Rectangle + { + Y = cy, + X = layout.Inside.X, + Width = layout.Inside.Width, + Height = layout.Inside.Bottom - cy + }; + Invalidate(refresh); + } + } + + internal void ParentRowsDataChanged() + { + Debug.Assert(originalState != null, "how can we get a list changed event from another listmanager/list while not navigating"); + + // do the reset work that is done in SetDataBindings, set_DataSource, set_DataMember; + parentRows.Clear(); + caption.BackButtonActive = caption.DownButtonActive = caption.BackButtonVisible = false; + caption.SetDownButtonDirection(!layout.ParentRowsVisible); + object dSource = originalState.DataSource; + string dMember = originalState.DataMember; + // we don't need to set the GRIDSTATE_metaDataChanged bit, cause + // the listManager from the originalState should be different from the current listManager + // + // set the originalState to null so that Set_ListManager knows that + // it has to unhook the MetaDataChanged events + originalState = null; + Set_ListManager(dSource, dMember, true); + } + + // =------------------------------------------------------------------ + // = Methods + // =------------------------------------------------------------------ + + private void AbortEdit() + { + Debug.WriteLineIf(CompModSwitches.DataGridEditing.TraceVerbose, "DataGridEditing: \t! AbortEdit"); + + // the same rules from editColumn.OnEdit + // while changing the editControl's visibility, do not + // PerformLayout on the entire DataGrid + gridState[GRIDSTATE_editControlChanging] = true; + + editColumn.Abort(editRow.RowNumber); + + // reset the editControl flag: + gridState[GRIDSTATE_editControlChanging] = false; + + gridState[GRIDSTATE_isEditing] = false; + editRow = null; + editColumn = null; + } + + /// + /// Occurs when the user navigates to a new table. + /// + [SRCategory(nameof(SR.CatAction)), SRDescription(nameof(SR.DataGridNavigateEventDescr))] + public event NavigateEventHandler Navigate + { + add => onNavigate += value; + remove => onNavigate -= value; + } + + /// + /// Occurs when a row header is clicked. + /// + protected event EventHandler RowHeaderClick + { + add => onRowHeaderClick += value; + remove => onRowHeaderClick -= value; + } + + /// + /// Adds an event handler for the 'System.Windows.Forms.DataGrid.OnNodeClick' + /// event. + /// + [SRCategory(nameof(SR.CatAction)), SRDescription(nameof(SR.DataGridNodeClickEventDescr))] + internal event EventHandler NodeClick + { + add => Events.AddHandler(EVENT_NODECLICKED, value); + remove => Events.RemoveHandler(EVENT_NODECLICKED, value); + } + + /// + /// Occurs when the user scrolls the control. + /// + [SRCategory(nameof(SR.CatAction)), SRDescription(nameof(SR.DataGridScrollEventDescr))] + public event EventHandler Scroll + { + add => Events.AddHandler(EVENT_SCROLL, value); + remove => Events.RemoveHandler(EVENT_SCROLL, value); + } + + public override ISite Site + { + get + { + return base.Site; + } + set + { + ISite temp = Site; + base.Site = value; + if (value != temp && !Disposing) + { + // we should site the tables and the columns + // only when our site changes + SubObjectsSiteChange(false); + SubObjectsSiteChange(true); + } + } + } + + internal void AddNewRow() + { + EnsureBound(); + ResetSelection(); + // EndEdit(); + UpdateListManager(); + gridState[GRIDSTATE_inListAddNew] = true; + gridState[GRIDSTATE_inAddNewRow] = true; + try + { + ListManager.AddNew(); + } + catch + { + gridState[GRIDSTATE_inListAddNew] = false; + gridState[GRIDSTATE_inAddNewRow] = false; + PerformLayout(); + InvalidateInside(); + throw; + } + + gridState[GRIDSTATE_inListAddNew] = false; + } + + /// + /// Attempts to + /// put the grid into a state where editing is + /// allowed. + /// + public bool BeginEdit(DataGridColumnStyle gridColumn, int rowNumber) + { + if (DataSource == null || myGridTable == null) + { + return false; + } + + // We deny edit requests if we are already editing a cell. + if (gridState[GRIDSTATE_isEditing]) + { + return false; + } + else + { + int col = -1; + if ((col = myGridTable.GridColumnStyles.IndexOf(gridColumn)) < 0) + { + return false; + } + + CurrentCell = new DataGridCell(rowNumber, col); + ResetSelection(); + Edit(); + return true; + } + } + + /// + /// Specifies the beginning of the initialization code. + /// + public void BeginInit() + { + if (inInit) + { + throw new InvalidOperationException(SR.DataGridBeginInit); + } + + inInit = true; + } + + private Rectangle CalcRowResizeFeedbackRect(MouseEventArgs e) + { + Rectangle inside = layout.Data; + Rectangle r = new Rectangle(inside.X, e.Y, inside.Width, 3); + r.Y = Math.Min(inside.Bottom - 3, r.Y); + r.Y = Math.Max(r.Y, 0); + return r; + } + + private Rectangle CalcColResizeFeedbackRect(MouseEventArgs e) + { + Rectangle inside = layout.Data; + Rectangle r = new Rectangle(e.X, inside.Y, 3, inside.Height); + r.X = Math.Min(inside.Right - 3, r.X); + r.X = Math.Max(r.X, 0); + return r; + } + + private void CancelCursorUpdate() + { + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: Requesting CancelEdit()"); + if (listManager != null) + { + EndEdit(); + listManager.CancelCurrentEdit(); + } + } + + private void CheckHierarchyState() + { + if (checkHierarchy && listManager != null && myGridTable != null) + { + if (myGridTable == null) + { + // there was nothing to check + return; + } + + for (int j = 0; j < myGridTable.GridColumnStyles.Count; j++) + { + DataGridColumnStyle gridColumn = myGridTable.GridColumnStyles[j]; + } + + checkHierarchy = false; + } + } + + /// + /// The DataGrid caches an array of rectangular areas + /// which represent the area which scrolls left to right. + /// This method is invoked whenever the DataGrid's + /// scrollable regions change in such a way as to require + /// a re-recalculation. + /// + private void ClearRegionCache() + { + cachedScrollableRegion = null; + } + + /// + /// Determines the best fit size for the given column. + /// + private void ColAutoResize(int col) + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: ColAutoResize"); + EndEdit(); + CurrencyManager listManager = this.listManager; + if (listManager == null) + { + return; + } + + int size; + Graphics g = CreateGraphicsInternal(); + try + { + DataGridColumnStyle column = myGridTable.GridColumnStyles[col]; + string columnName = column.HeaderText; + + Font headerFont; + if (myGridTable.IsDefault) + { + headerFont = HeaderFont; + } + else + { + headerFont = myGridTable.HeaderFont; + } + + size = (int)g.MeasureString(columnName, headerFont).Width + layout.ColumnHeaders.Height + 1; // The sort triangle's width is equal to it's height + int rowCount = listManager.Count; + for (int row = 0; row < rowCount; ++row) + { + object value = column.GetColumnValueAtRow(listManager, row); + int width = column.GetPreferredSize(g, value).Width; + if (width > size) + { + size = width; + } + } + + if (column.Width != size) + { + column._width = size; + + ComputeVisibleColumns(); + + bool lastColumnIsLastTotallyVisibleCol = true; + if (lastTotallyVisibleCol != -1) + { + for (int i = lastTotallyVisibleCol + 1; i < myGridTable.GridColumnStyles.Count; i++) + { + if (myGridTable.GridColumnStyles[i].PropertyDescriptor != null) + { + lastColumnIsLastTotallyVisibleCol = false; + break; + } + } + } + else + { + lastColumnIsLastTotallyVisibleCol = false; + } + + // if the column shrank and the last totally visible column was the last column + // then we need to recompute the horizontalOffset, firstVisibleCol, negOffset. + // lastTotallyVisibleCol remains the last column + if (lastColumnIsLastTotallyVisibleCol && + (negOffset != 0 || horizontalOffset != 0)) + { + // update the column width + column._width = size; + + int cx = 0; + int colCount = myGridTable.GridColumnStyles.Count; + int visibleWidth = layout.Data.Width; + GridColumnStylesCollection cols = myGridTable.GridColumnStyles; + + // assume everything fits + negOffset = 0; + horizontalOffset = 0; + firstVisibleCol = 0; + + for (int i = colCount - 1; i >= 0; i--) + { + if (cols[i].PropertyDescriptor == null) + { + continue; + } + + cx += cols[i].Width; + if (cx > visibleWidth) + { + if (negOffset == 0) + { + firstVisibleCol = i; + negOffset = cx - visibleWidth; + horizontalOffset = negOffset; + numVisibleCols++; + } + else + { + horizontalOffset += cols[i].Width; + } + } + else + { + numVisibleCols++; + } + } + + // refresh the horizontal scrollbar + PerformLayout(); + + // we need to invalidate the layout.Data and layout.ColumnHeaders + Invalidate(Rectangle.Union(layout.Data, layout.ColumnHeaders)); + } + else + { + // need to refresh the scroll bar + PerformLayout(); + + Rectangle rightArea = layout.Data; + if (layout.ColumnHeadersVisible) + { + rightArea = Rectangle.Union(rightArea, layout.ColumnHeaders); + } + + int left = GetColBeg(col); + + if (!isRightToLeft()) + { + rightArea.Width -= left - rightArea.X; + rightArea.X = left; + } + else + { + rightArea.Width -= left; + } + + Invalidate(rightArea); + } + } + } + finally + { + g.Dispose(); + } + + if (horizScrollBar.Visible) + { + horizScrollBar.Value = HorizontalOffset; + } + + // OnColumnResize(EventArgs.Empty); + } + + /// + /// Collapses child relations, if any exist for all rows, or for a + /// specified row. + /// + public void Collapse(int row) + { + SetRowExpansionState(row, false); + } + + private void ColResizeBegin(MouseEventArgs e, int col) + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: ColResizeBegin"); + Debug.Assert(myGridTable != null, "Column resizing operations can't be called when myGridTable == null."); + + int x = e.X; + EndEdit(); + Rectangle clip = Rectangle.Union(layout.ColumnHeaders, layout.Data); + if (isRightToLeft()) + { + clip.Width = GetColBeg(col) - layout.Data.X - 2; + } + else + { + int leftEdge = GetColBeg(col); + clip.X = leftEdge + 3; + clip.Width = layout.Data.X + layout.Data.Width - leftEdge - 2; + } + + Capture = true; + Cursor.Clip = RectangleToScreen(clip); + gridState[GRIDSTATE_trackColResize] = true; + trackColAnchor = x; + trackColumn = col; + + DrawColSplitBar(e); + lastSplitBar = e; + } + + private void ColResizeMove(MouseEventArgs e) + { + if (lastSplitBar != null) + { + DrawColSplitBar(lastSplitBar); + lastSplitBar = e; + } + + DrawColSplitBar(e); + } + + private void ColResizeEnd(MouseEventArgs e) + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: ColResizeEnd"); + Debug.Assert(myGridTable != null, "Column resizing operations can't be called when myGridTable == null."); + + gridState[GRIDSTATE_layoutSuspended] = true; + try + { + if (lastSplitBar != null) + { + DrawColSplitBar(lastSplitBar); + lastSplitBar = null; + } + + bool rightToLeft = isRightToLeft(); + + int x = rightToLeft ? Math.Max(e.X, layout.Data.X) : Math.Min(e.X, layout.Data.Right + 1); + int delta = x - GetColEnd(trackColumn); + if (rightToLeft) + { + delta = -delta; + } + + if (trackColAnchor != x && delta != 0) + { + DataGridColumnStyle column = myGridTable.GridColumnStyles[trackColumn]; + int proposed = column.Width + delta; + proposed = Math.Max(proposed, 3); + column.Width = proposed; + + // refresh scrolling data: horizontalOffset, negOffset, firstVisibleCol, numVisibleCols, lastTotallyVisibleCol + ComputeVisibleColumns(); + + bool lastColumnIsLastTotallyVisibleCol = true; + for (int i = lastTotallyVisibleCol + 1; i < myGridTable.GridColumnStyles.Count; i++) + { + if (myGridTable.GridColumnStyles[i].PropertyDescriptor != null) + { + lastColumnIsLastTotallyVisibleCol = false; + break; + } + } + + if (lastColumnIsLastTotallyVisibleCol && + (negOffset != 0 || horizontalOffset != 0)) + { + int cx = 0; + int colCount = myGridTable.GridColumnStyles.Count; + int visibleWidth = layout.Data.Width; + GridColumnStylesCollection cols = myGridTable.GridColumnStyles; + + // assume everything fits + negOffset = 0; + horizontalOffset = 0; + firstVisibleCol = 0; + + for (int i = colCount - 1; i > -1; i--) + { + if (cols[i].PropertyDescriptor == null) + { + continue; + } + + cx += cols[i].Width; + + if (cx > visibleWidth) + { + if (negOffset == 0) + { + negOffset = cx - visibleWidth; + firstVisibleCol = i; + horizontalOffset = negOffset; + numVisibleCols++; + } + else + { + horizontalOffset += cols[i].Width; + } + } + else + { + numVisibleCols++; + } + } + + // and invalidate pretty much everything + Invalidate(Rectangle.Union(layout.Data, layout.ColumnHeaders)); + } + else + { + Rectangle rightArea = Rectangle.Union(layout.ColumnHeaders, layout.Data); + int left = GetColBeg(trackColumn); + rightArea.Width -= rightToLeft ? rightArea.Right - left : left - rightArea.X; + rightArea.X = rightToLeft ? layout.Data.X : left; + Invalidate(rightArea); + } + } + } + finally + { + Cursor.Clip = Rectangle.Empty; + Capture = false; + gridState[GRIDSTATE_layoutSuspended] = false; + } + + PerformLayout(); + + if (horizScrollBar.Visible) + { + horizScrollBar.Value = HorizontalOffset; + } + + // OnColumnResize(EventArgs.Empty); + } + + private void MetaDataChanged() + { + // when we reset the Binding in the grid, we need to clear the parent rows. + // the same goes for all the caption UI: reset it when the datasource changes. + // + parentRows.Clear(); + caption.BackButtonActive = caption.DownButtonActive = caption.BackButtonVisible = false; + caption.SetDownButtonDirection(!layout.ParentRowsVisible); + + gridState[GRIDSTATE_metaDataChanged] = true; + try + { + if (originalState != null) + { + // set the originalState to null so that Set_ListManager knows that + // it has to unhook the MetaDataChanged events + Set_ListManager(originalState.DataSource, originalState.DataMember, true); + originalState = null; + } + else + { + Set_ListManager(DataSource, DataMember, true); + } + } + finally + { + gridState[GRIDSTATE_metaDataChanged] = false; + } + } + + // =------------------------------------------------------------------ + // = Functions to resize rows + // =------------------------------------------------------------------ + + // will autoResize "row" + private void RowAutoResize(int row) + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: RowAutoResize"); + + EndEdit(); + CurrencyManager listManager = ListManager; + if (listManager == null) + { + return; + } + + Graphics g = CreateGraphicsInternal(); + try + { + GridColumnStylesCollection columns = myGridTable.GridColumnStyles; + DataGridRow resizeRow = DataGridRows[row]; + int rowCount = listManager.Count; + int resizeHeight = 0; + + // compute the height that we should resize to: + int columnsCount = columns.Count; + for (int col = 0; col < columnsCount; col++) + { + object value = columns[col].GetColumnValueAtRow(listManager, row); + resizeHeight = Math.Max(resizeHeight, columns[col].GetPreferredHeight(g, value)); + } + + if (resizeRow.Height != resizeHeight) + { + resizeRow.Height = resizeHeight; + + // needed to refresh scrollbar properties + PerformLayout(); + + Rectangle rightArea = layout.Data; + if (layout.RowHeadersVisible) + { + rightArea = Rectangle.Union(rightArea, layout.RowHeaders); + } + + int top = GetRowTop(row); + rightArea.Height -= rightArea.Y - top; + rightArea.Y = top; + Invalidate(rightArea); + } + } + finally + { + g.Dispose(); + } + + // OnRowResize(EventArgs.Empty); + return; + } + + private void RowResizeBegin(MouseEventArgs e, int row) + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: RowResizeBegin"); + Debug.Assert(myGridTable != null, "Row resizing operations can't be called when myGridTable == null."); + + int y = e.Y; + EndEdit(); + Rectangle clip = Rectangle.Union(layout.RowHeaders, layout.Data); + int topEdge = GetRowTop(row); + clip.Y = topEdge + 3; + clip.Height = layout.Data.Y + layout.Data.Height - topEdge - 2; + + Capture = true; + Cursor.Clip = RectangleToScreen(clip); + gridState[GRIDSTATE_trackRowResize] = true; + trackRowAnchor = y; + trackRow = row; + + DrawRowSplitBar(e); + lastSplitBar = e; + } + + private void RowResizeMove(MouseEventArgs e) + { + if (lastSplitBar != null) + { + DrawRowSplitBar(lastSplitBar); + lastSplitBar = e; + } + + DrawRowSplitBar(e); + } + + private void RowResizeEnd(MouseEventArgs e) + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: RowResizeEnd"); + Debug.Assert(myGridTable != null, "Row resizing operations can't be called when myGridTable == null."); + + try + { + if (lastSplitBar != null) + { + DrawRowSplitBar(lastSplitBar); + lastSplitBar = null; + } + + int y = Math.Min(e.Y, layout.Data.Y + layout.Data.Height + 1); + int delta = y - GetRowBottom(trackRow); + if (trackRowAnchor != y && delta != 0) + { + DataGridRow row = DataGridRows[trackRow]; + int proposed = row.Height + delta; + proposed = Math.Max(proposed, 3); + row.Height = proposed; + + // needed to refresh scrollbar properties + PerformLayout(); + + Rectangle rightArea = Rectangle.Union(layout.RowHeaders, layout.Data); + int top = GetRowTop(trackRow); + rightArea.Height -= rightArea.Y - top; + rightArea.Y = top; + Invalidate(rightArea); + } + } + finally + { + Cursor.Clip = Rectangle.Empty; + Capture = false; + } + + // OnRowResize(EventArgs.Empty); + } + + /// + /// Fires the ColumnHeaderClicked event and handles column + /// sorting. + /// + private void ColumnHeaderClicked(PropertyDescriptor prop) + { + if (!CommitEdit()) + { + return; + } + + // OnColumnHeaderClick(EventArgs.Empty); + bool allowSorting; + if (myGridTable.IsDefault) + { + allowSorting = AllowSorting; + } + else + { + allowSorting = myGridTable.AllowSorting; + } + + if (!allowSorting) + { + return; + } + + // if (CompModSwitches.DataGridCursor.OutputVerbose) Debug.WriteLine("DataGridCursor: We are about to sort column " + col.ToString()); + ListSortDirection direction = ListManager.GetSortDirection(); + PropertyDescriptor sortColumn = ListManager.GetSortProperty(); + if (sortColumn != null && sortColumn.Equals(prop)) + { + direction = (direction == ListSortDirection.Ascending) ? ListSortDirection.Descending : ListSortDirection.Ascending; + } + else + { + // defaultSortDirection : ascending + direction = ListSortDirection.Ascending; + } + + if (listManager.Count == 0) + { + return; + } + + ListManager.SetSort(prop, direction); + ResetSelection(); + + InvalidateInside(); + } + + /// + /// Attempts to commit editing if a cell is being edited. + /// Return true if successfully commited editing. + /// Return false if editing can not be completed and the gird must + /// remain in our current Edit state. + /// + private bool CommitEdit() + { + Debug.WriteLineIf(CompModSwitches.DataGridEditing.TraceVerbose, "DataGridEditing: \t CommitEdit " + (editRow == null ? "" : editRow.RowNumber.ToString(CultureInfo.InvariantCulture))); + + // we want to commit the editing if + // 1. the user was editing or navigating around the data grid and + // 2. this is not the result of moving focus inside the data grid and + // 3. if the user was scrolling +#pragma warning disable SA1408 // Conditional expressions should declare precedence + if (!gridState[GRIDSTATE_isEditing] && !gridState[GRIDSTATE_isNavigating] || (gridState[GRIDSTATE_editControlChanging] && !gridState[GRIDSTATE_isScrolling])) +#pragma warning restore SA1408 // Conditional expressions should declare precedence + { + return true; + } + + // the same rules from editColumn.OnEdit + // flag that we are editing the Edit control, so if we get a OnLayout on the + // datagrid side of things while the edit control changes its visibility and bounds + // the datagrid does not perform a layout + gridState[GRIDSTATE_editControlChanging] = true; + + if ((editColumn != null && editColumn.ReadOnly) || gridState[GRIDSTATE_inAddNewRow]) + { + bool focusTheGrid = false; + if (ContainsFocus) + { + focusTheGrid = true; + } + + if (focusTheGrid && gridState[GRIDSTATE_canFocus]) + { + Focus(); + } + + editColumn.ConcedeFocus(); + + // set the focus back to the grid + if (focusTheGrid && gridState[GRIDSTATE_canFocus] && CanFocus && !Focused) + { + Focus(); + } + + // reset the editControl flag + gridState[GRIDSTATE_editControlChanging] = false; + return true; + } + + bool retVal = editColumn?.Commit(ListManager, currentRow) ?? true; + + // reset the editControl flag + gridState[GRIDSTATE_editControlChanging] = false; + + if (retVal) + { + gridState[GRIDSTATE_isEditing] = false; + } + + return retVal; + } + + /// + /// Figure out how many rows we need to scroll down + /// to move targetRow into visibility. + /// + private int ComputeDeltaRows(int targetRow) + { + //Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "DataGridScrolling: ComputeDeltaRows, firstVisibleRow = " + // + firstVisibleRow.ToString() + ", " + // + "targetRow = " + targetRow.ToString()); + + if (firstVisibleRow == targetRow) + { + return 0; + } + + int dRows = 0; + int firstVisibleRowLogicalTop = -1; + int targetRowLogicalTop = -1; + int nRows = DataGridRowsLength; + int cy = 0; + DataGridRow[] localGridRows = DataGridRows; + + for (int row = 0; row < nRows; ++row) + { + if (row == firstVisibleRow) + { + firstVisibleRowLogicalTop = cy; + } + + if (row == targetRow) + { + targetRowLogicalTop = cy; + } + + if (targetRowLogicalTop != -1 && firstVisibleRowLogicalTop != -1) + { + break; + } + + cy += localGridRows[row].Height; + } + + int targetRowLogicalBottom = targetRowLogicalTop + localGridRows[targetRow].Height; + int dataLogicalBottom = layout.Data.Height + firstVisibleRowLogicalTop; + if (targetRowLogicalBottom > dataLogicalBottom) + { + // we need to move down. + int downDelta = targetRowLogicalBottom - dataLogicalBottom; + firstVisibleRowLogicalTop += downDelta; + } + else if (firstVisibleRowLogicalTop < targetRowLogicalTop) + { + // we don't need to move + return 0; + } + else + { + // we need to move up. + int upDelta = firstVisibleRowLogicalTop - targetRowLogicalTop; + firstVisibleRowLogicalTop -= upDelta; + } + + int newFirstRow = ComputeFirstVisibleRow(firstVisibleRowLogicalTop); + dRows = (newFirstRow - firstVisibleRow); + //Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "DataGridScrolling: ComputeDeltaRows returning " + dRows.ToString()); + return dRows; + } + + /// + /// Given the a logical vertical offset, figure out + /// which row number should be the first fully visible + /// row on or after the offset. + /// + private int ComputeFirstVisibleRow(int firstVisibleRowLogicalTop) + { + int first; + int nRows = DataGridRowsLength; + int cy = 0; + DataGridRow[] localGridRows = DataGridRows; + for (first = 0; first < nRows; ++first) + { + if (cy >= firstVisibleRowLogicalTop) + { + break; + } + + cy += localGridRows[first].Height; + } + + return first; + } + + /// + /// Constructs an updated Layout object. + /// + private void ComputeLayout() + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: ComputeLayout"); + + bool alignLeft = !isRightToLeft(); + Rectangle oldResizeRect = layout.ResizeBoxRect; + + // hide the EditBox + EndEdit(); + + ClearRegionCache(); + + // NOTE : Since Rectangles are structs, then assignment is a + // : copy. Therefore, after saying "Rectangle inside = newLayout.Inside", + // : we must always assign back to newLayout.Inside. + // + + // Important since all of the visibility flags will move + // to the new layout here. + LayoutData newLayout = new LayoutData(layout) + { + // Inside + Inside = ClientRectangle + }; + Rectangle inside = newLayout.Inside; + int borderWidth = BorderWidth; + inside.Inflate(-borderWidth, -borderWidth); + + Rectangle insideLeft = inside; + + // Caption + if (layout.CaptionVisible) + { + int captionHeight = captionFontHeight + 6; + Rectangle cap = newLayout.Caption; + cap = insideLeft; + cap.Height = captionHeight; + insideLeft.Y += captionHeight; + insideLeft.Height -= captionHeight; + + newLayout.Caption = cap; + } + else + { + newLayout.Caption = Rectangle.Empty; + } + + // Parent Rows + if (layout.ParentRowsVisible) + { + Rectangle parents = newLayout.ParentRows; + int parentHeight = parentRows.Height; + parents = insideLeft; + parents.Height = parentHeight; + insideLeft.Y += parentHeight; + insideLeft.Height -= parentHeight; + + newLayout.ParentRows = parents; + } + else + { + newLayout.ParentRows = Rectangle.Empty; + } + + // Headers + // + int columnHeaderHeight = headerFontHeight + 6; + if (layout.ColumnHeadersVisible) + { + Rectangle colHeaders = newLayout.ColumnHeaders; + colHeaders = insideLeft; + colHeaders.Height = columnHeaderHeight; + insideLeft.Y += columnHeaderHeight; + insideLeft.Height -= columnHeaderHeight; + + newLayout.ColumnHeaders = colHeaders; + } + else + { + newLayout.ColumnHeaders = Rectangle.Empty; + } + + bool newRowHeadersVisible = myGridTable.IsDefault ? RowHeadersVisible : myGridTable.RowHeadersVisible; + int newRowHeaderWidth = myGridTable.IsDefault ? RowHeaderWidth : myGridTable.RowHeaderWidth; + newLayout.RowHeadersVisible = newRowHeadersVisible; + if (myGridTable != null && newRowHeadersVisible) + { + Rectangle rowHeaders = newLayout.RowHeaders; + if (alignLeft) + { + rowHeaders = insideLeft; + rowHeaders.Width = newRowHeaderWidth; + insideLeft.X += newRowHeaderWidth; + insideLeft.Width -= newRowHeaderWidth; + } + else + { + rowHeaders = insideLeft; + rowHeaders.Width = newRowHeaderWidth; + rowHeaders.X = insideLeft.Right - newRowHeaderWidth; + insideLeft.Width -= newRowHeaderWidth; + } + + newLayout.RowHeaders = rowHeaders; + + if (layout.ColumnHeadersVisible) + { + Rectangle topLeft = newLayout.TopLeftHeader; + Rectangle colHeaders = newLayout.ColumnHeaders; + if (alignLeft) + { + topLeft = colHeaders; + topLeft.Width = newRowHeaderWidth; + colHeaders.Width -= newRowHeaderWidth; + colHeaders.X += newRowHeaderWidth; + } + else + { + topLeft = colHeaders; + topLeft.Width = newRowHeaderWidth; + topLeft.X = colHeaders.Right - newRowHeaderWidth; + colHeaders.Width -= newRowHeaderWidth; + } + + newLayout.TopLeftHeader = topLeft; + newLayout.ColumnHeaders = colHeaders; + } + else + { + newLayout.TopLeftHeader = Rectangle.Empty; + } + } + else + { + newLayout.RowHeaders = Rectangle.Empty; + newLayout.TopLeftHeader = Rectangle.Empty; + } + + // The Data region + newLayout.Data = insideLeft; + newLayout.Inside = inside; + + layout = newLayout; + + LayoutScrollBars(); + + // if the user shrank the grid client area, then OnResize invalidated the old + // resize area. however, we need to invalidate the left upper corner in the new ResizeArea + // note that we can't take the Invalidate call from the OnResize method, because if the + // user enlarges the form then the old area will not be invalidated. + // + if (!oldResizeRect.Equals(layout.ResizeBoxRect) && !layout.ResizeBoxRect.IsEmpty) + { + Invalidate(layout.ResizeBoxRect); + } + + layout.dirty = false; + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: " + layout.ToString()); + } + + /// + /// Computes the number of pixels to scroll to scroll from one + /// row to another. + /// + private int ComputeRowDelta(int from, int to) + { + int first = from; + int last = to; + int sign = -1; + if (first > last) + { + first = to; + last = from; + sign = 1; + } + + DataGridRow[] localGridRows = DataGridRows; + int delta = 0; + for (int row = first; row < last; ++row) + { + delta += localGridRows[row].Height; + } + + return sign * delta; + } + + internal int MinimumRowHeaderWidth() + { + return minRowHeaderWidth; + } + + internal void ComputeMinimumRowHeaderWidth() + { + minRowHeaderWidth = errorRowBitmapWidth; // the size of the pencil, star and row selector images are the same as the image for the error bitmap + if (ListHasErrors) + { + minRowHeaderWidth += errorRowBitmapWidth; + } + + if (myGridTable != null && myGridTable.RelationsList.Count != 0) + { + minRowHeaderWidth += 15; // the size of the plus/minus glyph and spacing around it + } + } + + /// + /// Updates the internal variables with the number of columns visible + /// inside the Grid's client rectangle. + /// + private void ComputeVisibleColumns() + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: ComputeVisibleColumns"); + EnsureBound(); + + GridColumnStylesCollection columns = myGridTable.GridColumnStyles; + + int nGridCols = columns.Count; + int cx = -negOffset; + int visibleColumns = 0; + int visibleWidth = layout.Data.Width; + int curCol = firstVisibleCol; + + // the same problem with negative numbers: + // if the width passed in is negative, then return 0 + // + // added the check for the columns.Count == 0 + // + if (visibleWidth < 0 || columns.Count == 0) + { + numVisibleCols = firstVisibleCol = 0; + lastTotallyVisibleCol = -1; + return; + } + + while (cx < visibleWidth && curCol < nGridCols) + { + // if (columns.Visible && columns.PropertyDescriptor != null) + if (columns[curCol].PropertyDescriptor != null) + { + cx += columns[curCol].Width; + } + + curCol++; + visibleColumns++; + } + + numVisibleCols = visibleColumns; + + // if we inflate the data area + // then we paint columns to the left of firstVisibleColumn + if (cx < visibleWidth) + { + for (int i = firstVisibleCol - 1; i > 0; i--) + { + if (cx + columns[i].Width > visibleWidth) + { + break; + } + + // if (columns.Visible && columns.PropertyDescriptor != null) + if (columns[i].PropertyDescriptor != null) + { + cx += columns[i].Width; + } + + visibleColumns++; + firstVisibleCol--; + } + + if (numVisibleCols != visibleColumns) + { + Debug.Assert(numVisibleCols < visibleColumns, "the number of visible columns can only grow"); + // is there space for more columns than were visible? + // if so, then we need to repaint Data and ColumnHeaders + Invalidate(layout.Data); + Invalidate(layout.ColumnHeaders); + + // update the number of visible columns to the new reality + numVisibleCols = visibleColumns; + } + } + + lastTotallyVisibleCol = firstVisibleCol + numVisibleCols - 1; + if (cx > visibleWidth) + { + if (numVisibleCols <= 1 || (numVisibleCols == 2 && negOffset != 0)) + { + // no column is entirely visible + lastTotallyVisibleCol = -1; + } + else + { + lastTotallyVisibleCol--; + } + } + } + + /// + /// Determines which column is the first visible given + /// the object's horizontalOffset. + /// + private int ComputeFirstVisibleColumn() + { + int first = 0; + if (horizontalOffset == 0) + { + negOffset = 0; + return 0; + } + + // we will check to see if myGridTables.GridColumns.Count != 0 + // because when we reset the dataGridTable, we don't have any columns, and we still + // call HorizontalOffset = 0, and that will call ComputeFirstVisibleColumn with an empty collection of columns. + if (myGridTable != null && myGridTable.GridColumnStyles != null && myGridTable.GridColumnStyles.Count != 0) + { + GridColumnStylesCollection columns = myGridTable.GridColumnStyles; + int cx = 0; + int nGridCols = columns.Count; + + if (columns[0].Width == -1) + { + // the columns are not initialized yet + // +#if DEBUG + for (int i = 0; i < nGridCols; i++) + { + Debug.Assert(columns[i].Width == -1, "the columns' widths should not be initialized"); + } +#endif // DEBUG + negOffset = 0; + return 0; + } + + for (first = 0; first < nGridCols; first++) + { + // if (columns[first].Visible && columns[first].PropertyDescriptor != null); + if (columns[first].PropertyDescriptor != null) + { + cx += columns[first].Width; + } + + if (cx > horizontalOffset) + { + break; + } + } + + // first may actually be the number of columns + // in that case all the columns fit in the layout data + if (first == nGridCols) + { + Debug.Assert(cx <= horizontalOffset, "look at the for loop before: we only exit that loop early if the cx is over the horizontal offset"); + negOffset = 0; + return 0; + } + + negOffset = columns[first].Width - (cx - horizontalOffset); + //Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "DataGridScrolling: ComputeFirstVisibleColumn, ret = " + first.ToString() + ", negOffset = " + negOffset.ToString()); + } + + return first; + } + + /// + /// Updates the internal variables with the number of rows visible + /// in a given DataGrid Layout. + /// + private void ComputeVisibleRows() + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: ComputeVisibleRows"); + EnsureBound(); + + Rectangle data = layout.Data; + int visibleHeight = data.Height; + int cy = 0; + int visibleRows = 0; + DataGridRow[] localGridRows = DataGridRows; + int numRows = DataGridRowsLength; + + // when minimizing the dataGrid window, we will get negative values for the + // layout.Data.Width and layout.Data.Height ( is this a + + if (visibleHeight < 0) + { + numVisibleRows = numTotallyVisibleRows = 0; + return; + } + + for (int i = firstVisibleRow; i < numRows; ++i) + { + if (cy > visibleHeight) + { + break; + } + + cy += localGridRows[i].Height; + visibleRows++; + } + + if (cy < visibleHeight) + { + for (int i = firstVisibleRow - 1; i >= 0; i--) + { + int height = localGridRows[i].Height; + if (cy + height > visibleHeight) + { + break; + } + + cy += height; + firstVisibleRow--; + visibleRows++; + } + } + + numVisibleRows = numTotallyVisibleRows = visibleRows; + if (cy > visibleHeight) + { + numTotallyVisibleRows--; + } + + Debug.Assert(numVisibleRows >= 0, "the number of visible rows can't be negative"); + Debug.Assert(numTotallyVisibleRows >= 0, "the number of totally visible rows can't be negative"); + } + + /// + /// Constructs the new instance of the accessibility object for this control. Subclasses + /// should not call base.CreateAccessibilityObject. + /// + protected override AccessibleObject CreateAccessibilityInstance() + { + return new DataGridAccessibleObject(this); + } + + /// + /// Creates a DataGridState representing the child table retrieved + /// from the passed DataRelation. + /// + private DataGridState CreateChildState(string relationName, DataGridRow source) + { + DataGridState dgs = new DataGridState(); + + string newDataMember; + if (string.IsNullOrEmpty(DataMember)) + { + newDataMember = relationName; + } + else + { + newDataMember = DataMember + "." + relationName; + } + + CurrencyManager childLM = (CurrencyManager)BindingContext[DataSource, newDataMember]; + + dgs.DataSource = DataSource; + dgs.DataMember = newDataMember; + dgs.ListManager = childLM; + + dgs.DataGridRows = null; + dgs.DataGridRowsLength = childLM.Count + (policy.AllowAdd ? 1 : 0); + + return dgs; + } + + /// + /// Constructs a Layout object containing the state + /// for a newly constructed DataGrid. + /// + private LayoutData CreateInitialLayoutState() + { + Debug.WriteLineIf(CompModSwitches.DataGridLayout.TraceVerbose, "DataGridLayout: CreateInitialLayoutState"); + LayoutData newLayout = new LayoutData + { + Inside = new Rectangle(), + TopLeftHeader = new Rectangle(), + ColumnHeaders = new Rectangle(), + RowHeaders = new Rectangle(), + Data = new Rectangle(), + Caption = new Rectangle(), + ParentRows = new Rectangle(), + ResizeBoxRect = new Rectangle(), + ColumnHeadersVisible = true, + RowHeadersVisible = true, + CaptionVisible = defaultCaptionVisible, + ParentRowsVisible = defaultParentRowsVisible, + ClientRectangle = ClientRectangle + }; + return newLayout; + } + + /// + /// The DataGrid caches an array of rectangular areas + /// which represent the area which scrolls left to right. + /// This method is invoked whenever the DataGrid needs + /// this scrollable region. + /// + private RECT[] CreateScrollableRegion(Rectangle scroll) + { + if (cachedScrollableRegion != null) + { + return cachedScrollableRegion; + } + + bool alignToRight = isRightToLeft(); + + using (Region region = new Region(scroll)) + { + int nRows = numVisibleRows; + int cy = layout.Data.Y; + int cx = layout.Data.X; + DataGridRow[] localGridRows = DataGridRows; + for (int r = firstVisibleRow; r < nRows; r++) + { + int rowHeight = localGridRows[r].Height; + Rectangle rowExclude = localGridRows[r].GetNonScrollableArea(); + rowExclude.X += cx; + rowExclude.X = MirrorRectangle(rowExclude, layout.Data, alignToRight); + if (!rowExclude.IsEmpty) + { + region.Exclude(new Rectangle(rowExclude.X, + rowExclude.Y + cy, + rowExclude.Width, + rowExclude.Height)); + } + + cy += rowHeight; + } + + using (Graphics graphics = CreateGraphicsInternal()) + { + Gdi32.HRGN hrgn = default; + hrgn = (Gdi32.HRGN)region.GetHrgn(graphics); + + if (!hrgn.IsNull) + { + cachedScrollableRegion = hrgn.GetRegionRects(); + region.ReleaseHrgn((IntPtr)hrgn); + } + } + } + + return cachedScrollableRegion; + } + + /// + /// Disposes of the resources (other than memory) used + /// by the . + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (vertScrollBar != null) + { + vertScrollBar.Dispose(); + } + + if (horizScrollBar != null) + { + horizScrollBar.Dispose(); + } + + if (toBeDisposedEditingControl != null) + { + toBeDisposedEditingControl.Dispose(); + toBeDisposedEditingControl = null; + } + + GridTableStylesCollection tables = TableStyles; + if (tables != null) + { +#if DEBUG + Debug.Assert(myGridTable == null || myGridTable.IsDefault || tables.Contains(myGridTable), "how come that the currentTable is not in the list of tables?"); +#endif // DEBUG + for (int i = 0; i < tables.Count; i++) + { + tables[i].Dispose(); + } + } + } + + base.Dispose(disposing); + } + + /// + /// Draws an XOR region to give UI feedback for Column Resizing. + /// This looks just like the Splitter control's UI when resizing. + /// + private void DrawColSplitBar(MouseEventArgs e) + { + Rectangle r = CalcColResizeFeedbackRect(e); + DrawSplitBar(r); + } + + /// + /// Draws an XOR region to give UI feedback for Row Resizing. + /// This looks just like the Splitter control's UI when resizing. + /// + private void DrawRowSplitBar(MouseEventArgs e) + { + Rectangle r = CalcRowResizeFeedbackRect(e); + DrawSplitBar(r); + } + + /// + /// Draws an XOR region to give UI feedback for Column/Row Resizing. + /// This looks just like the Splitter control's UI when resizing. + /// + private void DrawSplitBar(Rectangle r) + { + Gdi32.HDC dc = User32.GetDCEx(this, IntPtr.Zero, User32.DCX.CACHE | User32.DCX.LOCKWINDOWUPDATE); + Gdi32.HBRUSH halftone = ControlPaint.CreateHalftoneHBRUSH2(); + Gdi32.HGDIOBJ saveBrush = Gdi32.SelectObject(dc, halftone); + Gdi32.PatBlt(dc, r.X, r.Y, r.Width, r.Height, Gdi32.ROP.PATINVERT); + Gdi32.SelectObject(dc, saveBrush); + Gdi32.DeleteObject(halftone); + User32.ReleaseDC(new HandleRef(this, Handle), dc); + } + + /// + /// Begin in-place editing of a cell. Any editing is commited + /// before the new edit takes place. + /// + /// This will always edit the currentCell + /// If you want to edit another cell than the current one, just reset CurrentCell + /// + private void Edit() + { + Edit(null); + } + + private void Edit(string displayText) + { + EnsureBound(); + + // we want to be able to edit a cell which is not visible, as in the case with editing and scrolling + // at the same time. So do not call Ensure Visible + // + // EnsureVisible(currentRow, currentCol); + + bool cellIsVisible = true; + + // whoever needs to call ResetSelection should not rely on + // Edit() to call it; + // + // ResetSelection(); + + EndEdit(); + + Debug.WriteLineIf(CompModSwitches.DataGridEditing.TraceVerbose, "DataGridEditing: Edit, currentRow = " + currentRow.ToString(CultureInfo.InvariantCulture) + + ", currentCol = " + currentCol.ToString(CultureInfo.InvariantCulture) + (displayText != null ? ", displayText= " + displayText : "")); + + /* allow navigation even if the policy does not allow editing + if (!policy.AllowEdit) + return; + */ + + DataGridRow[] localGridRows = DataGridRows; + + // what do you want to edit when there are no rows? + if (DataGridRowsLength == 0) + { + return; + } + + localGridRows[currentRow].OnEdit(); + editRow = localGridRows[currentRow]; + + // if the list has no columns, then what good is an edit? + if (myGridTable.GridColumnStyles.Count == 0) + { + return; + } + + // what if the currentCol does not have a propDesc? + editColumn = myGridTable.GridColumnStyles[currentCol]; + if (editColumn.PropertyDescriptor == null) + { + return; + } + + Rectangle cellBounds = Rectangle.Empty; + if (currentRow < firstVisibleRow || currentRow > firstVisibleRow + numVisibleRows || + currentCol < firstVisibleCol || currentCol > firstVisibleCol + numVisibleCols - 1 || + (currentCol == firstVisibleCol && negOffset != 0)) + { + cellIsVisible = false; + } + else + { + cellBounds = GetCellBounds(currentRow, currentCol); + } + + gridState[GRIDSTATE_isNavigating] = true; + gridState[GRIDSTATE_isEditing] = false; + + // once we call editColumn.Edit on a DataGridTextBoxColumn + // the edit control will become visible, and its bounds will get set. + // both actions cause Edit.Parent.OnLayout + // so we flag this change, cause we don't want to PerformLayout on the entire DataGrid + // everytime the edit column gets edited + gridState[GRIDSTATE_editControlChanging] = true; + + editColumn.Edit(ListManager, + currentRow, + cellBounds, + myGridTable.ReadOnly || ReadOnly || !policy.AllowEdit, + displayText, + cellIsVisible); + + // reset the editControlChanging to false + gridState[GRIDSTATE_editControlChanging] = false; + } + + /// + /// Requests an end to an edit operation taking place on the + /// + /// control. + /// + public bool EndEdit(DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort) + { + bool ret = false; + if (gridState[GRIDSTATE_isEditing]) + { + if (gridColumn != editColumn) + { + Debug.WriteLineIf(CompModSwitches.DataGridEditing.TraceVerbose, "DataGridEditing: EndEdit requested on a column we are not editing."); + } + + if (rowNumber != editRow.RowNumber) + { + Debug.WriteLineIf(CompModSwitches.DataGridEditing.TraceVerbose, "DataGridEditing: EndEdit requested on a row we are not editing."); + } + + if (shouldAbort) + { + AbortEdit(); + ret = true; + } + else + { + ret = CommitEdit(); + } + } + + return ret; + } + + /// + /// Ends any editing in progress by attempting to commit and then + /// aborting if not possible. + /// + private void EndEdit() + { + Debug.WriteLineIf(CompModSwitches.DataGridEditing.TraceVerbose, "DataGridEditing: EndEdit"); + + if (!gridState[GRIDSTATE_isEditing] && !gridState[GRIDSTATE_isNavigating]) + { + return; + } + + if (!CommitEdit()) + { + AbortEdit(); + } + } + + // PERF: we attempt to create a ListManager for the DataSource/DateMember combination + // we do this in order to check for a valid DataMember + // if the check succeeds, then it means that we actully put the listManager in the BindingContext's + // list of BindingManagers. this is fine, cause if the check succeds, then Set_ListManager + // will be called, and this will get the listManager from the bindingManagerBase hashTable kept in the BindingContext + // + // this will work if the dataMember does not contain any dots ('.') + // if the dataMember contains dots, then it will be more complicated: maybe part of the binding path + // is valid w/ the new dataSource + // but we can leave w/ this, cause in the designer the dataMember will be only a column name. and the DataSource/DataMember + // properties are for use w/ the designer. + // + private void EnforceValidDataMember(object value) + { + Debug.Assert(value != null, "we should not have a null dataSource when we want to check for a valid dataMember"); + if (DataMember == null || DataMember.Length == 0) + { + return; + } + + if (BindingContext == null) + { + return; + } + + // + try + { + BindingManagerBase bm = BindingContext[value, dataMember]; + } + catch + { + dataMember = string.Empty; + } + } + + // will be used by the columns to tell the grid that + // editing is taken place (ie, the grid is no longer in the + // editOrNavigateMode) + // + // also, tell the current row to lose child focus + // + internal protected virtual void ColumnStartedEditing(Rectangle bounds) + { + Debug.Assert(currentRow >= firstVisibleRow && currentRow <= firstVisibleRow + numVisibleRows, "how can one edit a row which is invisible?"); + DataGridRow[] localGridRows = DataGridRows; + + if (bounds.IsEmpty && editColumn is DataGridTextBoxColumn && currentRow != -1 && currentCol != -1) + { + // set the bounds on the control + // this will only work w/ our DataGridTexBox control + DataGridTextBoxColumn col = editColumn as DataGridTextBoxColumn; + Rectangle editBounds = GetCellBounds(currentRow, currentCol); + + gridState[GRIDSTATE_editControlChanging] = true; + try + { + col.TextBox.Bounds = editBounds; + } + finally + { + gridState[GRIDSTATE_editControlChanging] = false; + } + } + + if (gridState[GRIDSTATE_inAddNewRow]) + { + int currentRowCount = DataGridRowsLength; + DataGridRow[] newDataGridRows = new DataGridRow[currentRowCount + 1]; + for (int i = 0; i < currentRowCount; i++) + { + newDataGridRows[i] = localGridRows[i]; + } + + // put the AddNewRow + newDataGridRows[currentRowCount] = new DataGridAddNewRow(this, myGridTable, currentRowCount); + SetDataGridRows(newDataGridRows, currentRowCount + 1); + + Edit(); + // put this after the call to edit so that + // CommitEdit knows that the inAddNewRow is true; + gridState[GRIDSTATE_inAddNewRow] = false; + gridState[GRIDSTATE_isEditing] = true; + gridState[GRIDSTATE_isNavigating] = false; + return; + } + + gridState[GRIDSTATE_isEditing] = true; + gridState[GRIDSTATE_isNavigating] = false; + InvalidateRowHeader(currentRow); + + // tell the current row to lose the childFocuse + if (currentRow < localGridRows.Length) + { + localGridRows[currentRow].LoseChildFocus(layout.RowHeaders, isRightToLeft()); + } + } + + internal protected virtual void ColumnStartedEditing(Control editingControl) + { + if (editingControl == null) + { + return; + } + + ColumnStartedEditing(editingControl.Bounds); + } + + /// + /// Displays child relations, if any exist, for all rows or a + /// specific row. + /// + public void Expand(int row) + { + SetRowExpansionState(row, true); + } + + /// + /// Creates a using the specified . + /// + // protected and virtual because the SimpleDropdownDataGrid will override this + protected virtual DataGridColumnStyle CreateGridColumn(PropertyDescriptor prop, bool isDefault) + { + return myGridTable?.CreateGridColumn(prop, isDefault); + } + + protected virtual DataGridColumnStyle CreateGridColumn(PropertyDescriptor prop) + { + return myGridTable?.CreateGridColumn(prop); + } + +#if PARENT_LINKS + + private ListManager ListManagerForChildColumn(ListManager childListManager, PropertyDescriptor prop) + { + /* + DataKey key; + RelationsCollection relCollection = dataColumn.Table.ParentRelations; + */ + + // this will give us the list of properties of the child + PropertyDescriptorCollection propCollection = childListManager.GetItemProperties(); + + int relCount = propCollection.Count; + for (int i=0;i + /// Specifies the end of the initialization code. + /// + public void EndInit() + { + inInit = false; + if (myGridTable == null && ListManager != null) + { + SetDataGridTable(TableStyles[ListManager.GetListName()], true); // true for forcing column creation + } + + if (myGridTable != null) + { + myGridTable.DataGrid = this; + } + } + + /// + /// Given a x coordinate, returns the column it is over. + /// + private int GetColFromX(int x) + { + if (myGridTable == null) + { + return -1; + } + + Rectangle inside = layout.Data; + Debug.Assert(x >= inside.X && x < inside.Right, "x must be inside the horizontal bounds of layout.Data"); + + x = MirrorPoint(x, inside, isRightToLeft()); + + GridColumnStylesCollection columns = myGridTable.GridColumnStyles; + int columnCount = columns.Count; + + int cx = inside.X - negOffset; + int col = firstVisibleCol; + while (cx < inside.Width + inside.X && col < columnCount) + { + // if (columns[col].Visible && columns[col].PropertyDescriptor != null) + if (columns[col].PropertyDescriptor != null) + { + cx += columns[col].Width; + } + + if (cx > x) + { + return col; + } + + ++col; + } + + return -1; + } + + /// + /// Returns the coordinate of the left edge of the given column + /// Bi-Di: if the grid has the RightToLeft property set to RightToLeft.Yes, this will + /// return what appears as the right edge of the column + /// + internal int GetColBeg(int col) + { + Debug.Assert(myGridTable != null, "GetColBeg can't be called when myGridTable == null."); + + int offset = layout.Data.X - negOffset; + GridColumnStylesCollection columns = myGridTable.GridColumnStyles; + + int lastCol = Math.Min(col, columns.Count); + for (int i = firstVisibleCol; i < lastCol; ++i) + { + // if (columns[i].Visible && columns[i].PropertyDescriptor != null) + if (columns[i].PropertyDescriptor != null) + { + offset += columns[i].Width; + } + } + + return MirrorPoint(offset, layout.Data, isRightToLeft()); + } + + /// + /// Returns the coordinate of the right edge of the given column + /// Bi-Di: if the grid has the RightToLeft property set to RightToLeft.Yes, this will + /// return what appears as the left edge of the column + /// + internal int GetColEnd(int col) + { + // return MirrorPoint(GetColBeg(col) + myGridTable.GridColumnStyles[col].Width, layout.Data, isRightToLeft()); + int colBeg = GetColBeg(col); + Debug.Assert(myGridTable.GridColumnStyles[col].PropertyDescriptor != null, "why would we need the coordinate of a column that is not visible?"); + int width = myGridTable.GridColumnStyles[col].Width; + return isRightToLeft() ? colBeg - width : colBeg + width; + } + + private int GetColumnWidthSum() + { + int sum = 0; + if (myGridTable != null && myGridTable.GridColumnStyles != null) + { + GridColumnStylesCollection columns = myGridTable.GridColumnStyles; + + int columnsCount = columns.Count; + for (int i = 0; i < columnsCount; i++) + { + // if (columns[i].Visible && columns[i].PropertyDescriptor != null) + if (columns[i].PropertyDescriptor != null) + { + sum += columns[i].Width; + } + } + } + + return sum; + } + + /// + /// Not all rows in the DataGrid are expandable, + /// this computes which ones are and returns an array + /// of references to them. + /// + private DataGridRelationshipRow[] GetExpandableRows() + { + int nExpandableRows = DataGridRowsLength; + DataGridRow[] localGridRows = DataGridRows; + if (policy.AllowAdd) + { + nExpandableRows = Math.Max(nExpandableRows - 1, 0); + } + + DataGridRelationshipRow[] expandableRows = new DataGridRelationshipRow[nExpandableRows]; + for (int i = 0; i < nExpandableRows; i++) + { + expandableRows[i] = (DataGridRelationshipRow)localGridRows[i]; + } + + return expandableRows; + } + + /// + /// Returns the row number underneath the given y coordinate. + /// + private int GetRowFromY(int y) + { + Rectangle inside = layout.Data; + Debug.Assert(y >= inside.Y && y < inside.Bottom, "y must be inside the vertical bounds of the data"); + + int cy = inside.Y; + int row = firstVisibleRow; + int rowCount = DataGridRowsLength; + DataGridRow[] localGridRows = DataGridRows; + int bottom = inside.Bottom; + while (cy < bottom && row < rowCount) + { + cy += localGridRows[row].Height; + if (cy > y) + { + return row; + } + + ++row; + } + + return -1; + } + + internal Rectangle GetRowHeaderRect() + { + return layout.RowHeaders; + } + + internal Rectangle GetColumnHeadersRect() + { + return layout.ColumnHeaders; + } + + /// + /// Determines where on the control's ClientRectangle a given row is + /// painting to. + /// + private Rectangle GetRowRect(int rowNumber) + { + Rectangle inside = layout.Data; + int cy = inside.Y; + DataGridRow[] localGridRows = DataGridRows; + for (int row = firstVisibleRow; row <= rowNumber; ++row) + { + if (cy > inside.Bottom) + { + break; + } + + if (row == rowNumber) + { + Rectangle rowRect = new Rectangle(inside.X, + cy, + inside.Width, + localGridRows[row].Height); + if (layout.RowHeadersVisible) + { + rowRect.Width += layout.RowHeaders.Width; + rowRect.X -= isRightToLeft() ? 0 : layout.RowHeaders.Width; + } + + return rowRect; + } + + cy += localGridRows[row].Height; + } + + return Rectangle.Empty; + } + + /// + /// Returns the coordinate of the top edge of the given row + /// + private int GetRowTop(int row) + { + DataGridRow[] localGridRows = DataGridRows; + int offset = layout.Data.Y; + int lastRow = Math.Min(row, DataGridRowsLength); + for (int i = firstVisibleRow; i < lastRow; ++i) + { + offset += localGridRows[i].Height; + } + + for (int i = firstVisibleRow; i > lastRow; i--) + { + offset -= localGridRows[i].Height; + } + + return offset; + } + + /// + /// Returns the coordinate of the bottom edge of the given row + /// + private int GetRowBottom(int row) + { + DataGridRow[] localGridRows = DataGridRows; + + return GetRowTop(row) + localGridRows[row].Height; + } + + /// + /// This method is called on methods that need the grid + /// to be bound to a DataTable to work. + /// + private void EnsureBound() + { + if (!Bound) + { + throw new InvalidOperationException(SR.DataGridUnbound); + } + } + + private void EnsureVisible(int row, int col) + { + if (row < firstVisibleRow + || row >= firstVisibleRow + numTotallyVisibleRows) + { + int dRows = ComputeDeltaRows(row); + ScrollDown(dRows); + } + + if (firstVisibleCol == 0 && numVisibleCols == 0 && lastTotallyVisibleCol == -1) + { + // no columns are displayed whatsoever + // some sanity checks + Debug.Assert(negOffset == 0, " no columns are displayed so the negative offset should be 0"); + return; + } + + int previousFirstVisibleCol = firstVisibleCol; + int previousNegOffset = negOffset; + int previousLastTotallyVisibleCol = lastTotallyVisibleCol; + + while (col < firstVisibleCol +#pragma warning disable SA1408 // Conditional expressions should declare precedence + || col == firstVisibleCol && negOffset != 0 + || lastTotallyVisibleCol == -1 && col > firstVisibleCol + || lastTotallyVisibleCol > -1 && col > lastTotallyVisibleCol) +#pragma warning restore SA1408 // Conditional expressions should declare precedence + { + ScrollToColumn(col); + + if (previousFirstVisibleCol == firstVisibleCol && + previousNegOffset == negOffset && + previousLastTotallyVisibleCol == lastTotallyVisibleCol) + { + // nothing changed since the last iteration + // don't get into an infinite loop + break; + } + + previousFirstVisibleCol = firstVisibleCol; + previousNegOffset = negOffset; + previousLastTotallyVisibleCol = lastTotallyVisibleCol; + + // continue to scroll to the right until the scrollTo column is the totally last visible column or it is the first visible column + } + } + + /// + /// Gets a + /// that specifies the four corners of the selected cell. + /// + public Rectangle GetCurrentCellBounds() + { + DataGridCell current = CurrentCell; + return GetCellBounds(current.RowNumber, current.ColumnNumber); + } + + /// + /// Gets the of the cell specified by row and column number. + /// + public Rectangle GetCellBounds(int row, int col) + { + DataGridRow[] localGridRows = DataGridRows; + Rectangle cellBounds = localGridRows[row].GetCellBounds(col); + cellBounds.Y += GetRowTop(row); + cellBounds.X += layout.Data.X - negOffset; + cellBounds.X = MirrorRectangle(cellBounds, layout.Data, isRightToLeft()); + return cellBounds; + } + + /// + /// Gets the of the cell specified by . + /// + public Rectangle GetCellBounds(DataGridCell dgc) + { + return GetCellBounds(dgc.RowNumber, dgc.ColumnNumber); + } + + // + + internal Rectangle GetRowBounds(DataGridRow row) + { + Rectangle rowBounds = new Rectangle + { + Y = GetRowTop(row.RowNumber), + X = layout.Data.X, + Height = row.Height, + Width = layout.Data.Width + }; + return rowBounds; + } + + /// + /// Gets information, such as row and column number of a + /// clicked point on + /// the grid, + /// using the x + /// and y coordinate passed to the method. + /// + public HitTestInfo HitTest(int x, int y) + { + int topOfData = layout.Data.Y; + HitTestInfo ci = new HitTestInfo(); + + if (layout.CaptionVisible && layout.Caption.Contains(x, y)) + { + ci.type = HitTestType.Caption; + return ci; + } + + if (layout.ParentRowsVisible && layout.ParentRows.Contains(x, y)) + { + ci.type = HitTestType.ParentRows; + return ci; + } + + if (!layout.Inside.Contains(x, y)) + { + return ci; + } + + if (layout.TopLeftHeader.Contains(x, y)) + { + return ci; + } + + // check for column resize + if (layout.ColumnHeaders.Contains(x, y)) + { + ci.type = HitTestType.ColumnHeader; + ci.col = GetColFromX(x); + if (ci.col < 0) + { + return HitTestInfo.Nowhere; + } + + int right = GetColBeg(ci.col + 1); + bool rightToLeft = isRightToLeft(); + if ((rightToLeft && x - right < 8) || (!rightToLeft && right - x < 8)) + { + ci.type = HitTestType.ColumnResize; + } + + return (allowColumnResize ? ci : HitTestInfo.Nowhere); + } + + //check for RowResize: + if (layout.RowHeaders.Contains(x, y)) + { + ci.type = HitTestType.RowHeader; + ci.row = GetRowFromY(y); + if (ci.row < 0) + { + return HitTestInfo.Nowhere; + } + + // find out if the click was a RowResize click + DataGridRow[] localGridRows = DataGridRows; + int bottomBorder = GetRowTop(ci.row) + localGridRows[ci.row].Height; + if (bottomBorder - y - BorderWidth < 2 && !(localGridRows[ci.row] is DataGridAddNewRow)) + { + ci.type = HitTestType.RowResize; + } + + return (allowRowResize ? ci : HitTestInfo.Nowhere); + } + + if (layout.Data.Contains(x, y)) + { + ci.type = HitTestType.Cell; + ci.col = GetColFromX(x); + ci.row = GetRowFromY(y); + if (ci.col < 0 || ci.row < 0) + { + return HitTestInfo.Nowhere; + } + + return ci; + } + + return ci; + } + + /// + /// Gets information, such as row and column number of a + /// clicked point on the grid, about the + /// grid using a specific + /// . + /// + public HitTestInfo HitTest(Point position) + { + return HitTest(position.X, position.Y); + } + + /// + /// Initializes the values for column widths in the table. + /// + private void InitializeColumnWidths() + { + if (myGridTable == null) + { + return; + } + + GridColumnStylesCollection columns = myGridTable.GridColumnStyles; + int numCols = columns.Count; + + // Resize the columns to a approximation of a best fit. + // We find the best fit width of NumRowsForAutoResize rows + // and use it for each column. + int preferredColumnWidth = myGridTable.IsDefault ? PreferredColumnWidth : myGridTable.PreferredColumnWidth; + // if we set the PreferredColumnWidth to something else than AutoColumnSize + // then use that value + // + for (int col = 0; col < numCols; col++) + { + // if the column width is not -1, then this column was initialized already + if (columns[col]._width != -1) + { + continue; + } + + columns[col]._width = preferredColumnWidth; + } + } + + /// + /// Invalidates the scrollable area of the DataGrid. + /// + internal void InvalidateInside() + { + Invalidate(layout.Inside); + } + + /// + /// Invalidates the caption area of the DataGrid. + /// + internal void InvalidateCaption() + { + if (layout.CaptionVisible) + { + Invalidate(layout.Caption); + } + } + + /// + /// Invalidates a rectangle normalized to the caption's + /// visual bounds. + /// + internal void InvalidateCaptionRect(Rectangle r) + { + if (layout.CaptionVisible) + { + Invalidate(r); + } + } + + /// + /// Invalidates the display region of a given DataGridColumn. + /// + internal void InvalidateColumn(int column) + { + GridColumnStylesCollection gridColumns = myGridTable.GridColumnStyles; + if (column < 0 || gridColumns == null || gridColumns.Count <= column) + { + return; + } + + Debug.Assert(gridColumns[column].PropertyDescriptor != null, "how can we invalidate a column that is invisible?"); + // bail if the column is not visible. + if (column < firstVisibleCol || column > firstVisibleCol + numVisibleCols - 1) + { + return; + } + + Rectangle columnArea = new Rectangle + { + Height = layout.Data.Height, + Width = gridColumns[column].Width, + Y = layout.Data.Y + }; + + int x = layout.Data.X - negOffset; + int gridColumnsCount = gridColumns.Count; + for (int i = firstVisibleCol; i < gridColumnsCount; ++i) + { + if (i == column) + { + break; + } + + x += gridColumns[i].Width; + } + + columnArea.X = x; + columnArea.X = MirrorRectangle(columnArea, layout.Data, isRightToLeft()); + Invalidate(columnArea); + } + + /// + /// Invalidates the parent rows area of the DataGrid + /// + internal void InvalidateParentRows() + { + if (layout.ParentRowsVisible) + { + Invalidate(layout.ParentRows); + } + } + + /// + /// Invalidates a rectangle normalized to the parent + /// rows area's visual bounds. + /// + internal void InvalidateParentRowsRect(Rectangle r) + { + Rectangle parentRowsRect = layout.ParentRows; + Invalidate(r); + if (!parentRowsRect.IsEmpty) + { + //Invalidate(new Rectangle(parentRowsRect.X + r.X, parentRowsRect.Y + r.Y, + // r.Width, r.Height)); + } + } + + /// + /// Invalidate the painting region for the row specified. + /// + internal void InvalidateRow(int rowNumber) + { + Rectangle rowRect = GetRowRect(rowNumber); + if (!rowRect.IsEmpty) + { + Debug.WriteLineIf(CompModSwitches.DataGridPainting.TraceVerbose, "DataGridPainting: Invalidating row " + rowNumber.ToString(CultureInfo.InvariantCulture)); + Invalidate(rowRect); + } + } + + private void InvalidateRowHeader(int rowNumber) + { + if (rowNumber >= firstVisibleRow && rowNumber < firstVisibleRow + numVisibleRows) + { + if (!layout.RowHeadersVisible) + { + return; + } + + Rectangle invalid = new Rectangle + { + Y = GetRowTop(rowNumber), + X = layout.RowHeaders.X, + Width = layout.RowHeaders.Width, + Height = DataGridRows[rowNumber].Height + }; + Invalidate(invalid); + } + } + + // NOTE: + // because of Rtl, we assume that the only place that calls InvalidateRowRect is + // the DataGridRelationshipRow + internal void InvalidateRowRect(int rowNumber, Rectangle r) + { + Rectangle rowRect = GetRowRect(rowNumber); + if (!rowRect.IsEmpty) + { + Debug.WriteLineIf(CompModSwitches.DataGridPainting.TraceVerbose, "DataGridPainting: Invalidating a rect in row " + rowNumber.ToString(CultureInfo.InvariantCulture)); + Rectangle inner = new Rectangle(rowRect.X + r.X, rowRect.Y + r.Y, r.Width, r.Height); + if (vertScrollBar.Visible && isRightToLeft()) + { + inner.X -= vertScrollBar.Width; + } + + Invalidate(inner); + } + } + + /// + /// Gets a value that indicates whether a specified row's node is expanded or collapsed. + /// + public bool IsExpanded(int rowNumber) + { + if (rowNumber < 0 || rowNumber > DataGridRowsLength) + { + throw new ArgumentOutOfRangeException(nameof(rowNumber)); + } + + DataGridRow[] localGridRows = DataGridRows; + + // + + DataGridRow row = localGridRows[rowNumber]; + if (row is DataGridRelationshipRow relRow) + { + return relRow.Expanded; + } + else + { + return false; + } + } + + /// + /// Gets a value indicating whether a + /// specified row is selected. + /// + public bool IsSelected(int row) + { + // + DataGridRow[] localGridRows = DataGridRows; + return localGridRows[row].Selected; + } + + internal static bool IsTransparentColor(Color color) + { + return color.A < 255; + } + + /// + /// Determines if Scrollbars should be visible, + /// updates their bounds and the bounds of all + /// other regions in the DataGrid's Layout. + /// + private void LayoutScrollBars() + { + // if we set the dataSource to null, then take away the scrollbars. + if (listManager == null || myGridTable == null) + { + horizScrollBar.Visible = false; + vertScrollBar.Visible = false; + return; + } + + // Scrollbars are a tricky issue. + // We need to see if we can cram our columns and rows + // in without scrollbars and if they don't fit, we make + // scrollbars visible and then fixup our regions for the + // data and headers. + bool needHorizScrollbar = false; + bool needVertScrollbar = false; + bool recountRows = false; + bool alignToRight = isRightToLeft(); + + int nGridCols = myGridTable.GridColumnStyles.Count; + + // if we call LayoutScrollBars before CreateDataGridRows + // then the columns will have their default width ( 100 ) + // CreateDataGridRows will possibly change the columns' width + // + // and anyway, ComputeVisibleRows will call the DataGridRows accessor + // + DataGridRow[] gridRows = DataGridRows; + + // at this stage, the data grid columns may have their width set to -1 ( ie, their width is uninitialized ) + // make sure that the totalWidth is at least 0 + int totalWidth = Math.Max(0, GetColumnWidthSum()); + + if (totalWidth > layout.Data.Width && !needHorizScrollbar) + { + int horizHeight = horizScrollBar.Height; + layout.Data.Height -= horizHeight; + if (layout.RowHeadersVisible) + { + layout.RowHeaders.Height -= horizHeight; + } + + needHorizScrollbar = true; + } + + int oldFirstVisibleRow = firstVisibleRow; + + ComputeVisibleRows(); + if (numTotallyVisibleRows != DataGridRowsLength && !needVertScrollbar) + { + int vertWidth = vertScrollBar.Width; + layout.Data.Width -= vertWidth; + if (layout.ColumnHeadersVisible) + { + if (alignToRight) + { + layout.ColumnHeaders.X += vertWidth; + } + + layout.ColumnHeaders.Width -= vertWidth; + } + + needVertScrollbar = true; + } + + firstVisibleCol = ComputeFirstVisibleColumn(); + // we compute the number of visible columns only after we set up the vertical scroll bar. + ComputeVisibleColumns(); + + if (needVertScrollbar && totalWidth > layout.Data.Width && !needHorizScrollbar) + { + firstVisibleRow = oldFirstVisibleRow; + int horizHeight = horizScrollBar.Height; + layout.Data.Height -= horizHeight; + if (layout.RowHeadersVisible) + { + layout.RowHeaders.Height -= horizHeight; + } + + needHorizScrollbar = true; + recountRows = true; + } + + if (recountRows) + { + ComputeVisibleRows(); + if (numTotallyVisibleRows != DataGridRowsLength && !needVertScrollbar) + { + int vertWidth = vertScrollBar.Width; + layout.Data.Width -= vertWidth; + if (layout.ColumnHeadersVisible) + { + if (alignToRight) + { + layout.ColumnHeaders.X += vertWidth; + } + + layout.ColumnHeaders.Width -= vertWidth; + } + + needVertScrollbar = true; + } + } + + layout.ResizeBoxRect = new Rectangle(); + if (needVertScrollbar && needHorizScrollbar) + { + Rectangle data = layout.Data; + layout.ResizeBoxRect = new Rectangle(alignToRight ? data.X : data.Right, + data.Bottom, + vertScrollBar.Width, + horizScrollBar.Height); + } + + if (needHorizScrollbar && nGridCols > 0) + { + //Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "DataGridScrolling: foo"); + + int widthNotVisible = totalWidth - layout.Data.Width; + + horizScrollBar.Minimum = 0; + horizScrollBar.Maximum = totalWidth; + horizScrollBar.SmallChange = 1; + horizScrollBar.LargeChange = Math.Max(totalWidth - widthNotVisible, 0); + horizScrollBar.Enabled = Enabled; + horizScrollBar.RightToLeft = RightToLeft; + horizScrollBar.Bounds = new Rectangle(alignToRight ? layout.Inside.X + layout.ResizeBoxRect.Width : layout.Inside.X, + layout.Data.Bottom, + layout.Inside.Width - layout.ResizeBoxRect.Width, + horizScrollBar.Height); + horizScrollBar.Visible = true; + } + else + { + HorizontalOffset = 0; + horizScrollBar.Visible = false; + } + + if (needVertScrollbar) + { + int vertScrollBarTop = layout.Data.Y; + if (layout.ColumnHeadersVisible) + { + vertScrollBarTop = layout.ColumnHeaders.Y; + } + + // if numTotallyVisibleRows == 0 ( the height of the row is bigger than the height of + // the grid ) then scroll in increments of 1. + vertScrollBar.LargeChange = numTotallyVisibleRows != 0 ? numTotallyVisibleRows : 1; + vertScrollBar.Bounds = new Rectangle(alignToRight ? layout.Data.X : layout.Data.Right, + vertScrollBarTop, + vertScrollBar.Width, + layout.Data.Height + layout.ColumnHeaders.Height); + vertScrollBar.Enabled = Enabled; + vertScrollBar.Visible = true; + if (alignToRight) + { + layout.Data.X += vertScrollBar.Width; + } + } + else + { + vertScrollBar.Visible = false; + } + } + + /// + /// Navigates back to the table previously displayed in the grid. + /// + public void NavigateBack() + { + if (!CommitEdit() || parentRows.IsEmpty()) + { + return; + } + + // when navigating back, if the grid is inAddNewRow state, cancel the currentEdit. + // we do not need to recreate the rows cause we are navigating back. + // the grid will catch any exception that happens. + if (gridState[GRIDSTATE_inAddNewRow]) + { + gridState[GRIDSTATE_inAddNewRow] = false; + try + { + listManager.CancelCurrentEdit(); + } + catch + { + } + } + else + { + UpdateListManager(); + } + + DataGridState newState = parentRows.PopTop(); + + ResetMouseState(); + + newState.PullState(this, false); // we do not want to create columns when navigating back + + // we need to have originalState != null when we process + // Set_ListManager in the NavigateBack/NavigateTo methods. + // otherwise the DataSource_MetaDataChanged event will not get registered + // properly + if (parentRows.GetTopParent() == null) + { + originalState = null; + } + + DataGridRow[] localGridRows = DataGridRows; + // what if the user changed the ReadOnly property + // on the grid while the user was navigating to the child rows? + // + // what if the policy does not allow for allowAdd? + // + if ((ReadOnly || !policy.AllowAdd) == (localGridRows[DataGridRowsLength - 1] is DataGridAddNewRow)) + { + int newDataGridRowsLength = (ReadOnly || !policy.AllowAdd) ? DataGridRowsLength - 1 : DataGridRowsLength + 1; + DataGridRow[] newDataGridRows = new DataGridRow[newDataGridRowsLength]; + for (int i = 0; i < Math.Min(newDataGridRowsLength, DataGridRowsLength); i++) + { + newDataGridRows[i] = DataGridRows[i]; + } + + if (!ReadOnly && policy.AllowAdd) + { + newDataGridRows[newDataGridRowsLength - 1] = new DataGridAddNewRow(this, myGridTable, newDataGridRowsLength - 1); + } + + SetDataGridRows(newDataGridRows, newDataGridRowsLength); + } + + // when we navigate back from a child table, + // it may be the case that in between the user added a tableStyle that is different + // from the one that is currently in the grid + // in that case, we need to reset the dataGridTableStyle in the rows + localGridRows = DataGridRows; + if (localGridRows != null && localGridRows.Length != 0) + { + DataGridTableStyle dgTable = localGridRows[0].DataGridTableStyle; + if (dgTable != myGridTable) + { + for (int i = 0; i < localGridRows.Length; i++) + { + localGridRows[i].DataGridTableStyle = myGridTable; + } + } + } + + // if we have the default table, when we navigate back + // we also have the default gridColumns, w/ width = -1 + // we need to set the width on the new gridColumns + // + if (myGridTable.GridColumnStyles.Count > 0 && myGridTable.GridColumnStyles[0].Width == -1) + { +#if DEBUG + GridColumnStylesCollection cols = myGridTable.GridColumnStyles; + for (int i = 0; i < cols.Count; i++) + { + Debug.Assert(cols[i].Width == -1, "Sanity check"); + } + + Debug.Assert(myGridTable.IsDefault, "when we navigate to the parent rows and the columns have widths -1 we are using the default table"); +#endif // DEBUG + InitializeColumnWidths(); + } + + // reset the currentRow to the old position in the listmanager: + currentRow = ListManager.Position == -1 ? 0 : ListManager.Position; + + // if the AllowNavigation changed while the user was navigating the + // child tables, so that the new navigation mode does not allow childNavigation anymore + // then reset the rows + if (!AllowNavigation) + { + RecreateDataGridRows(); + } + + caption.BackButtonActive = (parentRows.GetTopParent() != null) && AllowNavigation; + caption.BackButtonVisible = caption.BackButtonActive; + caption.DownButtonActive = (parentRows.GetTopParent() != null); + + PerformLayout(); + Invalidate(); + // reposition the scroll bar + if (vertScrollBar.Visible) + { + vertScrollBar.Value = firstVisibleRow; + } + + if (horizScrollBar.Visible) + { + horizScrollBar.Value = HorizontalOffset + negOffset; + } + + Edit(); + OnNavigate(new NavigateEventArgs(false)); + } + + /// + /// Navigates to the table specified by row and relation + /// name. + /// + public void NavigateTo(int rowNumber, string relationName) + { + // do not navigate if AllowNavigation is set to false + if (!AllowNavigation) + { + return; + } + + DataGridRow[] localGridRows = DataGridRows; + if (rowNumber < 0 || rowNumber > DataGridRowsLength - (policy.AllowAdd ? 2 : 1)) + { + throw new ArgumentOutOfRangeException(nameof(rowNumber)); + } + + EnsureBound(); + + DataGridRow source = localGridRows[rowNumber]; + + NavigateTo(relationName, source, false); + } + + internal void NavigateTo(string relationName, DataGridRow source, bool fromRow) + { + // do not navigate if AllowNavigation is set to false + if (!AllowNavigation) + { + return; + } + + // Commit the edit if possible + if (!CommitEdit()) + { + return; + } + + DataGridState childState; + try + { + childState = CreateChildState(relationName, source); + } + catch + { + // if we get an error when creating the RelatedCurrencyManager + // then navigateBack and ignore the exception. + // + NavigateBack(); + return; + } + + // call EndCurrentEdit before navigating. + // if we get an exception, we do not navigate. + // + try + { + listManager.EndCurrentEdit(); + } + catch + { + return; + } + + // Preserve our current state + // we need to do this after the EndCurrentEdit, otherwise the + // DataGridState will get the listChanged event from the EndCurrentEdit + DataGridState dgs = new DataGridState(this) + { + LinkingRow = source + }; + + // we need to update the Position in the ListManager + // ( the RelatedListManager uses only the position in the parentManager + // to create the childRows + // + // before the code was calling CurrentCell = this and such + // we should only call EndCurrentEdit ( which the code was doing anyway ) + // and then set the position in the listManager to the new row. + // + if (source.RowNumber != CurrentRow) + { + listManager.Position = source.RowNumber; + } + + // We save our state if the parent rows stack is empty. + if (parentRows.GetTopParent() == null) + { + originalState = dgs; + } + + parentRows.AddParent(dgs); + + NavigateTo(childState); + + OnNavigate(new NavigateEventArgs(true)); + if (fromRow) + { + // OnLinkClick(EventArgs.Empty); + } + } + + private void NavigateTo(DataGridState childState) + { + // we are navigating... better stop editing. + EndEdit(); + + // also, we are no longer in editOrNavigate mode either + gridState[GRIDSTATE_isNavigating] = false; + + // reset hot tracking + ResetMouseState(); + + // Retrieve the child state + childState.PullState(this, true); // true for creating columns when we navigate to child rows + + if (listManager.Position != currentRow) + { + currentRow = listManager.Position == -1 ? 0 : listManager.Position; + } + + if (parentRows.GetTopParent() != null) + { + caption.BackButtonActive = AllowNavigation; + caption.BackButtonVisible = caption.BackButtonActive; + caption.DownButtonActive = true; + } + + HorizontalOffset = 0; + PerformLayout(); + Invalidate(); + } + + /// + /// Given a coordinate in the control this method returns + /// the equivalent point for a row. + /// + private Point NormalizeToRow(int x, int y, int row) + { + Debug.Assert(row >= firstVisibleRow && row < firstVisibleRow + numVisibleRows, + "Row " + row.ToString(CultureInfo.InvariantCulture) + "is not visible! firstVisibleRow = " + + firstVisibleRow.ToString(CultureInfo.InvariantCulture) + ", numVisibleRows = " + + numVisibleRows.ToString(CultureInfo.InvariantCulture)); + Point origin = new Point(0, layout.Data.Y); + + DataGridRow[] localGridRows = DataGridRows; + for (int r = firstVisibleRow; r < row; ++r) + { + origin.Y += localGridRows[r].Height; + } + + // when hittesting for the PlusMinus, the code in the DataGridRelationshipRow + // will use real X coordinate ( the one from layout.RowHeaders ) to paint the glyph + // + return new Point(x, y - origin.Y); + } + + internal void OnColumnCollectionChanged(object sender, CollectionChangeEventArgs e) + { + DataGridTableStyle table = (DataGridTableStyle)sender; + if (table.Equals(myGridTable)) + { + // if we changed the column collection, then we need to set the property + // descriptors in the column collection. + // unless the user set the propertyDescriptor in the columnCollection + // + if (!myGridTable.IsDefault) + { + // if the element in the collectionChangeEventArgs is not null + // and the action is refresh, then it means that the user + // set the propDesc. we do not want to override this. + if (e.Action != CollectionChangeAction.Refresh || e.Element == null) + { + PairTableStylesAndGridColumns(listManager, myGridTable, false); + } + } + + Invalidate(); + PerformLayout(); + } + } + + /// + /// Paints column headers. + /// + private void PaintColumnHeaders(Graphics g) + { + bool alignToLeft = isRightToLeft(); + Rectangle boundingRect = layout.ColumnHeaders; + if (!alignToLeft) + { + boundingRect.X -= negOffset; + } + + boundingRect.Width += negOffset; + + int columnHeaderWidth = PaintColumnHeaderText(g, boundingRect); + + if (alignToLeft) + { + boundingRect.X = boundingRect.Right - columnHeaderWidth; + } + + boundingRect.Width = columnHeaderWidth; + if (!FlatMode) + { + ControlPaint.DrawBorder3D(g, boundingRect, Border3DStyle.RaisedInner); + boundingRect.Inflate(-1, -1); + // g.SetPen(OldSystemPens.Control); + // g.OldBrush = (OldSystemBrushes.Hollow); + boundingRect.Width--; + boundingRect.Height--; + g.DrawRectangle(SystemPens.Control, boundingRect); + } + } + + private int PaintColumnHeaderText(Graphics g, Rectangle boundingRect) + { + int cx = 0; + Rectangle textBounds = boundingRect; + GridColumnStylesCollection gridColumns = myGridTable.GridColumnStyles; + bool alignRight = isRightToLeft(); + + int nGridCols = gridColumns.Count; + // for sorting + PropertyDescriptor sortProperty = null; + sortProperty = ListManager.GetSortProperty(); + + // Now paint the column header text! + for (int col = firstVisibleCol; col < nGridCols; ++col) + { + if (gridColumns[col].PropertyDescriptor == null) + { + continue; + } + + if (cx > boundingRect.Width) + { + break; + } + + bool columnSorted = sortProperty != null && sortProperty.Equals(gridColumns[col].PropertyDescriptor); + TriangleDirection whichWay = TriangleDirection.Up; + if (columnSorted) + { + ListSortDirection direction = ListManager.GetSortDirection(); + if (direction == ListSortDirection.Descending) + { + whichWay = TriangleDirection.Down; + } + } + + if (alignRight) + { + textBounds.Width = gridColumns[col].Width - + (columnSorted ? textBounds.Height : 0); + textBounds.X = boundingRect.Right - cx - textBounds.Width; + } + else + { + textBounds.X = boundingRect.X + cx; + textBounds.Width = gridColumns[col].Width - + (columnSorted ? textBounds.Height : 0); + } + + // at the moment we paint some pixels twice. + // we should not call FilLRectangle, once the real GDI+ is there, we will have no need to do that + + // if the user set the HeaderBackBrush property on the + // dataGrid, then use that property + Brush headerBrush; + if (myGridTable.IsDefault) + { + headerBrush = HeaderBackBrush; + } + else + { + headerBrush = myGridTable.HeaderBackBrush; + } + + g.FillRectangle(headerBrush, textBounds); + // granted, the code would be a lot cleaner if we were using a "new Rectangle" + // but like this will be faster + if (alignRight) + { + textBounds.X -= 2; + textBounds.Y += 2; + } + else + { + textBounds.X += 2; + textBounds.Y += 2; + } + + StringFormat format = new StringFormat(); + + // the columnHeaderText alignment should be the same as + // the alignment in the column + // + HorizontalAlignment colAlignment = gridColumns[col].Alignment; + format.Alignment = colAlignment == HorizontalAlignment.Right ? StringAlignment.Far : + colAlignment == HorizontalAlignment.Center ? StringAlignment.Center : + StringAlignment.Near; + + // part 1, section 1: the column headers should not wrap + format.FormatFlags |= StringFormatFlags.NoWrap; + + if (alignRight) + { + format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + format.Alignment = StringAlignment.Near; + } + + g.DrawString(gridColumns[col].HeaderText, + myGridTable.IsDefault ? HeaderFont : myGridTable.HeaderFont, + myGridTable.IsDefault ? HeaderForeBrush : myGridTable.HeaderForeBrush, + textBounds, + format); + format.Dispose(); + + if (alignRight) + { + textBounds.X += 2; + textBounds.Y -= 2; + } + else + { + textBounds.X -= 2; + textBounds.Y -= 2; + } + + if (columnSorted) + { + // + + Rectangle triBounds = new Rectangle(alignRight ? textBounds.X - textBounds.Height : textBounds.Right, + textBounds.Y, + textBounds.Height, + textBounds.Height); + + g.FillRectangle(headerBrush, triBounds); + int deflateValue = Math.Max(0, (textBounds.Height - 5) / 2); + triBounds.Inflate(-deflateValue, -deflateValue); + + Pen pen1 = new Pen(BackgroundBrush); + Pen pen2 = new Pen(myGridTable.BackBrush); + Triangle.Paint(g, triBounds, whichWay, headerBrush, pen1, pen2, pen1, true); + pen1.Dispose(); + pen2.Dispose(); + } + + int paintedWidth = textBounds.Width + (columnSorted ? textBounds.Height : 0); + + if (!FlatMode) + { + if (alignRight && columnSorted) + { + textBounds.X -= textBounds.Height; + } + + textBounds.Width = paintedWidth; + + ControlPaint.DrawBorder3D(g, textBounds, Border3DStyle.RaisedInner); + } + + cx += paintedWidth; + } + + // paint the possible exposed portion to the right ( or left, as the case may be) + if (cx < boundingRect.Width) + { + textBounds = boundingRect; + + if (!alignRight) + { + textBounds.X += cx; + } + + textBounds.Width -= cx; + g.FillRectangle(backgroundBrush, textBounds); + } + + return cx; + } + + /// + /// Paints a border around the bouding rectangle given + /// + private void PaintBorder(Graphics g, Rectangle bounds) + { + if (BorderStyle == BorderStyle.None) + { + return; + } + + if (BorderStyle == BorderStyle.Fixed3D) + { + Border3DStyle style = Border3DStyle.Sunken; + ControlPaint.DrawBorder3D(g, bounds, style); + } + else if (BorderStyle == BorderStyle.FixedSingle) + { + Brush br; + + if (myGridTable.IsDefault) + { + br = HeaderForeBrush; + } + else + { + br = myGridTable.HeaderForeBrush; + } + + g.FillRectangle(br, bounds.X, bounds.Y, bounds.Width + 2, 2); + g.FillRectangle(br, bounds.Right - 2, bounds.Y, 2, bounds.Height + 2); + g.FillRectangle(br, bounds.X, bounds.Bottom - 2, bounds.Width + 2, 2); + g.FillRectangle(br, bounds.X, bounds.Y, 2, bounds.Height + 2); + } + else + { + Pen pen = SystemPens.WindowFrame; + bounds.Width--; + bounds.Height--; + g.DrawRectangle(pen, bounds); + } + } + + /// + /// Paints the grid in the bounding rectangle given. + /// This includes the column headers and each visible row. + /// + private void PaintGrid(Graphics g, Rectangle gridBounds) + { + Debug.WriteLineIf(CompModSwitches.DataGridPainting.TraceVerbose, "DataGridPainting: PaintGrid on " + gridBounds.ToString()); + + Rectangle rc = gridBounds; + + if (listManager != null) + { + if (layout.ColumnHeadersVisible) + { + Region r = g.Clip; + g.SetClip(layout.ColumnHeaders); + PaintColumnHeaders(g); + g.Clip = r; + r.Dispose(); + int columnHeaderHeight = layout.ColumnHeaders.Height; + rc.Y += columnHeaderHeight; + rc.Height -= columnHeaderHeight; + } + + if (layout.TopLeftHeader.Width > 0) + { + if (myGridTable.IsDefault) + { + g.FillRectangle(HeaderBackBrush, layout.TopLeftHeader); + } + else + { + g.FillRectangle(myGridTable.HeaderBackBrush, layout.TopLeftHeader); + } + + if (!FlatMode) + { + ControlPaint.DrawBorder3D(g, layout.TopLeftHeader, Border3DStyle.RaisedInner); + } + } + + PaintRows(g, ref rc); + } + + // paint the possible exposed portion below + if (rc.Height > 0) + { + g.FillRectangle(backgroundBrush, rc); + } + } + + private void DeleteDataGridRows(int deletedRows) + { + if (deletedRows == 0) + { + return; + } + + int currentRowCount = DataGridRowsLength; + int newDataGridRowsLength = currentRowCount - deletedRows + (gridState[GRIDSTATE_inAddNewRow] ? 1 : 0); + DataGridRow[] newDataGridRows = new DataGridRow[newDataGridRowsLength]; + DataGridRow[] gridRows = DataGridRows; + + // the number of selected entries so far in the array + int selectedEntries = 0; + + for (int i = 0; i < currentRowCount; i++) + { + if (gridRows[i].Selected) + { + selectedEntries++; + } + else + { + newDataGridRows[i - selectedEntries] = gridRows[i]; + newDataGridRows[i - selectedEntries].number = i - selectedEntries; + } + } + + if (gridState[GRIDSTATE_inAddNewRow]) + { + newDataGridRows[currentRowCount - selectedEntries] = new DataGridAddNewRow(this, myGridTable, currentRowCount - selectedEntries); + gridState[GRIDSTATE_inAddNewRow] = false; + } + + Debug.Assert(selectedEntries == deletedRows, "all the rows that would have been deleted should have been selected: selectedGridEntries " + selectedEntries.ToString(CultureInfo.InvariantCulture) + " deletedRows " + deletedRows.ToString(CultureInfo.InvariantCulture)); + + SetDataGridRows(newDataGridRows, newDataGridRowsLength); + } + + /// + /// Paints the visible rows on the grid. + /// + private void PaintRows(Graphics g, ref Rectangle boundingRect) + { + int cy = 0; + bool alignRight = isRightToLeft(); + Rectangle rowBounds = boundingRect; + Rectangle dataBounds = Rectangle.Empty; + bool paintRowHeaders = layout.RowHeadersVisible; + Rectangle headerBounds = Rectangle.Empty; + + int numRows = DataGridRowsLength; + DataGridRow[] localGridRows = DataGridRows; + int numCols = myGridTable.GridColumnStyles.Count - firstVisibleCol; + + for (int row = firstVisibleRow; row < numRows; row++) + { + if (cy > boundingRect.Height) + { + break; + } + + rowBounds = boundingRect; + rowBounds.Height = localGridRows[row].Height; + rowBounds.Y = boundingRect.Y + cy; + + // will add some errors +#if false + if (forDebug == 0 || forDebug == 1) + { + object dRowView = listManager[row]; + DataRow dRow= ((DataRowView) dRowView).Row; + // dRow.RowError = "Error " + forDebug.ToString(); + dRow.SetColumnError(forDebug, "another error " + forDebug.ToString()); + + /* + if (localGridRows[row].DataRow != null) + { + localGridRows[row].DataRow.RowError = "error " + forDebug.ToString(); + localGridRows[row].DataRow.SetColumnError(forDebug, "another error " + forDebug.ToString()); + } + */ + forDebug ++; + } +#endif // false + if (paintRowHeaders) + { + headerBounds = rowBounds; + headerBounds.Width = layout.RowHeaders.Width; + + if (alignRight) + { + headerBounds.X = rowBounds.Right - headerBounds.Width; + } + + if (g.IsVisible(headerBounds)) + { + localGridRows[row].PaintHeader(g, headerBounds, alignRight, gridState[GRIDSTATE_isEditing]); + g.ExcludeClip(headerBounds); + } + + if (!alignRight) + { + rowBounds.X += headerBounds.Width; + } + + rowBounds.Width -= headerBounds.Width; + } + + if (g.IsVisible(rowBounds)) + { + dataBounds = rowBounds; + if (!alignRight) + { + dataBounds.X -= negOffset; + } + + dataBounds.Width += negOffset; + + localGridRows[row].Paint(g, dataBounds, rowBounds, firstVisibleCol, numCols, alignRight); + } + + cy += rowBounds.Height; + } + + boundingRect.Y += cy; + boundingRect.Height -= cy; + } + + /// + /// Gets or sets a value that indicates whether a key should be processed + /// further. + /// + protected override bool ProcessDialogKey(Keys keyData) + { + Debug.WriteLineIf(CompModSwitches.DataGridKeys.TraceVerbose, "DataGridKeys: ProcessDialogKey " + TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString(keyData)); + DataGridRow[] localGridRows = DataGridRows; + if (listManager != null && DataGridRowsLength > 0 && localGridRows[currentRow].OnKeyPress(keyData)) + { + Debug.WriteLineIf(CompModSwitches.DataGridKeys.TraceVerbose, "DataGridKeys: Current Row ate the keystroke"); + return true; + } + + switch (keyData & Keys.KeyCode) + { + case Keys.Tab: + case Keys.Up: + case Keys.Down: + case Keys.Left: + case Keys.Right: + case Keys.Next: + case Keys.Prior: + case Keys.Enter: + case Keys.Escape: + case Keys.Oemplus: + case Keys.Add: + case Keys.OemMinus: + case Keys.Subtract: + case Keys.Space: + case Keys.Delete: + case Keys.A: + KeyEventArgs ke = new KeyEventArgs(keyData); + if (ProcessGridKey(ke)) + { + return true; + } + + break; + + case Keys.C: + if ((keyData & Keys.Control) != 0 && (keyData & Keys.Alt) == 0) + { + // the user pressed Ctrl-C + if (!Bound) + { + break; + } + + // need to distinguish between selecting a set of rows, and + // selecting just one column. + if (numSelectedRows == 0) + { + // copy the data from one column only + if (currentRow < ListManager.Count) + { + GridColumnStylesCollection columns = myGridTable.GridColumnStyles; + if (currentCol >= 0 && currentCol < columns.Count) + { + DataGridColumnStyle column = columns[currentCol]; + string text = column.GetDisplayText(column.GetColumnValueAtRow(ListManager, currentRow)); + + // copy the data to the clipboard + Clipboard.SetDataObject(text); + return true; + } + } + } + else + { + // the user selected a set of rows to copy the data from + + int numRowsOutputted = 0; // the number of rows written to "text" + string text = string.Empty; + + for (int i = 0; i < DataGridRowsLength; ++i) + { + if (localGridRows[i].Selected) + { + GridColumnStylesCollection columns = myGridTable.GridColumnStyles; + int numCols = columns.Count; + for (int j = 0; j < numCols; j++) + { + DataGridColumnStyle column = columns[j]; + text += column.GetDisplayText(column.GetColumnValueAtRow(ListManager, i)); + + // do not put the delimiter at the end of the last column + if (j < numCols - 1) + { + text += GetOutputTextDelimiter(); + } + } + + // put the hard enter "\r\n" only if this is not the last selected row + if (numRowsOutputted < numSelectedRows - 1) + { + text += "\r\n"; + } + + numRowsOutputted++; + } + } + + // copy the data to the clipboard + Clipboard.SetDataObject(text); + return true; + } + } + + break; + } + + return base.ProcessDialogKey(keyData); + } + + private void DeleteRows(DataGridRow[] localGridRows) + { + int rowsDeleted = 0; + + int currentRowsCount = listManager == null ? 0 : listManager.Count; + + if (Visible) + { + BeginUpdateInternal(); + } + + try + { + if (ListManager != null) + { + for (int i = 0; i < DataGridRowsLength; i++) + { + if (localGridRows[i].Selected) + { + if (localGridRows[i] is DataGridAddNewRow) + { + Debug.Assert(i == DataGridRowsLength - 1, "the location of addNewRow is " + i.ToString(CultureInfo.InvariantCulture) + " and there are " + DataGridRowsLength.ToString(CultureInfo.InvariantCulture) + " rows "); + localGridRows[i].Selected = false; + } + else + { + ListManager.RemoveAt(i - rowsDeleted); + rowsDeleted++; + } + } + } + } + } + catch + { + // if we got an exception from the back end + // when deleting the rows then we should reset + // our rows and re-throw the exception + // + RecreateDataGridRows(); + gridState[GRIDSTATE_inDeleteRow] = false; + if (Visible) + { + EndUpdateInternal(); + } + + throw; + } + + // keep the copy of the old rows in place + // it may be the case that deleting one row could cause multiple rows to be deleted in the same list + // + if (listManager != null && currentRowsCount == listManager.Count + rowsDeleted) + { + DeleteDataGridRows(rowsDeleted); + } + else + { + RecreateDataGridRows(); + } + + gridState[GRIDSTATE_inDeleteRow] = false; + if (Visible) + { + EndUpdateInternal(); + } + + if (listManager != null && currentRowsCount != listManager.Count + rowsDeleted) + { + Invalidate(); + } + } + + // convention: + // if we return -1 it means that the user was going left and there were no visible columns to the left of the current one + // if we return cols.Count + 1 it means that the user was going right and there were no visible columns to the right of the currrent + private int MoveLeftRight(GridColumnStylesCollection cols, int startCol, bool goRight) + { + int i; + if (goRight) + { + for (i = startCol + 1; i < cols.Count; i++) + { + // if (cols[i].Visible && cols[i].PropertyDescriptor != null) + if (cols[i].PropertyDescriptor != null) + { + return i; + } + } + + return i; + } + else + { + for (i = startCol - 1; i >= 0; i--) + { + // if (cols[i].Visible && cols[i].PropertyDescriptor != null) + if (cols[i].PropertyDescriptor != null) + { + return i; + } + } + + return i; + } + } + + /// + /// Processes keys for grid navigation. + /// + protected bool ProcessGridKey(KeyEventArgs ke) + { + Debug.WriteLineIf(CompModSwitches.DataGridKeys.TraceVerbose, "DataGridKeys: ProcessGridKey " + TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString(ke.KeyCode)); + if (listManager == null || myGridTable == null) + { + return false; + } + + DataGridRow[] localGridRows = DataGridRows; + KeyEventArgs biDiKe = ke; + // check for Bi-Di + // + if (isRightToLeft()) + { + switch (ke.KeyCode) + { + case Keys.Left: + biDiKe = new KeyEventArgs((Keys.Right | ke.Modifiers)); + break; + case Keys.Right: + biDiKe = new KeyEventArgs((Keys.Left | ke.Modifiers)); + break; + default: + break; + } + } + + GridColumnStylesCollection cols = myGridTable.GridColumnStyles; + int firstColumnMarkedVisible = 0; + int lastColumnMarkedVisible = cols.Count; + for (int i = 0; i < cols.Count; i++) + { + if (cols[i].PropertyDescriptor != null) + { + firstColumnMarkedVisible = i; + break; + } + } + + for (int i = cols.Count - 1; i >= 0; i--) + { + if (cols[i].PropertyDescriptor != null) + { + lastColumnMarkedVisible = i; + break; + } + } + + switch (biDiKe.KeyCode) + { + case Keys.Tab: + return ProcessTabKey(biDiKe.KeyData); + case Keys.Up: + gridState[GRIDSTATE_childLinkFocused] = false; + if (dataGridRowsLength == 0) + { + return true; + } + + if (biDiKe.Control && !biDiKe.Alt) + { + if (biDiKe.Shift) + { + DataGridRow[] gridRows = DataGridRows; + + int savedCurrentRow = currentRow; + CurrentRow = 0; + + ResetSelection(); + + for (int i = 0; i <= savedCurrentRow; i++) + { + gridRows[i].Selected = true; + } + + numSelectedRows = savedCurrentRow + 1; + // hide the edit box + // + EndEdit(); + return true; + } + + // do not make the parentRowsVisible = false; + // ParentRowsVisible = false; + ResetSelection(); + CurrentRow = 0; + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + return true; + } + else if (biDiKe.Shift) + { + DataGridRow[] gridRows = DataGridRows; + // keep a continous selected region + if (gridRows[currentRow].Selected) + { + if (currentRow >= 1) + { + if (gridRows[currentRow - 1].Selected) + { + if (currentRow >= DataGridRowsLength - 1 || !gridRows[currentRow + 1].Selected) + { + numSelectedRows--; + gridRows[currentRow].Selected = false; + } + } + else + { + numSelectedRows += gridRows[currentRow - 1].Selected ? 0 : 1; + gridRows[currentRow - 1].Selected = true; + } + + CurrentRow--; + } + } + else + { + numSelectedRows++; + gridRows[currentRow].Selected = true; + if (currentRow >= 1) + { + numSelectedRows += gridRows[currentRow - 1].Selected ? 0 : 1; + gridRows[currentRow - 1].Selected = true; + CurrentRow--; + } + } + + // hide the edit box: + // + EndEdit(); + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + return true; + } + else if (biDiKe.Alt) + { + // will need to collapse all child table links + // -1 is for all rows, and false is for collapsing the rows + SetRowExpansionState(-1, false); + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + return true; + } + + ResetSelection(); + CurrentRow -= 1; + Edit(); + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + break; + case Keys.Down: + gridState[GRIDSTATE_childLinkFocused] = false; + if (dataGridRowsLength == 0) + { + return true; + } + + if (biDiKe.Control && !biDiKe.Alt) + { + if (biDiKe.Shift) + { + int savedCurrentRow = currentRow; + CurrentRow = Math.Max(0, DataGridRowsLength - (policy.AllowAdd ? 2 : 1)); + DataGridRow[] gridRows = DataGridRows; + + ResetSelection(); + + for (int i = savedCurrentRow; i <= currentRow; i++) + { + gridRows[i].Selected = true; + } + + numSelectedRows = currentRow - savedCurrentRow + 1; + // hide the edit box + // + EndEdit(); + return true; + } + + // do not make the parentRowsVisible = true; + // ParentRowsVisible = true; + ResetSelection(); + CurrentRow = Math.Max(0, DataGridRowsLength - (policy.AllowAdd ? 2 : 1)); + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + return true; + } + else if (biDiKe.Shift) + { + DataGridRow[] gridRows = DataGridRows; + + // keep a continous selected region + if (gridRows[currentRow].Selected) + { + // -1 because we index from 0 + if (currentRow < DataGridRowsLength - (policy.AllowAdd ? 1 : 0) - 1) + { + if (gridRows[currentRow + 1].Selected) + { + if (currentRow == 0 || !gridRows[currentRow - 1].Selected) + { + numSelectedRows--; + gridRows[currentRow].Selected = false; + } + } + else + { + numSelectedRows += gridRows[currentRow + 1].Selected ? 0 : 1; + gridRows[currentRow + 1].Selected = true; + } + + CurrentRow++; + } + } + else + { + numSelectedRows++; + gridRows[currentRow].Selected = true; + // -1 because we index from 0, and -1 so this is not the last row + // so it adds to -2 + if (currentRow < DataGridRowsLength - (policy.AllowAdd ? 1 : 0) - 1) + { + CurrentRow++; + numSelectedRows += gridRows[currentRow].Selected ? 0 : 1; + gridRows[currentRow].Selected = true; + } + } + + // hide the edit box: + // + EndEdit(); + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + return true; + } + else if (biDiKe.Alt) + { + // will need to expande all child table links + // -1 is for all rows, and true is for expanding the rows + SetRowExpansionState(-1, true); + return true; + } + + ResetSelection(); + Edit(); + CurrentRow += 1; + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + break; + case Keys.OemMinus: + case Keys.Subtract: + gridState[GRIDSTATE_childLinkFocused] = false; + if (biDiKe.Control && !biDiKe.Alt) + { + SetRowExpansionState(-1, false); + return true; + } + + return false; + case Keys.Oemplus: + case Keys.Add: + gridState[GRIDSTATE_childLinkFocused] = false; + if (biDiKe.Control) + { + SetRowExpansionState(-1, true); + // hide the edit box + // + EndEdit(); + return true; + } + + return false; + case Keys.Space: + gridState[GRIDSTATE_childLinkFocused] = false; + if (dataGridRowsLength == 0) + { + return true; + } + + if (biDiKe.Shift) + { + ResetSelection(); + EndEdit(); + DataGridRow[] gridRows = DataGridRows; + gridRows[currentRow].Selected = true; + numSelectedRows = 1; + + return true; + } + + return false; + case Keys.Next: + gridState[GRIDSTATE_childLinkFocused] = false; + if (dataGridRowsLength == 0) + { + return true; + } + + if (biDiKe.Shift) + { + int savedCurrentRow = currentRow; + CurrentRow = Math.Min(DataGridRowsLength - (policy.AllowAdd ? 2 : 1), currentRow + numTotallyVisibleRows); + + DataGridRow[] gridRows = DataGridRows; + for (int i = savedCurrentRow; i <= currentRow; i++) + { + if (!gridRows[i].Selected) + { + gridRows[i].Selected = true; + numSelectedRows++; + } + } + + // hide edit box + // + EndEdit(); + } + else if (biDiKe.Control && !biDiKe.Alt) + { + // map ctrl-pageDown to show the parentRows + ParentRowsVisible = true; + } + else + { + ResetSelection(); + CurrentRow = Math.Min(DataGridRowsLength - (policy.AllowAdd ? 2 : 1), + CurrentRow + numTotallyVisibleRows); + } + + break; + case Keys.Prior: + if (dataGridRowsLength == 0) + { + return true; + } + + gridState[GRIDSTATE_childLinkFocused] = false; + if (biDiKe.Shift) + { + int savedCurrentRow = currentRow; + CurrentRow = Math.Max(0, CurrentRow - numTotallyVisibleRows); + + DataGridRow[] gridRows = DataGridRows; + for (int i = savedCurrentRow; i >= currentRow; i--) + { + if (!gridRows[i].Selected) + { + gridRows[i].Selected = true; + numSelectedRows++; + } + } + + // hide the edit box + // + EndEdit(); + } + else if (biDiKe.Control && !biDiKe.Alt) + { + // map ctrl-pageUp to hide the parentRows + ParentRowsVisible = false; + } + else + { + ResetSelection(); + CurrentRow = Math.Max(0, + CurrentRow - numTotallyVisibleRows); + } + + break; + case Keys.Left: + gridState[GRIDSTATE_childLinkFocused] = false; + ResetSelection(); + if ((biDiKe.Modifiers & Keys.Modifiers) == Keys.Alt) + { + if (Caption.BackButtonVisible) + { + NavigateBack(); + } + + return true; + } + + if ((biDiKe.Modifiers & Keys.Control) == Keys.Control) + { + // we should navigate to the first visible column + CurrentColumn = firstColumnMarkedVisible; + break; + } + + if (currentCol == firstColumnMarkedVisible && currentRow != 0) + { + CurrentRow -= 1; + int newCol = MoveLeftRight(myGridTable.GridColumnStyles, myGridTable.GridColumnStyles.Count, false); + Debug.Assert(newCol != -1, "there should be at least a visible column, right?"); + CurrentColumn = newCol; + } + else + { + int newCol = MoveLeftRight(myGridTable.GridColumnStyles, currentCol, false); + if (newCol == -1) + { + if (currentRow == 0) + { + return true; + } + else + { + // go to the previous row: + CurrentRow -= 1; + CurrentColumn = lastColumnMarkedVisible; + } + } + else + { + CurrentColumn = newCol; + } + } + + break; + case Keys.Right: + gridState[GRIDSTATE_childLinkFocused] = false; + ResetSelection(); + if ((biDiKe.Modifiers & Keys.Control) == Keys.Control && !biDiKe.Alt) + { + // we should navigate to the last column that is marked as Visible + CurrentColumn = lastColumnMarkedVisible; + break; + } + + if (currentCol == lastColumnMarkedVisible && currentRow != DataGridRowsLength - 1) + { + CurrentRow += 1; + // navigate to the first visible column + CurrentColumn = firstColumnMarkedVisible; + } + else + { + int newCol = MoveLeftRight(myGridTable.GridColumnStyles, currentCol, true); + if (newCol == cols.Count + 1) + { + // navigate to the first visible column + // and the next row + // + CurrentColumn = firstColumnMarkedVisible; + CurrentRow++; + } + else + { + CurrentColumn = newCol; + } + } + + break; + case Keys.F2: + gridState[GRIDSTATE_childLinkFocused] = false; + ResetSelection(); + Edit(); + break; +#if DEBUG + case Keys.F12: + gridState[GRIDSTATE_childLinkFocused] = false; + AddNewRow(); + break; +#endif + case Keys.Home: + gridState[GRIDSTATE_childLinkFocused] = false; + if (dataGridRowsLength == 0) + { + return true; + } + + ResetSelection(); + CurrentColumn = 0; + if (biDiKe.Control && !biDiKe.Alt) + { + int currentRowSaved = currentRow; + CurrentRow = 0; + + if (biDiKe.Shift) + { + // Ctrl-Shift-Home will select all the rows up to the first one + DataGridRow[] gridRows = DataGridRows; + for (int i = 0; i <= currentRowSaved; i++) + { + gridRows[i].Selected = true; + numSelectedRows++; + } + + // hide the edit box: + EndEdit(); + } + + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + return true; + } + + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + break; + case Keys.Delete: + gridState[GRIDSTATE_childLinkFocused] = false; + if (policy.AllowRemove && numSelectedRows > 0) + { +#if DEBUG + // when the list is empty, then the position + // in the listManager is -1, and the currentPosition in the grid is 0 + if (ListManager != null && ListManager.Count > 0) + { + Debug.Assert(ListManager.Position == currentRow, + "Current row out of sync with DataSource", + "The DataSource's Position property should be mirrored by the CurrentCell.RowNumber of the DataGrid."); + } +#endif // DEBUG + + gridState[GRIDSTATE_inDeleteRow] = true; + DeleteRows(localGridRows); + // set the currentRow to the position in the list + currentRow = listManager.Count == 0 ? 0 : listManager.Position; + numSelectedRows = 0; + } + else + { + // if we did not use the the Delete key, let the dataGridTextBox use it + return false; + } + + break; + case Keys.End: + gridState[GRIDSTATE_childLinkFocused] = false; + if (dataGridRowsLength == 0) + { + return true; + } + + ResetSelection(); + // go the the last visible column + CurrentColumn = lastColumnMarkedVisible; + + if (biDiKe.Control && !biDiKe.Alt) + { + int savedCurrentRow = currentRow; + CurrentRow = Math.Max(0, DataGridRowsLength - (policy.AllowAdd ? 2 : 1)); + + if (biDiKe.Shift) + { + // Ctrl-Shift-Home will select all the rows up to the first one + DataGridRow[] gridRows = DataGridRows; + for (int i = savedCurrentRow; i <= currentRow; i++) + { + gridRows[i].Selected = true; + } + + numSelectedRows = currentRow - savedCurrentRow + 1; + // hide the edit box + // + EndEdit(); + } + + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + return true; + } + + Debug.Assert(ListManager.Position == CurrentCell.RowNumber || listManager.Count == 0, "current row out of ssync with DataSource"); + break; + case Keys.Enter: + gridState[GRIDSTATE_childLinkFocused] = false; + ResetSelection(); + + // yield the return key if there is no editing + if (!gridState[GRIDSTATE_isEditing]) + { + return false; + } + + // Ctrl-Enter will call EndCurrentEdit + if ((biDiKe.Modifiers & Keys.Control) != 0 && !biDiKe.Alt) + { + EndEdit(); + HandleEndCurrentEdit(); + Edit(); // put the edit box on the screen + } + else + { + // Do not commit the edit, cause reseting the + // current cell will do that + // + // CommitEdit(); + + CurrentRow = currentRow + 1; + } + + break; + case Keys.A: + gridState[GRIDSTATE_childLinkFocused] = false; + if (biDiKe.Control && !biDiKe.Alt) + { + DataGridRow[] gridRows = DataGridRows; + for (int i = 0; i < DataGridRowsLength; i++) + { + if (gridRows[i] is DataGridRelationshipRow) + { + gridRows[i].Selected = true; + } + } + + numSelectedRows = DataGridRowsLength - (policy.AllowAdd ? 1 : 0); + // hide the edit box + // + EndEdit(); + return true; + } + + return false; + case Keys.Escape: + gridState[GRIDSTATE_childLinkFocused] = false; + ResetSelection(); + if (gridState[GRIDSTATE_isEditing]) + { + // rollback + AbortEdit(); + + // we have to invalidate the row header ( make it display the row selector instead of the pencil ) + if (layout.RowHeadersVisible && currentRow > -1) + { + Rectangle rowHdrRect = GetRowRect(currentRow); + rowHdrRect.Width = layout.RowHeaders.Width; + Invalidate(rowHdrRect); + } + + // now put the edit column back on the screen + Edit(); + } + else + { + // add this protected virtual method for the XML designer team + CancelEditing(); + Edit(); + return false; + } + + break; + } + + return true; + } + + /// + /// Previews a keyboard message and returns a value indicating if the key was + /// consumed. + /// + protected override bool ProcessKeyPreview(ref Message m) + { + if (m.Msg == (int)User32.WM.KEYDOWN) + { + KeyEventArgs ke = new KeyEventArgs((Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys); + switch (ke.KeyCode) + { + case Keys.Up: + case Keys.Down: + case Keys.Prior: + case Keys.Next: + case Keys.Right: + case Keys.Left: + case Keys.Tab: + case Keys.Escape: + case Keys.Enter: + case Keys.OemMinus: + case Keys.Subtract: + case Keys.Oemplus: + case Keys.Add: + case Keys.Space: + case Keys.Home: + case Keys.End: + case Keys.F2: + case Keys.Delete: + case Keys.A: + return ProcessGridKey(ke); + } + + // Ctrl-Tab will be sent as a tab paired w/ a control on the KeyUp message + // + } + else if (m.Msg == (int)User32.WM.KEYUP) + { + KeyEventArgs ke = new KeyEventArgs((Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys); + if (ke.KeyCode == Keys.Tab) + { + return ProcessGridKey(ke); + } + } + + return base.ProcessKeyPreview(ref m); + } + + /// + /// Gets a value indicating whether the Tab key should be processed. + /// + protected bool ProcessTabKey(Keys keyData) + { + if (listManager == null || myGridTable == null) + { + return false; + } + + bool wasEditing = false; + int columnCount = myGridTable.GridColumnStyles.Count; + bool biDi = isRightToLeft(); + ResetSelection(); + + // Try to commit changes to cell if we were editing + if (gridState[GRIDSTATE_isEditing]) + { + wasEditing = true; + if (!CommitEdit()) + { + //MessageBox.Show("Could not commit changes! Press Escape to abort edit"); + Edit(); // if we can't commit the value put the edit box so that the user sees where the focus is + return true; + } + } + + if ((keyData & Keys.Control) == Keys.Control) + { + // when the user hits ctrl-alt-tab just ignore it. + if ((keyData & Keys.Alt) == Keys.Alt) + { + return true; + } + + // navigate to the next control in the form + Keys ke = keyData & ~(Keys.Control); + EndEdit(); + + gridState[GRIDSTATE_editControlChanging] = true; + try + { + Focus(); + } + finally + { + gridState[GRIDSTATE_editControlChanging] = false; + } + + return base.ProcessDialogKey(ke); + } + + // see if the child relationships can use this TAB key + DataGridRow[] localRows = DataGridRows; + GridColumnStylesCollection cols = myGridTable.GridColumnStyles; + + int lastColumnMarkedVisible = 0; + int firstColumnMarkedVisible = cols.Count - 1; + // + + if (localRows.Length == 0) + { + EndEdit(); + + return base.ProcessDialogKey(keyData); + } + + for (int i = 0; i < cols.Count; i++) + { + // if (cols[i].Visible && cols[i].PropertyDescriptor != null) { + if (cols[i].PropertyDescriptor != null) + { + firstColumnMarkedVisible = i; + break; + } + } + + for (int i = cols.Count - 1; i >= 0; i--) + { + // if (cols[i].Visible && cols[i].PropertyDescriptor != null) { + if (cols[i].PropertyDescriptor != null) + { + lastColumnMarkedVisible = i; + break; + } + } + + if (CurrentColumn == lastColumnMarkedVisible) + { + if (gridState[GRIDSTATE_childLinkFocused] || (!gridState[GRIDSTATE_childLinkFocused] && (keyData & Keys.Shift) != Keys.Shift)) + { + if (localRows[CurrentRow].ProcessTabKey(keyData, layout.RowHeaders, isRightToLeft())) + { + if (cols.Count > 0) + { + cols[CurrentColumn].ConcedeFocus(); + } + + gridState[GRIDSTATE_childLinkFocused] = true; + // let the grid regain focus + // introduced because of that BeginInvoke thing in the OnLeave method.... + if (gridState[GRIDSTATE_canFocus] && CanFocus && !Focused) + { + Focus(); + } + + return true; + } + } + + // actually, it turns out that we should leave the + // control if we are in the last row + if ((currentRow == DataGridRowsLength - 1) && ((keyData & Keys.Shift) == 0)) + { + EndEdit(); + return base.ProcessDialogKey(keyData); + } + } + + if (CurrentColumn == firstColumnMarkedVisible) + { + // if the childLink is focused, then navigate within the relations + // in the row, otherwise expand the relations list for the row above + if (!gridState[GRIDSTATE_childLinkFocused]) + { + if (CurrentRow != 0 && (keyData & Keys.Shift) == Keys.Shift) + { + if (localRows[CurrentRow - 1].ProcessTabKey(keyData, layout.RowHeaders, isRightToLeft())) + { + CurrentRow--; + if (cols.Count > 0) + { + cols[CurrentColumn].ConcedeFocus(); + } + + gridState[GRIDSTATE_childLinkFocused] = true; + // let the grid regain focus + // introduced because of that BeginInvoke thing in the OnLeave method.... + if (gridState[GRIDSTATE_canFocus] && CanFocus && !Focused) + { + Focus(); + } + + return true; + } + } + } + else + { + if (localRows[CurrentRow].ProcessTabKey(keyData, layout.RowHeaders, isRightToLeft())) + { + return true; + } + else + { + // we were on the firstColumn, previously the link was focused + // we have to navigate to the last column + gridState[GRIDSTATE_childLinkFocused] = false; + CurrentColumn = lastColumnMarkedVisible; + return true; + } + } + + // if we are on the first cell ( not on the addNewRow ) + // then shift - tab should move to the next control on the form + if (currentRow == 0 && ((keyData & Keys.Shift) == Keys.Shift)) + { + EndEdit(); + return base.ProcessDialogKey(keyData); + } + } + + // move + if ((keyData & Keys.Shift) != Keys.Shift) + { + // forward + if (CurrentColumn == lastColumnMarkedVisible) + { + if (CurrentRow != DataGridRowsLength - 1) + { + CurrentColumn = firstColumnMarkedVisible; + } + + CurrentRow += 1; + } + else + { + int nextCol = MoveLeftRight(cols, currentCol, true); // true for going right; + Debug.Assert(nextCol < cols.Count, "we already checked that we are not at the lastColumnMarkedVisible"); + CurrentColumn = nextCol; + } + } + else + { + // backward + if (CurrentColumn == firstColumnMarkedVisible) + { + if (CurrentRow != 0) + { + CurrentColumn = lastColumnMarkedVisible; + } + + if (!gridState[GRIDSTATE_childLinkFocused]) // + { + CurrentRow--; + } + } + else if (gridState[GRIDSTATE_childLinkFocused] && CurrentColumn == lastColumnMarkedVisible) + { + // part deux: when we hilite the childLink and then press shift-tab, we + // don't want to navigate at the second to last column + InvalidateRow(currentRow); + Edit(); + } + else + { + int prevCol = MoveLeftRight(cols, currentCol, false); // false for going left + Debug.Assert(prevCol != -1, "we already checked that we are not at the first columnMarked visible"); + CurrentColumn = prevCol; + } + } + + // if we got here, then invalidate childLinkFocused + // + gridState[GRIDSTATE_childLinkFocused] = false; + + // Begin another edit if we were editing before + if (wasEditing) + { + ResetSelection(); + Edit(); + } + + return true; + } + + virtual protected void CancelEditing() + { + CancelCursorUpdate(); + // yield the escape key if there is no editing + // make the last row a DataGridAddNewRow + if (gridState[GRIDSTATE_inAddNewRow]) + { + gridState[GRIDSTATE_inAddNewRow] = false; + DataGridRow[] localGridRows = DataGridRows; + + localGridRows[DataGridRowsLength - 1] = new DataGridAddNewRow(this, myGridTable, DataGridRowsLength - 1); + SetDataGridRows(localGridRows, DataGridRowsLength); + } + } + + internal void RecalculateFonts() + { + try + { + linkFont = new Font(Font, FontStyle.Underline); + } + catch + { + } + + fontHeight = Font.Height; + linkFontHeight = LinkFont.Height; + captionFontHeight = CaptionFont.Height; + + if (myGridTable == null || myGridTable.IsDefault) + { + headerFontHeight = HeaderFont.Height; + } + else + { + headerFontHeight = myGridTable.HeaderFont.Height; + } + } + + // the BackButtonClicked event: + // + /// + /// Occurs when the BackButton is clicked. + /// + [ + SRCategory(nameof(SR.CatAction)), + SRDescription(nameof(SR.DataGridBackButtonClickDescr)) + ] + public event EventHandler BackButtonClick + { + add => Events.AddHandler(EVENT_BACKBUTTONCLICK, value); + remove => Events.RemoveHandler(EVENT_BACKBUTTONCLICK, value); + } + + // the DownButtonClick event + // + /// + /// Occurs when the Down button is clicked. + /// + [ + SRCategory(nameof(SR.CatAction)), + SRDescription(nameof(SR.DataGridDownButtonClickDescr)) + ] + public event EventHandler ShowParentDetailsButtonClick + { + add => Events.AddHandler(EVENT_DOWNBUTTONCLICK, value); + remove => Events.RemoveHandler(EVENT_DOWNBUTTONCLICK, value); + } + + private void ResetMouseState() + { + oldRow = -1; + gridState[GRIDSTATE_overCaption] = true; + } + + /// + /// Turns off selection for all rows that are selected. + /// + protected void ResetSelection() + { + if (numSelectedRows > 0) + { + DataGridRow[] localGridRows = DataGridRows; + for (int i = 0; i < DataGridRowsLength; ++i) + { + if (localGridRows[i].Selected) + { + localGridRows[i].Selected = false; + } + } + } + + numSelectedRows = 0; + lastRowSelected = -1; + } + + private void ResetParentRows() + { + parentRows.Clear(); + originalState = null; + caption.BackButtonActive = caption.DownButtonActive = caption.BackButtonVisible = false; + caption.SetDownButtonDirection(!layout.ParentRowsVisible); + } + + /// + /// Re-initializes all UI related state. + /// + private void ResetUIState() + { + gridState[GRIDSTATE_childLinkFocused] = false; + ResetSelection(); + ResetMouseState(); + PerformLayout(); + Invalidate(); // we want to invalidate after we set up the scrollbars + + // invalidate the horizontalscrollbar and the vertical scrollbar + // + if (horizScrollBar.Visible) + { + horizScrollBar.Invalidate(); + } + + if (vertScrollBar.Visible) + { + vertScrollBar.Invalidate(); + } + } + + /// + /// Scrolls the datagrid down an arbritrary number of rows. + /// + private void ScrollDown(int rows) + { + //Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "DataGridScrolling: ScrollDown, rows = " + rows.ToString()); + if (rows != 0) + { + ClearRegionCache(); + + // we should put "dataGridRowsLength -1" + int newFirstRow = Math.Max(0, Math.Min(firstVisibleRow + rows, DataGridRowsLength - 1)); + int oldFirstRow = firstVisibleRow; + firstVisibleRow = newFirstRow; + vertScrollBar.Value = newFirstRow; + bool wasEditing = gridState[GRIDSTATE_isEditing]; + ComputeVisibleRows(); + + if (gridState[GRIDSTATE_isScrolling]) + { + Edit(); + // isScrolling is set to TRUE when the user scrolls. + // once we move the edit box, we finished processing the scroll event, so set isScrolling to FALSE + // to set isScrolling to TRUE, we need another scroll event. + gridState[GRIDSTATE_isScrolling] = false; + } + else + { + EndEdit(); + } + + int deltaY = ComputeRowDelta(oldFirstRow, newFirstRow); + Rectangle rowsRect = layout.Data; + if (layout.RowHeadersVisible) + { + rowsRect = Rectangle.Union(rowsRect, layout.RowHeaders); + } + + RECT scrollArea = rowsRect; + User32.ScrollWindow(this, 0, deltaY, ref scrollArea, ref scrollArea); + OnScroll(EventArgs.Empty); + + if (wasEditing) + { + // invalidate the rowHeader for the + InvalidateRowHeader(currentRow); + } + } + } + + /// + /// Scrolls the datagrid right an arbritrary number of columns. + /// + private void ScrollRight(int columns) + { + Debug.WriteLineIf(CompModSwitches.DataGridScrolling.TraceVerbose, "DataGridScrolling: ScrollRight, columns = " + columns.ToString(CultureInfo.InvariantCulture)); + int newCol = firstVisibleCol + columns; + + GridColumnStylesCollection gridColumns = myGridTable.GridColumnStyles; + int newColOffset = 0; + int nGridCols = gridColumns.Count; + int nVisibleCols = 0; + + // if we try to scroll past the last totally visible column, + // then the toolTips will dissapear + if (myGridTable.IsDefault) + { + nVisibleCols = nGridCols; + } + else + { + for (int i = 0; i < nGridCols; i++) + { + if (gridColumns[i].PropertyDescriptor != null) + { + nVisibleCols++; + } + } + } + +#pragma warning disable SA1408 // Conditional expressions should declare precedence + if (lastTotallyVisibleCol == nVisibleCols - 1 && columns > 0 || + firstVisibleCol == 0 && columns < 0 && negOffset == 0) +#pragma warning restore SA1408 // Conditional expressions should declare precedence + { + return; + } + + newCol = Math.Min(newCol, nGridCols - 1); + + for (int i = 0; i < newCol; i++) + { + // if (gridColumns[i].Visible && gridColumns[i].PropertyDescriptor != null) + if (gridColumns[i].PropertyDescriptor != null) + { + newColOffset += gridColumns[i].Width; + } + } + + HorizontalOffset = newColOffset; + } + + /// + /// Scrolls a given column into visibility. + /// + private void ScrollToColumn(int targetCol) + { + // do not flush the columns to the left + // so, scroll only as many columns as is necessary. + // + + int dCols = targetCol - firstVisibleCol; + + if (targetCol > lastTotallyVisibleCol && lastTotallyVisibleCol != -1) + { + dCols = targetCol - lastTotallyVisibleCol; + } + + // if only part of the currentCol is visible + // then we should still scroll + if (dCols != 0 || negOffset != 0) + { + ScrollRight(dCols); + } + } + + /// + /// Selects a given row + /// + public void Select(int row) + { + // + Debug.WriteLineIf(CompModSwitches.DataGridSelection.TraceVerbose, "Selecting row " + row.ToString(CultureInfo.InvariantCulture)); + DataGridRow[] localGridRows = DataGridRows; + if (!localGridRows[row].Selected) + { + localGridRows[row].Selected = true; + numSelectedRows++; + } + + // when selecting a row, hide the edit box + // + EndEdit(); + } + + // this function will pair the listManager w/ a table from the TableStylesCollection. + // and for each column in the TableStylesCollection will pair them w/ a propertyDescriptor + // from the listManager + // + // prerequisite: the current table is either the default table, or has the same name as the + // list in the listManager. + // + private void PairTableStylesAndGridColumns(CurrencyManager lm, DataGridTableStyle gridTable, bool forceColumnCreation) + { + PropertyDescriptorCollection props = lm.GetItemProperties(); + GridColumnStylesCollection gridCols = gridTable.GridColumnStyles; + + // ]it is possible to have a dataTable w/ an empty string for a name. + if (!gridTable.IsDefault && string.Compare(lm.GetListName(), gridTable.MappingName, true, CultureInfo.InvariantCulture) == 0) + { + // we will force column creation only at runtime + if (gridTable.GridColumnStyles.Count == 0 && !DesignMode) + { + // we have to create some default columns for each of the propertyDescriptors + // + if (forceColumnCreation) + { + gridTable.SetGridColumnStylesCollection(lm); + } + else + { + gridTable.SetRelationsList(lm); + } + } + else + { + // it may the case that the user will have two lists w/ the same name. + // When switching binding between those different lists, we need to invalidate + // the propertyDescriptors from the current gridColumns + // + for (int i = 0; i < gridCols.Count; i++) + { + gridCols[i].PropertyDescriptor = null; + } + + // pair the propertyDescriptor from each column to the actual property descriptor + // from the listManager + // + for (int i = 0; i < props.Count; i++) + { + DataGridColumnStyle col = gridCols.MapColumnStyleToPropertyName(props[i].Name); + if (col != null) + { + col.PropertyDescriptor = props[i]; + } + } + + // TableStyle::SetGridColumnStylesCollection will also set the + // relations list in the tableStyle. + gridTable.SetRelationsList(lm); + } + } + else + { + // we should put an assert, that this is the default Table Style +#if DEBUG + Debug.Assert(gridTable.IsDefault, "if we don't have a match, then the dataGRid should have the default table"); +#endif // DEBUG + gridTable.SetGridColumnStylesCollection(lm); + if (gridTable.GridColumnStyles.Count > 0 && gridTable.GridColumnStyles[0].Width == -1) + { +#if DEBUG + GridColumnStylesCollection cols = gridTable.GridColumnStyles; + for (int i = 0; i < cols.Count; i++) + { + Debug.Assert(cols[i].Width == -1, "if one column's width is not initialized, the same should be happening for the rest of the columns"); + } +#endif // DEBUG + InitializeColumnWidths(); + } + } + } + + /// + /// Sets the current GridTable for the DataGrid. + /// This GridTable is the table which is currently + /// being displayed on the grid. + /// + internal void SetDataGridTable(DataGridTableStyle newTable, bool forceColumnCreation) + { + // we have to listen to the dataGridTable for the propertyChangedEvent + if (myGridTable != null) + { + // unwire the propertyChanged event + UnWireTableStylePropChanged(myGridTable); + + if (myGridTable.IsDefault) + { + // reset the propertyDescriptors on the default table. + myGridTable.GridColumnStyles.ResetPropertyDescriptors(); + + // reset the relationship list from the default table + myGridTable.ResetRelationsList(); + } + } + + myGridTable = newTable; + + WireTableStylePropChanged(myGridTable); + + layout.RowHeadersVisible = newTable.IsDefault ? RowHeadersVisible : newTable.RowHeadersVisible; + + // we need to force the grid into the dataGridTableStyle + // this way the controls in the columns will be parented + // consider this scenario: when the user finished InitializeComponent, it added + // a bunch of tables. all of those tables will have the DataGrid property set to this + // grid. however, in InitializeComponent the tables will not have parented the + // edit controls w/ the grid. + // + // the code in DataGridTextBoxColumn already checks to see if the edits are parented + // before parenting them. + // + if (newTable != null) + { + newTable.DataGrid = this; + } + + // pair the tableStyles and GridColumns + // + if (listManager != null) + { + PairTableStylesAndGridColumns(listManager, myGridTable, forceColumnCreation); + } + + // reset the relations UI on the newTable + if (newTable != null) + { + newTable.ResetRelationsUI(); + } + + // set the isNavigating to false + gridState[GRIDSTATE_isNavigating] = false; + + horizScrollBar.Value = 0; + firstVisibleRow = 0; + currentCol = 0; + // if we add a tableStyle that mapps to the + // current listName, then we should set the currentRow to the + // position in the listManager + if (listManager == null) + { + currentRow = 0; + } + else + { + currentRow = listManager.Position == -1 ? 0 : listManager.Position; + } + + ResetHorizontalOffset(); + negOffset = 0; + ResetUIState(); + + // check the hierarchy + checkHierarchy = true; + } + + /// + /// Scrolls the data area down to make room for the parent rows + /// and lays out the different regions of the DataGrid. + /// + internal void SetParentRowsVisibility(bool visible) + { + Rectangle parentRowsRect = layout.ParentRows; + Rectangle underParentRows = layout.Data; + + if (layout.RowHeadersVisible) + { + underParentRows.X -= isRightToLeft() ? 0 : layout.RowHeaders.Width; + underParentRows.Width += layout.RowHeaders.Width; + } + + if (layout.ColumnHeadersVisible) + { + underParentRows.Y -= layout.ColumnHeaders.Height; + underParentRows.Height += layout.ColumnHeaders.Height; + } + + // hide the Edit Box + EndEdit(); + + if (visible) + { + layout.ParentRowsVisible = true; + PerformLayout(); + Invalidate(); + } + else + { + RECT scrollRECT = new Rectangle(underParentRows.X, underParentRows.Y - layout.ParentRows.Height, underParentRows.Width, underParentRows.Height + layout.ParentRows.Height); + + User32.ScrollWindow(this, 0, -parentRowsRect.Height, ref scrollRECT, ref scrollRECT); + + // If the vertical scrollbar was visible before and not after + // the ScrollWindow call, then we will not get invalidated + // completely. We need to translate the visual bounds of + // the scrollbar's old location up and invalidate. + // + if (vertScrollBar.Visible) + { + Rectangle fixupRect = vertScrollBar.Bounds; + fixupRect.Y -= parentRowsRect.Height; + fixupRect.Height += parentRowsRect.Height; + Invalidate(fixupRect); + } + + Debug.WriteLineIf(CompModSwitches.DataGridParents.TraceVerbose, "DataGridParents: Making parent rows invisible."); + layout.ParentRowsVisible = false; + PerformLayout(); + } + } + + /// + /// Sets whether a row is expanded or not. + /// + private void SetRowExpansionState(int row, bool expanded) + { + if (row < -1 || row > DataGridRowsLength - (policy.AllowAdd ? 2 : 1)) + { + throw new ArgumentOutOfRangeException(nameof(row)); + } + + DataGridRow[] localGridRows = DataGridRows; + if (row == -1) + { + DataGridRelationshipRow[] expandableRows = GetExpandableRows(); + bool repositionEditControl = false; + + for (int r = 0; r < expandableRows.Length; ++r) + { + if (expandableRows[r].Expanded != expanded) + { + expandableRows[r].Expanded = expanded; + repositionEditControl = true; + } + } + + if (repositionEditControl) + { + // we need to reposition the edit control + if (gridState[GRIDSTATE_isNavigating] || gridState[GRIDSTATE_isEditing]) + { + ResetSelection(); + Edit(); + } + } + } + else if (localGridRows[row] is DataGridRelationshipRow expandableRow) + { + if (expandableRow.Expanded != expanded) + { + // we need to reposition the edit control + if (gridState[GRIDSTATE_isNavigating] || gridState[GRIDSTATE_isEditing]) + { + ResetSelection(); + Edit(); + } + + expandableRow.Expanded = expanded; + } + } + } + + private void ObjectSiteChange(IContainer container, IComponent component, bool site) + { + if (site) + { + if (component.Site == null) + { + container.Add(component); + } + } + else + { + if (component.Site != null && component.Site.Container == container) + { + container.Remove(component); + } + } + } + + public void SubObjectsSiteChange(bool site) + { + DataGrid dgrid = this; + if (dgrid.DesignMode && dgrid.Site != null) + { + IDesignerHost host = (IDesignerHost)dgrid.Site.GetService(typeof(IDesignerHost)); + if (host != null) + { + DesignerTransaction trans = host.CreateTransaction(); + try + { + IContainer container = dgrid.Site.Container; + + DataGridTableStyle[] tables = new DataGridTableStyle[dgrid.TableStyles.Count]; + dgrid.TableStyles.CopyTo(tables, 0); + + for (int i = 0; i < tables.Length; i++) + { + DataGridTableStyle table = tables[i]; + ObjectSiteChange(container, table, site); + + DataGridColumnStyle[] columns = new DataGridColumnStyle[table.GridColumnStyles.Count]; + table.GridColumnStyles.CopyTo(columns, 0); + + for (int j = 0; j < columns.Length; j++) + { + DataGridColumnStyle column = columns[j]; + ObjectSiteChange(container, column, site); + } + } + } + finally + { + trans.Commit(); + } + } + } + } + + /// + /// Unselects a given row + /// + public void UnSelect(int row) + { + // + Debug.WriteLineIf(CompModSwitches.DataGridSelection.TraceVerbose, "DataGridSelection: Unselecting row " + row.ToString(CultureInfo.InvariantCulture)); + DataGridRow[] localGridRows = DataGridRows; + if (localGridRows[row].Selected) + { + localGridRows[row].Selected = false; + numSelectedRows--; + } + } + + /// + /// Asks the cursor to update. + /// + private void UpdateListManager() + { + Debug.WriteLineIf(CompModSwitches.DataGridCursor.TraceVerbose, "DataGridCursor: Requesting EndEdit()"); + try + { + if (listManager != null) + { + EndEdit(); + listManager.EndCurrentEdit(); + } + } + catch + { + } + } + + /// + /// Will return the string that will be used as a delimiter between columns + /// when copying rows contents to the Clipboard. + /// At the moment, return "\t" + /// + protected virtual string GetOutputTextDelimiter() + { + return "\t"; + } + + /// + /// The accessible object class for a DataGrid. The child accessible objects + /// are accessible objects corresponding to the propertygrid entries. + /// + [ComVisible(true)] + internal class DataGridAccessibleObject : ControlAccessibleObject + { + /// + /// Construct a PropertyGridViewAccessibleObject + /// + public DataGridAccessibleObject(DataGrid owner) : base(owner) + { + } + + internal DataGrid DataGrid + { + get + { + return (DataGrid)Owner; + } + } + + private int ColumnCountPrivate + { + get + { + return ((DataGrid)Owner).myGridTable.GridColumnStyles.Count; + } + } + + private int RowCountPrivate + { + get + { + return ((DataGrid)Owner).dataGridRows.Length; + } + } + + public override string Name + { + get + { + // Special case: If an explicit name has been set in the AccessibleName property, use that. + // Note: Any non-null value in AccessibleName overrides the default accessible name logic, + // even an empty string (this is the only way to *force* the accessible name to be blank). + string name = Owner.AccessibleName; + if (name != null) + { + return name; + } + + // Otherwise just return the default label string, minus any mnemonics + return "DataGrid"; + } + + set + { + // If anyone tries to set the accessible name, just cache the value in the control's + // AccessibleName property. This value will then end up overriding the normal accessible + // name logic, until such time as AccessibleName is set back to null. + Owner.AccessibleName = value; + } + } + + public override AccessibleRole Role + { + get + { + AccessibleRole role = Owner.AccessibleRole; + if (role != AccessibleRole.Default) + { + return role; + } + + return AccessibleRole.Table; + } + } + + public override AccessibleObject GetChild(int index) + { + DataGrid dataGrid = (DataGrid)Owner; + + int cols = ColumnCountPrivate; + int rows = RowCountPrivate; + + if (dataGrid.dataGridRows == null) + { + dataGrid.CreateDataGridRows(); + } + + if (index < 1) + { + return dataGrid.ParentRowsAccessibleObject; + } + else + { + index -= 1; + if (index < cols) + { + return dataGrid.myGridTable.GridColumnStyles[index].HeaderAccessibleObject; + } + else + { + index -= cols; + + if (index < rows) + { + Debug.Assert(dataGrid.dataGridRows[index].RowNumber == index, "Row number is wrong!"); + return dataGrid.dataGridRows[index].AccessibleObject; + } + else + { + index -= rows; + + if (dataGrid.horizScrollBar.Visible) + { + if (index == 0) + { + return dataGrid.horizScrollBar.AccessibilityObject; + } + + index--; + } + + if (dataGrid.vertScrollBar.Visible) + { + if (index == 0) + { + return dataGrid.vertScrollBar.AccessibilityObject; + } + + index--; + } + + int colCount = dataGrid.myGridTable.GridColumnStyles.Count; + int rowCount = dataGrid.dataGridRows.Length; + int currentRow = index / colCount; + int currentCol = index % colCount; + + if (currentRow < dataGrid.dataGridRows.Length && currentCol < dataGrid.myGridTable.GridColumnStyles.Count) + { + return dataGrid.dataGridRows[currentRow].AccessibleObject.GetChild(currentCol); + } + } + } + } + + return null; + } + + public override int GetChildCount() + { + int n = 1 + ColumnCountPrivate + ((DataGrid)Owner).DataGridRowsLength; + if (DataGrid.horizScrollBar.Visible) + { + n++; + } + + if (DataGrid.vertScrollBar.Visible) + { + n++; + } + + n += DataGrid.DataGridRows.Length * DataGrid.myGridTable.GridColumnStyles.Count; + return n; + } + + public override AccessibleObject GetFocused() + { + if (DataGrid.Focused) + { + return GetSelected(); + } + + return null; + } + + public override AccessibleObject GetSelected() + { + if (DataGrid.DataGridRows.Length == 0 || DataGrid.myGridTable.GridColumnStyles.Count == 0) + { + return null; + } + + DataGridCell cell = DataGrid.CurrentCell; + return GetChild(1 + ColumnCountPrivate + cell.RowNumber).GetChild(cell.ColumnNumber); + } + + public override AccessibleObject HitTest(int x, int y) + { + Point client = DataGrid.PointToClient(new Point(x, y)); + HitTestInfo hti = DataGrid.HitTest(client.X, client.Y); + + switch (hti.Type) + { + case HitTestType.RowHeader: + return GetChild(1 + ColumnCountPrivate + hti.Row); + case HitTestType.Cell: + return GetChild(1 + ColumnCountPrivate + hti.Row).GetChild(hti.Column); + case HitTestType.ColumnHeader: + return GetChild(1 + hti.Column); + case HitTestType.ParentRows: + return DataGrid.ParentRowsAccessibleObject; + case HitTestType.None: + case HitTestType.ColumnResize: + case HitTestType.RowResize: + case HitTestType.Caption: + break; + } + + return null; + } + + public override AccessibleObject Navigate(AccessibleNavigation navdir) + { + // We're only handling FirstChild and LastChild here + if (GetChildCount() > 0) + { + switch (navdir) + { + case AccessibleNavigation.FirstChild: + return GetChild(0); + case AccessibleNavigation.LastChild: + return GetChild(GetChildCount() - 1); + } + } + + return null; // Perform default behavior + } + } + + // + // This simple data structure holds all of the layout information + // for the DataGrid. + // + internal class LayoutData + { + internal bool dirty = true; + // region inside the Control's borders. + public Rectangle Inside = Rectangle.Empty; + + public Rectangle RowHeaders = Rectangle.Empty; + + public Rectangle TopLeftHeader = Rectangle.Empty; + public Rectangle ColumnHeaders = Rectangle.Empty; + public Rectangle Data = Rectangle.Empty; + + public Rectangle Caption = Rectangle.Empty; + public Rectangle ParentRows = Rectangle.Empty; + + public Rectangle ResizeBoxRect = Rectangle.Empty; + + public bool ColumnHeadersVisible; + public bool RowHeadersVisible; + public bool CaptionVisible; + public bool ParentRowsVisible; + + // used for resizing. + public Rectangle ClientRectangle = Rectangle.Empty; + + public LayoutData() + { + } + + public LayoutData(LayoutData src) + { + GrabLayout(src); + } + + private void GrabLayout(LayoutData src) + { + Inside = src.Inside; + TopLeftHeader = src.TopLeftHeader; + ColumnHeaders = src.ColumnHeaders; + RowHeaders = src.RowHeaders; + Data = src.Data; + Caption = src.Caption; + ParentRows = src.ParentRows; + ResizeBoxRect = src.ResizeBoxRect; + ColumnHeadersVisible = src.ColumnHeadersVisible; + RowHeadersVisible = src.RowHeadersVisible; + CaptionVisible = src.CaptionVisible; + ParentRowsVisible = src.ParentRowsVisible; + ClientRectangle = src.ClientRectangle; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(200); + sb.Append(base.ToString()); + sb.Append(" { \n"); + sb.Append("Inside = "); + sb.Append(Inside.ToString()); + sb.Append('\n'); + sb.Append("TopLeftHeader = "); + sb.Append(TopLeftHeader.ToString()); + sb.Append('\n'); + sb.Append("ColumnHeaders = "); + sb.Append(ColumnHeaders.ToString()); + sb.Append('\n'); + sb.Append("RowHeaders = "); + sb.Append(RowHeaders.ToString()); + sb.Append('\n'); + sb.Append("Data = "); + sb.Append(Data.ToString()); + sb.Append('\n'); + sb.Append("Caption = "); + sb.Append(Caption.ToString()); + sb.Append('\n'); + sb.Append("ParentRows = "); + sb.Append(ParentRows.ToString()); + sb.Append('\n'); + sb.Append("ResizeBoxRect = "); + sb.Append(ResizeBoxRect.ToString()); + sb.Append('\n'); + sb.Append("ColumnHeadersVisible = "); + sb.Append(ColumnHeadersVisible); + sb.Append('\n'); + sb.Append("RowHeadersVisible = "); + sb.Append(RowHeadersVisible); + sb.Append('\n'); + sb.Append("CaptionVisible = "); + sb.Append(CaptionVisible); + sb.Append('\n'); + sb.Append("ParentRowsVisible = "); + sb.Append(ParentRowsVisible); + sb.Append('\n'); + sb.Append("ClientRectangle = "); + sb.Append(ClientRectangle.ToString()); + sb.Append(" } "); + return sb.ToString(); + } + } + + /// + /// Contains information + /// about the part of the control the user + /// has clicked. This class cannot be inherited. + /// + public sealed class HitTestInfo + { + internal HitTestType type = HitTestType.None; + + internal int row; + internal int col; + + /// + /// Allows the object to inform you the + /// extent of the grid. + /// + public static readonly HitTestInfo Nowhere = new HitTestInfo(); + + internal HitTestInfo() + { + type = (HitTestType)0; + row = col = -1; + } + + internal HitTestInfo(HitTestType type) + { + this.type = type; + row = col = -1; + } + + /// + /// Gets the number of the clicked column. + /// + public int Column + { + get + { + return col; + } + } + + /// + /// Gets the + /// number of the clicked row. + /// + public int Row + { + get + { + return row; + } + } + + /// + /// Gets the part of the control, other than the row or column, that was + /// clicked. + /// + public HitTestType Type + { + get + { + return type; + } + } + + /// + /// Indicates whether two objects are identical. + /// + public override bool Equals(object value) + { + if (value is HitTestInfo ci) + { + return (type == ci.type && + row == ci.row && + col == ci.col); + } + + return false; + } + + /// + /// Gets the hash code for the instance. + /// + public override int GetHashCode() => HashCode.Combine(type, row, col); + + /// + /// Gets the type, row number, and column number. + /// + public override string ToString() + { + return "{ " + ((type).ToString()) + "," + row.ToString(CultureInfo.InvariantCulture) + "," + col.ToString(CultureInfo.InvariantCulture) + "}"; + } + } + + /// + /// Specifies the part of the + /// control the user has clicked. + /// + [Flags] + public enum HitTestType + { + None = 0x00000000, + Cell = 0x00000001, + ColumnHeader = 0x00000002, + RowHeader = 0x00000004, + ColumnResize = 0x00000008, + RowResize = 0x00000010, + Caption = 0x00000020, + ParentRows = 0x00000040 + } + + /// + /// Holds policy information for what the grid can and cannot do. + /// + private class Policy + { + private bool allowAdd = true; + private bool allowEdit = true; + private bool allowRemove = true; + + public Policy() + { + } + + public bool AllowAdd + { + get + { + return allowAdd; + } + set + { + if (allowAdd != value) + { + allowAdd = value; + } + } + } + + public bool AllowEdit + { + get + { + return allowEdit; + } + set + { + if (allowEdit != value) + { + allowEdit = value; + } + } + } + + public bool AllowRemove + { + get + { + return allowRemove; + } + set + { + if (allowRemove != value) + { + allowRemove = value; + } + } + } + + // returns true if the UI needs to be updated (here because addnew has changed) + public bool UpdatePolicy(CurrencyManager listManager, bool gridReadOnly) + { + bool change = false; + // only IBindingList can have an AddNewRow + IBindingList bl = listManager == null ? null : listManager.List as IBindingList; + if (listManager == null) + { + if (!allowAdd) + { + change = true; + } + + allowAdd = allowEdit = allowRemove = true; + } + else + { + if (AllowAdd != listManager.AllowAdd && !gridReadOnly) + { + change = true; + } + + AllowAdd = listManager.AllowAdd && !gridReadOnly && bl != null && bl.SupportsChangeNotification; + AllowEdit = listManager.AllowEdit && !gridReadOnly; + AllowRemove = listManager.AllowRemove && !gridReadOnly && bl != null && bl.SupportsChangeNotification; // + } + + return change; + } + } + + // + // Given the x coordinate and the Width of rectangle R1 inside rectangle rect, + // this function returns the x coordinate of the rectangle that + // corresponds to the Bi-Di transformation + // + private int MirrorRectangle(Rectangle R1, Rectangle rect, bool rightToLeft) + { + if (rightToLeft) + { + return rect.Right + rect.X - R1.Right; + } + else + { + return R1.X; + } + } + + // + // Given the x coordinate of a point inside rectangle rect, + // this function returns the x coordinate of the point that + // corresponds to the Bi-Di transformation + // + private int MirrorPoint(int x, Rectangle rect, bool rightToLeft) + { + if (rightToLeft) + { + return rect.Right + rect.X - x; + } + else + { + return x; + } + } + + // This function will return true if the RightToLeft property of the dataGrid is + // set to YES + private bool isRightToLeft() + { + return (RightToLeft == RightToLeft.Yes); + } + } +} + diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridAddNewRow.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridAddNewRow.cs new file mode 100644 index 00000000000..452d0fcc99b --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridAddNewRow.cs @@ -0,0 +1,128 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Drawing; + +namespace System.Windows.Forms +{ + /// + /// This class fully encapsulates the painting logic for an addnew row + /// appearing in a DataGrid. + /// + internal class DataGridAddNewRow : DataGridRow + { + private bool dataBound; + + public DataGridAddNewRow(DataGrid dGrid, DataGridTableStyle gridTable, int rowNum) + : base(dGrid, gridTable, rowNum) + { + } + + // =------------------------------------------------------------------ + // = Methods + // =------------------------------------------------------------------ + + /// + /// Since the DataView does not return a valid DataRow for + /// a newly added row, the DataGrid sets this property to + /// true to signal that the AddNewRow can safely render + /// row contents and permit editing, etc because a DataRecord + /// exists in the cursor that created this row. + /// + public bool DataBound + { + get + { + return dataBound; + } + set + { + dataBound = value; + } + } + + public override void OnEdit() + { + if (!DataBound) + { + DataGrid.AddNewRow(); + } + } + + public override void OnRowLeave() + { + if (DataBound) + { + DataBound = false; + } + } + + // the addNewRow has nothing to do with losing focus + // + internal override void LoseChildFocus(Rectangle rowHeader, bool alignToRight) + { + } + + // the newDataRow has nothing to do with TAB keys + // + internal override bool ProcessTabKey(Keys keyData, Rectangle rowHeaders, bool alignToRight) + { + return false; + } + + /// + /// Paints the row. + /// + public override int Paint(Graphics g, Rectangle bounds, Rectangle trueRowBounds, int firstVisibleColumn, int columnCount) + { + return Paint(g, bounds, trueRowBounds, firstVisibleColumn, columnCount, false); + } + + public override int Paint(Graphics g, + Rectangle bounds, + Rectangle trueRowBounds, + int firstVisibleColumn, + int columnCount, + bool alignToRight) + { + Rectangle dataBounds = bounds; + DataGridLineStyle gridStyle; + if (dgTable.IsDefault) + { + gridStyle = DataGrid.GridLineStyle; + } + else + { + gridStyle = dgTable.GridLineStyle; + } + + int bWidth = DataGrid == null ? 0 : gridStyle == DataGridLineStyle.Solid ? 1 : 0; + dataBounds.Height -= bWidth; + int cx = base.PaintData(g, dataBounds, firstVisibleColumn, columnCount, alignToRight); + + if (bWidth > 0) + { + PaintBottomBorder(g, bounds, cx, bWidth, alignToRight); + } + + return cx; + } + + protected override void PaintCellContents(Graphics g, Rectangle cellBounds, DataGridColumnStyle column, + Brush backBr, Brush foreBrush, bool alignToRight) + { + if (DataBound) + { + CurrencyManager listManager = DataGrid.ListManager; + column.Paint(g, cellBounds, listManager, RowNumber, alignToRight); + } + else + { + base.PaintCellContents(g, cellBounds, column, backBr, foreBrush, alignToRight); + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridBoolColumn.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridBoolColumn.cs new file mode 100644 index 00000000000..031fcb5a31e --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridBoolColumn.cs @@ -0,0 +1,538 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.ComponentModel; +using System.Drawing; + +namespace System.Windows.Forms +{ + /// + /// Specifies a column in + /// which each cell contains a check box for representing + /// a boolean value. + /// + public class DataGridBoolColumn : DataGridColumnStyle + { + private const int idealCheckSize = 14; + + private bool isEditing; + private bool isSelected; + private bool allowNull = true; + private int editingRow = -1; + private object currentValue = Convert.DBNull; + + private object trueValue = true; + private object falseValue = false; + private object nullValue = Convert.DBNull; + + private static readonly object EventTrueValue = new object(); + private static readonly object EventFalseValue = new object(); + private static readonly object EventAllowNull = new object(); + + /// + /// Initializes a new instance of the class. + /// + public DataGridBoolColumn() : base() { } + + /// + /// Initializes a new instance of a with the specified . + /// + public DataGridBoolColumn(PropertyDescriptor prop) + : base(prop) { } + + public DataGridBoolColumn(PropertyDescriptor prop, bool isDefault) + : base(prop, isDefault) { } + + /// + /// Gets or sets the actual value used when setting the + /// value of the column to . + /// + [TypeConverter(typeof(StringConverter)), + DefaultValue(true)] + public object TrueValue + { + get + { + return trueValue; + } + set + { + if (!trueValue.Equals(value)) + { + trueValue = value; + OnTrueValueChanged(EventArgs.Empty); + Invalidate(); + } + } + } + + public event EventHandler TrueValueChanged + { + add => Events.AddHandler(EventTrueValue, value); + remove => Events.RemoveHandler(EventTrueValue, value); + } + + /// + /// Gets or sets the actual value used when setting the value of the column to + /// . + /// + [TypeConverter(typeof(StringConverter)), DefaultValue(false)] + public object FalseValue + { + get + { + return falseValue; + } + set + { + if (!falseValue.Equals(value)) + { + falseValue = value; + OnFalseValueChanged(EventArgs.Empty); + Invalidate(); + } + } + } + + public event EventHandler FalseValueChanged + { + add => Events.AddHandler(EventFalseValue, value); + remove => Events.RemoveHandler(EventFalseValue, value); + } + + /// + /// Gets or sets the actual value used when setting the value of the column to + /// . + /// + [TypeConverter(typeof(StringConverter))] + public object NullValue + { + get + { + return nullValue; + } + set + { + if (!nullValue.Equals(value)) + { + nullValue = value; + OnFalseValueChanged(EventArgs.Empty); + Invalidate(); + } + } + } + + // =------------------------------------------------------------------ + // = Methods + // =------------------------------------------------------------------ + + // when the grid is in addNewRow it means that the user did not start typing + // so there is no data to be pushed back into the backEnd. + // make isEditing false so that in the Commit call we do not do any work. + // + protected internal override void ConcedeFocus() + { + base.ConcedeFocus(); + isSelected = false; + isEditing = false; + } + + private Rectangle GetCheckBoxBounds(Rectangle bounds, bool alignToRight) + { + if (alignToRight) + { + return new Rectangle(bounds.X + ((bounds.Width - idealCheckSize) / 2), + bounds.Y + ((bounds.Height - idealCheckSize) / 2), + bounds.Width < idealCheckSize ? bounds.Width : idealCheckSize, + idealCheckSize); + } + else + { + return new Rectangle(Math.Max(0, bounds.X + ((bounds.Width - idealCheckSize) / 2)), + Math.Max(0, bounds.Y + ((bounds.Height - idealCheckSize) / 2)), + bounds.Width < idealCheckSize ? bounds.Width : idealCheckSize, + idealCheckSize); + } + } + + /// + /// Gets the value at the specified row. + /// + protected internal override object GetColumnValueAtRow(CurrencyManager lm, int row) + { + object baseValue = base.GetColumnValueAtRow(lm, row); + object value = Convert.DBNull; + if (baseValue.Equals(trueValue)) + { + value = true; + } + else if (baseValue.Equals(falseValue)) + { + value = false; + } + + return value; + } + + private bool IsReadOnly() + { + bool ret = ReadOnly; + if (DataGridTableStyle != null) + { + ret = ret || DataGridTableStyle.ReadOnly; + if (DataGridTableStyle.DataGrid != null) + { + ret = ret || DataGridTableStyle.DataGrid.ReadOnly; + } + } + + return ret; + } + + /// + /// Sets the value a a specified row. + /// + protected internal override void SetColumnValueAtRow(CurrencyManager lm, int row, object value) + { + object baseValue = null; + if (true.Equals(value)) + { + baseValue = TrueValue; + } + else if (false.Equals(value)) + { + baseValue = FalseValue; + } + else if (Convert.IsDBNull(value)) + { + baseValue = NullValue; + } + + currentValue = baseValue; + base.SetColumnValueAtRow(lm, row, baseValue); + } + + /// + /// Gets the optimum width and height of a cell given + /// a specific value to contain. + /// + protected internal override Size GetPreferredSize(Graphics g, object value) + { + return new Size(idealCheckSize + 2, idealCheckSize + 2); + } + + /// + /// Gets + /// the height of a cell in a column. + /// + protected internal override int GetMinimumHeight() + { + return idealCheckSize + 2; + } + + /// + /// Gets the height used when resizing columns. + /// + protected internal override int GetPreferredHeight(Graphics g, object value) + { + return idealCheckSize + 2; + } + + /// + /// Initiates a request to interrupt an edit procedure. + /// + protected internal override void Abort(int rowNum) + { + isSelected = false; + isEditing = false; + Invalidate(); + return; + } + + /// + /// Initiates a request to complete an editing procedure. + /// + protected internal override bool Commit(CurrencyManager dataSource, int rowNum) + { + isSelected = false; + // always invalidate + Invalidate(); + if (!isEditing) + { + return true; + } + + SetColumnValueAtRow(dataSource, rowNum, currentValue); + isEditing = false; + return true; + } + + /// + /// Prepares the cell for editing a value. + /// + protected internal override void Edit(CurrencyManager source, + int rowNum, + Rectangle bounds, + bool readOnly, + string displayText, + bool cellIsVisible) + { + // toggle state right now... + isSelected = true; + + // move the focus away from the previous column and give it to the grid + // + DataGrid grid = DataGridTableStyle.DataGrid; + if (!grid.Focused) + { + grid.Focus(); + } + + if (!readOnly && !IsReadOnly()) + { + editingRow = rowNum; + currentValue = GetColumnValueAtRow(source, rowNum); + } + + base.Invalidate(); + } + + /// + /// Provides a handler for determining which key was pressed, and whether to + /// process it. + /// + internal override bool KeyPress(int rowNum, Keys keyData) + { + if (isSelected && editingRow == rowNum && !IsReadOnly()) + { + if ((keyData & Keys.KeyCode) == Keys.Space) + { + ToggleValue(); + Invalidate(); + return true; + } + } + + return base.KeyPress(rowNum, keyData); + } + + /// + /// Indicates whether the a mouse down event occurred at the specified row, at + /// the specified x and y coordinates. + /// + internal override bool MouseDown(int rowNum, int x, int y) + { + base.MouseDown(rowNum, x, y); + if (isSelected && editingRow == rowNum && !IsReadOnly()) + { + ToggleValue(); + Invalidate(); + return true; + } + + return false; + } + + private void OnTrueValueChanged(EventArgs e) + { + if (Events[EventTrueValue] is EventHandler eh) + { + eh(this, e); + } + } + + private void OnFalseValueChanged(EventArgs e) + { + if (Events[EventFalseValue] is EventHandler eh) + { + eh(this, e); + } + } + + private void OnAllowNullChanged(EventArgs e) + { + if (Events[EventAllowNull] is EventHandler eh) + { + eh(this, e); + } + } + + /// + /// Draws the + /// with the given , + /// and row number. + /// + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum) + { + Paint(g, bounds, source, rowNum, false); + } + + /// + /// Draws the + /// with the given , , + /// row number, and alignment settings. + /// + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) + { + Paint(g, bounds, source, rowNum, DataGridTableStyle.BackBrush, DataGridTableStyle.ForeBrush, alignToRight); + } + + /// + /// Draws the with the given , , + /// row number, , and . + /// + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, + Brush backBrush, Brush foreBrush, + bool alignToRight) + { + object value = (isEditing && editingRow == rowNum) ? currentValue : GetColumnValueAtRow(source, rowNum); + ButtonState checkedState = ButtonState.Inactive; + if (!Convert.IsDBNull(value)) + { + checkedState = ((bool)value ? ButtonState.Checked : ButtonState.Normal); + } + + Rectangle box = GetCheckBoxBounds(bounds, alignToRight); + + Region r = g.Clip; + g.ExcludeClip(box); + + Brush selectionBrush = DataGridTableStyle.IsDefault ? DataGridTableStyle.DataGrid.SelectionBackBrush : DataGridTableStyle.SelectionBackBrush; + if (isSelected && editingRow == rowNum && !IsReadOnly()) + { + g.FillRectangle(selectionBrush, bounds); + } + else + { + g.FillRectangle(backBrush, bounds); + } + + g.Clip = r; + + if (checkedState == ButtonState.Inactive) + { + ControlPaint.DrawMixedCheckBox(g, box, ButtonState.Checked); + } + else + { + ControlPaint.DrawCheckBox(g, box, checkedState); + } + + // if the column is read only we should still show selection + if (IsReadOnly() && isSelected && source.Position == rowNum) + { + bounds.Inflate(-1, -1); + Pen pen = new Pen(selectionBrush) + { + DashStyle = System.Drawing.Drawing2D.DashStyle.Dash + }; + g.DrawRectangle(pen, bounds); + pen.Dispose(); + // restore the bounds rectangle + bounds.Inflate(1, 1); + } + } + + /// + /// Gets or sets a value indicating whether null values are allowed. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(true), + SRDescription(nameof(SR.DataGridBoolColumnAllowNullValue)) + ] + public bool AllowNull + { + get + { + return allowNull; + } + set + { + if (allowNull != value) + { + allowNull = value; + // if we do not allow null, and the gridColumn had + // a null in it, discard it + if (!value && Convert.IsDBNull(currentValue)) + { + currentValue = false; + Invalidate(); + } + + OnAllowNullChanged(EventArgs.Empty); + } + } + } + + public event EventHandler AllowNullChanged + { + add => Events.AddHandler(EventAllowNull, value); + remove => Events.RemoveHandler(EventAllowNull, value); + } + + /// + /// Enters a into the column. + /// + protected internal override void EnterNullValue() + { + // do not throw an exception when the column is marked as readOnly or + // does not allowNull + if (!AllowNull || IsReadOnly()) + { + return; + } + + if (currentValue != Convert.DBNull) + { + currentValue = Convert.DBNull; + Invalidate(); + } + } + + private void ResetNullValue() + { + NullValue = Convert.DBNull; + } + + private bool ShouldSerializeNullValue() + { + return nullValue != Convert.DBNull; + } + + private void ToggleValue() + { + if (currentValue is bool && ((bool)currentValue) == false) + { + currentValue = true; + } + else + { + if (AllowNull) + { + if (Convert.IsDBNull(currentValue)) + { + currentValue = false; + } + else + { + currentValue = Convert.DBNull; + } + } + else + { + currentValue = false; + } + } + + // we started editing + isEditing = true; + // tell the dataGrid that things are changing + // we put Rectangle.Empty cause toggle will invalidate the row anyhow + DataGridTableStyle.DataGrid.ColumnStartedEditing(Rectangle.Empty); + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridCaption.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridCaption.cs new file mode 100644 index 00000000000..aacd7f25a26 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridCaption.cs @@ -0,0 +1,924 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; +using System.Globalization; + +namespace System.Windows.Forms +{ + /// + /// Represents a caption in the DataGrid control. + /// + internal class DataGridCaption + { + internal EventHandlerList events; + + private const int xOffset = 3; + private const int yOffset = 1; + private const int textPadding = 2; + private const int buttonToText = 4; + private static readonly ColorMap[] colorMap = new ColorMap[] { new ColorMap() }; + + private static readonly Point minimumBounds = new Point(50, 30); + + private readonly DataGrid dataGrid; + private bool backButtonVisible; + private bool downButtonVisible; + + private SolidBrush backBrush = DefaultBackBrush; + private SolidBrush foreBrush = DefaultForeBrush; + private readonly Pen textBorderPen = DefaultTextBorderPen; + + private string text = string.Empty; + private bool textBorderVisible; + private Font textFont; + + // use the datagridFont when the textFont is not set + // we cache this font ( cause we have to make it bold every time we paint the caption ) + // + private Font dataGridFont; + + private bool backActive; + private bool downActive; + private bool backPressed; + private bool downPressed; + + // if the downButton should point down or not + private bool downButtonDown; + + private static Bitmap leftButtonBitmap; + private static Bitmap leftButtonBitmap_bidi; + private static Bitmap magnifyingGlassBitmap; + + private Rectangle backButtonRect; + private Rectangle downButtonRect; + private Rectangle textRect; + + private CaptionLocation lastMouseLocation = CaptionLocation.Nowhere; + + private EventEntry eventList; + private static readonly object EVENT_BACKWARDCLICKED = new object(); + private static readonly object EVENT_DOWNCLICKED = new object(); + private static readonly object EVENT_CAPTIONCLICKED = new object(); + + internal DataGridCaption(DataGrid dataGrid) + { + this.dataGrid = dataGrid; + downButtonVisible = dataGrid.ParentRowsVisible; + colorMap[0].OldColor = Color.White; + colorMap[0].NewColor = ForeColor; + OnGridFontChanged(); + } + + internal void OnGridFontChanged() + { + if (dataGridFont == null || !dataGridFont.Equals(dataGrid.Font)) + { + try + { + dataGridFont = new Font(dataGrid.Font, FontStyle.Bold); + } + catch + { + } + } + } + + // =------------------------------------------------------------------ + // = Properties + // =------------------------------------------------------------------ + + internal bool BackButtonActive + { + get + { + return backActive; + } + set + { + if (backActive != value) + { + backActive = value; + InvalidateCaptionRect(backButtonRect); + } + } + } + + internal bool DownButtonActive + { + get + { + return downActive; + } + set + { + if (downActive != value) + { + downActive = value; + InvalidateCaptionRect(downButtonRect); + } + } + } + + internal static SolidBrush DefaultBackBrush + { + get + { + return (SolidBrush)SystemBrushes.ActiveCaption; + } + } + + internal static Pen DefaultTextBorderPen + { + get + { + return new Pen(SystemColors.ActiveCaptionText); + } + } + + internal static SolidBrush DefaultForeBrush + { + get + { + return (SolidBrush)SystemBrushes.ActiveCaptionText; + } + } + + internal Color BackColor + { + get + { + return backBrush.Color; + } + set + { + if (!backBrush.Color.Equals(value)) + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "Caption BackColor")); + } + + backBrush = new SolidBrush(value); + Invalidate(); + } + } + } + + internal EventHandlerList Events + { + get + { + if (events == null) + { + events = new EventHandlerList(); + } + + return events; + } + } + + internal Font Font + { + get + { + // use the dataGridFont only if the user + // did not set the CaptionFont + // + if (textFont == null) + { + return dataGridFont; + } + else + { + return textFont; + } + } + set + { + if (textFont == null || !textFont.Equals(value)) + { + textFont = value; + // this property gets called in the constructor before dataGrid has a caption + // and we don't need this special-handling then... + if (dataGrid.Caption != null) + { + dataGrid.RecalculateFonts(); + dataGrid.PerformLayout(); + dataGrid.Invalidate(); // smaller invalidate rect? + } + } + } + } + + internal bool ShouldSerializeFont() + { + return textFont != null && !textFont.Equals(dataGridFont); + } + + internal bool ShouldSerializeBackColor() + { + return !backBrush.Equals(DefaultBackBrush); + } + + internal void ResetBackColor() + { + if (ShouldSerializeBackColor()) + { + backBrush = DefaultBackBrush; + Invalidate(); + } + } + + internal void ResetForeColor() + { + if (ShouldSerializeForeColor()) + { + foreBrush = DefaultForeBrush; + Invalidate(); + } + } + + internal bool ShouldSerializeForeColor() + { + return !foreBrush.Equals(DefaultForeBrush); + } + + internal void ResetFont() + { + textFont = null; + Invalidate(); + } + + internal string Text + { + get + { + return text; + } + set + { + if (value == null) + { + text = string.Empty; + } + else + { + text = value; + } + + Invalidate(); + } + } + + internal bool TextBorderVisible + { + get + { + return textBorderVisible; + } + set + { + textBorderVisible = value; + Invalidate(); + } + } + + internal Color ForeColor + { + get + { + return foreBrush.Color; + } + set + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "Caption ForeColor")); + } + + foreBrush = new SolidBrush(value); + colorMap[0].NewColor = ForeColor; + Invalidate(); + } + } + + internal Point MinimumBounds + { + get + { + return minimumBounds; + } + } + + internal bool BackButtonVisible + { + get + { + return backButtonVisible; + } + set + { + if (backButtonVisible != value) + { + backButtonVisible = value; + Invalidate(); + } + } + } + + internal bool DownButtonVisible + { + get + { + return downButtonVisible; + } + set + { + if (downButtonVisible != value) + { + downButtonVisible = value; + Invalidate(); + } + } + } + + // =------------------------------------------------------------------ + // = Methods + // =------------------------------------------------------------------ + + protected virtual void AddEventHandler(object key, Delegate handler) + { + // Locking 'this' here is ok since this is an internal class. + lock (this) + { + if (handler == null) + { + return; + } + + for (EventEntry e = eventList; e != null; e = e.next) + { + if (e.key == key) + { + e.handler = Delegate.Combine(e.handler, handler); + return; + } + } + + eventList = new EventEntry(eventList, key, handler); + } + } + + /// + /// Adds a listener for the BackwardClicked event. + /// + internal event EventHandler BackwardClicked + { + add => Events.AddHandler(EVENT_BACKWARDCLICKED, value); + remove => Events.RemoveHandler(EVENT_BACKWARDCLICKED, value); + } + + /// + /// Adds a listener for the CaptionClicked event. + /// + internal event EventHandler CaptionClicked + { + add => Events.AddHandler(EVENT_CAPTIONCLICKED, value); + remove => Events.RemoveHandler(EVENT_CAPTIONCLICKED, value); + } + + internal event EventHandler DownClicked + { + add => Events.AddHandler(EVENT_DOWNCLICKED, value); + remove => Events.RemoveHandler(EVENT_DOWNCLICKED, value); + } + + private void Invalidate() + { + if (dataGrid != null) + { + dataGrid.InvalidateCaption(); + } + } + + private void InvalidateCaptionRect(Rectangle r) + { + if (dataGrid != null) + { + dataGrid.InvalidateCaptionRect(r); + } + } + + private void InvalidateLocation(CaptionLocation loc) + { + Rectangle r; + switch (loc) + { + case CaptionLocation.BackButton: + r = backButtonRect; + r.Inflate(1, 1); + InvalidateCaptionRect(r); + break; + case CaptionLocation.DownButton: + r = downButtonRect; + r.Inflate(1, 1); + InvalidateCaptionRect(r); + break; + } + } + + protected void OnBackwardClicked(EventArgs e) + { + if (backActive) + { + ((EventHandler)Events[EVENT_BACKWARDCLICKED])?.Invoke(this, e); + } + } + + protected void OnCaptionClicked(EventArgs e) + { + ((EventHandler)Events[EVENT_CAPTIONCLICKED])?.Invoke(this, e); + } + + protected void OnDownClicked(EventArgs e) + { + if (downActive && downButtonVisible) + { + ((EventHandler)Events[EVENT_DOWNCLICKED])?.Invoke(this, e); + } + } + + private Bitmap GetBitmap(string bitmapName) + { + try + { + return DpiHelper.GetBitmapFromIcon(typeof(DataGridCaption), bitmapName); + } + catch (Exception e) + { + Debug.Fail("Failed to load bitmap: " + bitmapName, e.ToString()); + return null; + } + } + + private Bitmap GetBackButtonBmp(bool alignRight) + { + if (alignRight) + { + if (leftButtonBitmap_bidi == null) + { + leftButtonBitmap_bidi = GetBitmap("DataGridCaption.backarrow_bidi"); + } + + return leftButtonBitmap_bidi; + } + else + { + if (leftButtonBitmap == null) + { + leftButtonBitmap = GetBitmap("DataGridCaption.backarrow"); + } + + return leftButtonBitmap; + } + } + + private Bitmap GetDetailsBmp() + { + if (magnifyingGlassBitmap == null) + { + magnifyingGlassBitmap = GetBitmap("DataGridCaption.Details"); + } + + return magnifyingGlassBitmap; + } + + protected virtual Delegate GetEventHandler(object key) + { + // Locking 'this' here is ok since this is an internal class. + lock (this) + { + for (EventEntry e = eventList; e != null; e = e.next) + { + if (e.key == key) + { + return e.handler; + } + } + + return null; + } + } + + internal Rectangle GetBackButtonRect(Rectangle bounds, bool alignRight, int downButtonWidth) + { + Bitmap backButtonBmp = GetBackButtonBmp(false); + Size backButtonSize; + lock (backButtonBmp) + { + backButtonSize = backButtonBmp.Size; + } + + return new Rectangle(bounds.Right - xOffset * 4 - downButtonWidth - backButtonSize.Width, + bounds.Y + yOffset + textPadding, + backButtonSize.Width, + backButtonSize.Height); + } + + internal int GetDetailsButtonWidth() + { + int width = 0; + Bitmap detailsBmp = GetDetailsBmp(); + lock (detailsBmp) + { + width = detailsBmp.Size.Width; + } + + return width; + } + + internal Rectangle GetDetailsButtonRect(Rectangle bounds, bool alignRight) + { + Size downButtonSize; + Bitmap detailsBmp = GetDetailsBmp(); + lock (detailsBmp) + { + downButtonSize = detailsBmp.Size; + } + + int downButtonWidth = downButtonSize.Width; + return new Rectangle(bounds.Right - xOffset * 2 - downButtonWidth, + bounds.Y + yOffset + textPadding, + downButtonWidth, + downButtonSize.Height); + } + + /// + /// Called by the dataGrid when it needs the caption + /// to repaint. + /// + internal void Paint(Graphics g, Rectangle bounds, bool alignRight) + { + Size textSize = new Size((int)g.MeasureString(text, Font).Width + 2, Font.Height + 2); + + downButtonRect = GetDetailsButtonRect(bounds, alignRight); + int downButtonWidth = GetDetailsButtonWidth(); + backButtonRect = GetBackButtonRect(bounds, alignRight, downButtonWidth); + + int backButtonArea = backButtonVisible ? backButtonRect.Width + xOffset + buttonToText : 0; + int downButtonArea = downButtonVisible && !dataGrid.ParentRowsIsEmpty() ? downButtonWidth + xOffset + buttonToText : 0; + + int textWidthLeft = bounds.Width - xOffset - backButtonArea - downButtonArea; + + textRect = new Rectangle( + bounds.X, + bounds.Y + yOffset, + Math.Min(textWidthLeft, 2 * textPadding + textSize.Width), + 2 * textPadding + textSize.Height); + + // align the caption text box, downButton, and backButton + // if the RigthToLeft property is set to true + if (alignRight) + { + textRect.X = bounds.Right - textRect.Width; + backButtonRect.X = bounds.X + xOffset * 4 + downButtonWidth; + downButtonRect.X = bounds.X + xOffset * 2; + } + + Debug.WriteLineIf(CompModSwitches.DGCaptionPaint.TraceVerbose, "text size = " + textSize.ToString()); + Debug.WriteLineIf(CompModSwitches.DGCaptionPaint.TraceVerbose, "downButtonWidth = " + downButtonWidth.ToString(CultureInfo.InvariantCulture)); + Debug.WriteLineIf(CompModSwitches.DGCaptionPaint.TraceVerbose, "textWidthLeft = " + textWidthLeft.ToString(CultureInfo.InvariantCulture)); + Debug.WriteLineIf(CompModSwitches.DGCaptionPaint.TraceVerbose, "backButtonRect " + backButtonRect.ToString()); + Debug.WriteLineIf(CompModSwitches.DGCaptionPaint.TraceVerbose, "textRect " + textRect.ToString()); + Debug.WriteLineIf(CompModSwitches.DGCaptionPaint.TraceVerbose, "downButtonRect " + downButtonRect.ToString()); + + // we should use the code that is commented out + // with today's code, there are pixels on the backButtonRect and the downButtonRect + // that are getting painted twice + // + g.FillRectangle(backBrush, bounds); + + if (backButtonVisible) + { + PaintBackButton(g, backButtonRect, alignRight); + if (backActive) + { + if (lastMouseLocation == CaptionLocation.BackButton) + { + backButtonRect.Inflate(1, 1); + ControlPaint.DrawBorder3D(g, backButtonRect, + backPressed ? Border3DStyle.SunkenInner : Border3DStyle.RaisedInner); + } + } + } + + PaintText(g, textRect, alignRight); + + if (downButtonVisible && !dataGrid.ParentRowsIsEmpty()) + { + PaintDownButton(g, downButtonRect); + // the rules have changed, yet again. + // now: if we show the parent rows and the mouse is + // not on top of this icon, then let the icon be depressed. + // if the mouse is pressed over the icon, then show the icon pressed + // if the mouse is over the icon and not pressed, then show the icon SunkenInner; + // + if (lastMouseLocation == CaptionLocation.DownButton) + { + downButtonRect.Inflate(1, 1); + ControlPaint.DrawBorder3D(g, downButtonRect, + downPressed ? Border3DStyle.SunkenInner : Border3DStyle.RaisedInner); + } + } + } + + private void PaintIcon(Graphics g, Rectangle bounds, Bitmap b) + { + ImageAttributes attr = new ImageAttributes(); + attr.SetRemapTable(colorMap, ColorAdjustType.Bitmap); + g.DrawImage(b, bounds, 0, 0, bounds.Width, bounds.Height, GraphicsUnit.Pixel, attr); + attr.Dispose(); + } + + private void PaintBackButton(Graphics g, Rectangle bounds, bool alignRight) + { + Bitmap backButtonBmp = GetBackButtonBmp(alignRight); + lock (backButtonBmp) + { + PaintIcon(g, bounds, backButtonBmp); + } + } + + private void PaintDownButton(Graphics g, Rectangle bounds) + { + Bitmap detailsBmp = GetDetailsBmp(); + lock (detailsBmp) + { + PaintIcon(g, bounds, detailsBmp); + } + } + + private void PaintText(Graphics g, Rectangle bounds, bool alignToRight) + { + Rectangle textBounds = bounds; + + if (textBounds.Width <= 0 || textBounds.Height <= 0) + { + return; + } + + if (textBorderVisible) + { + g.DrawRectangle(textBorderPen, textBounds.X, textBounds.Y, textBounds.Width - 1, textBounds.Height - 1); + textBounds.Inflate(-1, -1); + } + + if (textPadding > 0) + { + Rectangle border = textBounds; + border.Height = textPadding; + g.FillRectangle(backBrush, border); + + border.Y = textBounds.Bottom - textPadding; + g.FillRectangle(backBrush, border); + + border = new Rectangle(textBounds.X, textBounds.Y + textPadding, + textPadding, textBounds.Height - 2 * textPadding); + g.FillRectangle(backBrush, border); + + border.X = textBounds.Right - textPadding; + g.FillRectangle(backBrush, border); + textBounds.Inflate(-textPadding, -textPadding); + } + + g.FillRectangle(backBrush, textBounds); + + // Brush foreBrush = new SolidBrush(dataGrid.CaptionForeColor); + StringFormat format = new StringFormat(); + if (alignToRight) + { + format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + format.Alignment = StringAlignment.Far; + } + + g.DrawString(text, Font, foreBrush, textBounds, format); + format.Dispose(); + // foreBrush.Dispose(); + } + + private CaptionLocation FindLocation(int x, int y) + { + if (!backButtonRect.IsEmpty) + { + if (backButtonRect.Contains(x, y)) + { + return CaptionLocation.BackButton; + } + } + + if (!downButtonRect.IsEmpty) + { + if (downButtonRect.Contains(x, y)) + { + return CaptionLocation.DownButton; + } + } + + if (!textRect.IsEmpty) + { + if (textRect.Contains(x, y)) + { + return CaptionLocation.Text; + } + } + + return CaptionLocation.Nowhere; + } + + private bool DownButtonDown + { + get + { + return downButtonDown; + } + set + { + if (downButtonDown != value) + { + downButtonDown = value; + InvalidateLocation(CaptionLocation.DownButton); + } + } + } + + internal bool GetDownButtonDirection() + { + return DownButtonDown; + } + + /// + /// Called by the dataGrid when the mouse is pressed + /// inside the caption. + /// + internal void MouseDown(int x, int y) + { + CaptionLocation loc = FindLocation(x, y); + switch (loc) + { + case CaptionLocation.BackButton: + backPressed = true; + InvalidateLocation(loc); + break; + case CaptionLocation.DownButton: + downPressed = true; + InvalidateLocation(loc); + break; + case CaptionLocation.Text: + OnCaptionClicked(EventArgs.Empty); + break; + } + } + + /// + /// Called by the dataGrid when the mouse is released + /// inside the caption. + /// + internal void MouseUp(int x, int y) + { + CaptionLocation loc = FindLocation(x, y); + switch (loc) + { + case CaptionLocation.DownButton: + if (downPressed == true) + { + downPressed = false; + OnDownClicked(EventArgs.Empty); + } + + break; + case CaptionLocation.BackButton: + if (backPressed == true) + { + backPressed = false; + OnBackwardClicked(EventArgs.Empty); + } + + break; + } + } + + /// + /// Called by the dataGrid when the mouse leaves + /// the caption area. + /// + internal void MouseLeft() + { + CaptionLocation oldLoc = lastMouseLocation; + lastMouseLocation = CaptionLocation.Nowhere; + InvalidateLocation(oldLoc); + } + + /// + /// Called by the dataGrid when the mouse is + /// inside the caption. + /// + internal void MouseOver(int x, int y) + { + CaptionLocation newLoc = FindLocation(x, y); + + InvalidateLocation(lastMouseLocation); + InvalidateLocation(newLoc); + lastMouseLocation = newLoc; + } + + protected virtual void RaiseEvent(object key, EventArgs e) + { + Delegate handler = GetEventHandler(key); + if (handler != null) + { + ((EventHandler)handler)(this, e); + } + } + + protected virtual void RemoveEventHandler(object key, Delegate handler) + { + // Locking 'this' here is ok since this is an internal class. + lock (this) + { + if (handler == null) + { + return; + } + + for (EventEntry e = eventList, prev = null; e != null; prev = e, e = e.next) + { + if (e.key == key) + { + e.handler = Delegate.Remove(e.handler, handler); + if (e.handler == null) + { + if (prev == null) + { + eventList = e.next; + } + else + { + prev.next = e.next; + } + } + + return; + } + } + } + } + + protected virtual void RemoveEventHandlers() + { + eventList = null; + } + + internal void SetDownButtonDirection(bool pointDown) + { + DownButtonDown = pointDown; + } + + /// + /// Toggles the direction the "Down Button" is pointing. + /// + internal bool ToggleDownButtonDirection() + { + DownButtonDown = !DownButtonDown; + return DownButtonDown; + } + + internal enum CaptionLocation + { + Nowhere, + BackButton, + DownButton, + Text + } + + private sealed class EventEntry + { + internal EventEntry next; + internal object key; + internal Delegate handler; + + internal EventEntry(EventEntry next, object key, Delegate handler) + { + this.next = next; + this.key = key; + this.handler = handler; + } + } + } +} + diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridCell.cs new file mode 100644 index 00000000000..44d9e7ace01 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridCell.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +namespace System.Windows.Forms +{ + /// + /// Identifies a cell in the grid. + /// + public struct DataGridCell + { + /// + /// Gets or sets the number of a column in the control. + /// + public int ColumnNumber { get; set; } + + /// + /// Gets or sets the number of a row in the control. + /// + public int RowNumber { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public DataGridCell(int r, int c) + { + RowNumber = r; + ColumnNumber = c; + } + + /// + /// Gets a value indicating whether the is + /// identical to a second . + /// + public override bool Equals(object o) + { + if (!(o is DataGridCell rhs)) + { + return false; + } + + return rhs.RowNumber == RowNumber && rhs.ColumnNumber == ColumnNumber; + } + + /// + /// Gets a hash value that uniquely identifies the cell. + /// + public override int GetHashCode() => HashCode.Combine(RowNumber, ColumnNumber); + + /// + /// Gets the row number and column number of the cell. + /// + public override string ToString() + { + return "DataGridCell {RowNumber = " + RowNumber + ", ColumnNumber = " + ColumnNumber + "}"; + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridColumnStyle.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridColumnStyle.cs new file mode 100644 index 00000000000..0b0ff1e1627 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridColumnStyle.cs @@ -0,0 +1,787 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace System.Windows.Forms +{ + /// + /// Specifies the appearance and text formatting and behavior of a control column. + /// + [ToolboxItem(false)] + [DesignTimeVisible(false)] + [DefaultProperty(nameof(HeaderText))] + public abstract class DataGridColumnStyle : Component, IDataGridColumnStyleEditingNotificationService + { + private HorizontalAlignment _alignment = HorizontalAlignment.Left; + private PropertyDescriptor _propertyDescriptor; + private DataGridTableStyle _dataGridTableStyle; + private string _mappingName = string.Empty; + private string _headerName = string.Empty; + private bool _invalid; + private string _nullText = SR.DataGridNullText; + private bool _readOnly; + private bool _updating; + internal int _width = -1; + private AccessibleObject _headerAccessibleObject; + + private static readonly object s_alignmentEvent = new object(); + private static readonly object s_propertyDescriptorEvent = new object(); + private static readonly object s_headerTextEvent = new object(); + private static readonly object s_mappingNameEvent = new object(); + private static readonly object s_nullTextEvent = new object(); + private static readonly object s_readOnlyEvent = new object(); + private static readonly object s_widthEvent = new object(); + + /// + /// In a derived class, initializes a new instance of the + /// class. + /// + public DataGridColumnStyle() + { + } + + /// + /// Initializes a new instance of the + /// class with the specified . + /// + public DataGridColumnStyle(PropertyDescriptor prop) : this() + { + PropertyDescriptor = prop; + if (prop != null) + { + _readOnly = prop.IsReadOnly; + } + } + + private protected DataGridColumnStyle(PropertyDescriptor prop, bool isDefault) : this(prop) + { +#if DEBUG + IsDefault = isDefault; +#endif + if (isDefault && prop != null) + { + // take the header name from the property name + _headerName = prop.Name; + _mappingName = prop.Name; + } + } + +#if DEBUG + internal bool IsDefault { get; } +#endif + + /// + /// Gets or sets the alignment of text in a column. + /// + [SRCategory(nameof(SR.CatDisplay))] + [Localizable(true)] + [DefaultValue(HorizontalAlignment.Left)] + public virtual HorizontalAlignment Alignment + { + get => _alignment; + set + { + if (!ClientUtils.IsEnumValid(value, (int)value, (int)HorizontalAlignment.Left, (int)HorizontalAlignment.Center)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(DataGridLineStyle)); + } + + if (_alignment != value) + { + _alignment = value; + OnAlignmentChanged(EventArgs.Empty); + Invalidate(); + } + } + } + + public event EventHandler AlignmentChanged + { + add => Events.AddHandler(s_alignmentEvent, value); + remove => Events.RemoveHandler(s_alignmentEvent, value); + } + + /// + /// When overridden in a derived class, updates the value of a specified row with + /// the given text. + /// + protected internal virtual void UpdateUI(CurrencyManager source, int rowNum, string displayText) + { + } + + /// + /// Gets or sets the background color of the column. + /// + [Browsable(false)] + public AccessibleObject HeaderAccessibleObject + { + get => _headerAccessibleObject ?? (_headerAccessibleObject = CreateHeaderAccessibleObject()); + } + + /// + /// Gets or sets the that determines the + /// attributes of data displayed by the . + /// + [DefaultValue(null)] + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Advanced)] + public virtual PropertyDescriptor PropertyDescriptor + { + get => _propertyDescriptor; + set + { + if (_propertyDescriptor != value) + { + _propertyDescriptor = value; + OnPropertyDescriptorChanged(EventArgs.Empty); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)] + public event EventHandler PropertyDescriptorChanged + { + add => Events.AddHandler(s_propertyDescriptorEvent, value); + remove => Events.RemoveHandler(s_propertyDescriptorEvent, value); + } + + protected virtual AccessibleObject CreateHeaderAccessibleObject() + { + return new DataGridColumnHeaderAccessibleObject(this); + } + + /// + /// When overridden in a derived class, sets the + /// control that this column belongs to. + /// + protected virtual void SetDataGrid(DataGrid value) + { + SetDataGridInColumn(value); + } + + /// + /// When overridden in a derived class, sets the + /// for the column. + /// + protected virtual void SetDataGridInColumn(DataGrid value) + { + // we need to set up the PropertyDescriptor + if (PropertyDescriptor == null && value != null) + { + CurrencyManager lm = value.ListManager; + if (lm == null) + { + return; + } + + PropertyDescriptorCollection propCollection = lm.GetItemProperties(); + int propCount = propCollection.Count; + for (int i = 0; i < propCollection.Count; i++) + { + PropertyDescriptor prop = propCollection[i]; + if (!typeof(IList).IsAssignableFrom(prop.PropertyType) && prop.Name.Equals(HeaderText)) + { + PropertyDescriptor = prop; + return; + } + } + } + } + + internal void SetDataGridInternalInColumn(DataGrid value) + { + if (value == null || value.Initializing) + { + return; + } + + SetDataGridInColumn(value); + } + + /// + /// Gets the System.Windows.Forms.DataGridTableStyle for the column. + /// + [Browsable(false)] + public virtual DataGridTableStyle DataGridTableStyle => _dataGridTableStyle; + + internal void SetDataGridTableInColumn(DataGridTableStyle value, bool force) + { + if (_dataGridTableStyle != null && _dataGridTableStyle.Equals(value) && !force) + { + return; + } + + if (value != null && value.DataGrid != null && !value.DataGrid.Initializing) + { + SetDataGridInColumn(value.DataGrid); + } + + _dataGridTableStyle = value; + } + + /// + /// Gets the height of the column's font. + /// + protected int FontHeight + { + get => DataGridTableStyle?.DataGrid?.FontHeight ?? DataGridTableStyle.defaultFontHeight; + } + + public event EventHandler FontChanged + { + add { } + remove { } + } + + /// + /// Gets or sets the text of the column header. + /// + [Localizable(true)] + [SRCategory(nameof(SR.CatDisplay))] + public virtual string HeaderText + { + get => _headerName; + set + { + if (value == null) + { + value = string.Empty; + } + + if (!_headerName.Equals(value)) + { + _headerName = value; + OnHeaderTextChanged(EventArgs.Empty); + // we only invalidate columns that are visible ( ie, their propertyDescriptor is not null) + if (PropertyDescriptor != null) + { + Invalidate(); + } + } + } + } + + public event EventHandler HeaderTextChanged + { + add => Events.AddHandler(s_headerTextEvent, value); + remove => Events.RemoveHandler(s_headerTextEvent, value); + } + + [Editor("System.Windows.Forms.Design.DataGridColumnStyleMappingNameEditor, " + AssemblyRef.SystemDesign, typeof(Drawing.Design.UITypeEditor))] + [Localizable(true)] + [DefaultValue("")] + public string MappingName + { + get => _mappingName; + set + { + if (value == null) + { + value = string.Empty; + } + + if (!_mappingName.Equals(value)) + { + string originalMappingName = _mappingName; + _mappingName = value; + try + { + _dataGridTableStyle?.GridColumnStyles.CheckForMappingNameDuplicates(this); + } + catch + { + _mappingName = originalMappingName; + throw; + } + + OnMappingNameChanged(EventArgs.Empty); + } + } + } + + public event EventHandler MappingNameChanged + { + add => Events.AddHandler(s_mappingNameEvent, value); + remove => Events.RemoveHandler(s_mappingNameEvent, value); + } + + /// + /// Indicates whether the System.Windows.Forms.DataGridColumnStyle.HeaderText property + /// should be persisted. + /// + private bool ShouldSerializeHeaderText() + { + return (_headerName.Length != 0); + } + + /// + /// Resets the System.Windows.Forms.DataGridColumnStyle.HeaderText to its default value. + /// + public void ResetHeaderText() => HeaderText = string.Empty; + + /// + /// Gets or sets the text that is displayed when the column contains a null + /// value. + /// + [Localizable(true)] + [SRCategory(nameof(SR.CatDisplay))] + public virtual string NullText + { + get => _nullText; + set + { + if (_nullText != value) + { + _nullText = value; + OnNullTextChanged(EventArgs.Empty); + Invalidate(); + } + } + } + + public event EventHandler NullTextChanged + { + add => Events.AddHandler(s_nullTextEvent, value); + remove => Events.RemoveHandler(s_nullTextEvent, value); + } + + /// + /// Gets or sets a value indicating whether the data in the column cannot be edited. + /// + [DefaultValue(false)] + public virtual bool ReadOnly + { + get => _readOnly; + set + { + if (_readOnly != value) + { + _readOnly = value; + OnReadOnlyChanged(EventArgs.Empty); + } + } + } + + public event EventHandler ReadOnlyChanged + { + add => Events.AddHandler(s_readOnlyEvent, value); + remove => Events.RemoveHandler(s_readOnlyEvent, value); + } + + /// + /// Gets or sets the width of the column. + /// + [SRCategory(nameof(SR.CatLayout))] + [Localizable(true)] + [DefaultValue(100)] + public virtual int Width + { + get => _width; + set + { + if (_width != value) + { + _width = value; + DataGrid grid = DataGridTableStyle?.DataGrid; + if (grid != null) + { + // rearrange the scroll bars + grid.PerformLayout(); + + // force the grid to repaint + grid.InvalidateInside(); + } + + OnWidthChanged(EventArgs.Empty); + } + } + } + + public event EventHandler WidthChanged + { + add => Events.AddHandler(s_widthEvent, value); + remove => Events.RemoveHandler(s_widthEvent, value); + } + + /// + /// Suspends the painting of the column until the + /// method is called. + /// + protected void BeginUpdate() => _updating = true; + + /// + /// Resumes the painting of columns suspended by calling the + /// method. + /// + protected void EndUpdate() + { + _updating = false; + if (_invalid) + { + _invalid = false; + Invalidate(); + } + } + + internal virtual string GetDisplayText(object value) => value.ToString(); + + private void ResetNullText() => NullText = SR.DataGridNullText; + + private bool ShouldSerializeNullText() => !SR.DataGridNullText.Equals(_nullText); + + /// + /// When overridden in a derived class, gets the optimum width and height of the + /// specified value. + /// + protected internal abstract Size GetPreferredSize(Graphics g, object value); + + /// + /// Gets the minimum height of a row. + /// + protected internal abstract int GetMinimumHeight(); + + /// + /// When overridden in a derived class, gets the height to be used in for + /// automatically resizing columns. + /// + protected internal abstract int GetPreferredHeight(Graphics g, object value); + + /// + /// Gets the value in the specified row from the specified System.Windows.Forms.ListManager. + /// + protected internal virtual object GetColumnValueAtRow(CurrencyManager source, int rowNum) + { + CheckValidDataSource(source); + PropertyDescriptor descriptor = PropertyDescriptor; + if (descriptor == null) + { + throw new InvalidOperationException(SR.DataGridColumnNoPropertyDescriptor); + } + + return descriptor.GetValue(source[rowNum]); + } + + /// + /// Redraws the column and causes a paint message to be sent to the control. + /// + protected virtual void Invalidate() + { + if (_updating) + { + _invalid = true; + return; + } + + DataGridTableStyle?.InvalidateColumn(this); + } + + /// + /// Checks if the specified DataView is valid. + /// + protected void CheckValidDataSource(CurrencyManager value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + // The code may delete a gridColumn that was editing. + // In that case, we still have to push the value into the backend + // and we only need the propertyDescriptor to push the value. + // (take a look at gridEditAndDeleteEditColumn) + if (PropertyDescriptor == null) + { + throw new InvalidOperationException(string.Format(SR.DataGridColumnUnbound, HeaderText)); + } + } + + /// + /// When overridden in a derived class, initiates a request to interrrupt an edit + /// procedure. + /// + protected internal abstract void Abort(int rowNum); + + /// + /// When overridden in a derived class, inititates a request to complete an + /// editing procedure. + /// + protected internal abstract bool Commit(CurrencyManager dataSource, int rowNum); + + /// + /// When overridden in a deriving class, prepares a cell for editing. + /// + protected internal virtual void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly) + { + Edit(source, rowNum, bounds, readOnly, null, true); + } + + /// + /// Prepares the cell for editing, passing the specified , + /// row number, , argument indicating whether + /// the column is read-only, and the text to display in the new control. + /// + protected internal virtual void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText) + { + Edit(source, rowNum, bounds, readOnly, displayText, true); + } + + /// + /// When overridden in a deriving class, prepares a cell for editing. + /// + protected internal abstract void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText, bool cellIsVisible); + + /// + /// Indicates whether the a mouse down event occurred at the specified row, at + /// the specified x and y coordinates. + /// + internal virtual bool MouseDown(int rowNum, int x, int y) + { + return false; + } + + /// + /// When overriden in a derived class, enters a + /// into the column. + /// + protected internal virtual void EnterNullValue() + { + } + + /// + /// Provides a handler for determining which key was pressed, and whether to + /// process it. + /// + internal virtual bool KeyPress(int rowNum, Keys keyData) + { + // if this is read only then do not do anything + if (ReadOnly || (DataGridTableStyle != null && DataGridTableStyle.DataGrid != null && DataGridTableStyle.DataGrid.ReadOnly)) + { + return false; + } + + if (keyData == (Keys.Control | Keys.NumPad0) || keyData == (Keys.Control | Keys.D0)) + { + EnterNullValue(); + return true; + } + + return false; + } + + /// + /// When overridden in a derived class, directs the column to concede focus with + /// an appropriate action. + /// + protected internal virtual void ConcedeFocus() + { + } + + /// + /// Paints the a with the specified + /// , , + /// System.Windows.Forms.CurrencyManager, and row number. + /// + protected internal abstract void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum); + + /// + /// When overridden in a derived class, paints a + /// with the specified , , + /// see Rectangle, row number, and alignment. + /// + protected internal abstract void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight); + + /// + /// Paints a with the specified , , see System.Data.DataView, row number, background color, foreground color, and alignment. + /// + protected internal virtual void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, + Brush backBrush, Brush foreBrush, bool alignToRight) + { + Paint(g, bounds, source, rowNum, alignToRight); + } + + private void OnPropertyDescriptorChanged(EventArgs e) + { + EventHandler eh = Events[s_propertyDescriptorEvent] as EventHandler; + eh?.Invoke(this, e); + } + + private void OnAlignmentChanged(EventArgs e) + { + EventHandler eh = Events[s_alignmentEvent] as EventHandler; + eh?.Invoke(this, e); + } + + private void OnHeaderTextChanged(EventArgs e) + { + EventHandler eh = Events[s_headerTextEvent] as EventHandler; + eh?.Invoke(this, e); + } + + private void OnMappingNameChanged(EventArgs e) + { + EventHandler eh = Events[s_mappingNameEvent] as EventHandler; + eh?.Invoke(this, e); + } + + private void OnReadOnlyChanged(EventArgs e) + { + EventHandler eh = Events[s_readOnlyEvent] as EventHandler; + eh?.Invoke(this, e); + } + + private void OnNullTextChanged(EventArgs e) + { + EventHandler eh = Events[s_nullTextEvent] as EventHandler; + eh?.Invoke(this, e); + } + + private void OnWidthChanged(EventArgs e) + { + EventHandler eh = Events[s_widthEvent] as EventHandler; + eh?.Invoke(this, e); + } + + /// + /// Sets the value in a specified row with the value from a specified see DataView. + /// + protected internal virtual void SetColumnValueAtRow(CurrencyManager source, int rowNum, object value) + { + CheckValidDataSource(source); + PropertyDescriptor descriptor = PropertyDescriptor; + if (descriptor == null) + { + throw new InvalidOperationException(SR.DataGridColumnNoPropertyDescriptor); + } + + if (source.Position != rowNum) + { + throw new ArgumentException(SR.DataGridColumnListManagerPosition, nameof(rowNum)); + } + + if (source[rowNum] is IEditableObject editableObject) + { + editableObject.BeginEdit(); + } + + descriptor.SetValue(source[rowNum], value); + } + + protected internal virtual void ColumnStartedEditing(Control editingControl) + { + DataGridTableStyle?.DataGrid?.ColumnStartedEditing(editingControl); + } + + void IDataGridColumnStyleEditingNotificationService.ColumnStartedEditing(Control editingControl) + { + ColumnStartedEditing(editingControl); + } + + protected internal virtual void ReleaseHostedControl() + { + } + + protected class CompModSwitches + { + private static TraceSwitch dgEditColumnEditing; + + public static TraceSwitch DGEditColumnEditing + { + get + { + if (dgEditColumnEditing == null) + { + dgEditColumnEditing = new TraceSwitch("DGEditColumnEditing", "Editing related tracing"); + } + + return dgEditColumnEditing; + } + } + } + + [ComVisible(true)] + protected class DataGridColumnHeaderAccessibleObject : AccessibleObject + { + public DataGridColumnHeaderAccessibleObject(DataGridColumnStyle owner) : this() + { + Debug.Assert(owner != null, "DataGridColumnHeaderAccessibleObject must have a valid owner DataGridColumn"); + Owner = owner; + } + + public DataGridColumnHeaderAccessibleObject() : base() + { + } + + public override Rectangle Bounds + { + get + { + // we need to get the width and the X coordinate of this column on the screen + // we can't just cache this, cause the column may be moved in the collection + if (Owner.PropertyDescriptor == null) + { + return Rectangle.Empty; + } + + DataGrid dg = DataGrid; + if (dg.DataGridRowsLength == 0) + { + return Rectangle.Empty; + } + + // We need to find this column's offset in the gridColumnCollection. + GridColumnStylesCollection cols = Owner._dataGridTableStyle.GridColumnStyles; + int offset = -1; + for (int i = 0; i < cols.Count; i++) + { + if (cols[i] == Owner) + { + offset = i; + break; + } + } + + Debug.Assert(offset >= 0, "this column must be in a collection, otherwise its bounds are useless"); + Rectangle rect = dg.GetCellBounds(0, offset); + // Now add the Y coordinate of the datagrid.Layout.Data. + // It should be the same as dataGrid.Layout.ColumnHeaders + rect.Y = dg.GetColumnHeadersRect().Y; + return dg.RectangleToScreen(rect); + } + } + + public override string Name => Owner._headerName; + + protected DataGridColumnStyle Owner { get; } + + public override AccessibleObject Parent => DataGrid.AccessibilityObject; + + private DataGrid DataGrid => Owner._dataGridTableStyle.dataGrid; + + public override AccessibleRole Role => AccessibleRole.ColumnHeader; + + public override AccessibleObject Navigate(AccessibleNavigation navdir) + { + switch (navdir) + { + case AccessibleNavigation.Right: + case AccessibleNavigation.Next: + case AccessibleNavigation.Down: + return Parent.GetChild(1 + Owner._dataGridTableStyle.GridColumnStyles.IndexOf(Owner) + 1); + case AccessibleNavigation.Up: + case AccessibleNavigation.Left: + case AccessibleNavigation.Previous: + return Parent.GetChild(1 + Owner._dataGridTableStyle.GridColumnStyles.IndexOf(Owner) - 1); + } + + return null; + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridLineStyle.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridLineStyle.cs new file mode 100644 index 00000000000..6464f1606ae --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridLineStyle.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +namespace System.Windows.Forms +{ + /// + /// Specifies the style of gridlines in a . + /// + public enum DataGridLineStyle + { + /// + /// No gridlines between cells. + /// + None, + + /// + /// Solid gridlines between cells. + /// + Solid + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridParentRows.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridParentRows.cs new file mode 100644 index 00000000000..89d16919e76 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridParentRows.cs @@ -0,0 +1,1410 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Collections; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.Text; + +namespace System.Windows.Forms +{ + internal class DataGridParentRows + { + // siting + // + private readonly DataGrid dataGrid; + + // ui + // + // private Color backColor = DataGrid.defaultParentRowsBackColor; + // private Color foreColor = DataGrid.defaultParentRowsForeColor; + + private SolidBrush backBrush = DataGrid.DefaultParentRowsBackBrush; + private SolidBrush foreBrush = DataGrid.DefaultParentRowsForeBrush; + + private readonly int borderWidth = 1; + // private Color borderColor = SystemColors.WindowFrame; + private Brush borderBrush = new SolidBrush(SystemColors.WindowFrame); + + private static Bitmap rightArrow; + private static Bitmap leftArrow; + + private readonly ColorMap[] colorMap = new ColorMap[] { new ColorMap() }; + + // private bool gridLineDots = false; + // private Color gridLineColor = SystemColors.Control; + // private Brush gridLineBrush = SystemBrushes.Control; + private readonly Pen gridLinePen = SystemPens.Control; + + private int totalHeight; + private int textRegionHeight; + + // now that we have left and right arrows, we also have layout + private readonly Layout layout = new Layout(); + + // mouse info + // + // private bool overLeftArrow = false; + // private bool overRightArrow = false; + private bool downLeftArrow; + private bool downRightArrow; + + // a horizOffset of 0 means that the layout for the parent + // rows is left aligned. + // a horizOffset of 1 means that the leftmost unit of information ( let it be a + // table name, a column name or a column value ) is not visible. + // a horizOffset of 2 means that the leftmost 2 units of information are not visible, and so on + // + private int horizOffset; + + // storage for parent row states + // + private readonly ArrayList parents = new ArrayList(); + private int parentsCount; + private readonly ArrayList rowHeights = new ArrayList(); + AccessibleObject accessibleObject; + + internal DataGridParentRows(DataGrid dataGrid) + { + colorMap[0].OldColor = Color.Black; + this.dataGrid = dataGrid; + // UpdateGridLinePen(); + } + + // =------------------------------------------------------------------ + // = Properties + // =------------------------------------------------------------------ + + public AccessibleObject AccessibleObject + { + get + { + if (accessibleObject == null) + { + accessibleObject = new DataGridParentRowsAccessibleObject(this); + } + + return accessibleObject; + } + } + + internal Color BackColor + { + get + { + return backBrush.Color; + } + set + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "Parent Rows BackColor")); + } + + if (value != backBrush.Color) + { + backBrush = new SolidBrush(value); + Invalidate(); + } + } + } + + internal SolidBrush BackBrush + { + get + { + return backBrush; + } + set + { + if (value != backBrush) + { + CheckNull(value, "BackBrush"); + backBrush = value; + Invalidate(); + } + } + } + + internal SolidBrush ForeBrush + { + get + { + return foreBrush; + } + set + { + if (value != foreBrush) + { + CheckNull(value, "BackBrush"); + foreBrush = value; + Invalidate(); + } + } + } + + // since the layout of the parentRows is computed on every paint message, + // we can actually return true ClientRectangle coordinates + internal Rectangle GetBoundsForDataGridStateAccesibility(DataGridState dgs) + { + Rectangle ret = Rectangle.Empty; + int rectY = 0; + for (int i = 0; i < parentsCount; i++) + { + int height = (int)rowHeights[i]; + if (parents[i] == dgs) + { + ret.X = layout.leftArrow.IsEmpty ? layout.data.X : layout.leftArrow.Right; + ret.Height = height; + ret.Y = rectY; + ret.Width = layout.data.Width; + return ret; + } + + rectY += height; + } + + return ret; + } + + /* + internal Color BorderColor { + get { + return borderColor; + } + set { + if (value != borderColor) { + borderColor = value; + Invalidate(); + } + } + } + */ + + internal Brush BorderBrush + { + get + { + return borderBrush; + } + set + { + if (value != borderBrush) + { + borderBrush = value; + Invalidate(); + } + } + } + + /* + internal Brush GridLineBrush { + get { + return gridLineBrush; + } + set { + if (value != gridLineBrush) { + gridLineBrush = value; + UpdateGridLinePen(); + Invalidate(); + } + } + } + + internal bool GridLineDots { + get { + return gridLineDots; + } + set { + if (gridLineDots != value) { + gridLineDots = value; + UpdateGridLinePen(); + Invalidate(); + } + } + } + */ + + internal int Height + { + get + { + return totalHeight; + } + } + + internal Color ForeColor + { + get + { + return foreBrush.Color; + } + set + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, "Parent Rows ForeColor")); + } + + if (value != foreBrush.Color) + { + foreBrush = new SolidBrush(value); + Invalidate(); + } + } + } + + internal bool Visible + { + get + { + return dataGrid.ParentRowsVisible; + } + set + { + dataGrid.ParentRowsVisible = value; + } + } + + // =------------------------------------------------------------------ + // = Methods + // =------------------------------------------------------------------ + + /// + /// Adds a DataGridState object to the top of the list of parents. + /// + internal void AddParent(DataGridState dgs) + { + CurrencyManager childDataSource = (CurrencyManager)dataGrid.BindingContext[dgs.DataSource, dgs.DataMember]; + parents.Add(dgs); + SetParentCount(parentsCount + 1); + Debug.Assert(GetTopParent() != null, "we should have a parent at least"); + } + + internal void Clear() + { + for (int i = 0; i < parents.Count; i++) + { + DataGridState dgs = parents[i] as DataGridState; + dgs.RemoveChangeNotification(); + } + + parents.Clear(); + rowHeights.Clear(); + totalHeight = 0; + SetParentCount(0); + } + + internal void SetParentCount(int count) + { + parentsCount = count; + dataGrid.Caption.BackButtonVisible = (parentsCount > 0) && (dataGrid.AllowNavigation); + } + + internal void CheckNull(object value, string propName) + { + if (value == null) + { + throw new ArgumentNullException(nameof(propName)); + } + } + + internal void Dispose() + { + gridLinePen.Dispose(); + } + + /// + /// Retrieves the top most parent in the list of parents. + /// + internal DataGridState GetTopParent() + { + if (parentsCount < 1) + { + return null; + } + + return (DataGridState)(((ICloneable)(parents[parentsCount - 1])).Clone()); + } + + /// + /// Determines if there are any parent rows contained in this object. + /// + internal bool IsEmpty() + { + return parentsCount == 0; + } + + /// + /// Similar to GetTopParent() but also removes it. + /// + internal DataGridState PopTop() + { + if (parentsCount < 1) + { + return null; + } + + SetParentCount(parentsCount - 1); + DataGridState ret = (DataGridState)parents[parentsCount]; + ret.RemoveChangeNotification(); + parents.RemoveAt(parentsCount); + return ret; + } + + internal void Invalidate() + { + if (dataGrid != null) + { + dataGrid.InvalidateParentRows(); + } + } + + internal void InvalidateRect(Rectangle rect) + { + if (dataGrid != null) + { + Rectangle r = new Rectangle(rect.X, rect.Y, rect.Width + borderWidth, rect.Height + borderWidth); + dataGrid.InvalidateParentRowsRect(r); + } + } + + // called from DataGrid::OnLayout + internal void OnLayout() + { + if (parentsCount == rowHeights.Count) + { + return; + } + + int height = 0; + if (totalHeight == 0) + { + totalHeight += 2 * borderWidth; + } + + // figure out how tall each row's text will be + // + textRegionHeight = (int)dataGrid.Font.Height + 2; + + // make the height of the Column.Font count for the height + // of the parentRows; + // + // if the user wants to programatically + // navigate to a relation in the constructor of the form + // ( ie, when the form does not process PerformLayout ) + // the grid will receive an OnLayout message when there is more + // than one parent in the grid + if (parentsCount > rowHeights.Count) + { + Debug.Assert(parentsCount == rowHeights.Count + 1 || rowHeights.Count == 0, "see comment above for more info"); + int rowHeightsCount = rowHeights.Count; + for (int i = rowHeightsCount; i < parentsCount; i++) + { + DataGridState dgs = (DataGridState)parents[i]; + GridColumnStylesCollection cols = dgs.GridColumnStyles; + + int colsHeight = 0; + + for (int j = 0; j < cols.Count; j++) + { + colsHeight = Math.Max(colsHeight, cols[j].GetMinimumHeight()); + } + + height = Math.Max(colsHeight, textRegionHeight); + + // the height of the bottom border + height++; + rowHeights.Add(height); + + totalHeight += height; + } + } + else + { + Debug.Assert(parentsCount == rowHeights.Count - 1, "we do layout only for push/popTop"); + if (parentsCount == 0) + { + totalHeight = 0; + } + else + { + totalHeight -= (int)rowHeights[rowHeights.Count - 1]; + } + + rowHeights.RemoveAt(rowHeights.Count - 1); + } + } + + private int CellCount() + { + int cellCount = 0; + cellCount = ColsCount(); + + if (dataGrid.ParentRowsLabelStyle == DataGridParentRowsLabelStyle.TableName || + dataGrid.ParentRowsLabelStyle == DataGridParentRowsLabelStyle.Both) + { + cellCount++; + } + + return cellCount; + } + + private void ResetMouseInfo() + { + // overLeftArrow = false; + // overRightArrow = false; + downLeftArrow = false; + downRightArrow = false; + } + + private void LeftArrowClick(int cellCount) + { + if (horizOffset > 0) + { + ResetMouseInfo(); + horizOffset -= 1; + Invalidate(); + } + else + { + ResetMouseInfo(); + InvalidateRect(layout.leftArrow); + } + } + + private void RightArrowClick(int cellCount) + { + if (horizOffset < cellCount - 1) + { + ResetMouseInfo(); + horizOffset += 1; + Invalidate(); + } + else + { + ResetMouseInfo(); + InvalidateRect(layout.rightArrow); + } + } + + // the only mouse clicks that are handled are + // the mouse clicks on the LeftArrow and RightArrow + // + internal void OnMouseDown(int x, int y, bool alignToRight) + { + if (layout.rightArrow.IsEmpty) + { + Debug.Assert(layout.leftArrow.IsEmpty, "we can't have the leftArrow w/o the rightArrow"); + return; + } + + int cellCount = CellCount(); + + if (layout.rightArrow.Contains(x, y)) + { + // draw a nice sunken border around the right arrow area + // we want to keep a cell on the screen + + downRightArrow = true; + + if (alignToRight) + { + LeftArrowClick(cellCount); + } + else + { + RightArrowClick(cellCount); + } + } + else if (layout.leftArrow.Contains(x, y)) + { + downLeftArrow = true; + + if (alignToRight) + { + RightArrowClick(cellCount); + } + else + { + LeftArrowClick(cellCount); + } + } + else + { + if (downLeftArrow) + { + downLeftArrow = false; + InvalidateRect(layout.leftArrow); + } + + if (downRightArrow) + { + downRightArrow = false; + InvalidateRect(layout.rightArrow); + } + } + } + + internal void OnMouseLeave() + { + if (downLeftArrow) + { + downLeftArrow = false; + InvalidateRect(layout.leftArrow); + } + + if (downRightArrow) + { + downRightArrow = false; + InvalidateRect(layout.rightArrow); + } + } + + internal void OnMouseMove(int x, int y) + { + /* + if (!layout.leftArrow.IsEmpty && layout.leftArrow.Contains(x,y)) + { + ResetMouseInfo(); + overLeftArrow = true; + InvalidateRect(layout.leftArrow); + return; + } + if (!layout.rightArrow.IsEmpty && layout.rightArrow.Contains(x,y)) + { + ResetMouseInfo(); + overRightArrow = true; + InvalidateRect(layout.rightArrow); + return; + } + */ + + if (downLeftArrow) + { + downLeftArrow = false; + InvalidateRect(layout.leftArrow); + } + + if (downRightArrow) + { + downRightArrow = false; + InvalidateRect(layout.rightArrow); + } + } + + internal void OnMouseUp(int x, int y) + { + ResetMouseInfo(); + if (!layout.rightArrow.IsEmpty && layout.rightArrow.Contains(x, y)) + { + InvalidateRect(layout.rightArrow); + return; + } + + if (!layout.leftArrow.IsEmpty && layout.leftArrow.Contains(x, y)) + { + InvalidateRect(layout.leftArrow); + return; + } + } + + internal void OnResize(Rectangle oldBounds) + { + Invalidate(); + } + + /// + /// Paints the parent rows + /// + internal void Paint(Graphics g, Rectangle visualbounds, bool alignRight) + { + Rectangle bounds = visualbounds; + // Paint the border around our bounds + if (borderWidth > 0) + { + PaintBorder(g, bounds); + bounds.Inflate(-borderWidth, -borderWidth); + } + + PaintParentRows(g, bounds, alignRight); + } + + private void PaintBorder(Graphics g, Rectangle bounds) + { + Rectangle border = bounds; + + // top + border.Height = borderWidth; + g.FillRectangle(borderBrush, border); + + // bottom + border.Y = bounds.Bottom - borderWidth; + g.FillRectangle(borderBrush, border); + + // left + border = new Rectangle(bounds.X, bounds.Y + borderWidth, + borderWidth, bounds.Height - 2 * borderWidth); + g.FillRectangle(borderBrush, border); + + // right + border.X = bounds.Right - borderWidth; + g.FillRectangle(borderBrush, border); + } + + // will return the width of the text box that will fit all the + // tables names + private int GetTableBoxWidth(Graphics g, Font font) + { + // try to make the font BOLD + Font textFont = font; + try + { + textFont = new Font(font, FontStyle.Bold); + } + catch + { + } + + int width = 0; + for (int row = 0; row < parentsCount; row++) + { + DataGridState dgs = (DataGridState)parents[row]; + // Graphics.MeasureString(...) returns different results for ": " than for " :" + // + string displayTableName = dgs.ListManager.GetListName() + " :"; + int size = (int)g.MeasureString(displayTableName, textFont).Width; + width = Math.Max(size, width); + } + + return width; + } + + // will return the width of the text box that will + // fit all the column names + private int GetColBoxWidth(Graphics g, Font font, int colNum) + { + int width = 0; + + for (int row = 0; row < parentsCount; row++) + { + DataGridState dgs = (DataGridState)parents[row]; + GridColumnStylesCollection columns = dgs.GridColumnStyles; + if (colNum < columns.Count) + { + // Graphics.MeasureString(...) returns different results for ": " than for " :" + // + string colName = columns[colNum].HeaderText + " :"; + int size = (int)g.MeasureString(colName, font).Width; + width = Math.Max(size, width); + } + } + + return width; + } + + // will return the width of the best fit for the column + // + private int GetColDataBoxWidth(Graphics g, int colNum) + { + int width = 0; + for (int row = 0; row < parentsCount; row++) + { + DataGridState dgs = (DataGridState)parents[row]; + GridColumnStylesCollection columns = dgs.GridColumnStyles; + if (colNum < columns.Count) + { + object value = columns[colNum].GetColumnValueAtRow((CurrencyManager)dataGrid.BindingContext[dgs.DataSource, dgs.DataMember], + dgs.LinkingRow.RowNumber); + int size = columns[colNum].GetPreferredSize(g, value).Width; + width = Math.Max(size, width); + } + } + + return width; + } + + // will return the count of the table with the largest number of columns + private int ColsCount() + { + int colNum = 0; + for (int row = 0; row < parentsCount; row++) + { + DataGridState dgs = (DataGridState)parents[row]; + colNum = Math.Max(colNum, dgs.GridColumnStyles.Count); + } + + return colNum; + } + + // will return the total width required to paint the parentRows + private int TotalWidth(int tableNameBoxWidth, int[] colsNameWidths, int[] colsDataWidths) + { + int totalWidth = 0; + totalWidth += tableNameBoxWidth; + Debug.Assert(colsNameWidths.Length == colsDataWidths.Length, "both arrays are as long as the largest column count in dgs"); + for (int i = 0; i < colsNameWidths.Length; i++) + { + totalWidth += colsNameWidths[i]; + totalWidth += colsDataWidths[i]; + } + + // let 3 pixels in between datacolumns + // see DonnaWa + totalWidth += 3 * (colsNameWidths.Length - 1); + return totalWidth; + } + + // computes the layout for the parent rows + // + private void ComputeLayout(Rectangle bounds, int tableNameBoxWidth, int[] colsNameWidths, int[] colsDataWidths) + { + int totalWidth = TotalWidth(tableNameBoxWidth, colsNameWidths, colsDataWidths); + if (totalWidth > bounds.Width) + { + layout.leftArrow = new Rectangle(bounds.X, bounds.Y, 15, bounds.Height); + layout.data = new Rectangle(layout.leftArrow.Right, bounds.Y, bounds.Width - 30, bounds.Height); + layout.rightArrow = new Rectangle(layout.data.Right, bounds.Y, 15, bounds.Height); + } + else + { + layout.data = bounds; + layout.leftArrow = Rectangle.Empty; + layout.rightArrow = Rectangle.Empty; + } + } + + private void PaintParentRows(Graphics g, Rectangle bounds, bool alignToRight) + { + // variables needed for aligning the table and column names + int tableNameBoxWidth = 0; + int numCols = ColsCount(); + int[] colsNameWidths = new int[numCols]; + int[] colsDataWidths = new int[numCols]; + + // compute the size of the box that will contain the tableName + // + if (dataGrid.ParentRowsLabelStyle == DataGridParentRowsLabelStyle.TableName || + dataGrid.ParentRowsLabelStyle == DataGridParentRowsLabelStyle.Both) + { + tableNameBoxWidth = GetTableBoxWidth(g, dataGrid.Font); + } + + // initialiaze the arrays that contain the column names and the column size + // + for (int i = 0; i < numCols; i++) + { + if (dataGrid.ParentRowsLabelStyle == DataGridParentRowsLabelStyle.ColumnName || + dataGrid.ParentRowsLabelStyle == DataGridParentRowsLabelStyle.Both) + { + colsNameWidths[i] = GetColBoxWidth(g, dataGrid.Font, i); + } + else + { + colsNameWidths[i] = 0; + } + + colsDataWidths[i] = GetColDataBoxWidth(g, i); + } + + // compute the layout + // + ComputeLayout(bounds, tableNameBoxWidth, colsNameWidths, colsDataWidths); + + // paint the navigation arrows, if necessary + // + if (!layout.leftArrow.IsEmpty) + { + g.FillRectangle(BackBrush, layout.leftArrow); + PaintLeftArrow(g, layout.leftArrow, alignToRight); + } + + // paint the parent rows: + // + Rectangle rowBounds = layout.data; + for (int row = 0; row < parentsCount; ++row) + { + rowBounds.Height = (int)rowHeights[row]; + if (rowBounds.Y > bounds.Bottom) + { + break; + } + + int paintedWidth = PaintRow(g, rowBounds, row, dataGrid.Font, alignToRight, tableNameBoxWidth, colsNameWidths, colsDataWidths); + if (row == parentsCount - 1) + { + break; + } + + // draw the grid line below + g.DrawLine(gridLinePen, rowBounds.X, rowBounds.Bottom, + rowBounds.X + paintedWidth, + rowBounds.Bottom); + rowBounds.Y += rowBounds.Height; + } + + if (!layout.rightArrow.IsEmpty) + { + g.FillRectangle(BackBrush, layout.rightArrow); + PaintRightArrow(g, layout.rightArrow, alignToRight); + } + } + + private Bitmap GetBitmap(string bitmapName) + { + try + { + return DpiHelper.GetBitmapFromIcon(typeof(DataGridParentRows), bitmapName); + } + catch (Exception e) + { + Debug.Fail("Failed to load bitmap: " + bitmapName, e.ToString()); + return null; + } + } + + private Bitmap GetRightArrowBitmap() + { + if (rightArrow == null) + { + rightArrow = GetBitmap("DataGridParentRows.RightArrow"); + } + + return rightArrow; + } + + private Bitmap GetLeftArrowBitmap() + { + if (leftArrow == null) + { + leftArrow = GetBitmap("DataGridParentRows.LeftArrow"); + } + + return leftArrow; + } + + private void PaintBitmap(Graphics g, Bitmap b, Rectangle bounds) + { + // center the bitmap in the bounds: + int bmpX = bounds.X + (bounds.Width - b.Width) / 2; + int bmpY = bounds.Y + (bounds.Height - b.Height) / 2; + Rectangle bmpRect = new Rectangle(bmpX, bmpY, b.Width, b.Height); + + g.FillRectangle(BackBrush, bmpRect); + + // now draw the bitmap + ImageAttributes attr = new ImageAttributes(); + colorMap[0].NewColor = ForeColor; + attr.SetRemapTable(colorMap, ColorAdjustType.Bitmap); + g.DrawImage(b, bmpRect, 0, 0, bmpRect.Width, bmpRect.Height, GraphicsUnit.Pixel, attr); + attr.Dispose(); + } + + /* + private void PaintOverButton(Graphics g, Rectangle bounds) + { + } + */ + + private void PaintDownButton(Graphics g, Rectangle bounds) + { + g.DrawLine(Pens.Black, bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y); // the top + g.DrawLine(Pens.White, bounds.X + bounds.Width, bounds.Y, bounds.X + bounds.Width, bounds.Y + bounds.Height); // the right side + g.DrawLine(Pens.White, bounds.X + bounds.Width, bounds.Y + bounds.Height, bounds.X, bounds.Y + bounds.Height); // the right side + g.DrawLine(Pens.Black, bounds.X, bounds.Y + bounds.Height, bounds.X, bounds.Y); // the left side + } + + private void PaintLeftArrow(Graphics g, Rectangle bounds, bool alignToRight) + { + Bitmap bmp = GetLeftArrowBitmap(); + // paint the border around this bitmap if this is the case + // + /* + if (overLeftArrow) + { + Debug.Assert(!downLeftArrow, "can both of those happen?"); + PaintOverButton(g, bounds); + layout.leftArrow.Inflate(-1,-1); + } + */ + if (downLeftArrow) + { + PaintDownButton(g, bounds); + layout.leftArrow.Inflate(-1, -1); + lock (bmp) + { + PaintBitmap(g, bmp, bounds); + } + + layout.leftArrow.Inflate(1, 1); + } + else + { + lock (bmp) + { + PaintBitmap(g, bmp, bounds); + } + } + } + + private void PaintRightArrow(Graphics g, Rectangle bounds, bool alignToRight) + { + Bitmap bmp = GetRightArrowBitmap(); + // paint the border around this bitmap if this is the case + // + /* + if (overRightArrow) + { + Debug.Assert(!downRightArrow, "can both of those happen?"); + PaintOverButton(g, bounds); + layout.rightArrow.Inflate(-1,-1); + } + */ + if (downRightArrow) + { + PaintDownButton(g, bounds); + layout.rightArrow.Inflate(-1, -1); + lock (bmp) + { + PaintBitmap(g, bmp, bounds); + } + + layout.rightArrow.Inflate(1, 1); + } + else + { + lock (bmp) + { + PaintBitmap(g, bmp, bounds); + } + } + } + + private int PaintRow(Graphics g, Rectangle bounds, int row, Font font, bool alignToRight, + int tableNameBoxWidth, int[] colsNameWidths, int[] colsDataWidths) + { + DataGridState dgs = (DataGridState)parents[row]; + Rectangle paintBounds = bounds; + Rectangle rowBounds = bounds; + paintBounds.Height = (int)rowHeights[row]; + rowBounds.Height = (int)rowHeights[row]; + + int paintedWidth = 0; + // used for scrolling: when paiting, we will skip horizOffset cells in the dataGrid ParentRows + int skippedCells = 0; + + // paint the table name + if (dataGrid.ParentRowsLabelStyle == DataGridParentRowsLabelStyle.TableName || + dataGrid.ParentRowsLabelStyle == DataGridParentRowsLabelStyle.Both) + { + if (skippedCells < horizOffset) + { + // skip this + skippedCells++; + } + else + { + paintBounds.Width = Math.Min(paintBounds.Width, tableNameBoxWidth); + paintBounds.X = MirrorRect(bounds, paintBounds, alignToRight); + string displayTableName = dgs.ListManager.GetListName() + ": "; + PaintText(g, paintBounds, displayTableName, font, true, alignToRight); // true is for painting bold + paintedWidth += paintBounds.Width; + } + } + + if (paintedWidth >= bounds.Width) + { + return bounds.Width; // we painted everything + } + + rowBounds.Width -= paintedWidth; + rowBounds.X += alignToRight ? 0 : paintedWidth; + paintedWidth += PaintColumns(g, rowBounds, dgs, font, alignToRight, colsNameWidths, colsDataWidths, skippedCells); + + // paint the possible space left after columns + if (paintedWidth < bounds.Width) + { + paintBounds.X = bounds.X + paintedWidth; + paintBounds.Width = bounds.Width - paintedWidth; + paintBounds.X = MirrorRect(bounds, paintBounds, alignToRight); + g.FillRectangle(BackBrush, paintBounds); + } + + return paintedWidth; + } + + private int PaintColumns(Graphics g, Rectangle bounds, DataGridState dgs, Font font, bool alignToRight, + int[] colsNameWidths, int[] colsDataWidths, int skippedCells) + { + Rectangle paintBounds = bounds; + Rectangle rowBounds = bounds; + GridColumnStylesCollection cols = dgs.GridColumnStyles; + int cx = 0; + + for (int i = 0; i < cols.Count; i++) + { + if (cx >= bounds.Width) + { + break; + } + + // paint the column name, if we have to + if (dataGrid.ParentRowsLabelStyle == DataGridParentRowsLabelStyle.ColumnName || + dataGrid.ParentRowsLabelStyle == DataGridParentRowsLabelStyle.Both) + { + if (skippedCells < horizOffset) + { + // skip this column + } + else + { + paintBounds.X = bounds.X + cx; + paintBounds.Width = Math.Min(bounds.Width - cx, colsNameWidths[i]); + paintBounds.X = MirrorRect(bounds, paintBounds, alignToRight); + + string colName = cols[i].HeaderText + ": "; + PaintText(g, paintBounds, colName, font, false, alignToRight); // false is for not painting bold + + cx += paintBounds.Width; + } + } + + if (cx >= bounds.Width) + { + break; + } + + if (skippedCells < horizOffset) + { + // skip this cell + skippedCells++; + } + else + { + // paint the cell contents + paintBounds.X = bounds.X + cx; + paintBounds.Width = Math.Min(bounds.Width - cx, colsDataWidths[i]); + paintBounds.X = MirrorRect(bounds, paintBounds, alignToRight); + + // when we paint the data grid parent rows, we want to paint the data at the position + // stored in the currency manager. + cols[i].Paint(g, paintBounds, (CurrencyManager)dataGrid.BindingContext[dgs.DataSource, dgs.DataMember], + dataGrid.BindingContext[dgs.DataSource, dgs.DataMember].Position, BackBrush, ForeBrush, alignToRight); + + cx += paintBounds.Width; + + // draw the line to the right (or left, according to alignRight) + // + g.DrawLine(new Pen(SystemColors.ControlDark), + alignToRight ? paintBounds.X : paintBounds.Right, + paintBounds.Y, + alignToRight ? paintBounds.X : paintBounds.Right, + paintBounds.Bottom); + + // this is how wide the line is.... + cx++; + + // put 3 pixels in between columns + // see DonnaWa + // + if (i < cols.Count - 1) + { + paintBounds.X = bounds.X + cx; + paintBounds.Width = Math.Min(bounds.Width - cx, 3); + paintBounds.X = MirrorRect(bounds, paintBounds, alignToRight); + + g.FillRectangle(BackBrush, paintBounds); + cx += 3; + } + } + } + + return cx; + } + + /// + /// Draws on the screen the text. It is used only to paint the Table Name and the column Names + /// Returns the width of bounding rectangle that was passed in + /// + private int PaintText(Graphics g, Rectangle textBounds, string text, Font font, bool bold, bool alignToRight) + { + Font textFont = font; + if (bold) + { + try + { + textFont = new Font(font, FontStyle.Bold); + } + catch { } + } + else + { + textFont = font; + } + + // right now, we paint the entire box, cause it will be used anyway + g.FillRectangle(BackBrush, textBounds); + StringFormat format = new StringFormat(); + if (alignToRight) + { + format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + format.Alignment = StringAlignment.Far; + } + + format.FormatFlags |= StringFormatFlags.NoWrap; + // part 1, section 3: put the table and the column name in the + // parent rows at the same height as the dataGridTextBoxColumn draws the string + // + textBounds.Offset(0, 2); + textBounds.Height -= 2; + g.DrawString(text, textFont, ForeBrush, textBounds, format); + format.Dispose(); + return textBounds.Width; + } + + // will return the X coordinate of the containedRect mirrored within the surroundingRect + // according to the value of alignToRight + private int MirrorRect(Rectangle surroundingRect, Rectangle containedRect, bool alignToRight) + { + Debug.Assert(containedRect.X >= surroundingRect.X && containedRect.Right <= surroundingRect.Right, "containedRect is not contained in surroundingRect"); + if (alignToRight) + { + return surroundingRect.Right - containedRect.Right + surroundingRect.X; + } + else + { + return containedRect.X; + } + } + + private class Layout + { + public Rectangle data; + public Rectangle leftArrow; + public Rectangle rightArrow; + + public Layout() + { + data = Rectangle.Empty; + leftArrow = Rectangle.Empty; + rightArrow = Rectangle.Empty; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(200); + sb.Append("ParentRows Layout: \n"); + sb.Append("data = "); + sb.Append(data.ToString()); + sb.Append("\n leftArrow = "); + sb.Append(leftArrow.ToString()); + sb.Append("\n rightArrow = "); + sb.Append(rightArrow.ToString()); + sb.Append('\n'); + + return sb.ToString(); + } + } + + [ComVisible(true)] + protected internal class DataGridParentRowsAccessibleObject : AccessibleObject + { + readonly DataGridParentRows owner; + + public DataGridParentRowsAccessibleObject(DataGridParentRows owner) : base() + { + Debug.Assert(owner != null, "DataGridParentRowsAccessibleObject must have a valid owner"); + this.owner = owner; + } + + internal DataGridParentRows Owner + { + get + { + return owner; + } + } + + public override Rectangle Bounds + { + get + { + return owner.dataGrid.RectangleToScreen(owner.dataGrid.ParentRowsBounds); + } + } + + public override string DefaultAction + { + get + { + return SR.AccDGNavigateBack; + } + } + + public override string Name + { + get + { + return SR.AccDGParentRows; + } + } + + public override AccessibleObject Parent + { + get + { + return owner.dataGrid.AccessibilityObject; + } + } + + public override AccessibleRole Role + { + get + { + return AccessibleRole.List; + } + } + + public override AccessibleStates State + { + get + { + AccessibleStates state = AccessibleStates.ReadOnly; + + if (owner.parentsCount == 0) + { + state |= AccessibleStates.Invisible; + } + + if (owner.dataGrid.ParentRowsVisible) + { + state |= AccessibleStates.Expanded; + } + else + { + state |= AccessibleStates.Collapsed; + } + + return state; + } + } + + public override string Value + { + get + { + return null; + } + } + + public override void DoDefaultAction() + { + owner.dataGrid.NavigateBack(); + } + + public override AccessibleObject GetChild(int index) + { + return ((DataGridState)owner.parents[index]).ParentRowAccessibleObject; + } + + public override int GetChildCount() + { + return owner.parentsCount; + } + + /// + /// Returns the currently focused child, if any. + /// Returns this if the object itself is focused. + /// + public override AccessibleObject GetFocused() + { + return null; + } + + internal AccessibleObject GetNext(AccessibleObject child) + { + int children = GetChildCount(); + bool hit = false; + + for (int i = 0; i < children; i++) + { + if (hit) + { + return GetChild(i); + } + + if (GetChild(i) == child) + { + hit = true; + } + } + + return null; + } + + internal AccessibleObject GetPrev(AccessibleObject child) + { + int children = GetChildCount(); + bool hit = false; + + for (int i = children - 1; i >= 0; i--) + { + if (hit) + { + return GetChild(i); + } + + if (GetChild(i) == child) + { + hit = true; + } + } + + return null; + } + + /// + /// Navigate to the next or previous grid entry. + /// + public override AccessibleObject Navigate(AccessibleNavigation navdir) + { + switch (navdir) + { + case AccessibleNavigation.Right: + case AccessibleNavigation.Next: + case AccessibleNavigation.Down: + return Parent.GetChild(1); + case AccessibleNavigation.Up: + case AccessibleNavigation.Left: + case AccessibleNavigation.Previous: + return Parent.GetChild(GetChildCount() - 1); + case AccessibleNavigation.FirstChild: + if (GetChildCount() > 0) + { + return GetChild(0); + } + + break; + case AccessibleNavigation.LastChild: + if (GetChildCount() > 0) + { + return GetChild(GetChildCount() - 1); + } + + break; + } + + return null; + } + + public override void Select(AccessibleSelection flags) + { + } + } + } +} + diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridParentRowsLabelStyle.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridParentRowsLabelStyle.cs new file mode 100644 index 00000000000..151e1e62706 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridParentRowsLabelStyle.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +namespace System.Windows.Forms +{ + /// + /// Specifies how parent row labels of a DataGrid + /// control are displayed. + /// + public enum DataGridParentRowsLabelStyle + { + /// + /// Display no parent row labels. + /// + None = 0, + + /// + /// Displaya the parent table name. + /// + TableName = 1, + + /// + /// Displaya the parent column name. + /// + ColumnName = 2, + + /// + /// Displays + /// both the parent table and column names. + /// + Both = 3, + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridPreferredColumnWidthTypeConverter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridPreferredColumnWidthTypeConverter.cs new file mode 100644 index 00000000000..ddb041dfa54 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridPreferredColumnWidthTypeConverter.cs @@ -0,0 +1,77 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.ComponentModel; +using System.Globalization; + +namespace System.Windows.Forms +{ + public class DataGridPreferredColumnWidthTypeConverter : TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string) || sourceType == typeof(int)) + { + return true; + } + else + { + return false; + } + } + + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + if (value.GetType() == typeof(int)) + { + int pulica = (int)value; + if (pulica == -1) + { + return "AutoColumnResize (-1)"; + } + else + { + return pulica.ToString(CultureInfo.CurrentCulture); + } + } + else + { + return base.ConvertTo(context, culture, value, destinationType); + } + } + else + { + return base.ConvertTo(context, culture, value, destinationType); + } + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value.GetType() == typeof(string)) + { + string text = value.ToString(); + if (text.Equals("AutoColumnResize (-1)")) + { + return -1; + } + else + { + return int.Parse(text, CultureInfo.CurrentCulture); + } + } + else if (value.GetType() == typeof(int)) + { + return (int)value; + } + else + { + throw GetConvertFromException(value); + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridRelationshipRow.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridRelationshipRow.cs new file mode 100644 index 00000000000..016e4f7cb77 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridRelationshipRow.cs @@ -0,0 +1,1282 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace System.Windows.Forms +{ + /// + /// This class fully encapsulates the painting logic for a row + /// appearing in a DataGrid. + /// + internal class DataGridRelationshipRow : DataGridRow + { + private const bool defaultOpen = false; + private const int expandoBoxWidth = 14; + private const int indentWidth = 20; + // private const int relationshipSpacing = 1; + private const int triangleSize = 5; + + private bool expanded = defaultOpen; + // private bool hasRelationships = false; + // private Font linkFont = null; + // private new DataGrid dataGrid; // Currently used only to obtain a Graphics object for measuring text + + // private Rectangle relationshipRect = Rectangle.Empty; + // private int relationshipHeight = 0; + + // relationships + // we should get this directly from the dgTable. + // private ArrayList relationships; + // private int focusedRelation = -1; + // private int focusedTextWidth; + + public DataGridRelationshipRow(DataGrid dataGrid, DataGridTableStyle dgTable, int rowNumber) + : base(dataGrid, dgTable, rowNumber) + { + // this.dataGrid = dataGrid; + // linkFont = dataGrid.LinkFont; + // relationshipHeight = dataGrid.LinkFontHeight + this.dgTable.relationshipSpacing; + + // if (DataGrid.AllowNavigation) { + // hasRelationships = dgTable.RelationsList.Count > 0; + // } + } + + internal protected override int MinimumRowHeight(GridColumnStylesCollection cols) + { + /* + if (DataGrid != null && DataGrid.LinkFontHeight + this.dgTable.relationshipSpacing != relationshipHeight) { + relationshipRect = Rectangle.Empty; + relationshipHeight = DataGrid.LinkFontHeight + this.dgTable.relationshipSpacing; + } + */ + + return base.MinimumRowHeight(cols) + (expanded ? GetRelationshipRect().Height : 0); + } + + internal protected override int MinimumRowHeight(DataGridTableStyle dgTable) + { + /* + if (DataGrid != null && DataGrid.LinkFontHeight + this.dgTable.relationshipSpacing != relationshipHeight) { + relationshipRect = Rectangle.Empty; + relationshipHeight = DataGrid.LinkFontHeight + this.dgTable.relationshipSpacing; + } + */ + + return base.MinimumRowHeight(dgTable) + (expanded ? GetRelationshipRect().Height : 0); + } + + // =------------------------------------------------------------------ + // = Properties + // =------------------------------------------------------------------ + + public virtual bool Expanded + { + get + { + return expanded; + } + set + { + if (expanded == value) + { + return; + } + + if (expanded) + { + Collapse(); + } + else + { + Expand(); + } + } + } + + /* + private Color BorderColor { + get { + if (DataGrid == null) + return Color.Empty; + return DataGrid.GridLineColor; + } + } + */ + +#if FALSE + private int BorderWidth { + get { + DataGrid dataGrid = this.DataGrid; + if (dataGrid == null) + return 0; + // if the user set the GridLineStyle property on the dataGrid. + // then use the value of that property + DataGridLineStyle gridStyle; + int gridLineWidth; + if (this.dgTable.IsDefault) { + gridStyle = this.DataGrid.GridLineStyle; + gridLineWidth = this.DataGrid.GridLineWidth; + } else { + gridStyle = this.dgTable.GridLineStyle; + gridLineWidth = this.dgTable.GridLineWidth; + } + + if (gridStyle == DataGridLineStyle.None) + return 0; + + return gridLineWidth; + } + } +#endif //FALSE + + private int FocusedRelation + { + get + { + return dgTable.FocusedRelation; + } + set + { + dgTable.FocusedRelation = value; + } + } + + // =------------------------------------------------------------------ + // = Methods + // =------------------------------------------------------------------ + + private void Collapse() + { + Debug.Assert(dgTable.DataGrid.AllowNavigation, "how can the user collapse the relations if the grid does not allow navigation?"); + if (expanded) + { + expanded = false; + // relationshipRect = Rectangle.Empty; + FocusedRelation = -1; + DataGrid.OnRowHeightChanged(this); + } + } + + protected override AccessibleObject CreateAccessibleObject() + { + return new DataGridRelationshipRowAccessibleObject(this); + } + + private void Expand() + { + Debug.Assert(dgTable.DataGrid.AllowNavigation, "how can the user expand the relations if the grid does not allow navigation?"); + if (expanded == false + && DataGrid != null + && dgTable != null + && dgTable.RelationsList.Count > 0) + { + expanded = true; + FocusedRelation = -1; + + // relationshipRect = Rectangle.Empty; + DataGrid.OnRowHeightChanged(this); + } + } + + public override int Height + { + get + { + int height = base.Height; + if (expanded) + { + return height + GetRelationshipRect().Height; + } + else + { + return height; + } + } + set + { + // we should use the RelationshipRect only when the row is expanded + if (expanded) + { + base.Height = value - GetRelationshipRect().Height; + } + else + { + base.Height = value; + } + } + } + + // so the edit box will not paint under the + // grid line of the row + public override Rectangle GetCellBounds(int col) + { + Rectangle cellBounds = base.GetCellBounds(col); + // decrement base.Height by 1, so the edit box will not + // paint over the bottom line. + cellBounds.Height = base.Height - 1; + return cellBounds; + } + + /// + /// Given an origin, this procedure returns + /// a rectangle that describes the location of an outline box. + /// + private Rectangle GetOutlineRect(int xOrigin, int yOrigin) + { + Rectangle outline = new Rectangle(xOrigin + 2, + yOrigin + 2, + 9, + 9); + return outline; + } + + public override Rectangle GetNonScrollableArea() + { + if (expanded) + { + return GetRelationshipRect(); + } + else + { + return Rectangle.Empty; + } + } + + private Rectangle GetRelationshipRect() + { + Debug.Assert(expanded, "we should need this rectangle only when the row is expanded"); + Rectangle ret = dgTable.RelationshipRect; + ret.Y = base.Height - dgTable.BorderWidth; + return ret; + } + +#if FALSE + private Rectangle GetRelationshipRect() { + if (relationshipRect.IsEmpty) { + Debug.WriteLineIf(CompModSwitches.DGRelationShpRowLayout.TraceVerbose, "GetRelationshipRect grinding away"); + if (!expanded) { + return(relationshipRect = new Rectangle(0,0,0,0)); + } + Graphics g = DataGrid.CreateGraphicsInternal(); + relationshipRect = new Rectangle(); + relationshipRect.X = 0; //indentWidth; + relationshipRect.Y = base.Height - this.dgTable.BorderWidth; + + // Determine the width of the widest relationship name + int longestRelationship = 0; + for (int r = 0; r < this.dgTable.RelationsList.Count; ++r) { + int rwidth = (int) Math.Ceiling(g.MeasureString(((string) this.dgTable.RelationsList[r]), this.DataGrid.LinkFont).Width); + if (rwidth > longestRelationship) + longestRelationship = rwidth; + } + + g.Dispose(); + + relationshipRect.Width = longestRelationship + 5; + relationshipRect.Width += 2; // relationshipRect border; + relationshipRect.Height = this.dgTable.BorderWidth + relationshipHeight * this.dgTable.RelationsList.Count; + relationshipRect.Height += 2; // relationship border + if (this.dgTable.RelationsList.Count > 0) + relationshipRect.Height += 2 * System.Windows.Forms.DataGridTableStyle.relationshipSpacing; + } + return relationshipRect; + } + +#endif// FALSE + + private Rectangle GetRelationshipRectWithMirroring() + { + Rectangle relRect = GetRelationshipRect(); + bool rowHeadersVisible = dgTable.IsDefault ? DataGrid.RowHeadersVisible : dgTable.RowHeadersVisible; + if (rowHeadersVisible) + { + int rowHeaderWidth = dgTable.IsDefault ? DataGrid.RowHeaderWidth : dgTable.RowHeaderWidth; + relRect.X += DataGrid.GetRowHeaderRect().X + rowHeaderWidth; + } + + relRect.X = MirrorRelationshipRectangle(relRect, DataGrid.GetRowHeaderRect(), DataGrid.RightToLeft == RightToLeft.Yes); + return relRect; + } + + /// + /// Called by the DataGrid when a click occurs in the row's client + /// area. The coordinates are normalized to the rectangle's top + /// left point. + /// + private bool PointOverPlusMinusGlyph(int x, int y, Rectangle rowHeaders, bool alignToRight) + { + if (dgTable == null || dgTable.DataGrid == null || !dgTable.DataGrid.AllowNavigation) + { + return false; + } + + Rectangle insideRowHeaders = rowHeaders; + if (!DataGrid.FlatMode) + { + insideRowHeaders.Inflate(-1, -1); + } + + Rectangle outline = GetOutlineRect(insideRowHeaders.Right - expandoBoxWidth, 0); + + outline.X = MirrorRectangle(outline.X, outline.Width, insideRowHeaders, alignToRight); + + return outline.Contains(x, y); + } + + public override bool OnMouseDown(int x, int y, Rectangle rowHeaders, bool alignToRight) + { + bool rowHeadersVisible = dgTable.IsDefault ? DataGrid.RowHeadersVisible : dgTable.RowHeadersVisible; + if (rowHeadersVisible) + { + if (PointOverPlusMinusGlyph(x, y, rowHeaders, alignToRight)) + { + if (dgTable.RelationsList.Count == 0) + { + return false; + } + else if (expanded) + { + Collapse(); + } + else + { + Expand(); + } + + DataGrid.OnNodeClick(EventArgs.Empty); + return true; + } + } + + if (!expanded) + { + return base.OnMouseDown(x, y, rowHeaders, alignToRight); + } + + // hit test for relationships + Rectangle relRect = GetRelationshipRectWithMirroring(); + + if (relRect.Contains(x, y)) + { + int r = RelationFromY(y); + if (r != -1) + { + // first, reset the FocusedRelation + FocusedRelation = -1; + DataGrid.NavigateTo(((string)dgTable.RelationsList[r]), this, true); + } + + // DataGrid.OnLinkClick(EventArgs.Empty); + return true; + } + + return base.OnMouseDown(x, y, rowHeaders, alignToRight); + } + + public override bool OnMouseMove(int x, int y, Rectangle rowHeaders, bool alignToRight) + { + if (!expanded) + { + return false; + } + + Rectangle relRect = GetRelationshipRectWithMirroring(); + + if (relRect.Contains(x, y)) + { + DataGrid.Cursor = Cursors.Hand; + return true; + } + + DataGrid.Cursor = Cursors.Default; + return base.OnMouseMove(x, y, rowHeaders, alignToRight); + } + + // this function will not invalidate all of the + // row + public override void OnMouseLeft(Rectangle rowHeaders, bool alignToRight) + { + if (!expanded) + { + return; + } + + Rectangle relRect = GetRelationshipRect(); + relRect.X += rowHeaders.X + dgTable.RowHeaderWidth; + relRect.X = MirrorRelationshipRectangle(relRect, rowHeaders, alignToRight); + + if (FocusedRelation != -1) + { + InvalidateRowRect(relRect); + FocusedRelation = -1; + } + } + + public override void OnMouseLeft() + { + if (!expanded) + { + return; + } + + if (FocusedRelation != -1) + { + InvalidateRow(); + FocusedRelation = -1; + } + + base.OnMouseLeft(); + } + + /// + /// Called by the DataGrid when a keypress occurs on a row with "focus." + /// + public override bool OnKeyPress(Keys keyData) + { + // ignore the shift key if it is not paired w/ the TAB key + if ((keyData & Keys.Modifiers) == Keys.Shift && (keyData & Keys.KeyCode) != Keys.Tab) + { + return false; + } + + switch (keyData & Keys.KeyCode) + { + case Keys.F5: + if (dgTable == null || dgTable.DataGrid == null || !dgTable.DataGrid.AllowNavigation) + { + return false; + } + + if (expanded) + { + Collapse(); + } + else + { + Expand(); + } + + FocusedRelation = -1; + return true; + + // to make the gridTest run w/ the numLock key on + // + case Keys.NumLock: + if (FocusedRelation != -1) + { + return false; + } + else + { + return base.OnKeyPress(keyData); + } + + case Keys.Enter: + if (FocusedRelation != -1) + { + // somebody set the relation number up already + // navigate to the relation + DataGrid.NavigateTo(((string)dgTable.RelationsList[FocusedRelation]), this, true); + + // now reset the FocusedRelation + FocusedRelation = -1; + return true; + } + else + { + return false; + } + + case Keys.Tab: + return false; + + default: + FocusedRelation = -1; + return base.OnKeyPress(keyData); + } + } + + // will reset the FocusedRelation and will invalidate the + // rectangle so that the linkFont is no longer shown + internal override void LoseChildFocus(Rectangle rowHeaders, bool alignToRight) + { + // we only invalidate stuff if the row is expanded. + if (FocusedRelation == -1 || !expanded) + { + return; + } + + FocusedRelation = -1; + Rectangle relRect = GetRelationshipRect(); + relRect.X += rowHeaders.X + dgTable.RowHeaderWidth; + relRect.X = MirrorRelationshipRectangle(relRect, rowHeaders, alignToRight); + InvalidateRowRect(relRect); + } + + // here is the logic for FOCUSED: + // + // first the dataGrid gets the KeyPress. + // the dataGrid passes it to the currentRow. if it is anything other + // than Enter or TAB, the currentRow resets the FocusedRelation variable. + // + // Then the dataGrid takes another look at the TAB key and if it is the case + // it passes it to the row. If the dataRelationshipRow can become focused, + // then it eats the TAB key, otherwise it will give it back to the dataGrid. + // + internal override bool ProcessTabKey(Keys keyData, Rectangle rowHeaders, bool alignToRight) + { + Debug.Assert((keyData & Keys.Control) != Keys.Control, "the DataGridRelationshipRow only handles TAB and TAB-SHIFT"); + Debug.Assert((keyData & Keys.Alt) != Keys.Alt, "the DataGridRelationshipRow only handles TAB and TAB-SHIFT"); + + // if there are no relationships, this row can't do anything with the + // key + if (dgTable.RelationsList.Count == 0 || dgTable.DataGrid == null || !dgTable.DataGrid.AllowNavigation) + { + return false; + } + + // expand the relationship box + if (!expanded) + { + Expand(); + } + + if ((keyData & Keys.Shift) == Keys.Shift) + { + if (FocusedRelation == 0) + { + // if user hits TAB-SHIFT and the focus was on the first relationship then + // reset FocusedRelation and let the dataGrid use the key + // + // consider: Microsoft: if the relationships box is expanded, should we collapse it on leave? + FocusedRelation = -1; + return false; + } + + // we need to invalidate the relationshipRectangle, and cause the linkFont to move + // to the next relation + Rectangle relRect = GetRelationshipRect(); + relRect.X += rowHeaders.X + dgTable.RowHeaderWidth; + relRect.X = MirrorRelationshipRectangle(relRect, rowHeaders, alignToRight); + InvalidateRowRect(relRect); + + if (FocusedRelation == -1) + { + // is the first time that the user focuses on this + // set of relationships + FocusedRelation = dgTable.RelationsList.Count - 1; + } + else + { + FocusedRelation--; + } + + return true; + } + else + { + if (FocusedRelation == dgTable.RelationsList.Count - 1) + { + // if the user hits TAB and the focus was on the last relationship then + // reset FocusedRelation and let the dataGrid use the key + // + // consider: Microsoft: if the relationships box is expanded, should we collapse it on leave? + FocusedRelation = -1; + return false; + } + + // we need to invalidate the relationshipRectangle, and cause the linkFont to move + // to the next relation + Rectangle relRect = GetRelationshipRect(); + relRect.X += rowHeaders.X + dgTable.RowHeaderWidth; + relRect.X = MirrorRelationshipRectangle(relRect, rowHeaders, alignToRight); + InvalidateRowRect(relRect); + + FocusedRelation++; + return true; + } + } + + /// + /// Paints the row. + /// + public override int Paint(Graphics g, Rectangle bounds, Rectangle trueRowBounds, int firstVisibleColumn, int numVisibleColumns) + { + return Paint(g, bounds, trueRowBounds, firstVisibleColumn, numVisibleColumns, false); + } + + public override int Paint(Graphics g, + Rectangle bounds, // negative offsetted row bounds + Rectangle trueRowBounds, // real row bounds. + int firstVisibleColumn, + int numVisibleColumns, + bool alignToRight) + { + if (CompModSwitches.DGRelationShpRowPaint.TraceVerbose) + { + Debug.WriteLine("Painting row " + RowNumber.ToString(CultureInfo.InvariantCulture) + " with bounds " + bounds.ToString()); + } + + int bWidth = dgTable.BorderWidth; + + // paint the data cells + Rectangle dataBounds = bounds; + dataBounds.Height = base.Height - bWidth; + int dataWidth = PaintData(g, dataBounds, firstVisibleColumn, numVisibleColumns, alignToRight); + int dataWidthOffsetted = dataWidth + bounds.X - trueRowBounds.X; + + dataBounds.Offset(0, bWidth); // use bWidth, not 1 + if (bWidth > 0) + { + PaintBottomBorder(g, dataBounds, dataWidth, bWidth, alignToRight); + } + + if (expanded && dgTable.RelationsList.Count > 0) + { + // paint the relationships + Rectangle relationBounds = new Rectangle(trueRowBounds.X, + dataBounds.Bottom, + trueRowBounds.Width, + trueRowBounds.Height - dataBounds.Height - 2 * bWidth); + PaintRelations(g, relationBounds, trueRowBounds, dataWidthOffsetted, + firstVisibleColumn, numVisibleColumns, alignToRight); + relationBounds.Height += 1; + if (bWidth > 0) + { + PaintBottomBorder(g, relationBounds, dataWidthOffsetted, bWidth, alignToRight); + } + } + + return dataWidth; + } + + protected override void PaintCellContents(Graphics g, Rectangle cellBounds, DataGridColumnStyle column, + Brush backBr, Brush foreBrush, bool alignToRight) + { + CurrencyManager listManager = DataGrid.ListManager; + + // painting the error.. + // + string errString = string.Empty; + Rectangle bounds = cellBounds; + object errInfo = DataGrid.ListManager[number]; + if (errInfo is IDataErrorInfo) + { + errString = ((IDataErrorInfo)errInfo)[column.PropertyDescriptor.Name]; + } + + if (!string.IsNullOrEmpty(errString)) + { + Bitmap bmp = GetErrorBitmap(); + Rectangle errRect; + lock (bmp) + { + errRect = PaintIcon(g, bounds, true, alignToRight, bmp, backBr); + } + + // paint the errors correctly when RTL = true + if (alignToRight) + { + bounds.Width -= errRect.Width + xOffset; + } + else + { + bounds.X += errRect.Width + xOffset; + } + + DataGrid.ToolTipProvider.AddToolTip(errString, (IntPtr)(DataGrid.ToolTipId++), errRect); + } + + column.Paint(g, bounds, listManager, RowNumber, backBr, foreBrush, alignToRight); + } + + public override void PaintHeader(Graphics g, Rectangle bounds, bool alignToRight, bool isDirty) + { + DataGrid grid = DataGrid; + + Rectangle insideBounds = bounds; + + if (!grid.FlatMode) + { + ControlPaint.DrawBorder3D(g, insideBounds, Border3DStyle.RaisedInner); + insideBounds.Inflate(-1, -1); + } + + if (dgTable.IsDefault) + { + PaintHeaderInside(g, insideBounds, DataGrid.HeaderBackBrush, alignToRight, isDirty); + } + else + { + PaintHeaderInside(g, insideBounds, dgTable.HeaderBackBrush, alignToRight, isDirty); + } + } + + public void PaintHeaderInside(Graphics g, Rectangle bounds, Brush backBr, bool alignToRight, bool isDirty) + { + // paint the row header + bool paintPlusMinus = dgTable.RelationsList.Count > 0 && dgTable.DataGrid.AllowNavigation; + int rowHeaderBoundsX = MirrorRectangle(bounds.X, + bounds.Width - (paintPlusMinus ? expandoBoxWidth : 0), + bounds, alignToRight); + + if (!alignToRight) + { + Debug.Assert(bounds.X == rowHeaderBoundsX, "what's up doc?"); + } + + Rectangle rowHeaderBounds = new Rectangle(rowHeaderBoundsX, + bounds.Y, + bounds.Width - (paintPlusMinus ? expandoBoxWidth : 0), + bounds.Height); + + base.PaintHeader(g, rowHeaderBounds, alignToRight, isDirty); + + // Paint the expando on the right + int expandoBoxX = MirrorRectangle(bounds.X + rowHeaderBounds.Width, expandoBoxWidth, bounds, alignToRight); + + if (!alignToRight) + { + Debug.Assert(rowHeaderBounds.Right == expandoBoxX, "what's up doc?"); + } + + Rectangle expandoBox = new Rectangle(expandoBoxX, + bounds.Y, + expandoBoxWidth, + bounds.Height); + if (paintPlusMinus) + { + PaintPlusMinusGlyph(g, expandoBox, backBr, alignToRight); + } + } + + /// + /// Paints the relationships below the data area. + /// + private void PaintRelations(Graphics g, Rectangle bounds, Rectangle trueRowBounds, + int dataWidth, int firstCol, int nCols, bool alignToRight) + { + // Calculate the relationship rect. + // relationshipRect = Rectangle.Empty; + Rectangle relRect = GetRelationshipRect(); + //relRect.Offset(trueRowBounds.X, trueRowBounds.Y); + relRect.X = alignToRight ? bounds.Right - relRect.Width : bounds.X; + relRect.Y = bounds.Y; + int paintedWidth = Math.Max(dataWidth, relRect.Width); + + // Paint the stuff to the right , or left (Bi-Di) of the relationship rect. + Region r = g.Clip; + g.ExcludeClip(relRect); + + g.FillRectangle(GetBackBrush(), + alignToRight ? bounds.Right - dataWidth : bounds.X, + bounds.Y, + dataWidth, + bounds.Height); + + // Paint the relations' text + g.SetClip(bounds); + + relRect.Height -= dgTable.BorderWidth; // use bWidth not 1 + g.DrawRectangle(SystemPens.ControlText, relRect.X, relRect.Y, relRect.Width - 1, relRect.Height - 1); + relRect.Inflate(-1, -1); + + int cy = PaintRelationText(g, relRect, alignToRight); + + if (cy < relRect.Height) + { + g.FillRectangle(GetBackBrush(), relRect.X, relRect.Y + cy, relRect.Width, relRect.Height - cy); + } + + g.Clip = r; + + // paint any exposed area to the right or to the left (BI-DI) + if (paintedWidth < bounds.Width) + { + int bWidth; + if (dgTable.IsDefault) + { + bWidth = DataGrid.GridLineWidth; + } + else + { + bWidth = dgTable.GridLineWidth; + } + + g.FillRectangle(DataGrid.BackgroundBrush, + alignToRight ? bounds.X : bounds.X + paintedWidth, + bounds.Y, + bounds.Width - paintedWidth - bWidth + 1, // + 1 cause the relationship rectangle was deflated + bounds.Height); + + // Paint the border to the right of each cell + if (bWidth > 0) + { + Brush br; + // if the user changed the gridLineColor on the dataGrid + // from the defaultValue, then use that value; + if (dgTable.IsDefault) + { + br = DataGrid.GridLineBrush; + } + else + { + br = dgTable.GridLineBrush; + } + + g.FillRectangle(br, + alignToRight ? bounds.Right - bWidth - paintedWidth : bounds.X + paintedWidth - bWidth, + bounds.Y, + bWidth, + bounds.Height); + } + } + } + + private int PaintRelationText(Graphics g, Rectangle bounds, bool alignToRight) + { + g.FillRectangle(GetBackBrush(), bounds.X, bounds.Y, bounds.Width, System.Windows.Forms.DataGridTableStyle.relationshipSpacing); + + int relationshipHeight = dgTable.RelationshipHeight; + Rectangle textBounds = new Rectangle(bounds.X, bounds.Y + System.Windows.Forms.DataGridTableStyle.relationshipSpacing, + bounds.Width, + relationshipHeight); + int cy = System.Windows.Forms.DataGridTableStyle.relationshipSpacing; + for (int r = 0; r < dgTable.RelationsList.Count; ++r) + { + if (cy > bounds.Height) + { + break; + } + + Brush textBrush = dgTable.IsDefault ? DataGrid.LinkBrush : dgTable.LinkBrush; + + Font textFont = DataGrid.Font; + textBrush = dgTable.IsDefault ? DataGrid.LinkBrush : dgTable.LinkBrush; + textFont = DataGrid.LinkFont; + + g.FillRectangle(GetBackBrush(), textBounds); + + StringFormat format = new StringFormat(); + if (alignToRight) + { + format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + format.Alignment = StringAlignment.Far; + } + + g.DrawString(((string)dgTable.RelationsList[r]), textFont, textBrush, textBounds, + format); + if (r == FocusedRelation && number == DataGrid.CurrentCell.RowNumber) + { + textBounds.Width = dgTable.FocusedTextWidth; + ControlPaint.DrawFocusRectangle(g, textBounds, ((SolidBrush)textBrush).Color, ((SolidBrush)GetBackBrush()).Color); + textBounds.Width = bounds.Width; + } + + format.Dispose(); + + textBounds.Y += relationshipHeight; + cy += textBounds.Height; + } + + return cy; + } + + private void PaintPlusMinusGlyph(Graphics g, Rectangle bounds, Brush backBr, bool alignToRight) + { + if (CompModSwitches.DGRelationShpRowPaint.TraceVerbose) + { + Debug.WriteLine("PlusMinusGlyph painting in bounds -> " + bounds.ToString()); + } + + Rectangle outline = GetOutlineRect(bounds.X, bounds.Y); + + outline = Rectangle.Intersect(bounds, outline); + if (outline.IsEmpty) + { + return; + } + + g.FillRectangle(backBr, bounds); + + if (CompModSwitches.DGRelationShpRowPaint.TraceVerbose) + { + Debug.WriteLine("Painting PlusMinusGlyph with outline -> " + outline.ToString()); + } + + // draw the +/- box + Pen drawPen = dgTable.IsDefault ? DataGrid.HeaderForePen : dgTable.HeaderForePen; + g.DrawRectangle(drawPen, outline.X, outline.Y, outline.Width - 1, outline.Height - 1); + + int indent = 2; + // draw the - + g.DrawLine(drawPen, + outline.X + indent, outline.Y + outline.Width / 2, + outline.Right - indent - 1, outline.Y + outline.Width / 2); // -1 on the y coordinate + + if (!expanded) + { + // draw the vertical line to make + + g.DrawLine(drawPen, + outline.X + outline.Height / 2, outline.Y + indent, + outline.X + outline.Height / 2, outline.Bottom - indent - 1); // -1... hinting + } + else + { + Point[] points = new Point[3]; + points[0] = new Point(outline.X + outline.Height / 2, outline.Bottom); + + points[1] = new Point(points[0].X, bounds.Y + 2 * indent + base.Height); + + points[2] = new Point(alignToRight ? bounds.X : bounds.Right, + points[1].Y); + g.DrawLines(drawPen, points); + } + } + + private int RelationFromY(int y) + { + int relation = -1; + int relationshipHeight = dgTable.RelationshipHeight; + Rectangle relRect = GetRelationshipRect(); + int cy = base.Height - dgTable.BorderWidth + System.Windows.Forms.DataGridTableStyle.relationshipSpacing; + while (cy < relRect.Bottom) + { + if (cy > y) + { + break; + } + + cy += relationshipHeight; + relation++; + } + + if (relation >= dgTable.RelationsList.Count) + { + return -1; + } + + return relation; + } + + // given the relRect and the rowHeader, this function will return the + // X coordinate of the relationship rectangle as it should appear on the screen + private int MirrorRelationshipRectangle(Rectangle relRect, Rectangle rowHeader, bool alignToRight) + { + if (alignToRight) + { + return rowHeader.X - relRect.Width; + } + else + { + return relRect.X; + } + } + + // given the X and Width of a rectangle R1 contained in rect, + // this will return the X coordinate of the rectangle that corresponds to R1 in Bi-Di transformation + private int MirrorRectangle(int x, int width, Rectangle rect, bool alignToRight) + { + if (alignToRight) + { + return rect.Right + rect.X - width - x; + } + else + { + return x; + } + } + + [ComVisible(true)] + protected class DataGridRelationshipRowAccessibleObject : DataGridRowAccessibleObject + { + public DataGridRelationshipRowAccessibleObject(DataGridRow owner) : base(owner) + { + } + + protected override void AddChildAccessibleObjects(IList children) + { + base.AddChildAccessibleObjects(children); + DataGridRelationshipRow row = (DataGridRelationshipRow)Owner; + if (row.dgTable.RelationsList != null) + { + for (int i = 0; i < row.dgTable.RelationsList.Count; i++) + { + children.Add(new DataGridRelationshipAccessibleObject(row, i)); + } + } + } + + private DataGridRelationshipRow RelationshipRow + { + get + { + return (DataGridRelationshipRow)Owner; + } + } + + public override string DefaultAction + { + get + { + if (RelationshipRow.dgTable.RelationsList.Count > 0) + { + if (RelationshipRow.Expanded) + { + return SR.AccDGCollapse; + } + else + { + return SR.AccDGExpand; + } + } + + return null; + } + } + + public override AccessibleStates State + { + get + { + AccessibleStates state = base.State; + if (RelationshipRow.dgTable.RelationsList.Count > 0) + { + if (((DataGridRelationshipRow)Owner).Expanded) + { + state |= AccessibleStates.Expanded; + } + else + { + state |= AccessibleStates.Collapsed; + } + } + + return state; + } + } + + public override void DoDefaultAction() + { + if (RelationshipRow.dgTable.RelationsList.Count > 0) + { + ((DataGridRelationshipRow)Owner).Expanded = !((DataGridRelationshipRow)Owner).Expanded; + } + } + + public override AccessibleObject GetFocused() + { + DataGridRelationshipRow row = (DataGridRelationshipRow)Owner; + int focusRel = row.dgTable.FocusedRelation; + if (focusRel == -1) + { + return base.GetFocused(); + } + else + { + return GetChild(GetChildCount() - row.dgTable.RelationsList.Count + focusRel); + } + } + } + + [ComVisible(true)] + protected class DataGridRelationshipAccessibleObject : AccessibleObject + { + readonly DataGridRelationshipRow owner; + readonly int relationship; + + public DataGridRelationshipAccessibleObject(DataGridRelationshipRow owner, int relationship) : base() + { + Debug.Assert(owner != null, "DataGridRelationshipAccessibleObject must have a valid owner DataGridRow"); + this.owner = owner; + this.relationship = relationship; + } + + public override Rectangle Bounds + { + get + { + Rectangle rowBounds = DataGrid.GetRowBounds(owner); + + Rectangle bounds = owner.Expanded ? owner.GetRelationshipRectWithMirroring() : Rectangle.Empty; + bounds.Y += owner.dgTable.RelationshipHeight * relationship; + bounds.Height = owner.Expanded ? owner.dgTable.RelationshipHeight : 0; // when the row is collapsed the height of the relationship object should be 0 + // GetRelationshipRectWithMirroring will use the row headers width + if (!owner.Expanded) + { + bounds.X += rowBounds.X; + } + + bounds.Y += rowBounds.Y; + + return owner.DataGrid.RectangleToScreen(bounds); + } + } + + public override string Name + { + get + { + return (string)owner.dgTable.RelationsList[relationship]; + } + } + + protected DataGridRelationshipRow Owner + { + get + { + return owner; + } + } + + public override AccessibleObject Parent + { + get + { + return owner.AccessibleObject; + } + } + + protected DataGrid DataGrid + { + get + { + return owner.DataGrid; + } + } + + public override AccessibleRole Role + { + get + { + return AccessibleRole.Link; + } + } + + public override AccessibleStates State + { + get + { + DataGridRow[] dgRows = DataGrid.DataGridRows; + if (Array.IndexOf(dgRows, owner) == -1) + { + return AccessibleStates.Unavailable; + } + + AccessibleStates state = AccessibleStates.Selectable + | AccessibleStates.Focusable + | AccessibleStates.Linked; + + if (!owner.Expanded) + { + state |= AccessibleStates.Invisible; + } + + if (DataGrid.Focused && Owner.dgTable.FocusedRelation == relationship) + { + state |= AccessibleStates.Focused; + } + + return state; + } + } + + public override string Value + { + get + { + DataGridRow[] dgRows = DataGrid.DataGridRows; + if (Array.IndexOf(dgRows, owner) == -1) + { + return null; + } + else + { + return (string)owner.dgTable.RelationsList[relationship]; + } + } + set + { + // not supported + } + } + + public override string DefaultAction + { + get + { + return SR.AccDGNavigate; + } + } + + public override void DoDefaultAction() + { + ((DataGridRelationshipRow)Owner).Expanded = true; + owner.FocusedRelation = -1; + DataGrid.NavigateTo((string)owner.dgTable.RelationsList[relationship], owner, true); + DataGrid.BeginInvoke(new MethodInvoker(ResetAccessibilityLayer)); + } + + private void ResetAccessibilityLayer() + { + ((DataGrid.DataGridAccessibleObject)DataGrid.AccessibilityObject).NotifyClients(AccessibleEvents.Reorder, 0); + ((DataGrid.DataGridAccessibleObject)DataGrid.AccessibilityObject).NotifyClients(AccessibleEvents.Focus, DataGrid.CurrentCellAccIndex); + ((DataGrid.DataGridAccessibleObject)DataGrid.AccessibilityObject).NotifyClients(AccessibleEvents.Selection, DataGrid.CurrentCellAccIndex); + } + + /// + /// Navigate to the next or previous grid entry. + /// + public override AccessibleObject Navigate(AccessibleNavigation navdir) + { + switch (navdir) + { + case AccessibleNavigation.Right: + case AccessibleNavigation.Next: + case AccessibleNavigation.Down: + if (relationship + 1 < owner.dgTable.RelationsList.Count) + { + return Parent.GetChild(Parent.GetChildCount() - owner.dgTable.RelationsList.Count + relationship + 1); + } + + break; + case AccessibleNavigation.Up: + case AccessibleNavigation.Left: + case AccessibleNavigation.Previous: + if (relationship > 0) + { + return Parent.GetChild(Parent.GetChildCount() - owner.dgTable.RelationsList.Count + relationship - 1); + } + + break; + } + + return null; + } + + public override void Select(AccessibleSelection flags) + { + // Focus the PropertyGridView window + // + if ((flags & AccessibleSelection.TakeFocus) == AccessibleSelection.TakeFocus) + { + DataGrid.Focus(); + } + + if ((flags & AccessibleSelection.TakeSelection) == AccessibleSelection.TakeSelection) + { + Owner.FocusedRelation = relationship; + } + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridRow.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridRow.cs new file mode 100644 index 00000000000..6f0b0f00c39 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridRow.cs @@ -0,0 +1,1199 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; + +namespace System.Windows.Forms +{ + /// + /// Encapsulates the painting logic for a new row added to a control. + /// + internal abstract class DataGridRow : MarshalByRefObject + { + internal protected int number; // row number + private bool selected; + private int height; + // protected DataRow dataRow; + private IntPtr tooltipID = new IntPtr(-1); + private string tooltip = string.Empty; + AccessibleObject accessibleObject; + + // for accessibility... + // + // internal DataGrid dataGrid; + + // will need this for the painting information ( row header color ) + // + protected DataGridTableStyle dgTable; + + // we will be mapping only the black color to + // the HeaderForeColor + // + private static readonly ColorMap[] colorMap = new ColorMap[] { new ColorMap() }; + + // bitmaps + // + private static Bitmap rightArrow; + private static Bitmap leftArrow; + private static Bitmap errorBmp; + private static Bitmap pencilBmp; + private static Bitmap starBmp; + protected const int xOffset = 3; + protected const int yOffset = 2; + + /// + /// Initializes a new instance of a . + /// + public DataGridRow(DataGrid dataGrid, DataGridTableStyle dgTable, int rowNumber) + { + if (dataGrid == null || dgTable.DataGrid == null) + { + throw new ArgumentNullException(nameof(dataGrid)); + } + + if (rowNumber < 0) + { + throw new ArgumentException(SR.DataGridRowRowNumber, nameof(rowNumber)); + } + + // this.dataGrid = dataGrid; + number = rowNumber; + + // map the black color in the pictures to the DataGrid's HeaderForeColor + // + colorMap[0].OldColor = Color.Black; + colorMap[0].NewColor = dgTable.HeaderForeColor; + + this.dgTable = dgTable; + height = MinimumRowHeight(dgTable); + } + + public AccessibleObject AccessibleObject + { + get + { + if (accessibleObject == null) + { + accessibleObject = CreateAccessibleObject(); + } + + return accessibleObject; + } + } + + protected virtual AccessibleObject CreateAccessibleObject() + { + return new DataGridRowAccessibleObject(this); + } + + internal protected virtual int MinimumRowHeight(DataGridTableStyle dgTable) + { + return MinimumRowHeight(dgTable.GridColumnStyles); + } + + internal protected virtual int MinimumRowHeight(GridColumnStylesCollection columns) + { + int h = dgTable.IsDefault ? DataGrid.PreferredRowHeight : dgTable.PreferredRowHeight; + + try + { + if (dgTable.DataGrid.DataSource != null) + { + int nCols = columns.Count; + for (int i = 0; i < nCols; ++i) + { + // if (columns[i].Visible && columns[i].PropertyDescriptor != null) + if (columns[i].PropertyDescriptor != null) + { + h = Math.Max(h, columns[i].GetMinimumHeight()); + } + } + } + } + catch + { + } + + return h; + } + + // =------------------------------------------------------------------ + // = Properties + // =------------------------------------------------------------------ + + /// + /// Gets the control the row belongs to. + /// + public DataGrid DataGrid + { + get + { + return dgTable.DataGrid; + } + } + + internal DataGridTableStyle DataGridTableStyle + { + get + { + return dgTable; + } + set + { + dgTable = value; + } + } + + /* + public DataGridTable DataGridTable { + get { + return dgTable; + } + } + */ + + /* + public DataRow DataRow { + get { + return dataRow; + } + } + */ + + /// + /// Gets or sets the height of the row. + /// + public virtual int Height + { + get + { + return height; + } + set + { + // the height of the row should be at least 0. + // this way, if the row has a relationship list and the user resizes the row such that + // the new height does not accomodate the height of the relationship list + // the row will at least show the relationship list ( and not paint on the portion of the row above this one ) + height = Math.Max(0, value); + // when we resize the row, or when we set the PreferredRowHeigth on the + // DataGridTableStyle, we change the height of the Row, which will cause to invalidate, + // then the grid itself will do another invalidate call. + dgTable.DataGrid.OnRowHeightChanged(this); + } + } + + /// + /// Gets the row's number. + /// + public int RowNumber + { + get + { + return number; + } + } + + /// + /// Gets or sets a value indicating whether the row is selected. + /// + public virtual bool Selected + { + get + { + return selected; + } + set + { + selected = value; + InvalidateRow(); + } + } + + // =------------------------------------------------------------------ + // = Methods + // =------------------------------------------------------------------ + + /// + /// Gets the bitmap associated with the row. + /// + protected Bitmap GetBitmap(string bitmapName) + { + try + { + return DpiHelper.GetBitmapFromIcon(typeof(DataGridCaption), bitmapName); + } + catch (Exception e) + { + Debug.Fail("Failed to load bitmap: " + bitmapName, e.ToString()); + throw; + } + } + + /// + /// When overridden in a derived class, gets the + /// where a cell's contents gets painted. + /// + public virtual Rectangle GetCellBounds(int col) + { + int firstVisibleCol = dgTable.DataGrid.FirstVisibleColumn; + int cx = 0; + Rectangle cellBounds = new Rectangle(); + GridColumnStylesCollection columns = dgTable.GridColumnStyles; + if (columns != null) + { + for (int i = firstVisibleCol; i < col; i++) + { + if (columns[i].PropertyDescriptor != null) + { + cx += columns[i].Width; + } + } + + int borderWidth = dgTable.GridLineWidth; + cellBounds = new Rectangle(cx, + 0, + columns[col].Width - borderWidth, + Height - borderWidth); + } + + return cellBounds; + } + + /// + /// When overridden in a derived class, gets the of the non-scrollable area of + /// the row. + /// + public virtual Rectangle GetNonScrollableArea() + { + return Rectangle.Empty; + } + + /// + /// Gets or sets the bitmap displayed in the row header of a new row. + /// + protected Bitmap GetStarBitmap() + { + if (starBmp == null) + { + starBmp = GetBitmap("DataGridRow.star"); + } + + return starBmp; + } + + /// + /// Gets or sets the bitmap displayed in the row header that indicates a row can + /// be edited. + /// + protected Bitmap GetPencilBitmap() + { + if (pencilBmp == null) + { + pencilBmp = GetBitmap("DataGridRow.pencil"); + } + + return pencilBmp; + } + + /// + /// Gets or sets the bitmap displayed on a row with an error. + /// + protected Bitmap GetErrorBitmap() + { + if (errorBmp == null) + { + errorBmp = GetBitmap("DataGridRow.error"); + } + + return errorBmp; + } + + protected Bitmap GetLeftArrowBitmap() + { + if (leftArrow == null) + { + leftArrow = GetBitmap("DataGridRow.left"); + } + + return leftArrow; + } + + protected Bitmap GetRightArrowBitmap() + { + if (rightArrow == null) + { + rightArrow = GetBitmap("DataGridRow.right"); + } + + return rightArrow; + } + + public virtual void InvalidateRow() + { + dgTable.DataGrid.InvalidateRow(number); + } + + public virtual void InvalidateRowRect(Rectangle r) + { + dgTable.DataGrid.InvalidateRowRect(number, r); + } + + /// + /// When overridden in a derived class, notifies the grid that an edit will + /// occur. + /// + public virtual void OnEdit() + { + } + + /// + /// When overridden in a derived class, called by the control when a key press occurs on a row with focus. + /// + public virtual bool OnKeyPress(Keys keyData) + { + int currentColIndex = dgTable.DataGrid.CurrentCell.ColumnNumber; + GridColumnStylesCollection columns = dgTable.GridColumnStyles; + if (columns != null && currentColIndex >= 0 && currentColIndex < columns.Count) + { + DataGridColumnStyle currentColumn = columns[currentColIndex]; + if (currentColumn.KeyPress(RowNumber, keyData)) + { + return true; + } + } + + return false; + } + + /// + /// Called by the when a click occurs in the row's client area + /// specifed by the x and y coordinates and the specified + /// . + /// + public virtual bool OnMouseDown(int x, int y, Rectangle rowHeaders) + { + return OnMouseDown(x, y, rowHeaders, false); + } + + /// + /// When overridden in a derived class, is called by the when a click occurs + /// in the row's + /// client area, specified by x and y coordinates. + /// + public virtual bool OnMouseDown(int x, int y, Rectangle rowHeaders, bool alignToRight) + { + // if we call base.OnMouseDown, then the row could not use this + // mouse click at all. in that case LoseChildFocus, so the edit control + // will become visible + LoseChildFocus(rowHeaders, alignToRight); + + // we did not use this click at all. + return false; + } + + public virtual bool OnMouseMove(int x, int y, Rectangle rowHeaders) + { + return false; + } + + /// + /// When overridden in a derived class, is called by the when + /// the mouse moves within the row's client area. + /// + public virtual bool OnMouseMove(int x, int y, Rectangle rowHeaders, bool alignToRight) + { + return false; + } + + public virtual void OnMouseLeft(Rectangle rowHeaders, bool alignToRight) + { + } + + public virtual void OnMouseLeft() + { + } + + /// + /// When overridden in a derived class, causes the RowEnter event to occur. + /// + public virtual void OnRowEnter() { } + public virtual void OnRowLeave() { } + + // processes the Tab Key + // returns TRUE if the TAB key is processed + internal abstract bool ProcessTabKey(Keys keyData, Rectangle rowHeaders, bool alignToRight); + + // tells the dataGridRow that it lost the focus + internal abstract void LoseChildFocus(Rectangle rowHeaders, bool alignToRight); + + /// + /// Paints the row. + /// + public abstract int Paint(Graphics g, + Rectangle dataBounds, + Rectangle rowBounds, + int firstVisibleColumn, + int numVisibleColumns); + + public abstract int Paint(Graphics g, + Rectangle dataBounds, + Rectangle rowBounds, + int firstVisibleColumn, + int numVisibleColumns, + bool alignToRight); + + /// + /// Draws a border on the bottom DataGrid.GridLineWidth pixels + /// of the bounding rectangle passed in. + /// + protected virtual void PaintBottomBorder(Graphics g, Rectangle bounds, int dataWidth) + { + PaintBottomBorder(g, bounds, dataWidth, dgTable.GridLineWidth, false); + } + + protected virtual void PaintBottomBorder(Graphics g, Rectangle bounds, int dataWidth, int borderWidth, bool alignToRight) + { + // paint bottom border + Rectangle bottomBorder = new Rectangle(alignToRight ? bounds.Right - dataWidth : bounds.X, + bounds.Bottom - borderWidth, + dataWidth, + borderWidth); + + g.FillRectangle(dgTable.IsDefault ? DataGrid.GridLineBrush : dgTable.GridLineBrush, bottomBorder); + + // paint any exposed region to the right + if (dataWidth < bounds.Width) + { + g.FillRectangle(dgTable.DataGrid.BackgroundBrush, + alignToRight ? bounds.X : bottomBorder.Right, + bottomBorder.Y, + bounds.Width - bottomBorder.Width, + borderWidth); + } + } + + /// + /// Paints the row. + /// + public virtual int PaintData(Graphics g, + Rectangle bounds, + int firstVisibleColumn, + int columnCount) + { + return PaintData(g, bounds, firstVisibleColumn, columnCount, false); + } + + public virtual int PaintData(Graphics g, + Rectangle bounds, + int firstVisibleColumn, + int columnCount, + bool alignToRight) + { + Debug.WriteLineIf(CompModSwitches.DGRowPaint.TraceVerbose, "Painting DataGridAddNewRow: bounds = " + bounds.ToString()); + + Rectangle cellBounds = bounds; + int bWidth = dgTable.IsDefault ? DataGrid.GridLineWidth : dgTable.GridLineWidth; + int cx = 0; + + DataGridCell current = dgTable.DataGrid.CurrentCell; + + GridColumnStylesCollection columns = dgTable.GridColumnStyles; + int nCols = columns.Count; + for (int col = firstVisibleColumn; col < nCols; ++col) + { + if (cx > bounds.Width) + { + break; + } + + // if (!columns[col].Visible || columns[col].PropertyDescriptor == null) + if (columns[col].PropertyDescriptor == null || columns[col].Width <= 0) + { + continue; + } + + cellBounds.Width = columns[col].Width - bWidth; + + if (alignToRight) + { + cellBounds.X = bounds.Right - cx - cellBounds.Width; + } + else + { + cellBounds.X = bounds.X + cx; + } + + // Paint the data with the the DataGridColumn + Brush backBr = BackBrushForDataPaint(ref current, columns[col], col); + Brush foreBrush = ForeBrushForDataPaint(ref current, columns[col], col); + + PaintCellContents(g, + cellBounds, + columns[col], + backBr, + foreBrush, + alignToRight); + + // Paint the border to the right of each cell + if (bWidth > 0) + { + g.FillRectangle(dgTable.IsDefault ? DataGrid.GridLineBrush : dgTable.GridLineBrush, + alignToRight ? cellBounds.X - bWidth : cellBounds.Right, + cellBounds.Y, + bWidth, + cellBounds.Height); + } + + cx += cellBounds.Width + bWidth; + } + + // Paint any exposed area to the right ( or left ) of the data cell area + if (cx < bounds.Width) + { + g.FillRectangle(dgTable.DataGrid.BackgroundBrush, + alignToRight ? bounds.X : bounds.X + cx, + bounds.Y, + bounds.Width - cx, + bounds.Height); + } + + return cx; + } + + protected virtual void PaintCellContents(Graphics g, Rectangle cellBounds, DataGridColumnStyle column, + Brush backBr, Brush foreBrush) + { + PaintCellContents(g, cellBounds, column, backBr, foreBrush, false); + } + + protected virtual void PaintCellContents(Graphics g, Rectangle cellBounds, DataGridColumnStyle column, + Brush backBr, Brush foreBrush, bool alignToRight) + { + g.FillRectangle(backBr, cellBounds); + } + + // + // This function will do the following: if paintIcon is set to true, then + // will draw the image on the RowHeader. if paintIcon is set to false, + // then this function will fill the rectangle on which otherwise will + // have been drawn the image + // + // will return the rectangle that includes the Icon + // + protected Rectangle PaintIcon(Graphics g, Rectangle visualBounds, bool paintIcon, bool alignToRight, Bitmap bmp) + { + return PaintIcon(g, visualBounds, paintIcon, alignToRight, bmp, + dgTable.IsDefault ? DataGrid.HeaderBackBrush : dgTable.HeaderBackBrush); + } + + protected Rectangle PaintIcon(Graphics g, Rectangle visualBounds, bool paintIcon, bool alignToRight, Bitmap bmp, Brush backBrush) + { + Size bmpSize = bmp.Size; + Rectangle bmpRect = new Rectangle(alignToRight ? visualBounds.Right - xOffset - bmpSize.Width : visualBounds.X + xOffset, + visualBounds.Y + yOffset, + bmpSize.Width, + bmpSize.Height); + g.FillRectangle(backBrush, visualBounds); + if (paintIcon) + { + colorMap[0].NewColor = dgTable.IsDefault ? DataGrid.HeaderForeColor : dgTable.HeaderForeColor; + colorMap[0].OldColor = Color.Black; + ImageAttributes attr = new ImageAttributes(); + attr.SetRemapTable(colorMap, ColorAdjustType.Bitmap); + g.DrawImage(bmp, bmpRect, 0, 0, bmpRect.Width, bmpRect.Height, GraphicsUnit.Pixel, attr); + // g.DrawImage(bmp, bmpRect); + attr.Dispose(); + } + + return bmpRect; + } + + // assume that the row is not aligned to right, and that the row is not dirty + public virtual void PaintHeader(Graphics g, Rectangle visualBounds) + { + PaintHeader(g, visualBounds, false); + } + + // assume that the row is not dirty + public virtual void PaintHeader(Graphics g, Rectangle visualBounds, bool alignToRight) + { + PaintHeader(g, visualBounds, alignToRight, false); + } + + public virtual void PaintHeader(Graphics g, Rectangle visualBounds, bool alignToRight, bool rowIsDirty) + { + Rectangle bounds = visualBounds; + + // paint the first part of the row header: the Arror or Pencil/Star + Bitmap bmp; + if (this is DataGridAddNewRow) + { + bmp = GetStarBitmap(); + lock (bmp) + { + bounds.X += PaintIcon(g, bounds, true, alignToRight, bmp).Width + xOffset; + } + + return; + } + else if (rowIsDirty) + { + bmp = GetPencilBitmap(); + lock (bmp) + { + bounds.X += PaintIcon(g, bounds, RowNumber == DataGrid.CurrentCell.RowNumber, alignToRight, bmp).Width + xOffset; + } + } + else + { + bmp = alignToRight ? GetLeftArrowBitmap() : GetRightArrowBitmap(); + lock (bmp) + { + bounds.X += PaintIcon(g, bounds, RowNumber == DataGrid.CurrentCell.RowNumber, alignToRight, bmp).Width + xOffset; + } + } + + // Paint the error icon + // + object errorInfo = DataGrid.ListManager[number]; + if (!(errorInfo is IDataErrorInfo)) + { + return; + } + + string errString = ((IDataErrorInfo)errorInfo).Error; + if (errString == null) + { + errString = string.Empty; + } + + if (tooltip != errString) + { + if (!string.IsNullOrEmpty(tooltip)) + { + DataGrid.ToolTipProvider.RemoveToolTip(tooltipID); + tooltip = string.Empty; + tooltipID = new IntPtr(-1); + } + } + + if (string.IsNullOrEmpty(errString)) + { + return; + } + + // we now have an error string: paint the errorIcon and add the tooltip + Rectangle errRect; + bmp = GetErrorBitmap(); + lock (bmp) + { + errRect = PaintIcon(g, bounds, true, alignToRight, bmp); + } + + bounds.X += errRect.Width + xOffset; + + tooltip = errString; + tooltipID = (IntPtr)((int)DataGrid.ToolTipId++); + DataGrid.ToolTipProvider.AddToolTip(tooltip, tooltipID, errRect); + } + + protected Brush GetBackBrush() + { + Brush br = dgTable.IsDefault ? DataGrid.BackBrush : dgTable.BackBrush; + if (DataGrid.LedgerStyle && (RowNumber % 2 == 1)) + { + br = dgTable.IsDefault ? DataGrid.AlternatingBackBrush : dgTable.AlternatingBackBrush; + } + + return br; + } + + /// + /// Returns the BackColor and TextColor that the Graphics object should use + /// for the appropriate values for a given row and column when painting the data. + /// + protected Brush BackBrushForDataPaint(ref DataGridCell current, DataGridColumnStyle gridColumn, int column) + { + Brush backBr = GetBackBrush(); + + if (Selected) + { + backBr = dgTable.IsDefault ? DataGrid.SelectionBackBrush : dgTable.SelectionBackBrush; + } + + /* + if (RowNumber == current.RowNumber && column == current.ColumnNumber) { + backBr = grid.CurrentCellBackBrush; + } + */ + return backBr; + } + + protected Brush ForeBrushForDataPaint(ref DataGridCell current, DataGridColumnStyle gridColumn, int column) + { + // Brush foreBrush = gridColumn.ForeBrush; + Brush foreBrush = dgTable.IsDefault ? DataGrid.ForeBrush : dgTable.ForeBrush; + + if (Selected) + { + foreBrush = dgTable.IsDefault ? DataGrid.SelectionForeBrush : dgTable.SelectionForeBrush; + } + + /* + if (RowNumber == current.RowNumber && column == current.ColumnNumber) { + foreColor = grid.CurrentCellForeColor; + } + */ + return foreBrush; + } + + [ComVisible(true)] + protected class DataGridRowAccessibleObject : AccessibleObject + { + ArrayList cells; + readonly DataGridRow owner; + + internal static string CellToDisplayString(DataGrid grid, int row, int column) + { + if (column < grid.myGridTable.GridColumnStyles.Count) + { + return grid.myGridTable.GridColumnStyles[column].PropertyDescriptor.Converter.ConvertToString(grid[row, column]); + } + else + { + return ""; + } + } + + internal static object DisplayStringToCell(DataGrid grid, int row, int column, string value) + { + if (column < grid.myGridTable.GridColumnStyles.Count) + { + return grid.myGridTable.GridColumnStyles[column].PropertyDescriptor.Converter.ConvertFromString(value); + } + + // ignore... + // + return null; + } + + public DataGridRowAccessibleObject(DataGridRow owner) : base() + { + Debug.Assert(owner != null, "DataGridRowAccessibleObject must have a valid owner DataGridRow"); + this.owner = owner; + DataGrid grid = DataGrid; + Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, "Create row accessible object"); + + EnsureChildren(); + } + + private void EnsureChildren() + { + if (cells == null) + { + // default size... little extra for relationships... + // + cells = new ArrayList(DataGrid.myGridTable.GridColumnStyles.Count + 2); + AddChildAccessibleObjects(cells); + } + } + + protected virtual void AddChildAccessibleObjects(IList children) + { + Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, "Create row's accessible children"); + Debug.Indent(); + GridColumnStylesCollection cols = DataGrid.myGridTable.GridColumnStyles; + int len = cols.Count; + Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, len + " columns present"); + for (int i = 0; i < len; i++) + { + children.Add(CreateCellAccessibleObject(i)); + } + + Debug.Unindent(); + } + + protected virtual AccessibleObject CreateCellAccessibleObject(int column) + { + return new DataGridCellAccessibleObject(owner, column); + } + + public override Rectangle Bounds + { + get + { + return DataGrid.RectangleToScreen(DataGrid.GetRowBounds(owner)); + } + } + + public override string Name + { + get + { + if (owner is DataGridAddNewRow) + { + return SR.AccDGNewRow; + } + else + { + return DataGridRowAccessibleObject.CellToDisplayString(DataGrid, owner.RowNumber, 0); + } + } + } + + protected DataGridRow Owner + { + get + { + return owner; + } + } + + public override AccessibleObject Parent + { + get + { + return DataGrid.AccessibilityObject; + } + } + + private DataGrid DataGrid + { + get + { + return owner.DataGrid; + } + } + + public override AccessibleRole Role + { + get + { + return AccessibleRole.Row; + } + } + + public override AccessibleStates State + { + get + { + AccessibleStates state = AccessibleStates.Selectable | AccessibleStates.Focusable; + + // Determine focus + // + if (DataGrid.CurrentCell.RowNumber == owner.RowNumber) + { + state |= AccessibleStates.Focused; + } + + // Determine selected + // + if (DataGrid.CurrentRowIndex == owner.RowNumber) + { + state |= AccessibleStates.Selected; + } + + return state; + } + } + + public override string Value + { + get + { + return Name; + } + } + + public override AccessibleObject GetChild(int index) + { + if (index < cells.Count) + { + return (AccessibleObject)cells[index]; + } + + return null; + } + + public override int GetChildCount() + { + return cells.Count; + } + + /// + /// Returns the currently focused child, if any. + /// Returns this if the object itself is focused. + /// + public override AccessibleObject GetFocused() + { + if (DataGrid.Focused) + { + DataGridCell cell = DataGrid.CurrentCell; + if (cell.RowNumber == owner.RowNumber) + { + return (AccessibleObject)cells[cell.ColumnNumber]; + } + } + + return null; + } + + /// + /// Navigate to the next or previous grid entry.entry. + /// + public override AccessibleObject Navigate(AccessibleNavigation navdir) + { + switch (navdir) + { + case AccessibleNavigation.Down: + case AccessibleNavigation.Right: + case AccessibleNavigation.Next: + return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber + 1); + + case AccessibleNavigation.Up: + case AccessibleNavigation.Left: + case AccessibleNavigation.Previous: + return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber - 1); + + case AccessibleNavigation.FirstChild: + if (GetChildCount() > 0) + { + return GetChild(0); + } + + break; + case AccessibleNavigation.LastChild: + if (GetChildCount() > 0) + { + return GetChild(GetChildCount() - 1); + } + + break; + } + + return null; + } + + public override void Select(AccessibleSelection flags) + { + // Focus the PropertyGridView window + // + if ((flags & AccessibleSelection.TakeFocus) == AccessibleSelection.TakeFocus) + { + DataGrid.Focus(); + } + + // Select the grid entry + // + if ((flags & AccessibleSelection.TakeSelection) == AccessibleSelection.TakeSelection) + { + DataGrid.CurrentRowIndex = owner.RowNumber; + } + } + } + + [ComVisible(true)] + protected class DataGridCellAccessibleObject : AccessibleObject + { + readonly DataGridRow owner; + readonly int column; + + public DataGridCellAccessibleObject(DataGridRow owner, int column) : base() + { + Debug.Assert(owner != null, "DataGridColumnAccessibleObject must have a valid owner DataGridRow"); + this.owner = owner; + this.column = column; + Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, "Create cell accessible object"); + } + + public override Rectangle Bounds + { + get + { + return DataGrid.RectangleToScreen(DataGrid.GetCellBounds(new DataGridCell(owner.RowNumber, column))); + } + } + + public override string Name + { + get + { + return DataGrid.myGridTable.GridColumnStyles[column].HeaderText; + } + } + + public override AccessibleObject Parent + { + get + { + return owner.AccessibleObject; + } + } + + protected DataGrid DataGrid + { + get + { + return owner.DataGrid; + } + } + + public override string DefaultAction + { + get + { + return SR.AccDGEdit; + } + } + + public override AccessibleRole Role + { + get + { + return AccessibleRole.Cell; + } + } + + public override AccessibleStates State + { + get + { + AccessibleStates state = AccessibleStates.Selectable | AccessibleStates.Focusable; + + // Determine focus + // + if (DataGrid.CurrentCell.RowNumber == owner.RowNumber + && DataGrid.CurrentCell.ColumnNumber == column) + { + if (DataGrid.Focused) + { + state |= AccessibleStates.Focused; + } + + state |= AccessibleStates.Selected; + } + + return state; + } + } + + public override string Value + { + get + { + if (owner is DataGridAddNewRow) + { + return null; + } + else + { + return DataGridRowAccessibleObject.CellToDisplayString(DataGrid, owner.RowNumber, column); + } + } + + set + { + if (!(owner is DataGridAddNewRow)) + { + object realValue = DataGridRowAccessibleObject.DisplayStringToCell(DataGrid, owner.RowNumber, column, value); + DataGrid[owner.RowNumber, column] = realValue; + } + } + } + + public override void DoDefaultAction() + { + Select(AccessibleSelection.TakeFocus | AccessibleSelection.TakeSelection); + } + + /// + /// Returns the currently focused child, if any. + /// Returns this if the object itself is focused. + /// + public override AccessibleObject GetFocused() + { + // Datagrid always returns the cell as the focused thing... so do we! + // + return DataGrid.AccessibilityObject.GetFocused(); + } + + /// + /// Navigate to the next or previous grid entry. + /// + public override AccessibleObject Navigate(AccessibleNavigation navdir) + { + switch (navdir) + { + case AccessibleNavigation.Right: + case AccessibleNavigation.Next: + if (column < owner.AccessibleObject.GetChildCount() - 1) + { + return owner.AccessibleObject.GetChild(column + 1); + } + else + { + AccessibleObject o = DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber + 1); + if (o != null) + { + return o.Navigate(AccessibleNavigation.FirstChild); + } + } + + break; + case AccessibleNavigation.Down: + return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber + 1).Navigate(AccessibleNavigation.FirstChild); + case AccessibleNavigation.Up: + return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber - 1).Navigate(AccessibleNavigation.FirstChild); + case AccessibleNavigation.Left: + case AccessibleNavigation.Previous: + if (column > 0) + { + return owner.AccessibleObject.GetChild(column - 1); + } + else + { + AccessibleObject o = DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber - 1); + if (o != null) + { + return o.Navigate(AccessibleNavigation.LastChild); + } + } + + break; + + case AccessibleNavigation.FirstChild: + case AccessibleNavigation.LastChild: + + break; + } + + return null; + } + + public override void Select(AccessibleSelection flags) + { + // Focus the PropertyGridView window + // + if ((flags & AccessibleSelection.TakeFocus) == AccessibleSelection.TakeFocus) + { + DataGrid.Focus(); + } + + // Select the grid entry + // + if ((flags & AccessibleSelection.TakeSelection) == AccessibleSelection.TakeSelection) + { + DataGrid.CurrentCell = new DataGridCell(owner.RowNumber, column); + } + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridState.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridState.cs new file mode 100644 index 00000000000..22b36e98ddc --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridState.cs @@ -0,0 +1,262 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Drawing; +using System.Runtime.InteropServices; +using System.Text; + +namespace System.Windows.Forms +{ + /// + /// Encapsulates the state of a DataGrid that changes when the + /// user navigates back and forth through ADO.NET data relations. + /// + internal sealed class DataGridState : ICloneable + { + // fields + // + public object DataSource; + public string DataMember; + public CurrencyManager ListManager; + public DataGridRow[] DataGridRows = Array.Empty(); + public DataGrid DataGrid; + public int DataGridRowsLength; + public GridColumnStylesCollection GridColumnStyles; + + public int FirstVisibleRow; + public int FirstVisibleCol; + + public int CurrentRow; + public int CurrentCol; + + public DataGridRow LinkingRow; + AccessibleObject parentRowAccessibleObject; + + public DataGridState() + { + } + + public DataGridState(DataGrid dataGrid) + { + PushState(dataGrid); + } + + internal AccessibleObject ParentRowAccessibleObject + { + get + { + if (parentRowAccessibleObject == null) + { + parentRowAccessibleObject = new DataGridStateParentRowAccessibleObject(this); + } + + return parentRowAccessibleObject; + } + } + + // methods + // + + public object Clone() + { + DataGridState dgs = new DataGridState + { + DataGridRows = DataGridRows, + DataSource = DataSource, + DataMember = DataMember, + FirstVisibleRow = FirstVisibleRow, + FirstVisibleCol = FirstVisibleCol, + CurrentRow = CurrentRow, + CurrentCol = CurrentCol, + GridColumnStyles = GridColumnStyles, + ListManager = ListManager, + DataGrid = DataGrid + }; + return dgs; + } + + /// + /// Called by a DataGrid when it wishes to preserve its + /// transient state in the current DataGridState object. + /// + public void PushState(DataGrid dataGrid) + { + DataSource = dataGrid.DataSource; + DataMember = dataGrid.DataMember; + DataGrid = dataGrid; + DataGridRows = dataGrid.DataGridRows; + DataGridRowsLength = dataGrid.DataGridRowsLength; + FirstVisibleRow = dataGrid.firstVisibleRow; + FirstVisibleCol = dataGrid.firstVisibleCol; + CurrentRow = dataGrid.currentRow; + GridColumnStyles = new GridColumnStylesCollection(dataGrid.myGridTable); + + GridColumnStyles.Clear(); + foreach (DataGridColumnStyle style in dataGrid.myGridTable.GridColumnStyles) + { + GridColumnStyles.Add(style); + } + + ListManager = dataGrid.ListManager; + ListManager.ItemChanged += new ItemChangedEventHandler(DataSource_Changed); + ListManager.MetaDataChanged += new EventHandler(DataSource_MetaDataChanged); + CurrentCol = dataGrid.currentCol; + } + + // this is needed so that the parent rows will remove notification from the list + // when the datagridstate is no longer needed; + public void RemoveChangeNotification() + { + ListManager.ItemChanged -= new ItemChangedEventHandler(DataSource_Changed); + ListManager.MetaDataChanged -= new EventHandler(DataSource_MetaDataChanged); + } + + /// + /// Called by a grid when it wishes to match its transient + /// state with the current DataGridState object. + /// + public void PullState(DataGrid dataGrid, bool createColumn) + { + // dataGrid.DataSource = DataSource; + // dataGrid.DataMember = DataMember; + dataGrid.Set_ListManager(DataSource, DataMember, true, createColumn); // true for forcing new listManager, + + /* + if (DataSource.Table.ParentRelations.Count > 0) + dataGrid.PopulateColumns(); + */ + + dataGrid.firstVisibleRow = FirstVisibleRow; + dataGrid.firstVisibleCol = FirstVisibleCol; + dataGrid.currentRow = CurrentRow; + dataGrid.currentCol = CurrentCol; + dataGrid.SetDataGridRows(DataGridRows, DataGridRowsLength); + } + + private void DataSource_Changed(object sender, ItemChangedEventArgs e) + { + if (DataGrid != null && ListManager.Position == e.Index) + { + DataGrid.InvalidateParentRows(); + return; + } + + if (DataGrid != null) + { + DataGrid.ParentRowsDataChanged(); + } + } + + private void DataSource_MetaDataChanged(object sender, EventArgs e) + { + if (DataGrid != null) + { + DataGrid.ParentRowsDataChanged(); + } + } + + [ComVisible(true)] + internal class DataGridStateParentRowAccessibleObject : AccessibleObject + { + readonly DataGridState owner; + + public DataGridStateParentRowAccessibleObject(DataGridState owner) : base() + { + Debug.Assert(owner != null, "DataGridRowAccessibleObject must have a valid owner DataGridRow"); + this.owner = owner; + } + + public override Rectangle Bounds + { + get + { + DataGridParentRows dataGridParentRows = ((DataGridParentRows.DataGridParentRowsAccessibleObject)Parent).Owner; + DataGrid g = owner.LinkingRow.DataGrid; + Rectangle r = dataGridParentRows.GetBoundsForDataGridStateAccesibility(owner); + r.Y += g.ParentRowsBounds.Y; + return g.RectangleToScreen(r); + } + } + + public override string Name + { + get + { + return SR.AccDGParentRow; + } + } + + public override AccessibleObject Parent + { + get + { + return owner.LinkingRow.DataGrid.ParentRowsAccessibleObject; + } + } + + public override AccessibleRole Role + { + get + { + return AccessibleRole.ListItem; + } + } + + public override string Value + { + get + { + StringBuilder sb = new StringBuilder(); + + CurrencyManager source = (CurrencyManager)owner.LinkingRow.DataGrid.BindingContext[owner.DataSource, owner.DataMember]; + + sb.Append(owner.ListManager.GetListName()); + sb.Append(": "); + + bool needComma = false; + foreach (DataGridColumnStyle col in owner.GridColumnStyles) + { + if (needComma) + { + sb.Append(", "); + } + + string colName = col.HeaderText; + string cellValue = col.PropertyDescriptor.Converter.ConvertToString(col.PropertyDescriptor.GetValue(source.Current)); + sb.Append(colName); + sb.Append(": "); + sb.Append(cellValue); + needComma = true; + } + + return sb.ToString(); + } + } + + /// + /// Navigate to the next or previous grid entry. + /// + public override AccessibleObject Navigate(AccessibleNavigation navdir) + { + DataGridParentRows.DataGridParentRowsAccessibleObject parentAcc = (DataGridParentRows.DataGridParentRowsAccessibleObject)Parent; + + switch (navdir) + { + case AccessibleNavigation.Down: + case AccessibleNavigation.Right: + case AccessibleNavigation.Next: + return parentAcc.GetNext(this); + case AccessibleNavigation.Up: + case AccessibleNavigation.Left: + case AccessibleNavigation.Previous: + return parentAcc.GetPrev(this); + } + + return null; + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridTableStyle.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridTableStyle.cs new file mode 100644 index 00000000000..f7ae92ee159 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridTableStyle.cs @@ -0,0 +1,1812 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Collections; +using System.ComponentModel; +using System.Drawing; + +namespace System.Windows.Forms +{ + /// + /// Represents the table drawn by the control at run time. + /// + [ + ToolboxItem(false), + DesignTimeVisible(false), + //DefaultProperty("GridTableName") + ] + public class DataGridTableStyle : Component, IDataGridEditingService + { + // internal for DataGridColumn accessibility... + // + internal DataGrid dataGrid; + + // relationship UI + private int relationshipHeight; + internal const int relationshipSpacing = 1; + private Rectangle relationshipRect = Rectangle.Empty; + private int focusedRelation = -1; + private int focusedTextWidth; + + // will contain a list of relationships that this table has + private readonly ArrayList relationsList = new ArrayList(2); + + // the name of the table + private string mappingName = string.Empty; + private readonly GridColumnStylesCollection gridColumns; + private bool readOnly; + private readonly bool isDefaultTableStyle; + + private static readonly object EventAllowSorting = new object(); + private static readonly object EventGridLineColor = new object(); + private static readonly object EventGridLineStyle = new object(); + private static readonly object EventHeaderBackColor = new object(); + private static readonly object EventHeaderForeColor = new object(); + private static readonly object EventHeaderFont = new object(); + private static readonly object EventLinkColor = new object(); + private static readonly object EventLinkHoverColor = new object(); + private static readonly object EventPreferredColumnWidth = new object(); + private static readonly object EventPreferredRowHeight = new object(); + private static readonly object EventColumnHeadersVisible = new object(); + private static readonly object EventRowHeaderWidth = new object(); + private static readonly object EventSelectionBackColor = new object(); + private static readonly object EventSelectionForeColor = new object(); + private static readonly object EventMappingName = new object(); + private static readonly object EventAlternatingBackColor = new object(); + private static readonly object EventBackColor = new object(); + private static readonly object EventForeColor = new object(); + private static readonly object EventReadOnly = new object(); + private static readonly object EventRowHeadersVisible = new object(); + + // add a bunch of properties, taken from the dataGrid + // + + // default values + // + private const bool defaultAllowSorting = true; + private const DataGridLineStyle defaultGridLineStyle = DataGridLineStyle.Solid; + private const int defaultPreferredColumnWidth = 75; + private const int defaultRowHeaderWidth = 35; + internal static readonly Font defaultFont = Control.DefaultFont; + internal static readonly int defaultFontHeight = defaultFont.Height; + + // the actual place holders for properties + // + private bool allowSorting = defaultAllowSorting; + private SolidBrush alternatingBackBrush = DefaultAlternatingBackBrush; + private SolidBrush backBrush = DefaultBackBrush; + private SolidBrush foreBrush = DefaultForeBrush; + private SolidBrush gridLineBrush = DefaultGridLineBrush; + private DataGridLineStyle gridLineStyle = defaultGridLineStyle; + internal SolidBrush headerBackBrush = DefaultHeaderBackBrush; + internal Font headerFont; // this is ambient property to Font value. + internal SolidBrush headerForeBrush = DefaultHeaderForeBrush; + internal Pen headerForePen = DefaultHeaderForePen; + private SolidBrush linkBrush = DefaultLinkBrush; + internal int preferredColumnWidth = defaultPreferredColumnWidth; + private int preferredRowHeight = defaultFontHeight + 3; + private SolidBrush selectionBackBrush = DefaultSelectionBackBrush; + private SolidBrush selectionForeBrush = DefaultSelectionForeBrush; + private int rowHeaderWidth = defaultRowHeaderWidth; + private bool rowHeadersVisible = true; + private bool columnHeadersVisible = true; + + // the dataGrid would need to know when the ColumnHeaderVisible, RowHeadersVisible, RowHeaderWidth + // and preferredColumnWidth, preferredRowHeight properties are changed in the current dataGridTableStyle + // also: for GridLineStyle, GridLineColor, ForeColor, BackColor, HeaderBackColor, HeaderFont, HeaderForeColor + // LinkColor, LinkHoverColor + // + + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(defaultAllowSorting), + SRDescription(nameof(SR.DataGridAllowSortingDescr)) + ] + public bool AllowSorting + { + get + { + return allowSorting; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(AllowSorting))); + } + + if (allowSorting != value) + { + allowSorting = value; + OnAllowSortingChanged(EventArgs.Empty); + } + } + } + + /// + /// [To be supplied] + /// + public event EventHandler AllowSortingChanged + { + add => Events.AddHandler(EventAllowSorting, value); + remove => Events.RemoveHandler(EventAllowSorting, value); + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridAlternatingBackColorDescr)) + ] + public Color AlternatingBackColor + { + get + { + return alternatingBackBrush.Color; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(AlternatingBackColor))); + } + + if (System.Windows.Forms.DataGrid.IsTransparentColor(value)) + { + throw new ArgumentException(SR.DataGridTableStyleTransparentAlternatingBackColorNotAllowed, nameof(value)); + } + + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, nameof(AlternatingBackColor)), nameof(value)); + } + + if (!alternatingBackBrush.Color.Equals(value)) + { + alternatingBackBrush = new SolidBrush(value); + InvalidateInside(); + OnAlternatingBackColorChanged(EventArgs.Empty); + } + } + } + + public event EventHandler AlternatingBackColorChanged + { + add => Events.AddHandler(EventAlternatingBackColor, value); + remove => Events.RemoveHandler(EventAlternatingBackColor, value); + } + + public void ResetAlternatingBackColor() + { + if (ShouldSerializeAlternatingBackColor()) + { + AlternatingBackColor = DefaultAlternatingBackBrush.Color; + InvalidateInside(); + } + } + + protected virtual bool ShouldSerializeAlternatingBackColor() + { + return !AlternatingBackBrush.Equals(DefaultAlternatingBackBrush); + } + + internal SolidBrush AlternatingBackBrush + { + get + { + return alternatingBackBrush; + } + } + + protected bool ShouldSerializeBackColor() + { + return !System.Windows.Forms.DataGridTableStyle.DefaultBackBrush.Equals(backBrush); + } + + protected bool ShouldSerializeForeColor() + { + return !System.Windows.Forms.DataGridTableStyle.DefaultForeBrush.Equals(foreBrush); + } + + internal SolidBrush BackBrush + { + get + { + return backBrush; + } + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.ControlBackColorDescr)) + ] + public Color BackColor + { + get + { + return backBrush.Color; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(BackColor))); + } + + if (System.Windows.Forms.DataGrid.IsTransparentColor(value)) + { + throw new ArgumentException(SR.DataGridTableStyleTransparentBackColorNotAllowed, nameof(value)); + } + + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, nameof(BackColor)), nameof(value)); + } + + if (!backBrush.Color.Equals(value)) + { + backBrush = new SolidBrush(value); + InvalidateInside(); + OnBackColorChanged(EventArgs.Empty); + } + } + } + + public event EventHandler BackColorChanged + { + add => Events.AddHandler(EventBackColor, value); + remove => Events.RemoveHandler(EventBackColor, value); + } + + public void ResetBackColor() + { + if (!backBrush.Equals(DefaultBackBrush)) + { + BackColor = DefaultBackBrush.Color; + } + } + + internal int BorderWidth + { + get + { + DataGrid dataGrid = DataGrid; + if (dataGrid == null) + { + return 0; + } + + // if the user set the GridLineStyle property on the dataGrid. + // then use the value of that property + DataGridLineStyle gridStyle; + int gridLineWidth; + if (IsDefault) + { + gridStyle = DataGrid.GridLineStyle; + gridLineWidth = DataGrid.GridLineWidth; + } + else + { + gridStyle = GridLineStyle; + gridLineWidth = GridLineWidth; + } + + if (gridStyle == DataGridLineStyle.None) + { + return 0; + } + + return gridLineWidth; + } + } + + internal static SolidBrush DefaultAlternatingBackBrush + { + get + { + return (SolidBrush)SystemBrushes.Window; + } + } + + internal static SolidBrush DefaultBackBrush + { + get + { + return (SolidBrush)SystemBrushes.Window; + } + } + + internal static SolidBrush DefaultForeBrush + { + get + { + return (SolidBrush)SystemBrushes.WindowText; + } + } + + private static SolidBrush DefaultGridLineBrush + { + get + { + return (SolidBrush)SystemBrushes.Control; + } + } + + private static SolidBrush DefaultHeaderBackBrush + { + get + { + return (SolidBrush)SystemBrushes.Control; + } + } + + private static SolidBrush DefaultHeaderForeBrush + { + get + { + return (SolidBrush)SystemBrushes.ControlText; + } + } + + private static Pen DefaultHeaderForePen + { + get + { + return new Pen(SystemColors.ControlText); + } + } + + private static SolidBrush DefaultLinkBrush + { + get + { + return (SolidBrush)SystemBrushes.HotTrack; + } + } + + private static SolidBrush DefaultSelectionBackBrush + { + get + { + return (SolidBrush)SystemBrushes.ActiveCaption; + } + } + + private static SolidBrush DefaultSelectionForeBrush + { + get + { + return (SolidBrush)SystemBrushes.ActiveCaptionText; + } + } + + internal int FocusedRelation + { + get + { + return focusedRelation; + } + set + { + if (focusedRelation != value) + { + focusedRelation = value; + if (focusedRelation == -1) + { + focusedTextWidth = 0; + } + else + { + Graphics g = DataGrid.CreateGraphicsInternal(); + focusedTextWidth = (int)Math.Ceiling(g.MeasureString(((string)RelationsList[focusedRelation]), DataGrid.LinkFont).Width); + g.Dispose(); + } + } + } + } + + internal int FocusedTextWidth + { + get + { + return focusedTextWidth; + } + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.ControlForeColorDescr)) + ] + public Color ForeColor + { + get + { + return foreBrush.Color; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(ForeColor))); + } + + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, nameof(ForeColor)), nameof(value)); + } + + if (!foreBrush.Color.Equals(value)) + { + foreBrush = new SolidBrush(value); + InvalidateInside(); + OnForeColorChanged(EventArgs.Empty); + } + } + } + + public event EventHandler ForeColorChanged + { + add => Events.AddHandler(EventForeColor, value); + remove => Events.RemoveHandler(EventForeColor, value); + } + + internal SolidBrush ForeBrush + { + get + { + return foreBrush; + } + } + + public void ResetForeColor() + { + if (!foreBrush.Equals(DefaultForeBrush)) + { + ForeColor = DefaultForeBrush.Color; + } + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridGridLineColorDescr)) + ] + public Color GridLineColor + { + get + { + return gridLineBrush.Color; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(GridLineColor))); + } + + if (gridLineBrush.Color != value) + { + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, nameof(GridLineColor)), nameof(value)); + } + + gridLineBrush = new SolidBrush(value); + OnGridLineColorChanged(EventArgs.Empty); + } + } + } + + public event EventHandler GridLineColorChanged + { + add => Events.AddHandler(EventGridLineColor, value); + remove => Events.RemoveHandler(EventGridLineColor, value); + } + + protected virtual bool ShouldSerializeGridLineColor() + { + return !GridLineBrush.Equals(DefaultGridLineBrush); + } + + public void ResetGridLineColor() + { + if (ShouldSerializeGridLineColor()) + { + GridLineColor = DefaultGridLineBrush.Color; + } + } + + internal SolidBrush GridLineBrush + { + get + { + return gridLineBrush; + } + } + + internal int GridLineWidth + { + get + { + Debug.Assert(GridLineStyle == DataGridLineStyle.Solid || GridLineStyle == DataGridLineStyle.None, "are there any other styles?"); + return GridLineStyle == DataGridLineStyle.Solid ? 1 : 0; + } + } + + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(defaultGridLineStyle), + SRDescription(nameof(SR.DataGridGridLineStyleDescr)) + ] + public DataGridLineStyle GridLineStyle + { + get + { + return gridLineStyle; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(GridLineStyle))); + } + + //valid values are 0x0 to 0x1. + if (!ClientUtils.IsEnumValid(value, (int)value, (int)DataGridLineStyle.None, (int)DataGridLineStyle.Solid)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(DataGridLineStyle)); + } + + if (gridLineStyle != value) + { + gridLineStyle = value; + OnGridLineStyleChanged(EventArgs.Empty); + } + } + } + + public event EventHandler GridLineStyleChanged + { + add => Events.AddHandler(EventGridLineStyle, value); + remove => Events.RemoveHandler(EventGridLineStyle, value); + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridHeaderBackColorDescr)) + ] + public Color HeaderBackColor + { + get + { + return headerBackBrush.Color; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(HeaderBackColor))); + } + + if (System.Windows.Forms.DataGrid.IsTransparentColor(value)) + { + throw new ArgumentException(SR.DataGridTableStyleTransparentHeaderBackColorNotAllowed, nameof(value)); + } + + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, nameof(HeaderBackColor)), nameof(value)); + } + + if (!value.Equals(headerBackBrush.Color)) + { + headerBackBrush = new SolidBrush(value); + OnHeaderBackColorChanged(EventArgs.Empty); + } + } + } + + public event EventHandler HeaderBackColorChanged + { + add => Events.AddHandler(EventHeaderBackColor, value); + remove => Events.RemoveHandler(EventHeaderBackColor, value); + } + + internal SolidBrush HeaderBackBrush + { + get + { + return headerBackBrush; + } + } + + protected virtual bool ShouldSerializeHeaderBackColor() + { + return !HeaderBackBrush.Equals(DefaultHeaderBackBrush); + } + + public void ResetHeaderBackColor() + { + if (ShouldSerializeHeaderBackColor()) + { + HeaderBackColor = DefaultHeaderBackBrush.Color; + } + } + + [ + SRCategory(nameof(SR.CatAppearance)), + Localizable(true), + AmbientValue(null), + SRDescription(nameof(SR.DataGridHeaderFontDescr)) + ] + public Font HeaderFont + { + get + { + return (headerFont ?? (DataGrid == null ? Control.DefaultFont : DataGrid.Font)); + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(HeaderFont))); + } + + if ((value == null && headerFont != null) || (value != null && !value.Equals(headerFont))) + { + headerFont = value; + OnHeaderFontChanged(EventArgs.Empty); + } + } + } + + public event EventHandler HeaderFontChanged + { + add => Events.AddHandler(EventHeaderFont, value); + remove => Events.RemoveHandler(EventHeaderFont, value); + } + + private bool ShouldSerializeHeaderFont() + { + return (headerFont != null); + } + + public void ResetHeaderFont() + { + if (headerFont != null) + { + headerFont = null; + OnHeaderFontChanged(EventArgs.Empty); + } + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridHeaderForeColorDescr)) + ] + public Color HeaderForeColor + { + get + { + return headerForePen.Color; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(HeaderForeColor))); + } + + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, nameof(HeaderForeColor)), nameof(value)); + } + + if (!value.Equals(headerForePen.Color)) + { + headerForePen = new Pen(value); + headerForeBrush = new SolidBrush(value); + OnHeaderForeColorChanged(EventArgs.Empty); + } + } + } + + public event EventHandler HeaderForeColorChanged + { + add => Events.AddHandler(EventHeaderForeColor, value); + remove => Events.RemoveHandler(EventHeaderForeColor, value); + } + + protected virtual bool ShouldSerializeHeaderForeColor() + { + return !HeaderForePen.Equals(DefaultHeaderForePen); + } + + public void ResetHeaderForeColor() + { + if (ShouldSerializeHeaderForeColor()) + { + HeaderForeColor = DefaultHeaderForeBrush.Color; + } + } + + internal SolidBrush HeaderForeBrush + { + get + { + return headerForeBrush; + } + } + + internal Pen HeaderForePen + { + get + { + return headerForePen; + } + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridLinkColorDescr)) + ] + public Color LinkColor + { + get + { + return linkBrush.Color; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(LinkColor))); + } + + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, nameof(LinkColor)), nameof(value)); + } + + if (!linkBrush.Color.Equals(value)) + { + linkBrush = new SolidBrush(value); + OnLinkColorChanged(EventArgs.Empty); + } + } + } + + public event EventHandler LinkColorChanged + { + add => Events.AddHandler(EventLinkColor, value); + remove => Events.RemoveHandler(EventLinkColor, value); + } + + protected virtual bool ShouldSerializeLinkColor() + { + return !LinkBrush.Equals(DefaultLinkBrush); + } + + public void ResetLinkColor() + { + if (ShouldSerializeLinkColor()) + { + LinkColor = DefaultLinkBrush.Color; + } + } + + internal Brush LinkBrush + { + get + { + return linkBrush; + } + } + + [ + SRDescription(nameof(SR.DataGridLinkHoverColorDescr)), + SRCategory(nameof(SR.CatColors)), + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never) + ] + public Color LinkHoverColor + { + get + { + return LinkColor; + } + set + { + } + } + + public event EventHandler LinkHoverColorChanged + { + add => Events.AddHandler(EventLinkHoverColor, value); + remove => Events.RemoveHandler(EventLinkHoverColor, value); + } + + protected virtual bool ShouldSerializeLinkHoverColor() + { + return false; + } + + internal Rectangle RelationshipRect + { + get + { + if (relationshipRect.IsEmpty) + { + ComputeRelationshipRect(); + } + + return relationshipRect; + } + } + + private Rectangle ComputeRelationshipRect() + { + if (relationshipRect.IsEmpty && DataGrid.AllowNavigation) + { + Debug.WriteLineIf(CompModSwitches.DGRelationShpRowLayout.TraceVerbose, "GetRelationshipRect grinding away"); + Graphics g = DataGrid.CreateGraphicsInternal(); + relationshipRect = new Rectangle + { + X = 0 //indentWidth; + }; + // relationshipRect.Y = base.Height - BorderWidth; + + // Determine the width of the widest relationship name + int longestRelationship = 0; + for (int r = 0; r < RelationsList.Count; ++r) + { + int rwidth = (int)Math.Ceiling(g.MeasureString(((string)RelationsList[r]), DataGrid.LinkFont).Width) +; + if (rwidth > longestRelationship) + { + longestRelationship = rwidth; + } + } + + g.Dispose(); + + relationshipRect.Width = longestRelationship + 5; + relationshipRect.Width += 2; // relationshipRect border; + relationshipRect.Height = BorderWidth + relationshipHeight * RelationsList.Count; + relationshipRect.Height += 2; // relationship border + if (RelationsList.Count > 0) + { + relationshipRect.Height += 2 * relationshipSpacing; + } + } + + return relationshipRect; + } + + internal void ResetRelationsUI() + { + relationshipRect = Rectangle.Empty; + focusedRelation = -1; + relationshipHeight = dataGrid.LinkFontHeight + relationshipSpacing; + } + + internal int RelationshipHeight + { + get + { + return relationshipHeight; + } + } + + public void ResetLinkHoverColor() + { + } + + [ + DefaultValue(defaultPreferredColumnWidth), + SRCategory(nameof(SR.CatLayout)), + Localizable(true), + SRDescription(nameof(SR.DataGridPreferredColumnWidthDescr)), + TypeConverter(typeof(DataGridPreferredColumnWidthTypeConverter)) + ] + public int PreferredColumnWidth + { + get + { + return preferredColumnWidth; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(PreferredColumnWidth))); + } + + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), value, SR.DataGridColumnWidth); + } + + if (preferredColumnWidth != value) + { + preferredColumnWidth = value; + OnPreferredColumnWidthChanged(EventArgs.Empty); + } + } + } + + public event EventHandler PreferredColumnWidthChanged + { + add => Events.AddHandler(EventPreferredColumnWidth, value); + remove => Events.RemoveHandler(EventPreferredColumnWidth, value); + } + + [ + SRCategory(nameof(SR.CatLayout)), + Localizable(true), + SRDescription(nameof(SR.DataGridPreferredRowHeightDescr)) + ] + public int PreferredRowHeight + { + get + { + return preferredRowHeight; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(PreferredRowHeight))); + } + + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), value, SR.DataGridRowRowHeight); + } + + if (preferredRowHeight != value) + { + preferredRowHeight = value; + OnPreferredRowHeightChanged(EventArgs.Empty); + } + } + } + + public event EventHandler PreferredRowHeightChanged + { + add => Events.AddHandler(EventPreferredRowHeight, value); + remove => Events.RemoveHandler(EventPreferredRowHeight, value); + } + + private void ResetPreferredRowHeight() + { + PreferredRowHeight = defaultFontHeight + 3; + } + + protected bool ShouldSerializePreferredRowHeight() + { + return preferredRowHeight != defaultFontHeight + 3; + } + + [ + SRCategory(nameof(SR.CatDisplay)), + DefaultValue(true), + SRDescription(nameof(SR.DataGridColumnHeadersVisibleDescr)) + ] + public bool ColumnHeadersVisible + { + get + { + return columnHeadersVisible; + } + set + { + if (columnHeadersVisible != value) + { + columnHeadersVisible = value; + OnColumnHeadersVisibleChanged(EventArgs.Empty); + } + } + } + + public event EventHandler ColumnHeadersVisibleChanged + { + add => Events.AddHandler(EventColumnHeadersVisible, value); + remove => Events.RemoveHandler(EventColumnHeadersVisible, value); + } + + [ + SRCategory(nameof(SR.CatDisplay)), + DefaultValue(true), + SRDescription(nameof(SR.DataGridRowHeadersVisibleDescr)) + ] + public bool RowHeadersVisible + { + get + { + return rowHeadersVisible; + } + set + { + if (rowHeadersVisible != value) + { + rowHeadersVisible = value; + OnRowHeadersVisibleChanged(EventArgs.Empty); + } + } + } + + public event EventHandler RowHeadersVisibleChanged + { + add => Events.AddHandler(EventRowHeadersVisible, value); + remove => Events.RemoveHandler(EventRowHeadersVisible, value); + } + + [ + SRCategory(nameof(SR.CatLayout)), + DefaultValue(defaultRowHeaderWidth), + Localizable(true), + SRDescription(nameof(SR.DataGridRowHeaderWidthDescr)) + ] + public int RowHeaderWidth + { + get + { + return rowHeaderWidth; + } + set + { + if (DataGrid != null) + { + value = Math.Max(DataGrid.MinimumRowHeaderWidth(), value); + } + + if (rowHeaderWidth != value) + { + rowHeaderWidth = value; + OnRowHeaderWidthChanged(EventArgs.Empty); + } + } + } + + public event EventHandler RowHeaderWidthChanged + { + add => Events.AddHandler(EventRowHeaderWidth, value); + remove => Events.RemoveHandler(EventRowHeaderWidth, value); + } + + [ + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridSelectionBackColorDescr)) + ] + public Color SelectionBackColor + { + get + { + return selectionBackBrush.Color; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(SelectionBackColor))); + } + + if (System.Windows.Forms.DataGrid.IsTransparentColor(value)) + { + throw new ArgumentException(SR.DataGridTableStyleTransparentSelectionBackColorNotAllowed, nameof(value)); + } + + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, nameof(SelectionBackColor)), nameof(value)); + } + + if (!value.Equals(selectionBackBrush.Color)) + { + selectionBackBrush = new SolidBrush(value); + InvalidateInside(); + OnSelectionBackColorChanged(EventArgs.Empty); + } + } + } + + public event EventHandler SelectionBackColorChanged + { + add => Events.AddHandler(EventSelectionBackColor, value); + remove => Events.RemoveHandler(EventSelectionBackColor, value); + } + + internal SolidBrush SelectionBackBrush + { + get + { + return selectionBackBrush; + } + } + + internal SolidBrush SelectionForeBrush + { + get + { + return selectionForeBrush; + } + } + + protected bool ShouldSerializeSelectionBackColor() + { + return !DefaultSelectionBackBrush.Equals(selectionBackBrush); + } + + public void ResetSelectionBackColor() + { + if (ShouldSerializeSelectionBackColor()) + { + SelectionBackColor = DefaultSelectionBackBrush.Color; + } + } + + [ + Description("The foreground color for the current data grid row"), + SRCategory(nameof(SR.CatColors)), + SRDescription(nameof(SR.DataGridSelectionForeColorDescr)) + ] + public Color SelectionForeColor + { + get + { + return selectionForeBrush.Color; + } + set + { + if (isDefaultTableStyle) + { + throw new ArgumentException(string.Format(SR.DataGridDefaultTableSet, nameof(SelectionForeColor))); + } + + if (value.IsEmpty) + { + throw new ArgumentException(string.Format(SR.DataGridEmptyColor, nameof(SelectionForeColor)), nameof(value)); + } + + if (!value.Equals(selectionForeBrush.Color)) + { + selectionForeBrush = new SolidBrush(value); + InvalidateInside(); + OnSelectionForeColorChanged(EventArgs.Empty); + } + } + } + + public event EventHandler SelectionForeColorChanged + { + add => Events.AddHandler(EventSelectionForeColor, value); + remove => Events.RemoveHandler(EventSelectionForeColor, value); + } + + protected virtual bool ShouldSerializeSelectionForeColor() + { + return !SelectionForeBrush.Equals(DefaultSelectionForeBrush); + } + + public void ResetSelectionForeColor() + { + if (ShouldSerializeSelectionForeColor()) + { + SelectionForeColor = DefaultSelectionForeBrush.Color; + } + } + + // will need this function from the dataGrid + // + private void InvalidateInside() + { + if (DataGrid != null) + { + DataGrid.InvalidateInside(); + } + } + + public static readonly DataGridTableStyle DefaultTableStyle = new DataGridTableStyle(true); + + /// + /// Initializes a new instance of the class. + /// + public DataGridTableStyle(bool isDefaultTableStyle) + { + gridColumns = new GridColumnStylesCollection(this, isDefaultTableStyle); + gridColumns.CollectionChanged += new CollectionChangeEventHandler(OnColumnCollectionChanged); + this.isDefaultTableStyle = isDefaultTableStyle; + } + + public DataGridTableStyle() : this(false) + { + } + + /// + /// Initializes a new instance of the class with the specified + /// . + /// + public DataGridTableStyle(CurrencyManager listManager) : this() + { + Debug.Assert(listManager != null, "the DataGridTabel cannot use a null listManager"); + mappingName = listManager.GetListName(); + // set up the Relations and the columns + SetGridColumnStylesCollection(listManager); + } + + internal void SetRelationsList(CurrencyManager listManager) + { + PropertyDescriptorCollection propCollection = listManager.GetItemProperties(); + Debug.Assert(!IsDefault, "the grid can set the relations only on a table that was manually added by the user"); + int propCount = propCollection.Count; + if (relationsList.Count > 0) + { + relationsList.Clear(); + } + + for (int i = 0; i < propCount; i++) + { + PropertyDescriptor prop = propCollection[i]; + Debug.Assert(prop != null, "prop is null: how that happened?"); + if (PropertyDescriptorIsARelation(prop)) + { + // relation + relationsList.Add(prop.Name); + } + } + } + + internal void SetGridColumnStylesCollection(CurrencyManager listManager) + { + // when we are setting the gridColumnStyles, do not handle any gridColumnCollectionChanged events + gridColumns.CollectionChanged -= new CollectionChangeEventHandler(OnColumnCollectionChanged); + + PropertyDescriptorCollection propCollection = listManager.GetItemProperties(); + + // we need to clear the relations list + if (relationsList.Count > 0) + { + relationsList.Clear(); + } + + Debug.Assert(propCollection != null, "propCollection is null: how that happened?"); + int propCount = propCollection.Count; + for (int i = 0; i < propCount; i++) + { + PropertyDescriptor prop = propCollection[i]; + Debug.Assert(prop != null, "prop is null: how that happened?"); + // do not take into account the properties that are browsable. + if (!prop.IsBrowsable) + { + continue; + } + + if (PropertyDescriptorIsARelation(prop)) + { + // relation + relationsList.Add(prop.Name); + } + else + { + // column + DataGridColumnStyle col = CreateGridColumn(prop, isDefaultTableStyle); + if (isDefaultTableStyle) + { + gridColumns.AddDefaultColumn(col); + } + else + { + col.MappingName = prop.Name; + col.HeaderText = prop.Name; + gridColumns.Add(col); + } + } + } + + // now we are able to handle the collectionChangeEvents + gridColumns.CollectionChanged += new CollectionChangeEventHandler(OnColumnCollectionChanged); + } + + private static bool PropertyDescriptorIsARelation(PropertyDescriptor prop) + { + return typeof(IList).IsAssignableFrom(prop.PropertyType) && !typeof(Array).IsAssignableFrom(prop.PropertyType); + } + + internal protected virtual DataGridColumnStyle CreateGridColumn(PropertyDescriptor prop) + { + return CreateGridColumn(prop, false); + } + + internal protected virtual DataGridColumnStyle CreateGridColumn(PropertyDescriptor prop, bool isDefault) + { + if (prop == null) + { + throw new ArgumentNullException(nameof(prop)); + } + + DataGridColumnStyle ret = null; + Type dataType = prop.PropertyType; + + if (dataType.Equals(typeof(bool))) + { + ret = new DataGridBoolColumn(prop, isDefault); + } + else if (dataType.Equals(typeof(string))) + { + ret = new DataGridTextBoxColumn(prop, isDefault); + } + else if (dataType.Equals(typeof(DateTime))) + { + ret = new DataGridTextBoxColumn(prop, "d", isDefault); + } + else if (dataType.Equals(typeof(short)) || + dataType.Equals(typeof(int)) || + dataType.Equals(typeof(long)) || + dataType.Equals(typeof(ushort)) || + dataType.Equals(typeof(uint)) || + dataType.Equals(typeof(ulong)) || + dataType.Equals(typeof(decimal)) || + dataType.Equals(typeof(double)) || + dataType.Equals(typeof(float)) || + dataType.Equals(typeof(byte)) || + dataType.Equals(typeof(sbyte))) + { + ret = new DataGridTextBoxColumn(prop, "G", isDefault); + } + else + { + ret = new DataGridTextBoxColumn(prop, isDefault); + } + + return ret; + } + + internal void ResetRelationsList() + { + if (isDefaultTableStyle) + { + relationsList.Clear(); + } + } + + // =------------------------------------------------------------------ + // = Properties + // =------------------------------------------------------------------ + + /// + /// Gets the name of this grid table. + /// + [Editor("System.Windows.Forms.Design.DataGridTableStyleMappingNameEditor, " + AssemblyRef.SystemDesign, typeof(Drawing.Design.UITypeEditor)), DefaultValue("")] + public string MappingName + { + get + { + return mappingName; + } + set + { + if (value == null) + { + value = string.Empty; + } + + if (value.Equals(mappingName)) + { + return; + } + + string originalMappingName = MappingName; + mappingName = value; + + // this could throw + try + { + if (DataGrid != null) + { + DataGrid.TableStyles.CheckForMappingNameDuplicates(this); + } + } + catch + { + mappingName = originalMappingName; + throw; + } + + OnMappingNameChanged(EventArgs.Empty); + } + } + + public event EventHandler MappingNameChanged + { + add => Events.AddHandler(EventMappingName, value); + remove => Events.RemoveHandler(EventMappingName, value); + } + + /// + /// Gets the + /// list of relation objects for the grid table. + /// + internal ArrayList RelationsList + { + get + { + return relationsList; + } + } + + /// + /// Gets the collection of columns drawn for this table. + /// + [ + Localizable(true), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content) + ] + public virtual GridColumnStylesCollection GridColumnStyles + { + get + { + return gridColumns; + } + } + + /// + /// Gets or sets the + /// control displaying the table. + /// + internal void SetInternalDataGrid(DataGrid dG, bool force) + { + if (dataGrid != null && dataGrid.Equals(dG) && !force) + { + return; + } + else + { + dataGrid = dG; + if (dG != null && dG.Initializing) + { + return; + } + + int nCols = gridColumns.Count; + for (int i = 0; i < nCols; i++) + { + gridColumns[i].SetDataGridInternalInColumn(dG); + } + } + } + + /// + /// Gets or sets the control for the drawn table. + /// + [Browsable(false)] + public virtual DataGrid DataGrid + { + get + { + return dataGrid; + } + set + { + SetInternalDataGrid(value, true); + } + } + + /// + /// Gets or sets a value indicating whether columns can be + /// edited. + /// + [DefaultValue(false)] + public virtual bool ReadOnly + { + get + { + return readOnly; + } + set + { + if (readOnly != value) + { + readOnly = value; + OnReadOnlyChanged(EventArgs.Empty); + } + } + } + + public event EventHandler ReadOnlyChanged + { + add => Events.AddHandler(EventReadOnly, value); + remove => Events.RemoveHandler(EventReadOnly, value); + } + + // =------------------------------------------------------------------ + // = Methods + // =------------------------------------------------------------------ + + /// + /// Requests an edit operation. + /// + public bool BeginEdit(DataGridColumnStyle gridColumn, int rowNumber) + { + DataGrid grid = DataGrid; + if (grid == null) + { + return false; + } + else + { + return grid.BeginEdit(gridColumn, rowNumber); + } + } + + /// + /// Requests an end to an edit + /// operation. + /// + public bool EndEdit(DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort) + { + DataGrid grid = DataGrid; + if (grid == null) + { + return false; + } + else + { + return grid.EndEdit(gridColumn, rowNumber, shouldAbort); + } + } + + internal void InvalidateColumn(DataGridColumnStyle column) + { + int index = GridColumnStyles.IndexOf(column); + if (index >= 0 && DataGrid != null) + { + DataGrid.InvalidateColumn(index); + } + } + + private void OnColumnCollectionChanged(object sender, CollectionChangeEventArgs e) + { + gridColumns.CollectionChanged -= new CollectionChangeEventHandler(OnColumnCollectionChanged); + + try + { + DataGrid grid = DataGrid; + DataGridColumnStyle col = e.Element as DataGridColumnStyle; + if (e.Action == CollectionChangeAction.Add) + { + if (col != null) + { + col.SetDataGridInternalInColumn(grid); + } + } + else if (e.Action == CollectionChangeAction.Remove) + { + if (col != null) + { + col.SetDataGridInternalInColumn(null); + } + } + else + { + // refresh + Debug.Assert(e.Action == CollectionChangeAction.Refresh, "there are only Add, Remove and Refresh in the CollectionChangeAction"); + // if we get a column in this collectionChangeEventArgs it means + // that the propertyDescriptor in that column changed. + if (e.Element != null) + { + for (int i = 0; i < gridColumns.Count; i++) + { + gridColumns[i].SetDataGridInternalInColumn(null); + } + } + } + + if (grid != null) + { + grid.OnColumnCollectionChanged(this, e); + } + } + finally + { + gridColumns.CollectionChanged += new CollectionChangeEventHandler(OnColumnCollectionChanged); + } + } + +#if false + /// + /// The DataColumnCollection class actually wires up this + /// event handler to the PropertyChanged events of + /// a DataGridTable's columns. + /// + internal void OnColumnChanged(object sender, PropertyChangedEvent event) { + if (event.PropertyName.Equals("Visible")) + GenerateVisibleColumnsCache(); + } +#endif + protected virtual void OnReadOnlyChanged(EventArgs e) + { + if (Events[EventReadOnly] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnMappingNameChanged(EventArgs e) + { + if (Events[EventMappingName] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnAlternatingBackColorChanged(EventArgs e) + { + if (Events[EventAlternatingBackColor] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnForeColorChanged(EventArgs e) + { + if (Events[EventForeColor] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnBackColorChanged(EventArgs e) + { + if (Events[EventBackColor] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnAllowSortingChanged(EventArgs e) + { + if (Events[EventAllowSorting] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnGridLineColorChanged(EventArgs e) + { + if (Events[EventGridLineColor] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnGridLineStyleChanged(EventArgs e) + { + if (Events[EventGridLineStyle] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnHeaderBackColorChanged(EventArgs e) + { + if (Events[EventHeaderBackColor] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnHeaderFontChanged(EventArgs e) + { + if (Events[EventHeaderFont] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnHeaderForeColorChanged(EventArgs e) + { + if (Events[EventHeaderForeColor] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnLinkColorChanged(EventArgs e) + { + if (Events[EventLinkColor] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnLinkHoverColorChanged(EventArgs e) + { + if (Events[EventLinkHoverColor] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnPreferredRowHeightChanged(EventArgs e) + { + if (Events[EventPreferredRowHeight] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnPreferredColumnWidthChanged(EventArgs e) + { + if (Events[EventPreferredColumnWidth] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnColumnHeadersVisibleChanged(EventArgs e) + { + if (Events[EventColumnHeadersVisible] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnRowHeadersVisibleChanged(EventArgs e) + { + if (Events[EventRowHeadersVisible] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnRowHeaderWidthChanged(EventArgs e) + { + if (Events[EventRowHeaderWidth] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnSelectionForeColorChanged(EventArgs e) + { + if (Events[EventSelectionForeColor] is EventHandler eh) + { + eh(this, e); + } + } + + protected virtual void OnSelectionBackColorChanged(EventArgs e) + { + if (Events[EventSelectionBackColor] is EventHandler eh) + { + eh(this, e); + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + GridColumnStylesCollection cols = GridColumnStyles; + if (cols != null) + { + for (int i = 0; i < cols.Count; i++) + { + cols[i].Dispose(); + } + } + } + + base.Dispose(disposing); + } + + internal bool IsDefault + { + get + { + return isDefaultTableStyle; + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridTextBox.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridTextBox.cs new file mode 100644 index 00000000000..505cc301c72 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridTextBox.cs @@ -0,0 +1,302 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.ComponentModel; +using System.Runtime.InteropServices; + +namespace System.Windows.Forms +{ + /// + /// Represents a control that is hosted in a + /// . + /// + [ + ComVisible(true), + ClassInterface(ClassInterfaceType.AutoDispatch), + ToolboxItem(false), + DesignTimeVisible(false) + ] + public class DataGridTextBox : TextBox + { + private bool isInEditOrNavigateMode = true; + + // only needed to signal the dataGrid that an edit + // takes place + private DataGrid dataGrid; + + public DataGridTextBox() : base() + { + TabStop = false; + } + + /// + /// Sets the to which this control belongs. + /// + public void SetDataGrid(DataGrid parentGrid) + { + dataGrid = parentGrid; + } + + protected override void WndProc(ref Message m) + { + // but what if we get a CtrlV? + // what about deleting from the menu? + if (m.Msg == (int)Interop.User32.WM.PASTE || m.Msg == (int)Interop.User32.WM.CUT || m.Msg == (int)Interop.User32.WM.CLEAR) + { + IsInEditOrNavigateMode = false; + dataGrid.ColumnStartedEditing(Bounds); + } + + base.WndProc(ref m); + } + + protected override void OnMouseWheel(MouseEventArgs e) + { + dataGrid.TextBoxOnMouseWheel(e); + } + + protected override void OnKeyPress(KeyPressEventArgs e) + { + base.OnKeyPress(e); + + // Shift-Space should not cause the grid to + // be put in edit mode + if (e.KeyChar == ' ' && (Control.ModifierKeys & Keys.Shift) == Keys.Shift) + { + return; + } + + // if the edit box is in ReadOnly mode, then do not tell the DataGrid about the + // edit + if (ReadOnly) + { + return; + } + + // Ctrl-* should not put the grid in edit mode + if ((Control.ModifierKeys & Keys.Control) == Keys.Control && ((Control.ModifierKeys & Keys.Alt) == 0)) + { + return; + } + + IsInEditOrNavigateMode = false; + + // let the DataGrid know about the edit + dataGrid.ColumnStartedEditing(Bounds); + } + + protected internal override bool ProcessKeyMessage(ref Message m) + { + Keys key = (Keys)unchecked((int)(long)m.WParam); + Keys modifierKeys = ModifierKeys; + + if ((key | modifierKeys) == Keys.Enter || (key | modifierKeys) == Keys.Escape || ((key | modifierKeys) == (Keys.Enter | Keys.Control)) + ) + { + // enter and escape keys are sent directly to the DataGrid + // for those keys, eat the WM_CHAR part of the KeyMessage + // + if (m.Msg == (int)Interop.User32.WM.CHAR) + { + return true; + } + + return ProcessKeyPreview(ref m); + } + + if (m.Msg == (int)Interop.User32.WM.CHAR) + { + if (key == Keys.LineFeed) // eat the LineFeed we get when the user presses Ctrl-Enter in a gridTextBox + { + return true; + } + + return ProcessKeyEventArgs(ref m); + } + + // now the edit control will be always on top of the grid + // we only want to process the WM_KEYUP message ( the same way the grid was doing when the grid was getting all + // the keys ) + if (m.Msg == (int)Interop.User32.WM.KEYUP) + { + return true; + } + + Keys keyData = key & Keys.KeyCode; + + switch (keyData) + { + case Keys.Right: + // here is the deal with Keys.Right: + // if the end of the selection is at the end of the string + // send this character to the dataGrid + // else, process the KeyEvent + // + if (SelectionStart + SelectionLength == Text.Length) + { + return ProcessKeyPreview(ref m); + } + + return ProcessKeyEventArgs(ref m); + case Keys.Left: + // if the end of the selection is at the begining of the string + // or if the entire text is selected and we did not start editing + // send this character to the dataGrid + // else, process the KeyEvent + // + if (SelectionStart + SelectionLength == 0 || + (IsInEditOrNavigateMode && SelectionLength == Text.Length)) + { + return ProcessKeyPreview(ref m); + } + + return ProcessKeyEventArgs(ref m); + case Keys.Down: + // if the end of the selection is on the last line of the text then + // send this character to the dataGrid + // else, process the KeyEvent + // + int end = SelectionStart + SelectionLength; + if (Text.IndexOf("\r\n", end) == -1) + { + return ProcessKeyPreview(ref m); + } + + return ProcessKeyEventArgs(ref m); + case Keys.Up: + // if the end of the selection is on the first line of the text then + // send this character to the dataGrid + // else, process the KeyEvent + // + if (Text.IndexOf("\r\n") < 0 || SelectionStart + SelectionLength < Text.IndexOf("\r\n")) + { + return ProcessKeyPreview(ref m); + } + + return ProcessKeyEventArgs(ref m); + case Keys.Home: + case Keys.End: + if (SelectionLength == Text.Length) + { + return ProcessKeyPreview(ref m); + } + else + { + return ProcessKeyEventArgs(ref m); + } + + case Keys.Prior: + case Keys.Next: + case Keys.Oemplus: + case Keys.Add: + case Keys.OemMinus: + case Keys.Subtract: + if (IsInEditOrNavigateMode) + { + // this will ultimately call parent's ProcessKeyPreview + // in our case, DataGrid's ProcessKeyPreview + return ProcessKeyPreview(ref m); + } + else + { + return ProcessKeyEventArgs(ref m); + } + + case Keys.Space: + if (IsInEditOrNavigateMode && (Control.ModifierKeys & Keys.Shift) == Keys.Shift) + { + // when we get a SHIFT-SPACEBAR message, disregard the WM_CHAR part of the message + if (m.Msg == (int)Interop.User32.WM.CHAR) + { + return true; + } + + // if the user pressed the SHIFT key at the same time with + // the space key, send the key message to the DataGrid + return ProcessKeyPreview(ref m); + } + + return ProcessKeyEventArgs(ref m); + case Keys.A: + if (IsInEditOrNavigateMode && (Control.ModifierKeys & Keys.Control) == Keys.Control) + { + // when we get a Control-A message, disregard the WM_CHAR part of the message + if (m.Msg == (int)Interop.User32.WM.CHAR) + { + return true; + } + + // if the user pressed the Control key at the same time with + // the space key, send the key message to the DataGrid + return ProcessKeyPreview(ref m); + } + + return ProcessKeyEventArgs(ref m); + case Keys.F2: + IsInEditOrNavigateMode = false; + // do not select all the text, but + // position the caret at the end of the text + SelectionStart = Text.Length; + return true; + case Keys.Delete: + if (IsInEditOrNavigateMode) + { + // pass the delete to the parent, in our case, the DataGrid + // if the dataGrid used the key, then we aren't gonne + // use it anymore, else we are + if (ProcessKeyPreview(ref m)) + { + return true; + } + else + { + // the edit control will use the + // delete key: we are in Edit mode now: + IsInEditOrNavigateMode = false; + dataGrid.ColumnStartedEditing(Bounds); + + return ProcessKeyEventArgs(ref m); + } + } + else + { + return ProcessKeyEventArgs(ref m); + } + + case Keys.Tab: + // the TextBox gets the Control-Tab messages, + // not the parent + if ((ModifierKeys & Keys.Control) == Keys.Control) + { + return ProcessKeyPreview(ref m); + } + else + { + return ProcessKeyEventArgs(ref m); + } + + default: + return ProcessKeyEventArgs(ref m); + } + } + + public bool IsInEditOrNavigateMode + { + get + { + return isInEditOrNavigateMode; + } + set + { + isInEditOrNavigateMode = value; + if (value) + { + SelectAll(); + } + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridTextBoxColumn.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridTextBoxColumn.cs new file mode 100644 index 00000000000..a43eff8935c --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridTextBoxColumn.cs @@ -0,0 +1,645 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.ComponentModel; +using System.Drawing; +using System.Globalization; + +namespace System.Windows.Forms +{ + /// + /// Hosts a System.Windows.Forms.TextBox control in a cell of a System.Windows.Forms.DataGridColumnStyle for editing strings. + /// + public class DataGridTextBoxColumn : DataGridColumnStyle + { + // ui State + private readonly int xMargin = 2; + private readonly int yMargin = 1; + // private int fontHandle = 0; + private string format; + private TypeConverter typeConverter; + private IFormatProvider formatInfo; + private Reflection.MethodInfo parseMethod; + + // hosted control + private readonly DataGridTextBox edit; + + // editing state + private string oldValue; + private int editRow = -1; + + /// + /// Initializes a new instance of the System.Windows.Forms.DataGridTextBoxColumn + /// class. + /// + public DataGridTextBoxColumn() : this(null, null) + { + } + + /// + /// Initializes a new instance of a System.Windows.Forms.DataGridTextBoxColumn with + /// a specified System.Data.DataColumn. + /// + public DataGridTextBoxColumn(PropertyDescriptor prop) + : this(prop, null, false) + { + } + + /// + /// Initializes a new instance of a System.Windows.Forms.DataGridTextBoxColumn. with + /// the specified System.Data.DataColumn and System.Windows.Forms.ComponentModel.Format. + /// + public DataGridTextBoxColumn(PropertyDescriptor prop, string format) : this(prop, format, false) { } + + public DataGridTextBoxColumn(PropertyDescriptor prop, string format, bool isDefault) : base(prop, isDefault) + { + edit = new DataGridTextBox + { + BorderStyle = BorderStyle.None, + Multiline = true, + AcceptsReturn = true, + Visible = false + }; + Format = format; + } + + public DataGridTextBoxColumn(PropertyDescriptor prop, bool isDefault) : this(prop, null, isDefault) { } + + // =------------------------------------------------------------------ + // = Properties + // =------------------------------------------------------------------ + + /// + /// Gets the hosted System.Windows.Forms.TextBox control. + /// + [Browsable(false)] + public virtual TextBox TextBox + { + get + { + return edit; + } + } + + internal override bool KeyPress(int rowNum, Keys keyData) + { + if (edit.IsInEditOrNavigateMode) + { + return base.KeyPress(rowNum, keyData); + } + + // if the edit box is editing, then + // pass this keystroke to the edit box + // + return false; + } + + /// + /// Adds a System.Windows.Forms.TextBox control to the System.Windows.Forms.DataGrid control's System.Windows.Forms.Control.ControlCollection + /// . + /// + protected override void SetDataGridInColumn(DataGrid value) + { + base.SetDataGridInColumn(value); + if (edit.ParentInternal != null) + { + edit.ParentInternal.Controls.Remove(edit); + } + + if (value != null) + { + value.Controls.Add(edit); + } + + // we have to tell the edit control about its dataGrid + edit.SetDataGrid(value); + } + + /* CUT as part of the new DataGridTableStyleSheet thing + public override Font Font { + set { + base.Font = value; + Font f = base.Font; + edit.Font = f; + // if (f != null) { + // fontHandle = f.Handle; + // } + } + } + */ + + /// + /// Gets or sets the System.Windows.Forms.ComponentModel.Format for the System.Windows.Forms.DataGridTextBoxColumn + /// . + /// + [ + SRDescription(nameof(SR.FormatControlFormatDescr)), + DefaultValue(null) + ] + public override PropertyDescriptor PropertyDescriptor + { + set + { + base.PropertyDescriptor = value; + if (PropertyDescriptor != null) + { + if (PropertyDescriptor.PropertyType != typeof(object)) + { + typeConverter = TypeDescriptor.GetConverter(PropertyDescriptor.PropertyType); + parseMethod = PropertyDescriptor.PropertyType.GetMethod("Parse", new Type[] { typeof(string), typeof(IFormatProvider) }); + } + } + } + } + + // add the corresponding value Editor: rip one from the valueEditor for the DisplayMember in the + // format object + [DefaultValue(null), Editor("System.Windows.Forms.Design.DataGridColumnStyleFormatEditor, " + AssemblyRef.SystemDesign, typeof(Drawing.Design.UITypeEditor))] + public string Format + { + get + { + return format; + } + set + { + if (value == null) + { + value = string.Empty; + } + + if (format == null || !format.Equals(value)) + { + format = value; + + // if the associated typeConverter cannot convert from string, + // then we can't modify the column value. hence, make it readOnly + // + if (format.Length == 0) + { + if (typeConverter != null && !typeConverter.CanConvertFrom(typeof(string))) + { + ReadOnly = true; + } + } + + Invalidate(); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)] + public IFormatProvider FormatInfo + { + get + { + return formatInfo; + } + set + { + if (formatInfo == null || !formatInfo.Equals(value)) + { + formatInfo = value; + } + } + } + + public override bool ReadOnly + { + get + { + return base.ReadOnly; + } + set + { + // if the gridColumn is can't convert the string to + // the backGround propertyDescriptor, then make the column ReadOnly + if (!value && (format == null || format.Length == 0)) + { + if (typeConverter != null && !typeConverter.CanConvertFrom(typeof(string))) + { + return; + } + } + + base.ReadOnly = value; + } + } + + // =------------------------------------------------------------------ + // = Methods + // =------------------------------------------------------------------ + + private void DebugOut(string s) + { + Debug.WriteLineIf(CompModSwitches.DGEditColumnEditing.TraceVerbose, "DGEditColumnEditing: " + s); + } + + // will hide the edit control + /// + /// Informs the column the focus is being conceded. + /// + protected internal override void ConcedeFocus() + { + edit.Bounds = Rectangle.Empty; + // edit.Visible = false; + // HideEditBox(); + } + + /// + /// Hides the System.Windows.Forms.TextBox + /// control and moves the focus to the System.Windows.Forms.DataGrid + /// control. + /// + protected void HideEditBox() + { + bool wasFocused = edit.Focused; + edit.Visible = false; + + // it seems that edit.Visible = false will take away the focus from + // the edit control. And this means that we will not give the focus to the grid + // If all the columns would have an edit control this would not be bad + // ( or if the grid is the only control on the form ), + // but when we have a DataGridBoolColumn then the focus will be taken away + // by the next control in the form. + // + // if (edit.Focused && this.DataGridTableStyle.DataGrid.CanFocus) { + + // when the user deletes the current ( ie active ) column from the + // grid, the grid should still call EndEdit ( so that the changes that the user made + // before deleting the column will go to the backEnd) + // however, in that situation, we are left w/ the editColumn which is not parented. + // the grid will call Edit to reset the EditColumn + if (wasFocused && DataGridTableStyle != null && DataGridTableStyle.DataGrid != null && DataGridTableStyle.DataGrid.CanFocus) + { + DataGridTableStyle.DataGrid.Focus(); + Debug.Assert(!edit.Focused, "the edit control just conceeded focus to the dataGrid"); + } + } + + protected internal override void UpdateUI(CurrencyManager source, int rowNum, string displayText) + { + edit.Text = GetText(GetColumnValueAtRow(source, rowNum)); + if (!edit.ReadOnly && displayText != null) + { + edit.Text = displayText; + } + } + + /// + /// Ends an edit operation on the System.Windows.Forms.DataGridColumnStyle + /// . + /// + protected void EndEdit() + { + edit.IsInEditOrNavigateMode = true; + DebugOut("Ending Edit"); + Invalidate(); + } + + /// + /// Returns the optimum width and + /// height of the cell in a specified row relative + /// to the specified value. + /// + protected internal override Size GetPreferredSize(Graphics g, object value) + { + Size extents = Size.Ceiling(g.MeasureString(GetText(value), DataGridTableStyle.DataGrid.Font)); + extents.Width += xMargin * 2 + DataGridTableStyle.GridLineWidth; + extents.Height += yMargin; + return extents; + } + + /// + /// Gets the height of a cell in a System.Windows.Forms.DataGridColumnStyle + /// . + /// + protected internal override int GetMinimumHeight() + { + // why + 3? cause we have to give some way to the edit box. + return FontHeight + yMargin + 3; + } + + /// + /// Gets the height to be used in for automatically resizing columns. + /// + protected internal override int GetPreferredHeight(Graphics g, object value) + { + int newLineIndex = 0; + int newLines = 0; + string valueString = GetText(value); + while (newLineIndex != -1 && newLineIndex < valueString.Length) + { + newLineIndex = valueString.IndexOf("\r\n", newLineIndex + 1); + newLines++; + } + + return FontHeight * newLines + yMargin; + } + + /// + /// Initiates a request to interrupt an edit procedure. + /// + protected internal override void Abort(int rowNum) + { + RollBack(); + HideEditBox(); + EndEdit(); + } + + // used for Alt0 functionality + /// + /// Enters a in the column. + /// + protected internal override void EnterNullValue() + { + if (ReadOnly) + { + return; + } + + // if the edit box is not visible, then + // do not put the edit text in it + if (!edit.Visible) + { + return; + } + + // if we are editing, then we should be able to enter alt-0 in a cell. + // + if (!edit.IsInEditOrNavigateMode) + { + return; + } + + edit.Text = NullText; + // edit.Visible = true; + edit.IsInEditOrNavigateMode = false; + // tell the dataGrid that there is an edit: + if (DataGridTableStyle != null && DataGridTableStyle.DataGrid != null) + { + DataGridTableStyle.DataGrid.ColumnStartedEditing(edit.Bounds); + } + } + + /// + /// Inititates a request to complete an editing procedure. + /// + protected internal override bool Commit(CurrencyManager dataSource, int rowNum) + { + // always hide the edit box + // HideEditBox(); + edit.Bounds = Rectangle.Empty; + + if (edit.IsInEditOrNavigateMode) + { + return true; + } + + try + { + object value = edit.Text; + if (NullText.Equals(value)) + { + value = Convert.DBNull; + edit.Text = NullText; + } + else if (format != null && format.Length != 0 && parseMethod != null && FormatInfo != null) + { + // use reflection to get the Parse method on the + // type of the propertyDescriptor. + value = (object)parseMethod.Invoke(null, new object[] { edit.Text, FormatInfo }); + if (value is IFormattable) + { + edit.Text = ((IFormattable)value).ToString(format, formatInfo); + } + else + { + edit.Text = value.ToString(); + } + } + else if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string))) + { + value = typeConverter.ConvertFromString(edit.Text); + edit.Text = typeConverter.ConvertToString(value); + } + + SetColumnValueAtRow(dataSource, rowNum, value); + } + catch + { + // MessageBox.Show("There was an error caught setting field \"" + // + this.PropertyDescriptor.Name + "\" to the value \"" + edit.Text + "\"\n" + // + "The value is being rolled back to the original.\n" + // + "The error was a '" + e.Message + "' " + e.StackTrace + // , "Error commiting changes...", MessageBox.IconError); + // Debug.WriteLine(e.GetType().Name); + RollBack(); + return false; + } + + DebugOut("OnCommit completed without Exception."); + EndEdit(); + return true; + } + + /// + /// Prepares a cell for editing. + /// + protected internal override void Edit(CurrencyManager source, + int rowNum, + Rectangle bounds, + bool readOnly, + string displayText, + bool cellIsVisible) + { + DebugOut("Begining Edit, rowNum :" + rowNum.ToString(CultureInfo.InvariantCulture)); + + Rectangle originalBounds = bounds; + + edit.ReadOnly = readOnly || ReadOnly || DataGridTableStyle.ReadOnly; + + edit.Text = GetText(GetColumnValueAtRow(source, rowNum)); + if (!edit.ReadOnly && displayText != null) + { + // tell the grid that we are changing stuff + DataGridTableStyle.DataGrid.ColumnStartedEditing(bounds); + // tell the edit control that the user changed it + edit.IsInEditOrNavigateMode = false; + edit.Text = displayText; + } + + if (cellIsVisible) + { + bounds.Offset(xMargin, 2 * yMargin); + bounds.Width -= xMargin; + bounds.Height -= 2 * yMargin; + DebugOut("edit bounds: " + bounds.ToString()); + edit.Bounds = bounds; + + edit.Visible = true; + + edit.TextAlign = Alignment; + } + else + { + edit.Bounds = Rectangle.Empty; + // edit.Bounds = originalBounds; + // edit.Visible = false; + } + + edit.RightToLeft = DataGridTableStyle.DataGrid.RightToLeft; + + edit.Focus(); + + editRow = rowNum; + + if (!edit.ReadOnly) + { + oldValue = edit.Text; + } + + // select the text even if the text box is read only + // because the navigation code in the DataGridTextBox::ProcessKeyMessage + // uses the SelectedText property + if (displayText == null) + { + edit.SelectAll(); + } + else + { + int end = edit.Text.Length; + edit.Select(end, 0); + } + + if (edit.Visible) + { + DataGridTableStyle.DataGrid.Invalidate(originalBounds); + } + } + + internal override string GetDisplayText(object value) + { + return GetText(value); + } + + private string GetText(object value) + { + if (value is DBNull) + { + return NullText; + } + else if (format != null && format.Length != 0 && (value is IFormattable)) + { + try + { + return ((IFormattable)value).ToString(format, formatInfo); + } + catch + { + // + } + } + else + { + // use the typeConverter: + if (typeConverter != null && typeConverter.CanConvertTo(typeof(string))) + { + return (string)typeConverter.ConvertTo(value, typeof(string)); + } + } + + return (value != null ? value.ToString() : ""); + } + + /// + /// Paints the a System.Windows.Forms.DataGridColumnStyle with the specified System.Drawing.Graphics, + /// System.Drawing.Rectangle, DataView.Rectangle, and row number. + /// + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum) + { + Paint(g, bounds, source, rowNum, false); + } + + /// + /// Paints a System.Windows.Forms.DataGridColumnStyle with the specified System.Drawing.Graphics, System.Drawing.Rectangle, DataView, row number, and alignment. + /// + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) + { + string text = GetText(GetColumnValueAtRow(source, rowNum)); + PaintText(g, bounds, text, alignToRight); + } + + /// + /// Paints a System.Windows.Forms.DataGridColumnStyle with the specified System.Drawing.Graphics, + /// System.Drawing.Rectangle, DataView.Rectangle, row number, background color, + /// and foreground color.. + /// + protected internal override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, + Brush backBrush, Brush foreBrush, bool alignToRight) + { + string text = GetText(GetColumnValueAtRow(source, rowNum)); + PaintText(g, bounds, text, backBrush, foreBrush, alignToRight); + } + + /// + /// Draws the text and + /// rectangle at the given location with the specified alignment. + /// + protected void PaintText(Graphics g, Rectangle bounds, string text, bool alignToRight) + { + PaintText(g, bounds, text, DataGridTableStyle.BackBrush, DataGridTableStyle.ForeBrush, alignToRight); + } + + /// + /// Draws the text and rectangle at the specified location with the + /// specified colors and alignment. + /// + protected void PaintText(Graphics g, Rectangle textBounds, string text, Brush backBrush, Brush foreBrush, bool alignToRight) + { + /* + if (edit.Visible) + g.BackColor = BackColor; + */ + + Rectangle rect = textBounds; + + StringFormat format = new StringFormat(); + if (alignToRight) + { + format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + } + + format.Alignment = Alignment == HorizontalAlignment.Left ? StringAlignment.Near : Alignment == HorizontalAlignment.Center ? StringAlignment.Center : StringAlignment.Far; + + // do not wrap the text + // + format.FormatFlags |= StringFormatFlags.NoWrap; + + g.FillRectangle(backBrush, rect); + // by design, painting leaves a little padding around the rectangle. + // so do not deflate the rectangle. + rect.Offset(0, 2 * yMargin); + rect.Height -= 2 * yMargin; + g.DrawString(text, DataGridTableStyle.DataGrid.Font, foreBrush, rect, format); + format.Dispose(); + } + + private void RollBack() + { + Debug.Assert(!edit.IsInEditOrNavigateMode, "Must be editing to rollback changes..."); + edit.Text = oldValue; + } + + protected internal override void ReleaseHostedControl() + { + if (edit.ParentInternal != null) + { + edit.ParentInternal.Controls.Remove(edit); + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridToolTip.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridToolTip.cs new file mode 100644 index 00000000000..483eb661bdc --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridToolTip.cs @@ -0,0 +1,86 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Drawing; +using System.Runtime.InteropServices; +using static Interop; + +namespace System.Windows.Forms +{ + // this class is basically a NativeWindow that does toolTipping + // should be one for the entire grid + internal class DataGridToolTip : MarshalByRefObject + { + // the toolTip control + private NativeWindow tipWindow; + + // the dataGrid which contains this toolTip + private readonly DataGrid dataGrid; + + // CONSTRUCTOR + public DataGridToolTip(DataGrid dataGrid) + { + Debug.Assert(dataGrid != null, "can't attach a tool tip to a null grid"); + this.dataGrid = dataGrid; + } + + // will ensure that the toolTip window was created + public void CreateToolTipHandle() + { + if (tipWindow == null || tipWindow.Handle == IntPtr.Zero) + { + var icc = new ComCtl32.INITCOMMONCONTROLSEX + { + dwICC = ComCtl32.ICC.TAB_CLASSES + }; + ComCtl32.InitCommonControlsEx(ref icc); + + var cparams = new CreateParams + { + Parent = dataGrid.Handle, + ClassName = ComCtl32.WindowClasses.TOOLTIPS_CLASS, + Style = (int)ComCtl32.TTS.ALWAYSTIP, + }; + tipWindow = new NativeWindow(); + tipWindow.CreateHandle(cparams); + + User32.SendMessageW((IHandle)tipWindow, (User32.WM)ComCtl32.TTM.SETMAXTIPWIDTH, IntPtr.Zero, (IntPtr)SystemInformation.MaxWindowTrackSize.Width); + User32.SetWindowPos( + new HandleRef(tipWindow, tipWindow.Handle), + User32.HWND_NOTOPMOST, + flags: User32.SWP.NOSIZE | User32.SWP.NOMOVE | User32.SWP.NOACTIVATE); + User32.SendMessageW((IHandle)tipWindow, (User32.WM)ComCtl32.TTM.SETDELAYTIME, (IntPtr)ComCtl32.TTDT.INITIAL, (IntPtr)0); + } + } + + public void AddToolTip(string toolTipString, IntPtr toolTipId, Rectangle iconBounds) + { + Debug.Assert(tipWindow != null && tipWindow.Handle != IntPtr.Zero, "the tipWindow was not initialized, bailing out"); + if (iconBounds.IsEmpty) + throw new ArgumentNullException(nameof(iconBounds), SR.DataGridToolTipEmptyIcon); + + if (toolTipString == null) + throw new ArgumentNullException(nameof(toolTipString)); + + var info = new ComCtl32.ToolInfoWrapper(dataGrid, toolTipId, TOOLTIP_FLAGS.TTF_SUBCLASS, toolTipString, iconBounds); + info.SendMessage(tipWindow, PInvoke.TTM_ADDTOOLW); + } + + public void RemoveToolTip(IntPtr toolTipId) + { + var info = new ComCtl32.ToolInfoWrapper(dataGrid, toolTipId); + info.SendMessage(tipWindow, PInvoke.TTM_ADDTOOLW); + } + + // will destroy the tipWindow + public void Destroy() + { + Debug.Assert(tipWindow != null, "how can one destroy a null window"); + tipWindow.DestroyHandle(); + tipWindow = null; + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DateTimePicker.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DateTimePicker.cs index b0a0152816b..1084b7dbaa7 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/DateTimePicker.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DateTimePicker.cs @@ -9,6 +9,7 @@ using SourceGenerated; using static Interop; using static Interop.ComCtl32; +using INITCOMMONCONTROLSEX = Windows.Win32.UI.Controls.INITCOMMONCONTROLSEX; namespace System.Windows.Forms; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ErrorProvider.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ErrorProvider.cs index 67969cec02c..dbea2dc4c08 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ErrorProvider.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ErrorProvider.cs @@ -678,7 +678,7 @@ public void Clear() /// public bool CanExtend(object? extendee) { - return extendee is Control && extendee is not Form; + return extendee is Control && extendee is not Form && extendee is not ToolBar; } /// diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/FileDialog.cs b/src/System.Windows.Forms/src/System/Windows/Forms/FileDialog.cs index 1b2438f9850..7dcdc1984c2 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/FileDialog.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/FileDialog.cs @@ -457,13 +457,16 @@ private protected static bool FileExists(string? fileName) private static string[] GetMultiselectFiles(ReadOnlySpan fileBuffer) { var directory = fileBuffer.SliceAtFirstNull(); - var fileNames = fileBuffer[directory.Length..]; - if (fileNames.Length == 0) + var fileNames = fileBuffer[(directory.Length + 1)..]; + + // When a single file is returned, the directory is not null delimited. + // So we check here to see if the filename starts with a null. + if (fileNames.Length == 0 || fileNames[0] == '\0') { return new string[] { directory.ToString() }; } - List names = new List(); + List names = []; var fileName = fileNames.SliceAtFirstNull(); while (fileName.Length > 0) { @@ -471,7 +474,7 @@ private static string[] GetMultiselectFiles(ReadOnlySpan fileBuffer) ? fileName.ToString() : Path.Join(directory, fileName)); - fileNames = fileNames[fileName.Length..]; + fileNames = fileNames[(fileName.Length + 1)..]; fileName = fileNames.SliceAtFirstNull(); } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs index 45dd6330a3d..cd35ccbdd6c 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs @@ -131,6 +131,8 @@ public partial class Form : ContainerControl private static readonly int PropOpacity = PropertyStore.CreateKey(); private static readonly int PropTransparencyKey = PropertyStore.CreateKey(); + private static readonly int PropMainMenu = PropertyStore.CreateKey(); + // Form per instance members // Note: Do not add anything to this list unless absolutely necessary. @@ -715,6 +717,263 @@ public FormBorderStyle FormBorderStyle } } + /// + /// Gets or sets the + /// that is displayed in the form. + /// + [ + SRCategory(nameof(SR.CatWindowStyle)), + DefaultValue(null), + SRDescription(nameof(SR.FormMenuDescr)), + TypeConverter(typeof(ReferenceConverter)), + Browsable(false), + ] + public MainMenu? Menu + { + get + { + return (MainMenu)Properties.GetObject(PropMainMenu); + } + set + { + MainMenu mainMenu = Menu; + + if (mainMenu != value) + { + if (mainMenu != null) + { + mainMenu._form = null; + } + + Properties.SetObject(PropMainMenu, value); + + if (value != null) + { + if (value._form != null) + { + value._form.Menu = null; + } + + value._form = this; + } + + if (_formState[FormStateSetClientSize] == 1 && !IsHandleCreated) + { + ClientSize = ClientSize; + } + + MenuChanged(Windows.Forms.Menu.CHANGE_ITEMS, value); + } + } + } + + // Package scope for menu interop + internal void MenuChanged(int change, Menu menu) + { + Form parForm = ParentForm; + if (parForm != null && this == parForm.ActiveMdiChildInternal) + { + parForm.MenuChanged(change, menu); + return; + } + + switch (change) + { + case Windows.Forms.Menu.CHANGE_ITEMS: + case Windows.Forms.Menu.CHANGE_MERGE: + if (_ctlClient == null || !_ctlClient.IsHandleCreated) + { + if (menu == Menu && change == Windows.Forms.Menu.CHANGE_ITEMS) + { + UpdateMenuHandles(); + } + + break; + } + + // Tell the children to toss their mergedMenu. + if (IsHandleCreated) + { + UpdateMenuHandles(null, false); + } + + Control.ControlCollection children = _ctlClient.Controls; + for (int i = children.Count; i-- > 0;) + { + Control ctl = children[i]; + if (ctl is Form && ctl.Properties.ContainsObject(PropMergedMenu)) + { + if (ctl.Properties.GetObject(PropMergedMenu) is MainMenu mainMenu && mainMenu.ownerForm == ctl) + { + mainMenu.Dispose(); + } + + ctl.Properties.SetObject(PropMergedMenu, null); + } + } + + UpdateMenuHandles(); + break; + case Windows.Forms.Menu.CHANGE_VISIBLE: + if (menu == Menu || (ActiveMdiChildInternal != null && menu == ActiveMdiChildInternal.Menu)) + { + UpdateMenuHandles(); + } + + break; + case Windows.Forms.Menu.CHANGE_MDI: + if (_ctlClient != null && _ctlClient.IsHandleCreated) + { + UpdateMenuHandles(); + } + + break; + } + } + + private static readonly int PropCurMenu = PropertyStore.CreateKey(); + private static readonly int PropDummyMenu = PropertyStore.CreateKey(); + + private void UpdateMenuHandles() + { + Form form; + + // Forget the current menu. + if (Properties.GetObject(PropCurMenu) != null) + { + Properties.SetObject(PropCurMenu, null); + } + + if (IsHandleCreated) + { + if (!TopLevel) + { + UpdateMenuHandles(null, true); + } + else + { + form = ActiveMdiChildInternal; + if (form != null) + { + UpdateMenuHandles(form.MergedMenuPrivate, true); + } + else + { + UpdateMenuHandles(Menu, true); + } + } + } + } + + private void UpdateMenuHandles(MainMenu menu, bool forceRedraw) + { + Debug.Assert(IsHandleCreated, "shouldn't call when handle == 0"); + + int suspendCount = _formStateEx[FormStateExUpdateMenuHandlesSuspendCount]; + if (suspendCount > 0 && menu != null) + { + _formStateEx[FormStateExUpdateMenuHandlesDeferred] = 1; + return; + } + + MainMenu curMenu = menu; + if (curMenu != null) + { + curMenu._form = this; + } + + if (curMenu != null || Properties.ContainsObject(PropCurMenu)) + { + Properties.SetObject(PropCurMenu, curMenu); + } + + if (_ctlClient == null || !_ctlClient.IsHandleCreated) + { + if (menu != null) + { + User32.SetMenu(this, new HandleRef(menu, menu.Handle)); + } + else + { + User32.SetMenu(this, NativeMethods.NullHandleRef); + } + } + else + { + Debug.Assert(IsMdiContainer, "Not an MDI container!"); + // when both MainMenuStrip and Menu are set, we honor the win32 menu over + // the MainMenuStrip as the place to store the system menu controls for the maximized MDI child. + + MenuStrip mainMenuStrip = MainMenuStrip; + if (mainMenuStrip == null || menu != null) + { // We are dealing with a Win32 Menu; MenuStrip doesn't have control buttons. + + // We have a MainMenu and we're going to use it + + // We need to set the "dummy" menu even when a menu is being removed + // (set to null) so that duplicate control buttons are not placed on the menu bar when + // an ole menu is being removed. + // Make MDI forget the mdi item position. + MainMenu dummyMenu = (MainMenu)Properties.GetObject(PropDummyMenu); + + if (dummyMenu == null) + { + dummyMenu = new MainMenu + { + ownerForm = this + }; + Properties.SetObject(PropDummyMenu, dummyMenu); + } + + UnsafeNativeMethods.SendMessage(new HandleRef(_ctlClient, _ctlClient.Handle), WindowMessages.WM_MDISETMENU, dummyMenu.Handle, IntPtr.Zero); + + if (menu != null) + { + + // Microsoft, 5/2/1998 - don't use Win32 native Mdi lists... + // + UnsafeNativeMethods.SendMessage(new HandleRef(_ctlClient, _ctlClient.Handle), WindowMessages.WM_MDISETMENU, menu.Handle, IntPtr.Zero); + } + } + + // (New fix: Only destroy Win32 Menu if using a MenuStrip) + if (menu == null && mainMenuStrip != null) + { // If MainMenuStrip, we need to remove any Win32 Menu to make room for it. + IntPtr hMenu = User32.GetMenu(this); + if (hMenu != IntPtr.Zero) + { + + // We had a MainMenu and now we're switching over to MainMenuStrip + + // Remove the current menu. + User32.SetMenu(this, NativeMethods.NullHandleRef); + + // because we have messed with the child's system menu by shoving in our own dummy menu, + // once we clear the main menu we're in trouble - this eats the close, minimize, maximize gadgets + // of the child form. (See WM_MDISETMENU in MSDN) + Form activeMdiChild = ActiveMdiChildInternal; + if (activeMdiChild != null && activeMdiChild.WindowState == FormWindowState.Maximized) + { + activeMdiChild.RecreateHandle(); + } + + // Since we're removing a menu but we possibly had a menu previously, + // we need to clear the cached size so that new size calculations will be performed correctly. + CommonProperties.xClearPreferredSizeCache(this); + } + } + } + + if (forceRedraw) + { + SafeNativeMethods.DrawMenuBar(new HandleRef(this, Handle)); + } + + _formStateEx[FormStateExUpdateMenuHandlesDeferred] = 0; + } + + private static readonly int PropMergedMenu = PropertyStore.CreateKey(); + /// /// Gets /// or @@ -994,6 +1253,26 @@ public DialogResult DialogResult } } + internal override bool HasMenu + { + get + { + bool hasMenu = false; + + // Verify that the menu actually contains items so that any + // size calculations will only include a menu height if the menu actually exists. + // Note that Windows will not draw a menu bar for a menu that does not contain + // any items. + Menu menu = Menu; + if (TopLevel && menu != null && menu.ItemCount > 0) + { + hasMenu = true; + } + + return hasMenu; + } + } + /// /// Gets or sets a value indicating whether a /// help button should be displayed in the caption box of the form. @@ -1340,7 +1619,7 @@ public MenuStrip? MainMenuStrip Properties.SetObject(PropMainMenuStrip, value); if (IsHandleCreated) { - UpdateMenuHandles(recreateMenu: true); + UpdateMenuHandles(); } } } @@ -3081,7 +3360,7 @@ private Size ComputeWindowSize(Size clientSize) private Size ComputeWindowSize(Size clientSize, WINDOW_STYLE style, WINDOW_EX_STYLE exStyle) { RECT result = new(clientSize); - AdjustWindowRectExForControlDpi(ref result, style, false, exStyle); + AdjustWindowRectExForControlDpi(ref result, style, HasMenu, exStyle); return result.Size; } @@ -3203,7 +3482,7 @@ protected override void CreateHandle() } // avoid extra SetMenu calls for perf - if (!TopLevel || IsMdiContainer) + if (Menu != null || !TopLevel || IsMdiContainer) { UpdateMenuHandles(); } @@ -3389,10 +3668,46 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); _ctlClient = null; - if (Properties.TryGetObject(PropDummyMdiMenu, out HMENU dummyMenu) && !dummyMenu.IsNull) + MainMenu mainMenu = Menu; + + // We should only dispose this form's menus! + if (mainMenu != null && mainMenu.ownerForm == this) + { + mainMenu.Dispose(); + Properties.SetObject(PropMainMenu, null); + } + + if (Properties.GetObject(PropCurMenu) != null) + { + Properties.SetObject(PropCurMenu, null); + } + + MenuChanged(Windows.Forms.Menu.CHANGE_ITEMS, null); + + MainMenu dummyMenu = (MainMenu)Properties.GetObject(PropDummyMenu); + + if (dummyMenu != null) + { + dummyMenu.Dispose(); + Properties.SetObject(PropDummyMenu, null); + } + + MainMenu mergedMenu = (MainMenu)Properties.GetObject(PropMergedMenu); + + if (mergedMenu != null) + { + if (mergedMenu.ownerForm == this || mergedMenu._form == null) + { + mergedMenu.Dispose(); + } + + Properties.SetObject(PropMergedMenu, null); + } + + if (Properties.TryGetObject(PropDummyMdiMenu, out HMENU dummyMdiMenu) && !dummyMdiMenu.IsNull) { Properties.RemoveObject(PropDummyMdiMenu); - PInvoke.DestroyMenu(dummyMenu); + PInvoke.DestroyMenu(dummyMdiMenu); } } else @@ -3991,6 +4306,7 @@ protected override void OnHandleCreated(EventArgs e) _formStateEx[FormStateExUseMdiChildProc] = (IsMdiChild && Visible) ? 1 : 0; base.OnHandleCreated(e); UpdateLayered(); + UpdateMenuHandles(); } /// @@ -4503,6 +4819,9 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) msg.LParamInternal = win32Message.lParam; msg.HWnd = win32Message.hwnd; + // Process main menu accelerator keys. + retValue = Menu?.ProcessCmdKey(ref msg, keyData) == true || retValue; + return retValue; } @@ -5651,71 +5970,6 @@ private void UpdateLayered() } } - private void UpdateMenuHandles(bool recreateMenu = false) - { - if (!IsHandleCreated) - { - return; - } - - if (_ctlClient is null || !_ctlClient.IsHandleCreated) - { - PInvoke.SetMenu(this, HMENU.Null); - } - else - { - Debug.Assert(IsMdiContainer, "Not an MDI container!"); - // when both MainMenuStrip and Menu are set, we honor the win32 menu over - // the MainMenuStrip as the place to store the system menu controls for the maximized MDI child. - - MenuStrip? mainMenuStrip = MainMenuStrip; - if (mainMenuStrip is null) - { - // We are dealing with a Win32 Menu; MenuStrip doesn't have control buttons. - - // We need to set the "dummy" menu even when a menu is being removed - // (set to null) so that duplicate control buttons are not placed on the menu bar when - // an ole menu is being removed. - // Make MDI forget the mdi item position. - if (!Properties.TryGetObject(PropDummyMdiMenu, out HMENU dummyMenu) || dummyMenu.IsNull || recreateMenu) - { - dummyMenu = PInvoke.CreateMenu(); - Properties.SetObject(PropDummyMdiMenu, dummyMenu); - } - - PInvoke.SendMessage(_ctlClient, PInvoke.WM_MDISETMENU, (WPARAM)dummyMenu.Value); - } - - // (New fix: Only destroy Win32 Menu if using a MenuStrip) - if (mainMenuStrip is not null) - { - // If MainMenuStrip, we need to remove any Win32 Menu to make room for it. - HMENU hMenu = PInvoke.GetMenu(this); - if (hMenu != HMENU.Null) - { - // Remove the current menu. - PInvoke.SetMenu(this, HMENU.Null); - - // because we have messed with the child's system menu by shoving in our own dummy menu, - // once we clear the main menu we're in trouble - this eats the close, minimize, maximize gadgets - // of the child form. (See WM_MDISETMENU in MSDN) - Form? activeMdiChild = ActiveMdiChildInternal; - if (activeMdiChild is not null && activeMdiChild.WindowState == FormWindowState.Maximized) - { - activeMdiChild.RecreateHandle(); - } - - // Since we're removing a menu but we possibly had a menu previously, - // we need to clear the cached size so that new size calculations will be performed correctly. - CommonProperties.xClearPreferredSizeCache(this); - } - } - } - - PInvoke.DrawMenuBar(this); - _formStateEx[FormStateExUpdateMenuHandlesDeferred] = 0; - } - // Call this function instead of UpdateStyles() when the form's client-size must // be preserved e.g. when changing the border style. // @@ -5787,6 +6041,66 @@ private void UpdateToolStrip() UpdateMdiControlStrip(activeMdiForm is not null && activeMdiForm.IsMaximized); } + /// + /// Gets the merged menu for the + /// form. + /// + [ + SRCategory(nameof(SR.CatWindowStyle)), + Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SRDescription(nameof(SR.FormMergedMenuDescr)), + ] + public MainMenu MergedMenu + { + get + { + return MergedMenuPrivate; + } + } + + private MainMenu MergedMenuPrivate + { + get + { + Form formMdiParent = (Form)Properties.GetObject(PropFormMdiParent); + if (formMdiParent == null) + { + return null; + } + + MainMenu mergedMenu = (MainMenu)Properties.GetObject(PropMergedMenu); + if (mergedMenu != null) + { + return mergedMenu; + } + + MainMenu parentMenu = formMdiParent.Menu; + MainMenu mainMenu = Menu; + + if (mainMenu == null) + { + return parentMenu; + } + + if (parentMenu == null) + { + return mainMenu; + } + + // Create a menu that merges the two and save it for next time. + mergedMenu = new MainMenu + { + ownerForm = this + }; + + mergedMenu.MergeMenu(parentMenu); + mergedMenu.MergeMenu(mainMenu); + Properties.SetObject(PropMergedMenu, mergedMenu); + return mergedMenu; + } + } + private void UpdateMdiControlStrip(bool maximized) { if (_formStateEx[FormStateExInUpdateMdiControlStrip] != 0) @@ -6406,6 +6720,57 @@ private unsafe void WmGetMinMaxInfoHelper(ref Message m, Size minTrack, Size max m.ResultInternal = (LRESULT)0; } + /// + /// WM_INITMENUPOPUP handler + /// + private void WmInitMenuPopup(ref Message m) + { + MainMenu curMenu = (MainMenu)Properties.GetObject(PropCurMenu); + if (curMenu != null) + { + + //curMenu.UpdateRtl((RightToLeft == RightToLeft.Yes)); + + if (curMenu.ProcessInitMenuPopup(m.WParam)) + { + return; + } + } + + base.WndProc(ref m); + } + + /// + /// Handles the WM_MENUCHAR message + /// + private void WmMenuChar(ref Message m) + { + MainMenu curMenu = (MainMenu)Properties.GetObject(PropCurMenu); + if (curMenu == null) + { + + Form formMdiParent = (Form)Properties.GetObject(PropFormMdiParent); + if (formMdiParent != null && formMdiParent.Menu != null) + { + PInvoke.PostMessage(formMdiParent, WindowMessages.WM_SYSCOMMAND, NativeMethods.SC_KEYMENU, m.WParam); + m.Result = (IntPtr)NativeMethods.Util.MAKELONG(0, 1); + return; + } + } + + if (curMenu != null) + { + curMenu.WmMenuChar(ref m); + if (m.Result != IntPtr.Zero) + { + // This char is a mnemonic on our menu. + return; + } + } + + base.WndProc(ref m); + } + /// /// WM_MDIACTIVATE handler /// @@ -6593,6 +6958,18 @@ private void WmSize(ref Message m) } } + /// + /// WM_UNINITMENUPOPUP handler + /// + private void WmUnInitMenuPopup(ref Message m) + { + if (Menu != null) + { + //Whidbey addition - also raise the MainMenu.Collapse event for the current menu + Menu.OnCollapse(EventArgs.Empty); + } + } + /// /// WM_WINDOWPOSCHANGED handler /// @@ -6657,6 +7034,16 @@ protected override void WndProc(ref Message m) WmEraseBkgnd(ref m); break; + case WindowMessages.WM_INITMENUPOPUP: + WmInitMenuPopup(ref m); + break; + case WindowMessages.WM_UNINITMENUPOPUP: + WmUnInitMenuPopup(ref m); + break; + case WindowMessages.WM_MENUCHAR: + WmMenuChar(ref m); + break; + case PInvoke.WM_NCDESTROY: WmNCDestroy(ref m); break; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/GridColumnStylesCollection.cs b/src/System.Windows.Forms/src/System/Windows/Forms/GridColumnStylesCollection.cs new file mode 100644 index 00000000000..f47fbb47da1 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/GridColumnStylesCollection.cs @@ -0,0 +1,566 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Collections; +using System.ComponentModel; +using System.Drawing.Design; +using System.Globalization; + +namespace System.Windows.Forms +{ + /// + /// Represents a collection of System.Windows.Forms.DataGridColumnStyle objects in the + /// control. + /// + [ + Editor("System.Windows.Forms.Design.DataGridColumnCollectionEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), + ListBindable(false) + ] + public class GridColumnStylesCollection : BaseCollection, IList + { + CollectionChangeEventHandler onCollectionChanged; + readonly ArrayList items = new ArrayList(); + readonly DataGridTableStyle owner; + private readonly bool isDefault; + + // we have to implement IList for the Collection editor to work + // + int IList.Add(object value) + { + return Add((DataGridColumnStyle)value); + } + + void IList.Clear() + { + Clear(); + } + + bool IList.Contains(object value) + { + return items.Contains(value); + } + + int IList.IndexOf(object value) + { + return items.IndexOf(value); + } + + void IList.Insert(int index, object value) + { + throw new NotSupportedException(); + } + + void IList.Remove(object value) + { + Remove((DataGridColumnStyle)value); + } + + void IList.RemoveAt(int index) + { + RemoveAt(index); + } + + bool IList.IsFixedSize + { + get { return false; } + } + + bool IList.IsReadOnly + { + get { return false; } + } + + object IList.this[int index] + { + get { return items[index]; } + set { throw new NotSupportedException(); } + } + + void ICollection.CopyTo(Array array, int index) + { + items.CopyTo(array, index); + } + + int ICollection.Count + { + get { return items.Count; } + } + + bool ICollection.IsSynchronized + { + get { return false; } + } + + object ICollection.SyncRoot + { + get { return this; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return items.GetEnumerator(); + } + + internal GridColumnStylesCollection(DataGridTableStyle table) + { + owner = table; + } + + internal GridColumnStylesCollection(DataGridTableStyle table, bool isDefault) : this(table) + { + this.isDefault = isDefault; + } + + /// + /// Gets the list of items in the collection. + /// + protected override ArrayList List + { + get + { + return items; + } + } + + /* implemented in BaseCollection + /// + /// Gets the number of System.Windows.Forms.DataGridColumnStyle objects in the collection. + /// + /// + /// The number of System.Windows.Forms.DataGridColumnStyle objects in the System.Windows.Forms.GridColumnsStyleCollection . + /// + /// + /// The following example uses the + /// property to determine how many System.Windows.Forms.DataGridColumnStyle objects are in a System.Windows.Forms.GridColumnsStyleCollection, and uses that number to iterate through the + /// collection. + /// + /// Private Sub PrintGridColumns() + /// Dim colsCount As Integer + /// colsCount = DataGrid1.GridColumns.Count + /// Dim i As Integer + /// For i = 0 to colsCount - 1 + /// Debug.Print DataGrid1.GridColumns(i).GetType.ToString + /// Next i + /// End Sub + /// + /// + /// + /// + public override int Count { + get { + return items.Count; + } + } + */ + + /// + /// Gets the System.Windows.Forms.DataGridColumnStyle at a specified index. + /// + public DataGridColumnStyle this[int index] + { + get + { + return (DataGridColumnStyle)items[index]; + } + } + + /// + /// Gets the System.Windows.Forms.DataGridColumnStyle + /// with the specified name. + /// + public DataGridColumnStyle this[string columnName] + { + get + { + int itemCount = items.Count; + for (int i = 0; i < itemCount; ++i) + { + DataGridColumnStyle column = (DataGridColumnStyle)items[i]; + // NOTE: case-insensitive + if (string.Equals(column.MappingName, columnName, StringComparison.OrdinalIgnoreCase)) + { + return column; + } + } + + return null; + } + } + + internal DataGridColumnStyle MapColumnStyleToPropertyName(string mappingName) + { + int itemCount = items.Count; + for (int i = 0; i < itemCount; ++i) + { + DataGridColumnStyle column = (DataGridColumnStyle)items[i]; + // NOTE: case-insensitive + if (string.Equals(column.MappingName, mappingName, StringComparison.OrdinalIgnoreCase)) + { + return column; + } + } + + return null; + } + + /// + /// Gets the System.Windows.Forms.DataGridColumnStyle associated with the + /// specified . + /// + public DataGridColumnStyle this[PropertyDescriptor propertyDesciptor] + { + get + { + int itemCount = items.Count; + for (int i = 0; i < itemCount; ++i) + { + DataGridColumnStyle column = (DataGridColumnStyle)items[i]; + if (propertyDesciptor.Equals(column.PropertyDescriptor)) + { + return column; + } + } + + return null; + } + } + + internal DataGridTableStyle DataGridTableStyle + { + get + { + return owner; + } + } + + /// + /// Adds a System.Windows.Forms.DataGridColumnStyle to the System.Windows.Forms.GridColumnStylesCollection + /// + internal void CheckForMappingNameDuplicates(DataGridColumnStyle column) + { + if (string.IsNullOrEmpty(column.MappingName)) + { + return; + } + + for (int i = 0; i < items.Count; i++) + { + if (((DataGridColumnStyle)items[i]).MappingName.Equals(column.MappingName) && column != items[i]) + { + throw new ArgumentException(SR.DataGridColumnStyleDuplicateMappingName, nameof(column)); + } + } + } + + private void ColumnStyleMappingNameChanged(object sender, EventArgs pcea) + { + OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, null)); + } + + private void ColumnStylePropDescChanged(object sender, EventArgs pcea) + { + OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, (DataGridColumnStyle)sender)); + } + + public virtual int Add(DataGridColumnStyle column) + { + if (isDefault) + { + throw new ArgumentException(SR.DataGridDefaultColumnCollectionChanged); + } + + CheckForMappingNameDuplicates(column); + + column.SetDataGridTableInColumn(owner, true); + column.MappingNameChanged += new EventHandler(ColumnStyleMappingNameChanged); + column.PropertyDescriptorChanged += new EventHandler(ColumnStylePropDescChanged); + + // columns which are not the default should have a default + // width of DataGrid.PreferredColumnWidth + if (DataGridTableStyle != null && column.Width == -1) + { + column._width = DataGridTableStyle.PreferredColumnWidth; + } +#if false + column.AddOnPropertyChanged(owner.OnColumnChanged); +#endif + int index = items.Add(column); + OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Add, column)); + return index; + } + + public void AddRange(DataGridColumnStyle[] columns) + { + if (columns == null) + { + throw new ArgumentNullException(nameof(columns)); + } + + for (int i = 0; i < columns.Length; i++) + { + Add(columns[i]); + } + } + + // the dataGrid will need to add default columns to a default + // table when there is no match for the listName in the tableStyle + internal void AddDefaultColumn(DataGridColumnStyle column) + { +#if DEBUG + Debug.Assert(isDefault, "we should be calling this function only for default tables"); + Debug.Assert(column.IsDefault, "we should be a default column"); +#endif // DEBUG + column.SetDataGridTableInColumn(owner, true); + items.Add(column); + } + + internal void ResetDefaultColumnCollection() + { + Debug.Assert(isDefault, "we should be calling this function only for default tables"); + // unparent the edit controls + for (int i = 0; i < Count; i++) + { + this[i].ReleaseHostedControl(); + } + + // get rid of the old list and get a new empty list + items.Clear(); + } + + /// + /// Occurs when a change is made to the System.Windows.Forms.GridColumnStylesCollection. + /// + public event CollectionChangeEventHandler CollectionChanged + { + add => onCollectionChanged += value; + remove => onCollectionChanged -= value; + } + + public void Clear() + { + for (int i = 0; i < Count; i++) + { + this[i].ReleaseHostedControl(); + } + + items.Clear(); + OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, null)); + } + + /// + /// Gets a value indicating whether the System.Windows.Forms.GridColumnStylesCollection contains a System.Windows.Forms.DataGridColumnStyle associated with the + /// specified . + /// + public bool Contains(PropertyDescriptor propertyDescriptor) + { + return this[propertyDescriptor] != null; + } + + /// + /// Gets a value indicating whether the System.Windows.Forms.GridColumnsStyleCollection contains the specified System.Windows.Forms.DataGridColumnStyle. + /// + public bool Contains(DataGridColumnStyle column) + { + int index = items.IndexOf(column); + return index != -1; + } + + /// + /// Gets a value indicating whether the System.Windows.Forms.GridColumnsStyleCollection contains the System.Windows.Forms.DataGridColumnStyle with the specified name. + /// + public bool Contains(string name) + { + IEnumerator e = items.GetEnumerator(); + while (e.MoveNext()) + { + DataGridColumnStyle column = (DataGridColumnStyle)e.Current; + // NOTE: case-insensitive + if (string.Compare(column.MappingName, name, true, CultureInfo.InvariantCulture) == 0) + { + return true; + } + } + + return false; + } + + /* implemented at BaseCollection + /// + /// Gets an enumerator for the System.Windows.Forms.GridColumnsStyleCollection. + /// + /// + /// Gets an enumerator for the System.Windows.Forms.GridColumnsStyleCollection. + /// + /// + /// An + /// that can be used to iterate through the collection. + /// + /// + /// The following example gets an that iterates through the System.Windows.Forms.GridColumnsStyleCollection. and prints the + /// of each + /// associated with the object. + /// + /// Private Sub EnumerateThroughGridColumns() + /// Dim ie As System.Collections.IEnumerator + /// Dim dgCol As DataGridColumn + /// Set ie = DataGrid1.GridColumns.GetEnumerator + /// Do While ie.GetNext = True + /// Set dgCol = ie.GetObject + /// Debug.Print dgCol.DataColumn.Caption + /// Loop + /// End Sub + /// + /// + /// + /// + /// + /// + public override IEnumerator GetEnumerator() { + return items.GetEnumerator(); + } + + /// + /// Gets an enumerator for the System.Windows.Forms.GridColumnsStyleCollection + /// . + /// + /// + /// A value that indicates if the enumerator can remove elements. , if removals are allowed; otherwise, . The default is . + /// + /// + /// An that can be used to iterate through the + /// collection. + /// + /// + /// An attempt was made to remove the System.Windows.Forms.DataGridColumnStyle through the object's method. Use the System.Windows.Forms.GridColumnsStyleCollection object's method instead. + /// + /// + /// Because this implementation doesn't support the removal + /// of System.Windows.Forms.DataGridColumnStyle objects through the + /// class's method, you must use the class's + /// method instead. + /// + /// + /// The following example gets an for that iterates through the System.Windows.Forms.GridColumnsStyleCollection. If a column in the collection is of type , it is deleted. + /// + /// Private Sub RemoveBoolColumns() + /// Dim ie As System.Collections.IEnumerator + /// Dim dgCol As DataGridColumn + /// Set ie = DataGrid1.GridColumns.GetEnumerator(true) + /// Do While ie.GetNext + /// Set dgCol = ie.GetObject + /// + /// If dgCol.ToString = "DataGridBoolColumn" Then + /// DataGrid1.GridColumns.Remove dgCol + /// End If + /// Loop + /// End If + /// + /// + /// + /// + /// + /// + public override IEnumerator GetEnumerator(bool allowRemove) { + if (!allowRemove) + return GetEnumerator(); + else + throw new NotSupportedException(SR.DataGridColumnCollectionGetEnumerator); + } + */ + + /// + /// Gets the index of a specified System.Windows.Forms.DataGridColumnStyle. + /// + public int IndexOf(DataGridColumnStyle element) + { + int itemCount = items.Count; + for (int i = 0; i < itemCount; ++i) + { + DataGridColumnStyle column = (DataGridColumnStyle)items[i]; + if (element == column) + { + return i; + } + } + + return -1; + } + + /// + /// Raises the System.Windows.Forms.GridColumnsCollection.CollectionChanged event. + /// + protected void OnCollectionChanged(CollectionChangeEventArgs e) + { + onCollectionChanged?.Invoke(this, e); + + DataGrid grid = owner.DataGrid; + if (grid != null) + { + grid.checkHierarchy = true; + } + } + + /// + /// Removes the specified System.Windows.Forms.DataGridColumnStyle from the System.Windows.Forms.GridColumnsStyleCollection. + /// + public void Remove(DataGridColumnStyle column) + { + if (isDefault) + { + throw new ArgumentException(SR.DataGridDefaultColumnCollectionChanged); + } + + int columnIndex = -1; + int itemsCount = items.Count; + for (int i = 0; i < itemsCount; ++i) + { + if (items[i] == column) + { + columnIndex = i; + break; + } + } + + if (columnIndex == -1) + { + throw new InvalidOperationException(SR.DataGridColumnCollectionMissing); + } + else + { + RemoveAt(columnIndex); + } + } + + /// + /// Removes the System.Windows.Forms.DataGridColumnStyle with the specified index from the System.Windows.Forms.GridColumnsStyleCollection. + /// + public void RemoveAt(int index) + { + if (isDefault) + { + throw new ArgumentException(SR.DataGridDefaultColumnCollectionChanged); + } + + DataGridColumnStyle toRemove = (DataGridColumnStyle)items[index]; + toRemove.SetDataGridTableInColumn(null, true); + toRemove.MappingNameChanged -= new EventHandler(ColumnStyleMappingNameChanged); + toRemove.PropertyDescriptorChanged -= new EventHandler(ColumnStylePropDescChanged); +#if false + toRemove.RemoveOnPropertyChange(owner.OnColumnChanged); +#endif + items.RemoveAt(index); + OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Remove, toRemove)); + } + + public void ResetPropertyDescriptors() + { + for (int i = 0; i < Count; i++) + { + this[i].PropertyDescriptor = null; + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/GridTableStylesCollection.cs b/src/System.Windows.Forms/src/System/Windows/Forms/GridTableStylesCollection.cs new file mode 100644 index 00000000000..0a57466ed37 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/GridTableStylesCollection.cs @@ -0,0 +1,342 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System.Collections; +using System.ComponentModel; +using System.Globalization; + +namespace System.Windows.Forms +{ + /// + /// Represents a collection of objects in the + /// control. + /// + [ListBindable(false)] + public class GridTableStylesCollection : BaseCollection, IList + { + CollectionChangeEventHandler onCollectionChanged; + readonly ArrayList items = new ArrayList(); + readonly DataGrid owner; + + int IList.Add(object value) + { + return Add((DataGridTableStyle)value); + } + + void IList.Clear() + { + Clear(); + } + + bool IList.Contains(object value) + { + return items.Contains(value); + } + + int IList.IndexOf(object value) + { + return items.IndexOf(value); + } + + void IList.Insert(int index, object value) + { + throw new NotSupportedException(); + } + + void IList.Remove(object value) + { + Remove((DataGridTableStyle)value); + } + + void IList.RemoveAt(int index) + { + RemoveAt(index); + } + + bool IList.IsFixedSize + { + get { return false; } + } + + bool IList.IsReadOnly + { + get { return false; } + } + + object IList.this[int index] + { + get { return items[index]; } + set { throw new NotSupportedException(); } + } + + void ICollection.CopyTo(Array array, int index) + { + items.CopyTo(array, index); + } + + int ICollection.Count + { + get { return items.Count; } + } + + bool ICollection.IsSynchronized + { + get { return false; } + } + + object ICollection.SyncRoot + { + get { return this; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return items.GetEnumerator(); + } + + internal GridTableStylesCollection(DataGrid grid) + { + owner = grid; + } + + protected override ArrayList List + { + get + { + return items; + } + } + + /* implemented in BaseCollection + /// + /// Retrieves the number of GridTables in the collection. + /// + /// + /// The number of GridTables in the collection. + /// + public override int Count { + get { + return items.Count; + } + } + */ + + /// + /// Retrieves the DataGridTable with the specified index. + /// + public DataGridTableStyle this[int index] + { + get + { + return (DataGridTableStyle)items[index]; + } + } + + /// + /// Retrieves the DataGridTable with the name provided. + /// + public DataGridTableStyle this[string tableName] + { + get + { + if (tableName == null) + { + throw new ArgumentNullException(nameof(tableName)); + } + + int itemCount = items.Count; + for (int i = 0; i < itemCount; ++i) + { + DataGridTableStyle table = (DataGridTableStyle)items[i]; + // NOTE: case-insensitive + if (string.Equals(table.MappingName, tableName, StringComparison.OrdinalIgnoreCase)) + { + return table; + } + } + + return null; + } + } + + internal void CheckForMappingNameDuplicates(DataGridTableStyle table) + { + if (string.IsNullOrEmpty(table.MappingName)) + { + return; + } + + for (int i = 0; i < items.Count; i++) + { + if (((DataGridTableStyle)items[i]).MappingName.Equals(table.MappingName) && table != items[i]) + { + throw new ArgumentException(SR.DataGridTableStyleDuplicateMappingName, nameof(table)); + } + } + } + + /// + /// Adds a to this collection. + /// + public virtual int Add(DataGridTableStyle table) + { + // set the rowHeaderWidth on the newly added table to at least the minimum value + // on its owner + if (owner != null && owner.MinimumRowHeaderWidth() > table.RowHeaderWidth) + { + table.RowHeaderWidth = owner.MinimumRowHeaderWidth(); + } + + if (table.DataGrid != owner && table.DataGrid != null) + { + throw new ArgumentException(SR.DataGridTableStyleCollectionAddedParentedTableStyle, nameof(table)); + } + + table.DataGrid = owner; + CheckForMappingNameDuplicates(table); + table.MappingNameChanged += new EventHandler(TableStyleMappingNameChanged); + int index = items.Add(table); + OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Add, table)); + + return index; + } + + private void TableStyleMappingNameChanged(object sender, EventArgs pcea) + { + OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, null)); + } + + public virtual void AddRange(DataGridTableStyle[] tables) + { + if (tables == null) + { + throw new ArgumentNullException(nameof(tables)); + } + + foreach (DataGridTableStyle table in tables) + { + table.DataGrid = owner; + table.MappingNameChanged += new EventHandler(TableStyleMappingNameChanged); + items.Add(table); + } + + OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, null)); + } + + public event CollectionChangeEventHandler CollectionChanged + { + add => onCollectionChanged += value; + remove => onCollectionChanged -= value; + } + + public void Clear() + { + for (int i = 0; i < items.Count; i++) + { + DataGridTableStyle element = (DataGridTableStyle)items[i]; + element.MappingNameChanged -= new EventHandler(TableStyleMappingNameChanged); + } + + items.Clear(); + OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, null)); + } + + /// + /// Checks to see if a DataGridTableStyle is contained in this collection. + /// + public bool Contains(DataGridTableStyle table) + { + int index = items.IndexOf(table); + return index != -1; + } + + /// + /// Checks to see if a with the given name + /// is contained in this collection. + /// + public bool Contains(string name) + { + int itemCount = items.Count; + for (int i = 0; i < itemCount; ++i) + { + DataGridTableStyle table = (DataGridTableStyle)items[i]; + // NOTE: case-insensitive + if (string.Compare(table.MappingName, name, true, CultureInfo.InvariantCulture) == 0) + { + return true; + } + } + + return false; + } + + /* + public override IEnumerator GetEnumerator() { + return items.GetEnumerator(); + } + + public override IEnumerator GetEnumerator(bool allowRemove) { + if (!allowRemove) + return GetEnumerator(); + else + throw new NotSupportedException(SR.DataGridTableCollectionGetEnumerator); + } + */ + + protected void OnCollectionChanged(CollectionChangeEventArgs e) + { + onCollectionChanged?.Invoke(this, e); + + DataGrid grid = owner; + if (grid != null) + { + /* FOR DEMO: Microsoft: TableStylesCollection::OnCollectionChanged: set the datagridtble + DataView dataView = ((DataView) grid.DataSource); + if (dataView != null) { + DataTable dataTable = dataView.Table; + if (dataTable != null) { + if (Contains(dataTable)) { + grid.SetDataGridTable(this[dataTable]); + } + } + } + */ + grid.checkHierarchy = true; + } + } + + public void Remove(DataGridTableStyle table) + { + int tableIndex = -1; + int itemsCount = items.Count; + for (int i = 0; i < itemsCount; ++i) + { + if (items[i] == table) + { + tableIndex = i; + break; + } + } + + if (tableIndex == -1) + { + throw new ArgumentException(SR.DataGridTableCollectionMissingTable, nameof(table)); + } + else + { + RemoveAt(tableIndex); + } + } + + public void RemoveAt(int index) + { + DataGridTableStyle element = (DataGridTableStyle)items[index]; + element.MappingNameChanged -= new EventHandler(TableStyleMappingNameChanged); + items.RemoveAt(index); + OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Remove, element)); + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/GridTablesFactory.cs b/src/System.Windows.Forms/src/System/Windows/Forms/GridTablesFactory.cs new file mode 100644 index 00000000000..401f8f555f0 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/GridTablesFactory.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.System.Windows.Forms +{ + public static class GridTablesFactory + { + /// + /// Takes a DataView and creates an intelligent mapping of DataView storage + /// types into available DataColumn types. + /// + public static DataGridTableStyle[] CreateGridTables(DataGridTableStyle gridTable, object dataSource, string dataMember, BindingContext bindingManager) + { + return new DataGridTableStyle[] { gridTable }; + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/IDataGridEditingService.cs b/src/System.Windows.Forms/src/System/Windows/Forms/IDataGridEditingService.cs new file mode 100644 index 00000000000..911af12452a --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/IDataGridEditingService.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// The DataGrid exposes hooks to request editing commands via this interface. + /// + public interface IDataGridEditingService + { + bool BeginEdit(DataGridColumnStyle gridColumn, int rowNumber); + bool EndEdit(DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort); + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Layout/DefaultLayout.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Layout/DefaultLayout.cs index 99966ff8f27..47003f2d521 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Layout/DefaultLayout.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Layout/DefaultLayout.cs @@ -790,24 +790,12 @@ private static void UpdateAnchorInfo(IArrangedElement element) AnchorStyles anchor = GetAnchor(element); if (IsAnchored(anchor, AnchorStyles.Right)) { - if (DpiHelper.IsScalingRequirementMet && (anchorInfo.Right - parentWidth > 0) && (oldAnchorInfo.Right < 0)) - { - // Parent was resized to fit its parent, or screen, we need to reuse old anchors info to prevent losing control beyond right edge. - anchorInfo.Right = oldAnchorInfo.Right; - if (!IsAnchored(anchor, AnchorStyles.Left)) - { - // Control might have been resized, update Left anchors. - anchorInfo.Left = oldAnchorInfo.Right - cachedBounds.Width; - } - } - else - { - anchorInfo.Right -= parentWidth; + // This differs from the official WinForms implementation because we encountered an issue with DPI handling. See WI00955507. + anchorInfo.Right -= parentWidth; - if (!IsAnchored(anchor, AnchorStyles.Left)) - { - anchorInfo.Left -= parentWidth; - } + if (!IsAnchored(anchor, AnchorStyles.Left)) + { + anchorInfo.Left -= parentWidth; } } else if (!IsAnchored(anchor, AnchorStyles.Left)) @@ -818,25 +806,12 @@ private static void UpdateAnchorInfo(IArrangedElement element) if (IsAnchored(anchor, AnchorStyles.Bottom)) { - if (DpiHelper.IsScalingRequirementMet && (anchorInfo.Bottom - parentHeight > 0) && (oldAnchorInfo.Bottom < 0)) - { - // The parent was resized to fit its parent or the screen, we need to reuse the old anchors info to prevent positioning the control beyond the bottom edge. - anchorInfo.Bottom = oldAnchorInfo.Bottom; + // This differs from the official WinForms implementation because we encountered an issue with DPI handling. See WI00955507. + anchorInfo.Bottom -= parentHeight; - if (!IsAnchored(anchor, AnchorStyles.Top)) - { - // The control might have been resized, update the Top anchor. - anchorInfo.Top = oldAnchorInfo.Bottom - cachedBounds.Height; - } - } - else + if (!IsAnchored(anchor, AnchorStyles.Top)) { - anchorInfo.Bottom -= parentHeight; - - if (!IsAnchored(anchor, AnchorStyles.Top)) - { - anchorInfo.Top -= parentHeight; - } + anchorInfo.Top -= parentHeight; } } else if (!IsAnchored(anchor, AnchorStyles.Top)) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ListView.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ListView.cs index d9c790b1421..2a1c8e2adb9 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ListView.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ListView.cs @@ -14,6 +14,7 @@ using static System.Windows.Forms.ListViewGroup; using static Interop; using static Interop.ComCtl32; +using INITCOMMONCONTROLSEX = Windows.Win32.UI.Controls.INITCOMMONCONTROLSEX; namespace System.Windows.Forms; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MainMenu.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MainMenu.cs new file mode 100644 index 00000000000..84443373549 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/MainMenu.cs @@ -0,0 +1,355 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.Drawing; +using static System.Windows.Forms.ToolStrip; +using static Interop; + +namespace System.Windows.Forms +{ + /// + /// Represents a menu structure for a form. + /// + [ToolboxItemFilter("System.Windows.Forms.MainMenu")] + public class MainMenu : Menu + { + internal Form? _form; + internal Form ownerForm; // this is the form that created this menu, and is the only form allowed to dispose it. + private RightToLeft _rightToLeft = RightToLeft.Inherit; + private EventHandler _onCollapse; + + +#if DEBUG + internal static readonly TraceSwitch s_selectionDebug = new("SelectionDebug", "Debug ToolStrip Selection code"); + internal static readonly TraceSwitch s_dropTargetDebug = new("DropTargetDebug", "Debug ToolStrip Drop code"); + internal static readonly TraceSwitch s_layoutDebugSwitch = new("Layout debug", "Debug ToolStrip layout code"); + internal static readonly TraceSwitch s_mouseActivateDebug = new("ToolStripMouseActivate", "Debug ToolStrip WM_MOUSEACTIVATE code"); + internal static readonly TraceSwitch s_mergeDebug = new("ToolStripMergeDebug", "Debug toolstrip merging"); + internal static readonly TraceSwitch s_snapFocusDebug = new("SnapFocus", "Debug snapping/restoration of focus"); + internal static readonly TraceSwitch s_flickerDebug = new("FlickerDebug", "Debug excessive calls to Invalidate()"); + internal static readonly TraceSwitch s_itemReorderDebug = new("ItemReorderDebug", "Debug excessive calls to Invalidate()"); + internal static readonly TraceSwitch s_mdiMergeDebug = new("MDIMergeDebug", "Debug toolstrip MDI merging"); + internal static readonly TraceSwitch s_menuAutoExpandDebug = new("MenuAutoExpand", "Debug menu auto expand"); + internal static readonly TraceSwitch s_controlTabDebug = new("ControlTab", "Debug ToolStrip Control+Tab selection"); +#else + internal static readonly TraceSwitch? s_selectionDebug; + internal static readonly TraceSwitch? s_dropTargetDebug; + internal static readonly TraceSwitch? s_layoutDebugSwitch; + internal static readonly TraceSwitch? s_mouseActivateDebug; + internal static readonly TraceSwitch? s_mergeDebug; + internal static readonly TraceSwitch? s_snapFocusDebug; + internal static readonly TraceSwitch? s_flickerDebug; + internal static readonly TraceSwitch? s_itemReorderDebug; + internal static readonly TraceSwitch? s_mdiMergeDebug; + internal static readonly TraceSwitch? s_menuAutoExpandDebug; + internal static readonly TraceSwitch? s_controlTabDebug; +#endif + + private Point _mouseEnterWhenShown = s_invalidMouseEnter; + internal static Point s_invalidMouseEnter = new(int.MaxValue, int.MaxValue); + private HWND _hwndThatLostFocus; + + /// handy check for painting and sizing + [Browsable(false)] + public bool IsDropDown + { + get { return (this is ToolStripDropDown); } + } + + // remembers the current mouse location so we can determine + // later if we need to shift selection. + internal void SnapMouseLocation() + { + _mouseEnterWhenShown = WindowsFormsUtils.LastCursorPoint; + } + + /// SnapFocus + /// When get focus to the toolstrip (and we're not participating in the tab order) + /// it's probably cause someone hit the ALT key. We need to remember who that was + /// so when we're done here we can RestoreFocus back to it. + /// + /// We're called from WM_SETFOCUS, and otherHwnd is the HWND losing focus. + /// + /// Required checks + /// - make sure it's not a dropdown + /// - make sure it's not a child control of this control. + /// - make sure the control is on this window + /// + private void SnapFocus(HWND otherHwnd) + { +#if DEBUG + Debug.WriteLineIf(s_snapFocusDebug.TraceVerbose, $"{!Environment.StackTrace.Contains("FocusInternal")}", "who is setting focus to us?"); +#endif + // we need to know who sent us focus so we know who to send it back to later. + + if (!TabStop && !IsDropDown) + { + bool snapFocus = false; + if (Focused && (otherHwnd != Handle)) + { + // the case here is a label before a combo box calling FocusInternal in ProcessMnemonic. + // we'll filter out children later. + snapFocus = true; + } + else if (!ContainsFocus && !Focused) + { + snapFocus = true; + } + + if (snapFocus) + { + // remember the current mouse position so that we can check later if it actually moved + // otherwise we'd unexpectedly change selection to whatever the cursor was over at this moment. + SnapMouseLocation(); + + // make sure the otherHandle is not a child of thisHandle + if ((Handle != otherHwnd) && !PInvoke.IsChild(this, otherHwnd)) + { + // make sure the root window of the otherHwnd is the same as + // the root window of thisHwnd. + HWND thisHwndRoot = PInvoke.GetAncestor(this, GET_ANCESTOR_FLAGS.GA_ROOT); + HWND otherHwndRoot = PInvoke.GetAncestor(otherHwnd, GET_ANCESTOR_FLAGS.GA_ROOT); + + if (thisHwndRoot == otherHwndRoot && !thisHwndRoot.IsNull) + { + s_snapFocusDebug.TraceVerbose( + $"[ToolStrip SnapFocus]: Caching for return focus:{WindowsFormsUtils.GetControlInformation(otherHwnd)}"); + + // We know we're in the same window heirarchy. + _hwndThatLostFocus = otherHwnd; + } + } + } + } + } + + private ToolStripItem? _lastMouseActiveItem; + private ToolStripItem? _lastMouseDownedItem; + + internal bool IsInDesignMode + { + get + { + return DesignMode; + } + } + + protected override void WndProc(ref Message m) + { + if (m.MsgInternal == PInvoke.WM_SETFOCUS) + { + SnapFocus((HWND)(nint)m.WParamInternal); + } + + if (m.MsgInternal == PInvoke.WM_MOUSEACTIVATE) + { + // We want to prevent taking focus if someone clicks on the toolstrip dropdown itself. The mouse message + // will still go through, but focus won't be taken. If someone clicks on a child control (combobox, + // textbox, etc) focus will be taken - but we'll handle that in WM_NCACTIVATE handler. + Point pt = PointToClient(WindowsFormsUtils.LastCursorPoint); + HWND hwndClicked = PInvoke.ChildWindowFromPointEx( + this, + pt, + CWP_FLAGS.CWP_SKIPINVISIBLE | CWP_FLAGS.CWP_SKIPDISABLED | CWP_FLAGS.CWP_SKIPTRANSPARENT); + + // If we click on the toolstrip itself, eat the activation. + // If we click on a child control, allow the toolstrip to activate. + if (hwndClicked == HWND) + { + _lastMouseDownedItem = null; + m.ResultInternal = (LRESULT)(nint)PInvoke.MA_NOACTIVATE; + + if (!IsDropDown && !IsInDesignMode) + { + // If our root HWND is not the active hwnd,eat the mouse message and bring the form to the front. + HWND rootHwnd = PInvoke.GetAncestor(this, GET_ANCESTOR_FLAGS.GA_ROOT); + if (!rootHwnd.IsNull) + { + // snap the active window and compare to our root window. + HWND hwndActive = PInvoke.GetActiveWindow(); + if (hwndActive != rootHwnd) + { + // Activate the window, and discard the mouse message. + // this appears to be the same behavior as office. + m.ResultInternal = (LRESULT)(nint)PInvoke.MA_ACTIVATEANDEAT; + } + } + } + + return; + } + else + { + // We're setting focus to a child control - remember who gave it to us so we can restore it on ESC. + SnapFocus(PInvoke.GetFocus()); + if (!IsDropDown && !TabStop) + { + s_snapFocusDebug.TraceVerbose("Installing restoreFocusFilter"); + // PERF + //Application.ThreadContext.FromCurrent().AddMessageFilter(RestoreFocusFilter); + } + } + } + + base.WndProc(ref m); + + if (m.Msg == (int)PInvoke.WM_NCDESTROY) + { + // Destroy the owner window, if we created one. We + // cannot do this in OnHandleDestroyed, because at + // that point our handle is not actually destroyed so + // destroying our parent actually causes a recursive + // WM_DESTROY. + _dropDownOwnerWindow?.DestroyHandle(); + } + } + + private NativeWindow? _dropDownOwnerWindow; + + private RestoreFocusMessageFilter? _restoreFocusFilter; + + internal RestoreFocusMessageFilter RestoreFocusFilter + { + get + { + //_restoreFocusFilter ??= new RestoreFocusMessageFilter(this); + + return _restoreFocusFilter; + } + } + + /// + /// Creates a new MainMenu control. + /// + public MainMenu() : base(null) + { + } + + /// + /// Initializes a new instance of the class with the specified container. + /// + public MainMenu(IContainer container) : this() + { + if (container == null) + { + throw new ArgumentNullException(nameof(container)); + } + + container.Add(this); + } + + /// + /// Creates a new MainMenu control with the given items to start with. + /// + public MainMenu(MenuItem[] items) : base(items) + { + } + + [SRDescription(nameof(SR.MainMenuCollapseDescr))] + public event EventHandler Collapse + { + add => _onCollapse += value; + remove => _onCollapse -= value; + } + + /// + /// This is used for international applications where the language is written from RightToLeft. + /// When this property is true, text alignment and reading order will be from right to left. + /// + [Localizable(true)] + [AmbientValue(RightToLeft.Inherit)] + [SRDescription(nameof(SR.MenuRightToLeftDescr))] + public virtual RightToLeft RightToLeft + { + get + { + if (_rightToLeft == RightToLeft.Inherit) + { + if (_form != null) + { + return _form.RightToLeft; + } + + return RightToLeft.Inherit; + } + + return _rightToLeft; + } + set + { + if (!ClientUtils.IsEnumValid(value, (int)value, (int)RightToLeft.No, (int)RightToLeft.Inherit)) + { + throw new InvalidEnumArgumentException(nameof(RightToLeft), (int)value, typeof(RightToLeft)); + } + + if (_rightToLeft != value) + { + _rightToLeft = value; + UpdateRtl((value == RightToLeft.Yes)); + } + } + } + + internal override bool RenderIsRightToLeft => (RightToLeft == RightToLeft.Yes && (_form == null || !_form.IsMirrored)); + + /// + /// Creates a new MainMenu object which is a dupliate of this one. + /// + public virtual MainMenu CloneMenu() + { + var newMenu = new MainMenu(); + newMenu.CloneMenu(this); + return newMenu; + } + + protected override IntPtr CreateMenuHandle() => User32.CreateMenu(); + + /// + /// Clears out this MainMenu object and discards all of it's resources. + /// If the menu is parented in a form, it is disconnected from that as + /// well. + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_form != null && (ownerForm == null || _form == ownerForm)) + { + _form.Menu = null; + } + } + + base.Dispose(disposing); + } + + /// + /// Indicates which form in which we are currently residing [if any] + /// + public Form GetForm() => _form; + + internal override void ItemsChanged(int change) + { + base.ItemsChanged(change); + _form?.MenuChanged(change, this); + } + + internal virtual void ItemsChanged(int change, Menu menu) => _form?.MenuChanged(change, menu); + + /// + /// Fires the collapse event + /// + protected internal virtual void OnCollapse(EventArgs e) => _onCollapse?.Invoke(this, e); + + /// + /// Returns true if the RightToLeft should be persisted in code gen. + /// + internal virtual bool ShouldSerializeRightToLeft() => _rightToLeft == RightToLeft.Inherit; + + /// + /// Returns a string representation for this control. + /// + public override string ToString() => base.ToString(); + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Menu.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Menu.cs new file mode 100644 index 00000000000..951128c5e60 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Menu.cs @@ -0,0 +1,1262 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.ComponentModel; +using System.Globalization; +using System.Runtime.InteropServices; +using static Interop; + +namespace System.Windows.Forms +{ + /// + /// This is the base class for all menu components (MainMenu, MenuItem, and ContextMenu). + /// + [ToolboxItemFilter("System.Windows.Forms")] + [ListBindable(false)] + public abstract class Menu : ScrollableControl + { + internal const int CHANGE_ITEMS = 0; // item(s) added or removed + internal const int CHANGE_VISIBLE = 1; // item(s) hidden or shown + internal const int CHANGE_MDI = 2; // mdi item changed + internal const int CHANGE_MERGE = 3; // mergeType or mergeOrder changed + internal const int CHANGE_ITEMADDED = 4; // mergeType or mergeOrder changed + + /// + /// Used by findMenuItem + /// + public const int FindHandle = 0; + /// + /// Used by findMenuItem + /// + public const int FindShortcut = 1; + + private MenuItemCollection itemsCollection; + internal MenuItem[] items; + private int _itemCount; + internal IntPtr handle; + internal bool created; + private object userData; + private string name; + + /// + /// This is an abstract class. Instances cannot be created, so the constructor + /// is only called from derived classes. + /// + protected Menu(MenuItem[] items) + { + if (items != null) + { + MenuItems.AddRange(items); + } + } + + /// + /// The HMENU handle corresponding to this menu. + /// + [ + Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SRDescription(nameof(SR.ControlHandleDescr)) + ] + public IntPtr Handle + { + get + { + if (handle == IntPtr.Zero) + { + handle = CreateMenuHandle(); + } + + CreateMenuItems(); + return handle; + } + } + + /// + /// Specifies whether this menu contains any items. + /// + [ + Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SRDescription(nameof(SR.MenuIsParentDescr)) + ] + public virtual bool IsParent + { + get + { + return null != items && ItemCount > 0; + } + } + + internal int ItemCount + { + get + { + return _itemCount; + } + } + + /// + /// The MenuItem that contains the list of MDI child windows. + /// + [ + Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SRDescription(nameof(SR.MenuMDIListItemDescr)) + ] + public MenuItem MdiListItem + { + get + { + for (int i = 0; i < ItemCount; i++) + { + MenuItem item = items[i]; + if (item.MdiList) + { + return item; + } + + if (item.IsParent) + { + item = item.MdiListItem; + if (item != null) + { + return item; + } + } + } + + return null; + } + } + + /// + /// Name of this control. The designer will set this to the same + /// as the programatic Id "(name)" of the control - however this + /// property has no bearing on the runtime aspects of this control. + /// + [ + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + Browsable(false) + ] + public string Name + { + get + { + return WindowsFormsUtils.GetComponentName(this, name); + } + set + { + if (value == null || value.Length == 0) + { + name = null; + } + else + { + name = value; + } + + if (Site != null) + { + Site.Name = name; + } + } + } + + [ + Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), + SRDescription(nameof(SR.MenuMenuItemsDescr)), + MergableProperty(false) + ] + public MenuItemCollection MenuItems + { + get + { + if (itemsCollection == null) + { + itemsCollection = new MenuItemCollection(this); + } + + return itemsCollection; + } + } + + internal virtual bool RenderIsRightToLeft + { + get + { + Debug.Assert(true, "Should never get called"); + return false; + + } + } + + [ + SRCategory(nameof(SR.CatData)), + Localizable(false), + Bindable(true), + SRDescription(nameof(SR.ControlTagDescr)), + DefaultValue(null), + TypeConverter(typeof(StringConverter)), + ] + public object Tag + { + get + { + return userData; + } + set + { + userData = value; + } + } + + /// + /// Notifies Menu that someone called Windows.DeleteMenu on its handle. + /// + internal void ClearHandles() + { + if (handle != IntPtr.Zero) + { + User32.DestroyMenu(new HandleRef(this, handle)); + } + + handle = IntPtr.Zero; + if (created) + { + for (int i = 0; i < ItemCount; i++) + { + items[i].ClearHandles(); + } + + created = false; + } + } + + /// + /// Sets this menu to be an identical copy of another menu. + /// + protected internal void CloneMenu(Menu menuSrc) + { + if (menuSrc == null) + { + throw new ArgumentNullException(nameof(menuSrc)); + } + + MenuItem[] newItems = null; + if (menuSrc.items != null) + { + int count = menuSrc.MenuItems.Count; + newItems = new MenuItem[count]; + for (int i = 0; i < count; i++) + { + newItems[i] = menuSrc.MenuItems[i].CloneMenu(); + } + } + + MenuItems.Clear(); + if (newItems != null) + { + MenuItems.AddRange(newItems); + } + } + + protected virtual IntPtr CreateMenuHandle() => User32.CreatePopupMenu(); + + internal void CreateMenuItems() + { + if (!created) + { + for (int i = 0; i < ItemCount; i++) + { + items[i].CreateMenuItem(); + } + + created = true; + } + } + + internal void DestroyMenuItems() + { + if (created) + { + for (int i = 0; i < ItemCount; i++) + { + items[i].ClearHandles(); + } + + while (User32.GetMenuItemCount(new HandleRef(this, handle)) > 0) + { + User32.RemoveMenu(new HandleRef(this, handle), 0, User32.MF.BYPOSITION); + } + + created = false; + } + } + + /// + /// Disposes of the component. Call dispose when the component is no longer needed. + /// This method removes the component from its container (if the component has a site) + /// and triggers the dispose event. + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + while (ItemCount > 0) + { + MenuItem item = items[--_itemCount]; + + // remove the item before we dispose it so it still has valid state + // for undo/redo + // + if (item.Site != null && item.Site.Container != null) + { + item.Site.Container.Remove(item); + } + + item.Parent = null; + item.Dispose(); + } + + items = null; + } + + if (handle != IntPtr.Zero) + { + User32.DestroyMenu(new HandleRef(this, handle)); + handle = IntPtr.Zero; + if (disposing) + { + ClearHandles(); + } + } + + base.Dispose(disposing); + } + + public MenuItem FindMenuItem(int type, IntPtr value) + { + for (int i = 0; i < ItemCount; i++) + { + MenuItem item = items[i]; + switch (type) + { + case FindHandle: + if (item.handle == value) + { + return item; + } + + break; + case FindShortcut: + if (item.Shortcut == (Shortcut)(int)value) + { + return item; + } + + break; + } + + item = item.FindMenuItem(type, value); + if (item != null) + { + return item; + } + } + + return null; + } + + protected int FindMergePosition(int mergeOrder) + { + int iMin, iLim, iT; + + for (iMin = 0, iLim = ItemCount; iMin < iLim;) + { + iT = (iMin + iLim) / 2; + if (items[iT].MergeOrder <= mergeOrder) + { + iMin = iT + 1; + } + else + { + iLim = iT; + } + } + + return iMin; + } + + // A new method for finding the approximate merge position. The original + // method assumed (incorrectly) that the MergeOrder of the target menu would be sequential + // as it's guaranteed to be in the MDI imlementation of merging container and child + // menus. However, user code can call MergeMenu independently on a source and target + // menu whose MergeOrder values are not necessarily pre-sorted. + internal int xFindMergePosition(int mergeOrder) + { + int nPosition = 0; + + // Iterate from beginning to end since we can't assume any sequential ordering to MergeOrder + for (int nLoop = 0; nLoop < ItemCount; nLoop++) + { + + if (items[nLoop].MergeOrder > mergeOrder) + { + // We didn't find what we're looking for, but we've found a stopping point. + break; + } + else if (items[nLoop].MergeOrder < mergeOrder) + { + // We might have found what we're looking for, but we'll have to come around again + // to know. + nPosition = nLoop + 1; + } + else if (mergeOrder == items[nLoop].MergeOrder) + { + // We've found what we're looking for, so use this value for the merge order + nPosition = nLoop; + break; + } + } + + return nPosition; + } + + //There's a win32 problem that doesn't allow menus to cascade right to left + //unless we explicitely set the bit on the menu the first time it pops up + internal void UpdateRtl(bool setRightToLeftBit) + { + foreach (MenuItem item in MenuItems) + { + item.UpdateItemRtl(setRightToLeftBit); + item.UpdateRtl(setRightToLeftBit); + } + } + + /// + /// Returns the ContextMenu that contains this menu. The ContextMenu + /// is at the top of this menu's parent chain. + /// Returns null if this menu is not contained in a ContextMenu. + /// This can occur if it's contained in a MainMenu or if it isn't + /// currently contained in any menu at all. + /// + public ContextMenu GetContextMenu() + { + Menu menuT; + for (menuT = this; !(menuT is ContextMenu);) + { + if (!(menuT is MenuItem)) + { + return null; + } + + menuT = ((MenuItem)menuT).Parent; + } + + return (ContextMenu)menuT; + + } + + /// + /// Returns the MainMenu item that contains this menu. The MainMenu + /// is at the top of this menu's parent chain. + /// Returns null if this menu is not contained in a MainMenu. + /// This can occur if it's contained in a ContextMenu or if it isn't + /// currently contained in any menu at all. + /// + public MainMenu GetMainMenu() + { + Menu menuT; + for (menuT = this; !(menuT is MainMenu);) + { + if (!(menuT is MenuItem)) + { + return null; + } + + menuT = ((MenuItem)menuT).Parent; + } + + return (MainMenu)menuT; + } + + internal virtual void ItemsChanged(int change) + { + switch (change) + { + case CHANGE_ITEMS: + case CHANGE_VISIBLE: + DestroyMenuItems(); + break; + } + } + + /// + /// Walks the menu item collection, using a caller-supplied delegate to find one + /// with a matching access key. Walk starts at specified item index and performs one + /// full pass of the entire collection, looping back to the top if necessary. + /// + /// Return value is intended for return from WM_MENUCHAR message. It includes both + /// index of matching item, and action for OS to take (execute or select). Zero is + /// used to indicate that no match was found (OS should ignore key and beep). + /// + private IntPtr MatchKeyToMenuItem(int startItem, char key, MenuItemKeyComparer comparer) + { + int firstMatch = -1; + bool multipleMatches = false; + + for (int i = 0; i < items.Length && !multipleMatches; ++i) + { + int itemIndex = (startItem + i) % items.Length; + MenuItem mi = items[itemIndex]; + if (mi != null && comparer(mi, key)) + { + if (firstMatch < 0) + { + // Using Index doesnt respect hidden items. + firstMatch = mi.MenuIndex; + } + else + { + multipleMatches = true; + } + } + } + + if (firstMatch < 0) + { + return IntPtr.Zero; + } + + int action = multipleMatches ? NativeMethods.MNC_SELECT : NativeMethods.MNC_EXECUTE; + return (IntPtr)NativeMethods.Util.MAKELONG(firstMatch, action); + } + + /// Delegate type used by MatchKeyToMenuItem + private delegate bool MenuItemKeyComparer(MenuItem mi, char key); + + /// + /// Merges another menu's items with this one's. Menu items are merged according to their + /// mergeType and mergeOrder properties. This function is typically used to + /// merge an MDI container's menu with that of its active MDI child. + /// + public virtual void MergeMenu(Menu menuSrc) + { + if (menuSrc == null) + { + throw new ArgumentNullException(nameof(menuSrc)); + } + + if (menuSrc == this) + { + throw new ArgumentException(SR.MenuMergeWithSelf, nameof(menuSrc)); + } + + int i, j; + MenuItem item; + MenuItem itemDst; + + if (menuSrc.items != null && items == null) + { + MenuItems.Clear(); + } + + for (i = 0; i < menuSrc.ItemCount; i++) + { + item = menuSrc.items[i]; + + switch (item.MergeType) + { + default: + continue; + case MenuMerge.Add: + MenuItems.Add(FindMergePosition(item.MergeOrder), item.MergeMenu()); + continue; + case MenuMerge.Replace: + case MenuMerge.MergeItems: + break; + } + + int mergeOrder = item.MergeOrder; + // Can we find a menu item with a matching merge order? + // Use new method to find the approximate merge position. The original + // method assumed (incorrectly) that the MergeOrder of the target menu would be sequential + // as it's guaranteed to be in the MDI imlementation of merging container and child + // menus. However, user code can call MergeMenu independently on a source and target + // menu whose MergeOrder values are not necessarily pre-sorted. + for (j = xFindMergePosition(mergeOrder); ; j++) + { + + if (j >= ItemCount) + { + // A matching merge position could not be found, + // so simply append this menu item to the end. + MenuItems.Add(j, item.MergeMenu()); + break; + } + + itemDst = items[j]; + if (itemDst.MergeOrder != mergeOrder) + { + MenuItems.Add(j, item.MergeMenu()); + break; + } + + if (itemDst.MergeType != MenuMerge.Add) + { + if (item.MergeType != MenuMerge.MergeItems + || itemDst.MergeType != MenuMerge.MergeItems) + { + itemDst.Dispose(); + MenuItems.Add(j, item.MergeMenu()); + } + else + { + itemDst.MergeMenu(item); + } + + break; + } + } + } + } + + internal virtual bool ProcessInitMenuPopup(IntPtr handle) + { + MenuItem item = FindMenuItem(FindHandle, handle); + if (item != null) + { + item.OnInitMenuPopup(EventArgs.Empty); + item.CreateMenuItems(); + return true; + } + + return false; + } + + protected internal virtual bool ProcessCmdKey(ref Message msg, Keys keyData) + { + MenuItem item = FindMenuItem(FindShortcut, (IntPtr)(int)keyData); + return item != null ? item.ShortcutClick() : false; + } + + /// + /// Returns index of currently selected menu item in + /// this menu, or -1 if no item is currently selected. + /// + internal int SelectedMenuItemIndex + { + get + { + for (int i = 0; i < items.Length; ++i) + { + MenuItem mi = items[i]; + if (mi != null && mi.Selected) + { + return i; + } + } + + return -1; + } + } + + /// + /// Returns a string representation for this control. + /// + public override string ToString() + { + string s = base.ToString(); + return s + ", Items.Count: " + ItemCount.ToString(CultureInfo.CurrentCulture); + } + + /// + /// Handles the WM_MENUCHAR message, forwarding it to the intended Menu + /// object. All the real work is done inside WmMenuCharInternal(). + /// + internal void WmMenuChar(ref Message m) + { + Menu menu = (m.LParam == handle) ? this : FindMenuItem(FindHandle, m.LParam); + + if (menu == null) + { + return; + } + + char menuKey = char.ToUpper((char)NativeMethods.Util.LOWORD(m.WParam), CultureInfo.CurrentCulture); + + m.Result = menu.WmMenuCharInternal(menuKey); + } + + /// + /// Handles WM_MENUCHAR to provide access key support for owner-draw menu items (which + /// means *all* menu items on a menu when IsImageMarginPresent == true). Attempts to + /// simulate the exact behavior that the OS provides for non owner-draw menu items. + /// + internal IntPtr WmMenuCharInternal(char key) + { + // Start looking just beyond the current selected item (otherwise just start at the top) + int startItem = (SelectedMenuItemIndex + 1) % items.Length; + + // First, search for match among owner-draw items with explicitly defined access keys (eg. "S&ave") + IntPtr result = MatchKeyToMenuItem(startItem, key, new MenuItemKeyComparer(CheckOwnerDrawItemWithMnemonic)); + + // Next, search for match among owner-draw items with no access keys (looking at first char of item text) + if (result == IntPtr.Zero) + { + result = MatchKeyToMenuItem(startItem, key, new MenuItemKeyComparer(CheckOwnerDrawItemNoMnemonic)); + } + + return result; + } + + /// MenuItemKeyComparer delegate used by WmMenuCharInternal + private bool CheckOwnerDrawItemWithMnemonic(MenuItem mi, char key) + { + return mi.OwnerDraw && + mi.Mnemonic == key; + } + + /// MenuItemKeyComparer delegate used by WmMenuCharInternal + private bool CheckOwnerDrawItemNoMnemonic(MenuItem mi, char key) + { + return mi.OwnerDraw && + mi.Mnemonic == 0 && + mi.Text.Length > 0 && + char.ToUpper(mi.Text[0], CultureInfo.CurrentCulture) == key; + } + + [ListBindable(false)] + public class MenuItemCollection : IList + { + private readonly Menu owner; + + /// A caching mechanism for key accessor + /// We use an index here rather than control so that we don't have lifetime + /// issues by holding on to extra references. + private int lastAccessedIndex = -1; + + public MenuItemCollection(Menu owner) + { + this.owner = owner; + } + + public virtual MenuItem this[int index] + { + get + { + if (index < 0 || index >= owner.ItemCount) + { + throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(SR.InvalidArgument, nameof(index), index)); + } + + return owner.items[index]; + } + + // set not supported + } + + object IList.this[int index] + { + get + { + return this[index]; + } + set + { + throw new NotSupportedException(); + } + } + + /// + /// Retrieves the child control with the specified key. + /// + public virtual MenuItem this[string key] + { + get + { + // We do not support null and empty string as valid keys. + if (string.IsNullOrEmpty(key)) + { + return null; + } + + // Search for the key in our collection + int index = IndexOfKey(key); + if (IsValidIndex(index)) + { + return this[index]; + } + else + { + return null; + } + + } + } + + public int Count + { + get + { + return owner.ItemCount; + } + } + + object ICollection.SyncRoot + { + get + { + return this; + } + } + + bool ICollection.IsSynchronized + { + get + { + return false; + } + } + + bool IList.IsFixedSize + { + get + { + return false; + } + } + + public bool IsReadOnly + { + get + { + return false; + } + } + + /// + /// Adds a new MenuItem to the end of this menu with the specified caption. + /// + public virtual MenuItem Add(string caption) + { + MenuItem item = new MenuItem(caption); + Add(item); + return item; + } + + /// + /// Adds a new MenuItem to the end of this menu with the specified caption, + /// and click handler. + /// + public virtual MenuItem Add(string caption, EventHandler onClick) + { + MenuItem item = new MenuItem(caption, onClick); + Add(item); + return item; + } + + /// + /// Adds a new MenuItem to the end of this menu with the specified caption, + /// click handler, and items. + /// + public virtual MenuItem Add(string caption, MenuItem[] items) + { + MenuItem item = new MenuItem(caption, items); + Add(item); + return item; + } + + /// + /// Adds a MenuItem to the end of this menu + /// MenuItems can only be contained in one menu at a time, and may not be added + /// more than once to the same menu. + /// + public virtual int Add(MenuItem item) + { + return Add(owner.ItemCount, item); + } + + /// + /// Adds a MenuItem to this menu at the specified index. The item currently at + /// that index, and all items after it, will be moved up one slot. + /// MenuItems can only be contained in one menu at a time, and may not be added + /// more than once to the same menu. + /// + public virtual int Add(int index, MenuItem item) + { + if (item == null) + { + throw new ArgumentNullException(nameof(item)); + } + + // MenuItems can only belong to one menu at a time + if (item.Parent != null) + { + + // First check that we're not adding ourself, i.e. walk + // the parent chain for equality + if (owner is MenuItem parent) + { + while (parent != null) + { + if (parent.Equals(item)) + { + throw new ArgumentException(string.Format(SR.MenuItemAlreadyExists, item.Text), "item"); + } + + if (parent.Parent is MenuItem) + { + parent = (MenuItem)parent.Parent; + } + else + { + break; + } + } + } + + //if we're re-adding an item back to the same collection + //the target index needs to be decremented since we're + //removing an item from the collection + if (item.Parent.Equals(owner) && index > 0) + { + index--; + } + + item.Parent.MenuItems.Remove(item); + } + + // Validate our index + if (index < 0 || index > owner.ItemCount) + { + throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(SR.InvalidArgument, nameof(index), index)); + } + + if (owner.items == null || owner.items.Length == owner.ItemCount) + { + MenuItem[] newItems = new MenuItem[owner.ItemCount < 2 ? 4 : owner.ItemCount * 2]; + if (owner.ItemCount > 0) + { + System.Array.Copy(owner.items, 0, newItems, 0, owner.ItemCount); + } + + owner.items = newItems; + } + + System.Array.Copy(owner.items, index, owner.items, index + 1, owner.ItemCount - index); + owner.items[index] = item; + owner._itemCount++; + item.Parent = owner; + owner.ItemsChanged(CHANGE_ITEMS); + if (owner is MenuItem) + { + ((MenuItem)owner).ItemsChanged(CHANGE_ITEMADDED, item); + } + + return index; + } + + public virtual void AddRange(MenuItem[] items) + { + if (items == null) + { + throw new ArgumentNullException(nameof(items)); + } + + foreach (MenuItem item in items) + { + Add(item); + } + } + + int IList.Add(object value) + { + if (value is MenuItem) + { + return Add((MenuItem)value); + } + else + { + throw new ArgumentException(SR.MenuBadMenuItem, "value"); + } + } + + public bool Contains(MenuItem value) + { + return IndexOf(value) != -1; + } + + bool IList.Contains(object value) + { + if (value is MenuItem) + { + return Contains((MenuItem)value); + } + else + { + return false; + } + } + + /// + /// Returns true if the collection contains an item with the specified key, false otherwise. + /// + public virtual bool ContainsKey(string key) + { + return IsValidIndex(IndexOfKey(key)); + } + + /// + /// Searches for Controls by their Name property, builds up an array + /// of all the controls that match. + /// + public MenuItem[] Find(string key, bool searchAllChildren) + { + + if ((key == null) || (key.Length == 0)) + { + throw new ArgumentNullException(nameof(key), SR.FindKeyMayNotBeEmptyOrNull); + } + + ArrayList foundMenuItems = FindInternal(key, searchAllChildren, this, new ArrayList()); + + // Make this a stongly typed collection. + MenuItem[] stronglyTypedfoundMenuItems = new MenuItem[foundMenuItems.Count]; + foundMenuItems.CopyTo(stronglyTypedfoundMenuItems, 0); + + return stronglyTypedfoundMenuItems; + } + + /// + /// Searches for Controls by their Name property, builds up an array list + /// of all the controls that match. + /// + private ArrayList FindInternal(string key, bool searchAllChildren, MenuItemCollection menuItemsToLookIn, ArrayList foundMenuItems) + { + if ((menuItemsToLookIn == null) || (foundMenuItems == null)) + { + return null; // + } + + // Perform breadth first search - as it's likely people will want controls belonging + // to the same parent close to each other. + + for (int i = 0; i < menuItemsToLookIn.Count; i++) + { + if (menuItemsToLookIn[i] == null) + { + continue; + } + + if (WindowsFormsUtils.SafeCompareStrings(menuItemsToLookIn[i].Name, key, /* ignoreCase = */ true)) + { + foundMenuItems.Add(menuItemsToLookIn[i]); + } + } + + // Optional recurive search for controls in child collections. + + if (searchAllChildren) + { + for (int i = 0; i < menuItemsToLookIn.Count; i++) + { + if (menuItemsToLookIn[i] == null) + { + continue; + } + + if ((menuItemsToLookIn[i].MenuItems != null) && menuItemsToLookIn[i].MenuItems.Count > 0) + { + // if it has a valid child collecion, append those results to our collection + foundMenuItems = FindInternal(key, searchAllChildren, menuItemsToLookIn[i].MenuItems, foundMenuItems); + } + } + } + + return foundMenuItems; + } + + public int IndexOf(MenuItem value) + { + for (int index = 0; index < Count; ++index) + { + if (this[index] == value) + { + return index; + } + } + + return -1; + } + + int IList.IndexOf(object value) + { + if (value is MenuItem) + { + return IndexOf((MenuItem)value); + } + else + { + return -1; + } + } + + /// + /// The zero-based index of the first occurrence of value within the entire CollectionBase, if found; otherwise, -1. + /// + public virtual int IndexOfKey(string key) + { + // Step 0 - Arg validation + if (string.IsNullOrEmpty(key)) + { + return -1; // we dont support empty or null keys. + } + + // step 1 - check the last cached item + if (IsValidIndex(lastAccessedIndex)) + { + if (WindowsFormsUtils.SafeCompareStrings(this[lastAccessedIndex].Name, key, /* ignoreCase = */ true)) + { + return lastAccessedIndex; + } + } + + // step 2 - search for the item + for (int i = 0; i < Count; i++) + { + if (WindowsFormsUtils.SafeCompareStrings(this[i].Name, key, /* ignoreCase = */ true)) + { + lastAccessedIndex = i; + return i; + } + } + + // step 3 - we didn't find it. Invalidate the last accessed index and return -1. + lastAccessedIndex = -1; + return -1; + } + + void IList.Insert(int index, object value) + { + if (value is MenuItem) + { + Add(index, (MenuItem)value); + } + else + { + throw new ArgumentException(SR.MenuBadMenuItem, "value"); + } + } + + /// + /// Determines if the index is valid for the collection. + /// + private bool IsValidIndex(int index) + { + return ((index >= 0) && (index < Count)); + } + + /// + /// Removes all existing MenuItems from this menu + /// + public virtual void Clear() + { + if (owner.ItemCount > 0) + { + + for (int i = 0; i < owner.ItemCount; i++) + { + owner.items[i].Parent = null; + } + + owner._itemCount = 0; + owner.items = null; + + owner.ItemsChanged(CHANGE_ITEMS); + + if (owner is MenuItem) + { + ((MenuItem)(owner)).UpdateMenuItem(true); + } + } + } + + public void CopyTo(Array dest, int index) + { + if (owner.ItemCount > 0) + { + System.Array.Copy(owner.items, 0, dest, index, owner.ItemCount); + } + } + + public IEnumerator GetEnumerator() + { + return new WindowsFormsUtils.ArraySubsetEnumerator(owner.items, owner.ItemCount); + } + + /// + /// Removes the item at the specified index in this menu. All subsequent + /// items are moved up one slot. + /// + public virtual void RemoveAt(int index) + { + if (index < 0 || index >= owner.ItemCount) + { + throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(SR.InvalidArgument, nameof(index), index)); + } + + MenuItem item = owner.items[index]; + item.Parent = null; + owner._itemCount--; + System.Array.Copy(owner.items, index + 1, owner.items, index, owner.ItemCount - index); + owner.items[owner.ItemCount] = null; + owner.ItemsChanged(CHANGE_ITEMS); + + //if the last item was removed, clear the collection + // + if (owner.ItemCount == 0) + { + Clear(); + } + + } + + /// + /// Removes the menu iteml with the specified key. + /// + public virtual void RemoveByKey(string key) + { + int index = IndexOfKey(key); + if (IsValidIndex(index)) + { + RemoveAt(index); + } + } + + /// + /// Removes the specified item from this menu. All subsequent + /// items are moved down one slot. + /// + public virtual void Remove(MenuItem item) + { + if (item.Parent == owner) + { + RemoveAt(item.Index); + } + } + + void IList.Remove(object value) + { + if (value is MenuItem) + { + Remove((MenuItem)value); + } + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MenuItem.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MenuItem.cs new file mode 100644 index 00000000000..e68b979a307 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/MenuItem.cs @@ -0,0 +1,1802 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.Runtime.InteropServices; +using static Interop; + +namespace System.Windows.Forms +{ + /// + /// Represents an individual item that is displayed within a + /// or . + /// + [ToolboxItem(false)] + [DesignTimeVisible(false)] + [DefaultEvent(nameof(Click))] + [DefaultProperty(nameof(Text))] + public class MenuItem : Menu + { + private const int StateBarBreak = 0x00000020; + private const int StateBreak = 0x00000040; + private const int StateChecked = 0x00000008; + private const int StateDefault = 0x00001000; + private const int StateDisabled = 0x00000003; + private const int StateRadioCheck = 0x00000200; + private const int StateHidden = 0x00010000; + private const int StateMdiList = 0x00020000; + private const int StateCloneMask = 0x0003136B; + private const int StateOwnerDraw = 0x00000100; + private const int StateInMdiPopup = 0x00000200; + private const int StateHiLite = 0x00000080; + + private bool _hasHandle; + private MenuItemData _data; + private int _dataVersion; + private MenuItem _nextLinkedItem; // Next item linked to the same MenuItemData. + + // We need to store a table of all created menuitems, so that other objects + // such as ContainerControl can get a reference to a particular menuitem, + // given a unique ID. + private static readonly Hashtable s_allCreatedMenuItems = new Hashtable(); + private const uint FirstUniqueID = 0xC0000000; + private static long s_nextUniqueID = FirstUniqueID; + private uint _uniqueID = 0; + private IntPtr _msaaMenuInfoPtr = IntPtr.Zero; + private bool _menuItemIsCreated = false; + +#if DEBUG + private string _debugText; + private readonly int _creationNumber; + private static int CreateCount; +#endif + + /// + /// Initializes a with a blank caption. + /// + public MenuItem() : this(MenuMerge.Add, 0, 0, null, null, null, null, null) + { + } + + /// + /// Initializes a new instance of the class + /// with a specified caption for the menu item. + /// + public MenuItem(string text) : this(MenuMerge.Add, 0, 0, text, null, null, null, null) + { + } + + /// + /// Initializes a new instance of the class with a specified caption and event handler + /// for the menu item. + /// + public MenuItem(string text, EventHandler onClick) : this(MenuMerge.Add, 0, 0, text, onClick, null, null, null) + { + } + + /// + /// Initializes a new instance of the class with a specified caption, event handler, + /// and associated shorcut key for the menu item. + /// + public MenuItem(string text, EventHandler onClick, Shortcut shortcut) : this(MenuMerge.Add, 0, shortcut, text, onClick, null, null, null) + { + } + + /// + /// Initializes a new instance of the class with a specified caption and an array of + /// submenu items defined for the menu item. + /// + public MenuItem(string text, MenuItem[] items) : this(MenuMerge.Add, 0, 0, text, null, null, null, items) + { + } + + internal MenuItem(MenuItemData data) : base(null) + { + data.AddItem(this); + +#if DEBUG + _debugText = data._caption; +#endif + } + + /// + /// Initializes a new instance of the class with a specified caption, defined + /// event-handlers for the Click, Select and Popup events, a shortcut key, + /// a merge type, and order specified for the menu item. + /// + public MenuItem(MenuMerge mergeType, int mergeOrder, Shortcut shortcut, + string text, EventHandler onClick, EventHandler onPopup, + EventHandler onSelect, MenuItem[] items) : base(items) + { + new MenuItemData(this, mergeType, mergeOrder, shortcut, true, + text, onClick, onPopup, onSelect, null, null); + +#if DEBUG + _debugText = text; + _creationNumber = CreateCount++; +#endif + } + + internal unsafe void WmDrawItem(ref Message m) + { + // Handles the OnDrawItem message sent from ContainerControl + User32.DRAWITEMSTRUCT* dis = (User32.DRAWITEMSTRUCT*)m.LParam; + Debug.WriteLineIf(Control.s_paletteTracing.TraceVerbose, Handle + ": Force set palette in MenuItem drawitem"); + IntPtr oldPal = Control.SetUpPalette(dis->hDC, force: false, realizePalette: false); + try + { + Graphics g = Graphics.FromHdcInternal(dis->hDC); + OnDrawItem(new DrawItemEventArgs(g, SystemInformation.MenuFont, dis->rcItem, Index, (DrawItemState)dis->itemState)); + } + finally + { + if (oldPal != IntPtr.Zero) + { + Gdi32.SelectPalette(dis->hDC, oldPal, BOOL.FALSE); + } + } + + m.Result = (IntPtr)1; + } + + /// + /// Gets or sets a value indicating whether the item is placed on a new line (for a + /// menu item added to a object) or in a + /// new column (for a submenu or menu displayed in a ). + /// + [Browsable(false)] + [DefaultValue(false)] + public bool BarBreak + { + get + { + CheckIfDisposed(); + return (_data.State & StateBarBreak) != 0; + } + set + { + CheckIfDisposed(); + _data.SetState(StateBarBreak, value); + } + } + + /// + /// Gets or sets a value indicating whether the item is placed on a new line (for a + /// menu item added to a object) or in a + /// new column (for a submenu or menu displayed in a ). + /// + [Browsable(false)] + [DefaultValue(false)] + public bool Break + { + get + { + CheckIfDisposed(); + return (_data.State & StateBreak) != 0; + } + set + { + CheckIfDisposed(); + _data.SetState(StateBreak, value); + } + } + + /// + /// Gets or sets a value indicating whether a checkmark appears beside the text of + /// the menu item. + /// + [DefaultValue(false)] + [SRDescription(nameof(SR.MenuItemCheckedDescr))] + public bool Checked + { + get + { + CheckIfDisposed(); + return (_data.State & StateChecked) != 0; + } + set + { + CheckIfDisposed(); + + if (value && (ItemCount != 0 || Parent is MainMenu)) + { + throw new ArgumentException(SR.MenuItemInvalidCheckProperty, nameof(value)); + } + + _data.SetState(StateChecked, value); + } + } + + /// + /// Gets or sets a value indicating whether the menu item is the default. + /// + [DefaultValue(false)] + [SRDescription(nameof(SR.MenuItemDefaultDescr))] + public bool DefaultItem + { + get + { + CheckIfDisposed(); + return (_data.State & StateDefault) != 0; + } + set + { + CheckIfDisposed(); + if (Parent != null) + { + if (value) + { + User32.SetMenuDefaultItem(new HandleRef(Parent, Parent.handle), MenuID, BOOL.FALSE); + } + else if (DefaultItem) + { + User32.SetMenuDefaultItem(new HandleRef(Parent, Parent.handle), -1, BOOL.FALSE); + } + } + + _data.SetState(StateDefault, value); + } + } + + /// + /// Gets or sets a value indicating whether code that you provide draws the menu + /// item or Windows draws the menu item. + /// + [SRCategory(nameof(SR.CatBehavior))] + [DefaultValue(false)] + [SRDescription(nameof(SR.MenuItemOwnerDrawDescr))] + public bool OwnerDraw + { + get + { + CheckIfDisposed(); + return ((_data.State & StateOwnerDraw) != 0); + } + set + { + CheckIfDisposed(); + _data.SetState(StateOwnerDraw, value); + } + } + + /// + /// Gets or sets a value indicating whether the menu item is enabled. + /// + [Localizable(true)] + [DefaultValue(true)] + [SRDescription(nameof(SR.MenuItemEnabledDescr))] + public bool Enabled + { + get + { + CheckIfDisposed(); + return (_data.State & StateDisabled) == 0; + } + set + { + CheckIfDisposed(); + _data.SetState(StateDisabled, !value); + } + } + + /// + /// Gets or sets the menu item's position in its parent menu. + /// + [Browsable(false)] + public int Index + { + get + { + if (Parent != null) + { + for (int i = 0; i < Parent.ItemCount; i++) + { + if (Parent.items[i] == this) + { + return i; + } + } + } + + return -1; + } + set + { + int oldIndex = Index; + if (oldIndex >= 0) + { + if (value < 0 || value >= Parent.ItemCount) + { + throw new ArgumentOutOfRangeException(nameof(value), string.Format(SR.InvalidArgument, nameof(Index), value)); + } + + if (value != oldIndex) + { + // The menu reverts to null when we're removed, so hold onto it in a + // local variable + Menu parent = Parent; + parent.MenuItems.RemoveAt(oldIndex); + parent.MenuItems.Add(value, this); + } + } + } + } + + /// + /// Gets a value indicating whether the menu item contains child menu items. + /// + [Browsable(false)] + public override bool IsParent + { + get + { + if (_data != null && MdiList) + { + for (int i = 0; i < ItemCount; i++) + { + if (!(items[i]._data.UserData is MdiListUserData)) + { + return true; + } + } + + if (FindMdiForms().Length > 0) + { + return true; + } + + if (Parent != null && !(Parent is MenuItem)) + { + return true; + } + + return false; + } + + return base.IsParent; + } + } + + /// + /// Gets or sets a value indicating whether the menu item will be populated with a + /// list of the MDI child windows that are displayed within the associated form. + /// + [DefaultValue(false)] + [SRDescription(nameof(SR.MenuItemMDIListDescr))] + public bool MdiList + { + get + { + CheckIfDisposed(); + return (_data.State & StateMdiList) != 0; + } + set + { + CheckIfDisposed(); + _data.MdiList = value; + CleanListItems(this); + } + } + + /// + /// Gets the Windows identifier for this menu item. + /// + protected int MenuID + { + get + { + CheckIfDisposed(); + return _data.GetMenuID(); + } + } + + /// + /// Is this menu item currently selected (highlighted) by the user? + /// + internal bool Selected + { + get + { + if (Parent == null) + { + return false; + } + + var info = new NativeMethods.MENUITEMINFO_T + { + cbSize = Marshal.SizeOf(), + fMask = NativeMethods.MIIM_STATE + }; + UnsafeNativeMethods.GetMenuItemInfo(new HandleRef(Parent, Parent.handle), MenuID, false, info); + + return (info.fState & StateHiLite) != 0; + } + } + + /// + /// Gets the zero-based index of this menu item in the parent menu, or -1 if this + /// menu item is not associated with a parent menu. + /// + internal int MenuIndex + { + get + { + if (Parent == null) + { + return -1; + } + + int count = User32.GetMenuItemCount(new HandleRef(Parent, Parent.Handle)); + int id = MenuID; + NativeMethods.MENUITEMINFO_T info = new NativeMethods.MENUITEMINFO_T + { + cbSize = Marshal.SizeOf(), + fMask = NativeMethods.MIIM_ID | NativeMethods.MIIM_SUBMENU + }; + + for (int i = 0; i < count; i++) + { + UnsafeNativeMethods.GetMenuItemInfo(new HandleRef(Parent, Parent.handle), i, true, info); + + // For sub menus, the handle is always valid. + // For items, however, it is always zero. + if ((info.hSubMenu == IntPtr.Zero || info.hSubMenu == Handle) && info.wID == id) + { + return i; + } + } + + return -1; + } + } + + /// + /// Gets or sets a value that indicates the behavior of this + /// menu item when its menu is merged with another. + /// + [DefaultValue(MenuMerge.Add)] + [SRDescription(nameof(SR.MenuItemMergeTypeDescr))] + public MenuMerge MergeType + { + get + { + CheckIfDisposed(); + return _data._mergeType; + } + set + { + CheckIfDisposed(); + if (!ClientUtils.IsEnumValid(value, (int)value, (int)MenuMerge.Add, (int)MenuMerge.Remove)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(MenuMerge)); + } + + _data.MergeType = value; + } + } + + /// + /// Gets or sets the relative position the menu item when its + /// menu is merged with another. + /// + [DefaultValue(0)] + [SRDescription(nameof(SR.MenuItemMergeOrderDescr))] + public int MergeOrder + { + get + { + CheckIfDisposed(); + return _data._mergeOrder; + } + set + { + CheckIfDisposed(); + _data.MergeOrder = value; + } + } + + /// + /// Retrieves the hotkey mnemonic that is associated with this menu item. + /// The mnemonic is the first character after an ampersand symbol in the menu's text + /// that is not itself an ampersand symbol. If no such mnemonic is defined this + /// will return zero. + /// + [Browsable(false)] + public char Mnemonic + { + get + { + CheckIfDisposed(); + return _data.Mnemonic; + } + } + + /// + /// Gets the menu in which this menu item appears. + /// + [Browsable(false)] + public Menu Parent { get; internal set; } + + /// + /// Gets or sets a value that indicates whether the menu item, if checked, + /// displays a radio-button mark instead of a check mark. + /// + [DefaultValue(false)] + [SRDescription(nameof(SR.MenuItemRadioCheckDescr))] + public bool RadioCheck + { + get + { + CheckIfDisposed(); + return (_data.State & StateRadioCheck) != 0; + } + set + { + CheckIfDisposed(); + _data.SetState(StateRadioCheck, value); + } + } + + internal override bool RenderIsRightToLeft => Parent != null && Parent.RenderIsRightToLeft; + + /// + /// Gets or sets the text of the menu item. + /// + [Localizable(true)] + [SRDescription(nameof(SR.MenuItemTextDescr))] + public string Text + { + get + { + CheckIfDisposed(); + return _data._caption; + } + set + { + CheckIfDisposed(); + _data.SetCaption(value); + } + } + + /// + /// Gets or sets the shortcut key associated with the menu item. + /// + [Localizable(true)] + [DefaultValue(Shortcut.None)] + [SRDescription(nameof(SR.MenuItemShortCutDescr))] + public Shortcut Shortcut + { + get + { + CheckIfDisposed(); + return _data._shortcut; + } + set + { + CheckIfDisposed(); + if (!Enum.IsDefined(typeof(Shortcut), value)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(Shortcut)); + } + + _data._shortcut = value; + UpdateMenuItem(force: true); + } + } + + /// + /// Gets or sets a value that indicates whether the shortcut key that is associated + /// with the menu item is displayed next to the menu item caption. + /// + [DefaultValue(true), + Localizable(true)] + [SRDescription(nameof(SR.MenuItemShowShortCutDescr))] + public bool ShowShortcut + { + get + { + CheckIfDisposed(); + return _data._showShortcut; + } + set + { + CheckIfDisposed(); + if (value != _data._showShortcut) + { + _data._showShortcut = value; + UpdateMenuItem(force: true); + } + } + } + + /// + /// Gets or sets a value that indicates whether the menu item is visible on its + /// parent menu. + /// + [Localizable(true)] + [DefaultValue(true)] + [SRDescription(nameof(SR.MenuItemVisibleDescr))] + public bool Visible + { + get + { + CheckIfDisposed(); + return (_data.State & StateHidden) == 0; + } + set + { + CheckIfDisposed(); + _data.Visible = value; + } + } + + /// + /// Occurs when the menu item is clicked or selected using a shortcut key defined + /// for the menu item. + /// + [SRDescription(nameof(SR.MenuItemOnClickDescr))] + public event EventHandler Click + { + add + { + CheckIfDisposed(); + _data._onClick += value; + } + remove + { + CheckIfDisposed(); + _data._onClick -= value; + } + } + + /// + /// Occurs when when the property of a menu item is set to and + /// a request is made to draw the menu item. + /// + [SRCategory(nameof(SR.CatBehavior)), SRDescription(nameof(SR.drawItemEventDescr))] + public event DrawItemEventHandler DrawItem + { + add + { + CheckIfDisposed(); + _data._onDrawItem += value; + } + remove + { + CheckIfDisposed(); + _data._onDrawItem -= value; + } + } + + /// + /// Occurs when when the menu needs to know the size of a menu item before drawing it. + /// + [SRCategory(nameof(SR.CatBehavior)), SRDescription(nameof(SR.measureItemEventDescr))] + public event MeasureItemEventHandler MeasureItem + { + add + { + CheckIfDisposed(); + _data._onMeasureItem += value; + } + remove + { + CheckIfDisposed(); + _data._onMeasureItem -= value; + } + } + + /// + /// Occurs before a menu item's list of menu items is displayed. + /// + [SRDescription(nameof(SR.MenuItemOnInitDescr))] + public event EventHandler Popup + { + add + { + CheckIfDisposed(); + _data._onPopup += value; + } + remove + { + CheckIfDisposed(); + _data._onPopup -= value; + } + } + + /// + /// Occurs when the user hovers their mouse over a menu item or selects it with the + /// keyboard but has not activated it. + /// + [SRDescription(nameof(SR.MenuItemOnSelectDescr))] + public event EventHandler Select + { + add + { + CheckIfDisposed(); + _data._onSelect += value; + } + remove + { + CheckIfDisposed(); + _data._onSelect -= value; + } + } + + private static void CleanListItems(MenuItem senderMenu) + { + // Remove dynamic items. + for (int i = senderMenu.MenuItems.Count - 1; i >= 0; i--) + { + MenuItem item = senderMenu.MenuItems[i]; + if (item._data.UserData is MdiListUserData) + { + item.Dispose(); + continue; + } + } + } + + /// + /// Creates and returns an identical copy of this menu item. + /// + public virtual MenuItem CloneMenu() + { + var newItem = new MenuItem(); + newItem.CloneMenu(this); + return newItem; + } + + /// + /// Creates a copy of the specified menu item. + /// + protected void CloneMenu(MenuItem itemSrc) + { + base.CloneMenu(itemSrc); + int state = itemSrc._data.State; + new MenuItemData(this, + itemSrc.MergeType, itemSrc.MergeOrder, itemSrc.Shortcut, itemSrc.ShowShortcut, + itemSrc.Text, itemSrc._data._onClick, itemSrc._data._onPopup, itemSrc._data._onSelect, + itemSrc._data._onDrawItem, itemSrc._data._onMeasureItem); + _data.SetState(state & StateCloneMask, true); + } + + internal virtual void CreateMenuItem() + { + if ((_data.State & StateHidden) == 0) + { + NativeMethods.MENUITEMINFO_T info = CreateMenuItemInfo(); + UnsafeNativeMethods.InsertMenuItem(new HandleRef(Parent, Parent.handle), -1, true, info); + + _hasHandle = info.hSubMenu != IntPtr.Zero; + _dataVersion = _data._version; + + _menuItemIsCreated = true; + if (RenderIsRightToLeft) + { + Parent.UpdateRtl(true); + } + +#if DEBUG + NativeMethods.MENUITEMINFO_T infoVerify = new NativeMethods.MENUITEMINFO_T + { + cbSize = Marshal.SizeOf(), + fMask = NativeMethods.MIIM_ID | NativeMethods.MIIM_STATE | + NativeMethods.MIIM_SUBMENU | NativeMethods.MIIM_TYPE + }; + UnsafeNativeMethods.GetMenuItemInfo(new HandleRef(Parent, Parent.handle), MenuID, false, infoVerify); +#endif + } + } + + private NativeMethods.MENUITEMINFO_T CreateMenuItemInfo() + { + var info = new NativeMethods.MENUITEMINFO_T + { + fMask = NativeMethods.MIIM_ID | NativeMethods.MIIM_STATE | + NativeMethods.MIIM_SUBMENU | NativeMethods.MIIM_TYPE | NativeMethods.MIIM_DATA, + fType = _data.State & (StateBarBreak | StateBreak | StateRadioCheck | StateOwnerDraw) + }; + + // Top level menu items shouldn't have barbreak or break bits set on them. + bool isTopLevel = Parent == GetMainMenu(); + + if (_data._caption.Equals("-")) + { + if (isTopLevel) + { + _data._caption = " "; + info.fType |= NativeMethods.MFT_MENUBREAK; + } + else + { + info.fType |= NativeMethods.MFT_SEPARATOR; + } + } + + info.fState = _data.State & (StateChecked | StateDefault | StateDisabled); + + info.wID = MenuID; + if (IsParent) + { + info.hSubMenu = Handle; + } + + info.hbmpChecked = IntPtr.Zero; + info.hbmpUnchecked = IntPtr.Zero; + + // Assign a unique ID to this menu item object. + // The ID is stored in the dwItemData of the corresponding Win32 menu item, so + // that when we get Win32 messages about the item later, we can delegate to the + // original object menu item object. A static hash table is used to map IDs to + // menu item objects. + if (_uniqueID == 0) + { + lock (s_allCreatedMenuItems) + { + _uniqueID = (uint)Interlocked.Increment(ref s_nextUniqueID); + Debug.Assert(_uniqueID >= FirstUniqueID); // ...check for ID range exhaustion (unlikely!) + // We add a weak ref wrapping a MenuItem to the static hash table, as + // supposed to adding the item ref itself, to allow the item to be finalized + // in case it is not disposed and no longer referenced anywhere else, hence + // preventing leaks. + s_allCreatedMenuItems.Add(_uniqueID, new WeakReference(this)); + } + } + + if (IntPtr.Size == 4) + { + // Store the unique ID in the dwItemData.. + // For simple menu items, we can just put the unique ID in the dwItemData. + // But for owner-draw items, we need to point the dwItemData at an MSAAMENUINFO + // structure so that MSAA can get the item text. + // To allow us to reliably distinguish between IDs and structure pointers later + // on, we keep IDs in the 0xC0000000-0xFFFFFFFF range. This is the top 1Gb of + // unmananged process memory, where an app's heap allocations should never come + // from. So that we can still get the ID from the dwItemData for an owner-draw + // item later on, a copy of the ID is tacked onto the end of the MSAAMENUINFO + // structure. + if (_data.OwnerDraw) + { + info.dwItemData = AllocMsaaMenuInfo(); + } + else + { + info.dwItemData = (IntPtr)unchecked((int)_uniqueID); + } + } + else + { + // On Win64, there are no reserved address ranges we can use for menu item IDs. So instead we will + // have to allocate an MSAMENUINFO heap structure for all menu items, not just owner-drawn ones. + info.dwItemData = AllocMsaaMenuInfo(); + } + + // We won't render the shortcut if: 1) it's not set, 2) we're a parent, 3) we're toplevel + if (_data._showShortcut && _data._shortcut != 0 && !IsParent && !isTopLevel) + { + info.dwTypeData = _data._caption + "\t" + TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString((Keys)(int)_data._shortcut); + } + else + { + // Windows issue: Items with empty captions sometimes block keyboard + // access to other items in same menu. + info.dwTypeData = (_data._caption.Length == 0 ? " " : _data._caption); + } + + info.cch = 0; + + return info; + } + + /// + /// Disposes the . + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + Parent?.MenuItems.Remove(this); + _data?.RemoveItem(this); + lock (s_allCreatedMenuItems) + { + s_allCreatedMenuItems.Remove(_uniqueID); + } + + _uniqueID = 0; + + } + + FreeMsaaMenuInfo(); + base.Dispose(disposing); + } + + /// + /// Given a unique menu item ID, find the corresponding MenuItem + /// object, using the master lookup table of all created MenuItems. + /// + internal static MenuItem GetMenuItemFromUniqueID(uint uniqueID) + { + WeakReference weakRef = (WeakReference)s_allCreatedMenuItems[uniqueID]; + if (weakRef != null && weakRef.IsAlive) + { + return (MenuItem)weakRef.Target; + } + + Debug.Fail("Weakref for menu item has expired or has been removed! Who is trying to access this ID?"); + return null; + } + + /// + /// Given the "item data" value of a Win32 menu item, find the corresponding MenuItem object (using + /// the master lookup table of all created MenuItems). The item data may be either the unique menu + /// item ID, or a pointer to an MSAAMENUINFO structure with a copy of the unique ID tacked to the end. + /// To reliably tell IDs and structure addresses apart, IDs live in the 0xC0000000-0xFFFFFFFF range. + /// This is the top 1Gb of unmananged process memory, where an app's heap allocations should never be. + /// + internal static MenuItem GetMenuItemFromItemData(IntPtr itemData) + { + uint uniqueID = (uint)(ulong)itemData; + if (uniqueID == 0) + { + return null; + } + + if (IntPtr.Size == 4) + { + if (uniqueID < FirstUniqueID) + { + MsaaMenuInfoWithId msaaMenuInfo = Marshal.PtrToStructure(itemData); + uniqueID = msaaMenuInfo._uniqueID; + } + } + else + { + // Its always a pointer on Win64 (see CreateMenuItemInfo) + MsaaMenuInfoWithId msaaMenuInfo = Marshal.PtrToStructure(itemData); + uniqueID = msaaMenuInfo._uniqueID; + } + + return GetMenuItemFromUniqueID(uniqueID); + } + + /// + /// MsaaMenuInfoWithId is an MSAAMENUINFO structure with a menu item ID field tacked onto the + /// end. This allows us to pass the data we need to Win32 / MSAA, and still be able to get the ID + /// out again later on, so we can delegate Win32 menu messages back to the correct MenuItem object. + /// + [StructLayout(LayoutKind.Sequential)] + private struct MsaaMenuInfoWithId + { + public readonly NativeMethods.MSAAMENUINFO _msaaMenuInfo; + public readonly uint _uniqueID; + + public MsaaMenuInfoWithId(string text, uint uniqueID) + { + _msaaMenuInfo = new NativeMethods.MSAAMENUINFO(text); + _uniqueID = uniqueID; + } + } + + /// + /// Creates an MSAAMENUINFO structure (in the unmanaged heap) based on the current state + /// of this MenuItem object. Address of this structure is cached in the object so we can + /// free it later on using FreeMsaaMenuInfo(). If structure has already been allocated, + /// it is destroyed and a new one created. + /// + private IntPtr AllocMsaaMenuInfo() + { + FreeMsaaMenuInfo(); + _msaaMenuInfoPtr = Marshal.AllocHGlobal(Marshal.SizeOf()); + + if (IntPtr.Size == 4) + { + // We only check this on Win32, irrelevant on Win64 (see CreateMenuItemInfo) + // Check for incursion into menu item ID range (unlikely!) + Debug.Assert(((uint)(ulong)_msaaMenuInfoPtr) < FirstUniqueID); + } + + MsaaMenuInfoWithId msaaMenuInfoStruct = new MsaaMenuInfoWithId(_data._caption, _uniqueID); + Marshal.StructureToPtr(msaaMenuInfoStruct, _msaaMenuInfoPtr, false); + Debug.Assert(_msaaMenuInfoPtr != IntPtr.Zero); + return _msaaMenuInfoPtr; + } + + /// + /// Frees the MSAAMENUINFO structure (in the unmanaged heap) for the current MenuObject + /// object, if one has previously been allocated. Takes care to free sub-structures too, + /// to avoid leaks! + /// + private void FreeMsaaMenuInfo() + { + if (_msaaMenuInfoPtr != IntPtr.Zero) + { + Marshal.DestroyStructure(_msaaMenuInfoPtr, typeof(MsaaMenuInfoWithId)); + Marshal.FreeHGlobal(_msaaMenuInfoPtr); + _msaaMenuInfoPtr = IntPtr.Zero; + } + } + + internal override void ItemsChanged(int change) + { + base.ItemsChanged(change); + + if (change == CHANGE_ITEMS) + { + // when the menu collection changes deal with it locally + Debug.Assert(!created, "base.ItemsChanged should have wiped out our handles"); + if (Parent != null && Parent.created) + { + UpdateMenuItem(force: true); + CreateMenuItems(); + } + } + else + { + if (!_hasHandle && IsParent) + { + UpdateMenuItem(force: true); + } + + MainMenu main = GetMainMenu(); + if (main != null && ((_data.State & StateInMdiPopup) == 0)) + { + main.ItemsChanged(change, this); + } + } + } + + internal void ItemsChanged(int change, MenuItem item) + { + if (change == CHANGE_ITEMADDED && + _data != null && + _data.baseItem != null && + _data.baseItem.MenuItems.Contains(item)) + { + if (Parent != null && Parent.created) + { + UpdateMenuItem(force: true); + CreateMenuItems(); + } + else if (_data != null) + { + MenuItem currentMenuItem = _data.firstItem; + while (currentMenuItem != null) + { + if (currentMenuItem.created) + { + MenuItem newItem = item.CloneMenu(); + item._data.AddItem(newItem); + currentMenuItem.MenuItems.Add(newItem); + break; + } + + currentMenuItem = currentMenuItem._nextLinkedItem; + } + } + } + } + + internal Form[] FindMdiForms() + { + Form[] forms = null; + MainMenu main = GetMainMenu(); + Form menuForm = null; + if (main != null) + { + menuForm = main.GetForm(); + } + + if (menuForm != null) + { + forms = menuForm.MdiChildren; + } + + if (forms == null) + { + forms = Array.Empty(); + } + + return forms; + } + + /// + /// See the similar code in MdiWindowListStrip.PopulateItems, which is + /// unfortunately just different enough in its working environment that we + /// can't readily combine the two. But if you're fixing something here, chances + /// are that the same issue will need scrutiny over there. + /// +// "-" is OK + private void PopulateMdiList() + { + MenuItem senderMenu = this; + _data.SetState(StateInMdiPopup, true); + try + { + CleanListItems(this); + + // Add new items + Form[] forms = FindMdiForms(); + if (forms != null && forms.Length > 0) + { + + Form activeMdiChild = GetMainMenu().GetForm().ActiveMdiChild; + + if (senderMenu.MenuItems.Count > 0) + { + MenuItem sep = (MenuItem)Activator.CreateInstance(GetType()); + sep._data.UserData = new MdiListUserData(); + sep.Text = "-"; + senderMenu.MenuItems.Add(sep); + } + + // Build a list of child windows to be displayed in + // the MDIList menu item... + // Show the first maxMenuForms visible elements of forms[] as Window menu items, except: + // Always show the active form, even if it's not in the first maxMenuForms visible elements of forms[]. + // If the active form isn't in the first maxMenuForms forms, then show the first maxMenuForms-1 elements + // in forms[], and make the active form the last one on the menu. + // Don't count nonvisible forms against the limit on Window menu items. + + const int MaxMenuForms = 9; // Max number of Window menu items for forms + int visibleChildren = 0; // the number of visible child forms (so we know to show More Windows...) + int accel = 1; // prefix the form name with this digit, underlined, as an accelerator + int formsAddedToMenu = 0; + bool activeFormAdded = false; + for (int i = 0; i < forms.Length; i++) + { + if (forms[i].Visible) + { + visibleChildren++; + if ((activeFormAdded && (formsAddedToMenu < MaxMenuForms)) || // don't exceed max +#pragma warning disable SA1408 // Conditional expressions should declare precedence + (!activeFormAdded && (formsAddedToMenu < (MaxMenuForms - 1)) || // save room for active if it's not in yet +#pragma warning restore SA1408 // Conditional expressions should declare precedence + (forms[i].Equals(activeMdiChild)))) + { + // there's always room for activeMdiChild + MenuItem windowItem = (MenuItem)Activator.CreateInstance(GetType()); + windowItem._data.UserData = new MdiListFormData(this, i); + + if (forms[i].Equals(activeMdiChild)) + { + windowItem.Checked = true; + activeFormAdded = true; + } + + windowItem.Text = string.Format(CultureInfo.CurrentUICulture, "&{0} {1}", accel, forms[i].Text); + accel++; + formsAddedToMenu++; + senderMenu.MenuItems.Add(windowItem); + } + } + } + + // Display the More Windows menu option when there are more than 9 MDI + // Child menu items to be displayed. This is necessary because we're managing our own + // MDI lists, rather than letting Windows do this for us. + if (visibleChildren > MaxMenuForms) + { + MenuItem moreWindows = (MenuItem)Activator.CreateInstance(GetType()); + moreWindows._data.UserData = new MdiListMoreWindowsData(this); + moreWindows.Text = SR.MDIMenuMoreWindows; + senderMenu.MenuItems.Add(moreWindows); + } + } + } + finally + { + _data.SetState(StateInMdiPopup, false); + } + } + + /// + /// Merges this menu item with another menu item and returns the resulting merged + /// . + /// + public virtual MenuItem MergeMenu() + { + CheckIfDisposed(); + + MenuItem newItem = (MenuItem)Activator.CreateInstance(GetType()); + _data.AddItem(newItem); + newItem.MergeMenu(this); + return newItem; + } + + /// + /// Merges another menu item with this menu item. + /// + public void MergeMenu(MenuItem itemSrc) + { + base.MergeMenu(itemSrc); + itemSrc._data.AddItem(this); + } + + /// + /// Raises the event. + /// + protected virtual void OnClick(EventArgs e) + { + CheckIfDisposed(); + + if (_data.UserData is MdiListUserData) + { + ((MdiListUserData)_data.UserData).OnClick(e); + } + else if (_data.baseItem != this) + { + _data.baseItem.OnClick(e); + } + else + { + _data._onClick?.Invoke(this, e); + } + } + + /// + /// Raises the event. + /// + protected virtual void OnDrawItem(DrawItemEventArgs e) + { + CheckIfDisposed(); + + if (_data.baseItem != this) + { + _data.baseItem.OnDrawItem(e); + } + else + { + _data._onDrawItem?.Invoke(this, e); + } + } + + /// + /// Raises the event. + /// + protected virtual void OnMeasureItem(MeasureItemEventArgs e) + { + CheckIfDisposed(); + + if (_data.baseItem != this) + { + _data.baseItem.OnMeasureItem(e); + } + else + { + _data._onMeasureItem?.Invoke(this, e); + } + } + + /// + /// Raises the event. + /// + protected virtual void OnPopup(EventArgs e) + { + CheckIfDisposed(); + + bool recreate = false; + for (int i = 0; i < ItemCount; i++) + { + if (items[i].MdiList) + { + recreate = true; + items[i].UpdateMenuItem(force: true); + } + } + + if (recreate || (_hasHandle && !IsParent)) + { + UpdateMenuItem(force: true); + } + + if (_data.baseItem != this) + { + _data.baseItem.OnPopup(e); + } + else + { + _data._onPopup?.Invoke(this, e); + } + + // Update any subitem states that got changed in the event + for (int i = 0; i < ItemCount; i++) + { + MenuItem item = items[i]; + if (item._dataVersion != item._data._version) + { + item.UpdateMenuItem(force: true); + } + } + + if (MdiList) + { + PopulateMdiList(); + } + } + + /// + /// Raises the event. + /// + protected virtual void OnSelect(EventArgs e) + { + CheckIfDisposed(); + + if (_data.baseItem != this) + { + _data.baseItem.OnSelect(e); + } + else + { + _data._onSelect?.Invoke(this, e); + } + } + + protected internal virtual void OnInitMenuPopup(EventArgs e) => OnPopup(e); + + /// + /// Generates a event for the MenuItem, + /// simulating a click by a user. + /// + public void PerformClick() => OnClick(EventArgs.Empty); + + /// + /// Raises the event for this menu item. + /// + public virtual void PerformSelect() => OnSelect(EventArgs.Empty); + + internal virtual bool ShortcutClick() + { + if (Parent is MenuItem parent) + { + if (!parent.ShortcutClick() || Parent != parent) + { + return false; + } + } + + if ((_data.State & StateDisabled) != 0) + { + return false; + } + + if (ItemCount > 0) + { + OnPopup(EventArgs.Empty); + } + else + { + OnClick(EventArgs.Empty); + } + + return true; + } + + public override string ToString() + { + string s = base.ToString(); + string menuItemText = _data?._caption ?? string.Empty; + ; + return s + ", Text: " + menuItemText; + } + + internal void UpdateItemRtl(bool setRightToLeftBit) + { + if (!_menuItemIsCreated) + { + return; + } + + var info = new NativeMethods.MENUITEMINFO_T + { + fMask = NativeMethods.MIIM_TYPE | NativeMethods.MIIM_STATE | NativeMethods.MIIM_SUBMENU, + dwTypeData = new string('\0', Text.Length + 2), + cbSize = Marshal.SizeOf() + }; + info.cch = info.dwTypeData.Length - 1; + UnsafeNativeMethods.GetMenuItemInfo(new HandleRef(Parent, Parent.handle), MenuID, false, info); + if (setRightToLeftBit) + { + info.fType |= NativeMethods.MFT_RIGHTJUSTIFY | NativeMethods.MFT_RIGHTORDER; + } + else + { + info.fType &= ~(NativeMethods.MFT_RIGHTJUSTIFY | NativeMethods.MFT_RIGHTORDER); + } + + UnsafeNativeMethods.SetMenuItemInfo(new HandleRef(Parent, Parent.handle), MenuID, false, info); + } + + internal void UpdateMenuItem(bool force) + { + if (Parent == null || !Parent.created) + { + return; + } + + if (force || Parent is MainMenu || Parent is ContextMenu) + { + NativeMethods.MENUITEMINFO_T info = CreateMenuItemInfo(); + UnsafeNativeMethods.SetMenuItemInfo(new HandleRef(Parent, Parent.handle), MenuID, false, info); +#if DEBUG + var infoVerify = new NativeMethods.MENUITEMINFO_T + { + cbSize = Marshal.SizeOf(), + fMask = NativeMethods.MIIM_ID | NativeMethods.MIIM_STATE | + NativeMethods.MIIM_SUBMENU | NativeMethods.MIIM_TYPE + }; + UnsafeNativeMethods.GetMenuItemInfo(new HandleRef(Parent, Parent.handle), MenuID, false, infoVerify); +#endif + + if (_hasHandle && info.hSubMenu == IntPtr.Zero) + { + ClearHandles(); + } + + _hasHandle = info.hSubMenu != IntPtr.Zero; + _dataVersion = _data._version; + if (Parent is MainMenu mainMenu) + { + Form f = mainMenu.GetForm(); + if (f != null) + { + SafeNativeMethods.DrawMenuBar(new HandleRef(f, f.Handle)); + } + } + } + } + + /// + /// Handles the OnMeasureItem message sent from ContainerControl + /// + internal unsafe void WmMeasureItem(ref Message m) + { + // Obtain the measure item struct + User32.MEASUREITEMSTRUCT* mis = (User32.MEASUREITEMSTRUCT*)m.LParam; + + // The OnMeasureItem handler now determines the height and width of the item + using var screendc = GetDcScope.ScreenDC; + using Graphics graphics = Graphics.FromHdcInternal(screendc); + + var mie = new MeasureItemEventArgs(graphics, Index); + OnMeasureItem(mie); + + // Update the measure item struct with the new width and height + mis->itemHeight = unchecked((uint)mie.ItemHeight); + mis->itemWidth = unchecked((uint)mie.ItemWidth); + + m.Result = (IntPtr)1; + } + + private void CheckIfDisposed() + { + if (_data == null) + { + throw new ObjectDisposedException(GetType().FullName); + } + } + + internal class MenuItemData : ICommandExecutor + { + internal MenuItem baseItem; + internal MenuItem firstItem; + + private int _state; + internal int _version; + internal MenuMerge _mergeType; + internal int _mergeOrder; + internal string _caption; + internal short _mnemonic; + internal Shortcut _shortcut; + internal bool _showShortcut; + internal EventHandler _onClick; + internal EventHandler _onPopup; + internal EventHandler _onSelect; + internal DrawItemEventHandler _onDrawItem; + internal MeasureItemEventHandler _onMeasureItem; + + private Command _cmd; + + internal MenuItemData(MenuItem baseItem, MenuMerge mergeType, int mergeOrder, Shortcut shortcut, bool showShortcut, + string caption, EventHandler onClick, EventHandler onPopup, EventHandler onSelect, + DrawItemEventHandler onDrawItem, MeasureItemEventHandler onMeasureItem) + { + AddItem(baseItem); + _mergeType = mergeType; + _mergeOrder = mergeOrder; + _shortcut = shortcut; + _showShortcut = showShortcut; + _caption = caption ?? string.Empty; + _onClick = onClick; + _onPopup = onPopup; + _onSelect = onSelect; + _onDrawItem = onDrawItem; + _onMeasureItem = onMeasureItem; + _version = 1; + _mnemonic = -1; + } + + internal bool OwnerDraw + { + get => ((State & StateOwnerDraw) != 0); + set => SetState(StateOwnerDraw, value); + } + + internal bool MdiList + { + get => ((State & StateMdiList) == StateMdiList); + set + { + if (((_state & StateMdiList) != 0) != value) + { + SetState(StateMdiList, value); + for (MenuItem item = firstItem; item != null; item = item._nextLinkedItem) + { + item.ItemsChanged(Menu.CHANGE_MDI); + } + } + } + } + + internal MenuMerge MergeType + { + get => _mergeType; + set + { + if (_mergeType != value) + { + _mergeType = value; + ItemsChanged(Menu.CHANGE_MERGE); + } + } + } + + internal int MergeOrder + { + get => _mergeOrder; + set + { + if (_mergeOrder != value) + { + _mergeOrder = value; + ItemsChanged(Menu.CHANGE_MERGE); + } + } + } + + internal char Mnemonic + { + get + { + if (_mnemonic == -1) + { + _mnemonic = (short)WindowsFormsUtils.GetMnemonic(_caption, true); + } + + return (char)_mnemonic; + } + } + + internal int State => _state; + + internal bool Visible + { + get => (_state & MenuItem.StateHidden) == 0; + set + { + if (((_state & MenuItem.StateHidden) == 0) != value) + { + _state = value ? _state & ~MenuItem.StateHidden : _state | MenuItem.StateHidden; + ItemsChanged(Menu.CHANGE_VISIBLE); + } + } + } + + internal object UserData { get; set; } + + internal void AddItem(MenuItem item) + { + if (item._data != this) + { + item._data?.RemoveItem(item); + + item._nextLinkedItem = firstItem; + firstItem = item; + if (baseItem == null) + { + baseItem = item; + } + + item._data = this; + item._dataVersion = 0; + item.UpdateMenuItem(false); + } + } + + public void Execute() + { + baseItem?.OnClick(EventArgs.Empty); + } + + internal int GetMenuID() + { + if (_cmd == null) + { + _cmd = new Command(this); + } + + return _cmd.ID; + } + + internal void ItemsChanged(int change) + { + for (MenuItem item = firstItem; item != null; item = item._nextLinkedItem) + { + item.Parent?.ItemsChanged(change); + } + } + + internal void RemoveItem(MenuItem item) + { + Debug.Assert(item._data == this, "bad item passed to MenuItemData.removeItem"); + + if (item == firstItem) + { + firstItem = item._nextLinkedItem; + } + else + { + MenuItem itemT; + for (itemT = firstItem; item != itemT._nextLinkedItem;) + { + itemT = itemT._nextLinkedItem; + } + + itemT._nextLinkedItem = item._nextLinkedItem; + } + + item._nextLinkedItem = null; + item._data = null; + item._dataVersion = 0; + + if (item == baseItem) + { + baseItem = firstItem; + } + + if (firstItem == null) + { + // No longer needed. Toss all references and the Command object. + Debug.Assert(baseItem == null, "why isn't baseItem null?"); + _onClick = null; + _onPopup = null; + _onSelect = null; + _onDrawItem = null; + _onMeasureItem = null; + if (_cmd != null) + { + _cmd.Dispose(); + _cmd = null; + } + } + } + + internal void SetCaption(string value) + { + if (value == null) + { + value = string.Empty; + } + + if (!_caption.Equals(value)) + { + _caption = value; + UpdateMenuItems(); + } + +#if DEBUG + if (value.Length > 0) + { + baseItem._debugText = value; + } +#endif + } + + internal void SetState(int flag, bool value) + { + if (((_state & flag) != 0) != value) + { + _state = value ? _state | flag : _state & ~flag; + UpdateMenuItems(); + } + } + + internal void UpdateMenuItems() + { + _version++; + for (MenuItem item = firstItem; item != null; item = item._nextLinkedItem) + { + item.UpdateMenuItem(force: true); + } + } + + } + + private class MdiListUserData + { + public virtual void OnClick(EventArgs e) + { + } + } + + private class MdiListFormData : MdiListUserData + { + private readonly MenuItem _parent; + private readonly int _boundIndex; + + public MdiListFormData(MenuItem parentItem, int boundFormIndex) + { + _boundIndex = boundFormIndex; + _parent = parentItem; + } + + public override void OnClick(EventArgs e) + { + if (_boundIndex != -1) + { + Form[] forms = _parent.FindMdiForms(); + Debug.Assert(forms != null, "Didn't get a list of the MDI Forms."); + + if (forms != null && forms.Length > _boundIndex) + { + Form boundForm = forms[_boundIndex]; + boundForm.Activate(); + if (boundForm.ActiveControl != null && !boundForm.ActiveControl.Focused) + { + boundForm.ActiveControl.Focus(); + } + } + } + } + } + + private class MdiListMoreWindowsData : MdiListUserData + { + private readonly MenuItem _parent; + + public MdiListMoreWindowsData(MenuItem parent) + { + _parent = parent; + } + + public override void OnClick(EventArgs e) + { + Form[] forms = _parent.FindMdiForms(); + Debug.Assert(forms != null, "Didn't get a list of the MDI Forms."); + Form active = _parent.GetMainMenu().GetForm().ActiveMdiChild; + Debug.Assert(active != null, "Didn't get the active MDI child"); + if (forms != null && forms.Length > 0 && active != null) + { + using (var dialog = new MdiWindowDialog()) + { + dialog.SetItems(active, forms); + DialogResult result = dialog.ShowDialog(); + if (result == DialogResult.OK) + { + dialog.ActiveChildForm.Activate(); + if (dialog.ActiveChildForm.ActiveControl != null && !dialog.ActiveChildForm.ActiveControl.Focused) + { + dialog.ActiveChildForm.ActiveControl.Focus(); + } + } + } + } + } + } + } +} + diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MenuMerge.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MenuMerge.cs new file mode 100644 index 00000000000..d7e4cc08ff8 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/MenuMerge.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Specifies the behavior of a when it is merged with items in another menu. + /// + public enum MenuMerge + { + /// + /// The is added to the + /// existing objects in a + /// merged menu. + /// + Add = 0, + + /// + /// The replaces the + /// existing at the same + /// position in a merged menu. + /// + Replace = 1, + + /// + /// Subitems of this are merged + /// with those of existing + /// objects at the same position in a merged menu. + /// + MergeItems = 2, + + /// + /// The is not included in a + /// merged menu. + /// + Remove = 3, + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.cs index 83362dea105..934fc8b3569 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.cs @@ -8,6 +8,7 @@ using Microsoft.Win32; using static Interop; using static Interop.ComCtl32; +using INITCOMMONCONTROLSEX = Windows.Win32.UI.Controls.INITCOMMONCONTROLSEX; namespace System.Windows.Forms; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/NotifyIcon.cs b/src/System.Windows.Forms/src/System/Windows/Forms/NotifyIcon.cs index bb92ad1bdc3..c2897a419fb 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/NotifyIcon.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/NotifyIcon.cs @@ -48,6 +48,7 @@ public sealed partial class NotifyIcon : Component private static uint s_nextId; private object? _userData; private bool _doubleClick; // checks if doubleclick is fired + private ContextMenu contextMenu = null; // Visible defaults to false, but the NotifyIconDesigner makes it seem like the default is // true. We do this because while visible is the more common case, if it was a true default, @@ -74,6 +75,29 @@ public NotifyIcon(IContainer container) : this() container.Add(this); } + /// + /// Gets or sets context menu + /// for the tray icon. + /// + [ + Browsable(false), + DefaultValue(null), + SRCategory(nameof(SR.CatBehavior)), + SRDescription(nameof(SR.NotifyIconMenuDescr)) + ] + public ContextMenu ContextMenu + { + get + { + return contextMenu; + } + + set + { + contextMenu = value; + } + } + /// /// Gets or sets the BalloonTip text displayed when /// the mouse hovers over a system tray icon. @@ -398,6 +422,7 @@ protected override void Dispose(bool disposing) _window.DestroyHandle(); _window = null!; _contextMenuStrip = null; + contextMenu = null; } } else diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Printing/PrintPreviewDialog.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Printing/PrintPreviewDialog.cs index 7a3ffff7956..bf111b913e9 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Printing/PrintPreviewDialog.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Printing/PrintPreviewDialog.cs @@ -267,6 +267,23 @@ public override ContextMenuStrip? ContextMenuStrip set => base.KeyPreview = value; } + /// + /// The contextMenu associated with this control. The contextMenu + /// will be shown when the user right clicks the mouse on the control. + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override ContextMenu? ContextMenu + { + get + { + return base.ContextMenu; + } + set + { + base.ContextMenu = value; + } + } + /// /// Gets or Sets the maximum size the dialog can be resized to. /// diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/RichTextBox.OleCallback.cs b/src/System.Windows.Forms/src/System/Windows/Forms/RichTextBox.OleCallback.cs index bafd2e42965..b57ef64bfa9 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/RichTextBox.OleCallback.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/RichTextBox.OleCallback.cs @@ -314,15 +314,64 @@ public HRESULT GetContextMenu( CHARRANGE* lpchrg, HMENU* hmenu) { - RichTextDbg.TraceVerbose("IRichEditOleCallback::GetContextMenu"); - - // Do nothing, we don't have ContextMenu any longer - if (hmenu is not null) + Debug.WriteLineIf(RichTextDbg.TraceVerbose, "IRichEditOleCallback::GetContextMenu"); + ContextMenu cm = _owner.ContextMenu; + if (cm == null || _owner.ShortcutsEnabled == false) { - *hmenu = HMENU.Null; + hmenu = (HMENU*)IntPtr.Zero; + } + else + { + cm.sourceControl = _owner; + cm.OnPopup(EventArgs.Empty); + // RichEd calls DestroyMenu after displaying the context menu + IntPtr handle = cm.Handle; + // if another control shares the same context menu + // then we have to mark the context menu's handles empty because + // RichTextBox will delete the menu handles once the popup menu is dismissed. + Menu menu = cm; + while (true) + { + int i = 0; + int count = menu.ItemCount; + for (; i < count; i++) + { + if (menu.items[i].handle != IntPtr.Zero) + { + menu = menu.items[i]; + break; + } + } + + if (i == count) + { + menu.handle = IntPtr.Zero; + menu.created = false; + if (menu == cm) + { + break; + } + else + { + menu = ((MenuItem)menu).Parent; + } + } + } + + hmenu = (HMENU*)handle; } return HRESULT.S_OK; + + //RichTextDbg.TraceVerbose("IRichEditOleCallback::GetContextMenu"); + + //// Do nothing, we don't have ContextMenu any longer + //if (hmenu is not null) + //{ + // *hmenu = HMENU.Null; + //} + + //return HRESULT.S_OK; } private void UpdateDropDescription(DragEventArgs e) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/SimpleDataGrid.cs b/src/System.Windows.Forms/src/System/Windows/Forms/SimpleDataGrid.cs new file mode 100644 index 00000000000..27c6e027fde --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/SimpleDataGrid.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +namespace System.Windows.Forms +{ + public class SimpleDataGrid : Control + { + public SimpleDataGrid() + { + } + + public string Hello { get; set; } = "Hello, WTG"; + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/StatusBar.cs b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBar.cs new file mode 100644 index 00000000000..b49b0482fc4 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBar.cs @@ -0,0 +1,1947 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Windows.Forms.VisualStyles; +using WTG.System.Windows.Forms.System.Windows.Forms; +using static Interop; + +namespace System.Windows.Forms +{ + /// + /// Represents a Windows status bar control. + /// + [ + ComVisible(true), + ClassInterface(ClassInterfaceType.AutoDispatch), + DefaultEvent(nameof(PanelClick)), + DefaultProperty(nameof(Text)), + Designer("System.Windows.Forms.Design.StatusBarDesigner, " + AssemblyRef.SystemDesign), + ] + public class StatusBar : Control + { + private int sizeGripWidth = 0; + private const int SIMPLE_INDEX = 0xFF; + + private static readonly object EVENT_PANELCLICK = new object(); + private static readonly object EVENT_SBDRAWITEM = new object(); + + private bool showPanels; + private bool layoutDirty; + private int panelsRealized; + private bool sizeGrip = true; + private string simpleText; + private Point lastClick = new Point(0, 0); + private readonly IList panels = new ArrayList(); + private StatusBarPanelCollection panelsCollection; + private ControlToolTip tooltips; + + private ToolTip mainToolTip = null; + private bool toolTipSet = false; + + /// + /// Initializes a new default instance of the class. + /// + public StatusBar() + : base() + { + base.SetStyle(ControlStyles.UserPaint | ControlStyles.Selectable, false); + + Dock = DockStyle.Bottom; + TabStop = false; + } + + private static VisualStyleRenderer renderer = null; + + /// + /// A VisualStyleRenderer we can use to get information about the current UI theme + /// + private static VisualStyleRenderer VisualStyleRenderer + { + get + { + if (VisualStyleRenderer.IsSupported) + { + if (renderer == null) + { + renderer = new VisualStyleRenderer(VisualStyleElement.ToolBar.Button.Normal); + } + } + else + { + renderer = null; + } + + return renderer; + } + + } + + private int SizeGripWidth + { + get + { + if (sizeGripWidth == 0) + { + if (Application.RenderWithVisualStyles && VisualStyleRenderer != null) + { + // Need to build up accurate gripper width to avoid cutting off other panes. + VisualStyleRenderer vsRenderer = VisualStyleRenderer; + VisualStyleElement thisElement; + Size elementSize; + + // gripper pane width... + thisElement = VisualStyleElement.Status.GripperPane.Normal; + vsRenderer.SetParameters(thisElement); + elementSize = vsRenderer.GetPartSize(Graphics.FromHwndInternal(Handle), ThemeSizeType.True); + sizeGripWidth = elementSize.Width; + + // ...plus gripper width + thisElement = VisualStyleElement.Status.Gripper.Normal; + vsRenderer.SetParameters(thisElement); + elementSize = vsRenderer.GetPartSize(Graphics.FromHwndInternal(Handle), ThemeSizeType.True); + sizeGripWidth += elementSize.Width; + + // Either GetPartSize could have returned a width of zero, so make sure we have a reasonable number: + sizeGripWidth = Math.Max(sizeGripWidth, 16); + } + else + { + sizeGripWidth = 16; + } + } + + return sizeGripWidth; + } + } + + /// + /// The background color of this control. This is an ambient property and will + /// always return a non-null value. + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override Color BackColor + { + get + { + // not supported, always return CONTROL + return SystemColors.Control; + } + set + { + // no op, not supported. + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler BackColorChanged + { + add => base.BackColorChanged += value; + remove => base.BackColorChanged -= value; + } + + /// + /// Gets or sets the image rendered on the background of the + /// + /// control. + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override Image BackgroundImage + { + get + { + return base.BackgroundImage; + } + set + { + base.BackgroundImage = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler BackgroundImageChanged + { + add => base.BackgroundImageChanged += value; + remove => base.BackgroundImageChanged -= value; + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override ImageLayout BackgroundImageLayout + { + get + { + return base.BackgroundImageLayout; + } + set + { + base.BackgroundImageLayout = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler BackgroundImageLayoutChanged + { + add => base.BackgroundImageLayoutChanged += value; + remove => base.BackgroundImageLayoutChanged -= value; + } + + /// + /// Returns the CreateParams used to create the handle for this control. + /// Inheriting classes should call base.getCreateParams in the manor below: + /// + protected override CreateParams CreateParams + { + get + { + CreateParams cp = base.CreateParams; + cp.ClassName = NativeMethods.WC_STATUSBAR; + + if (sizeGrip) + { + cp.Style |= NativeMethods.SBARS_SIZEGRIP; + } + else + { + cp.Style &= (~NativeMethods.SBARS_SIZEGRIP); + } + + cp.Style |= NativeMethods.CCS_NOPARENTALIGN | NativeMethods.CCS_NORESIZE; + + return cp; + } + } + + protected override ImeMode DefaultImeMode + { + get + { + return ImeMode.Disable; + } + } + + /// + /// Deriving classes can override this to configure a default size for their control. + /// This is more efficient than setting the size in the control's constructor. + /// + protected override Size DefaultSize + { + get + { + return new Size(100, 22); + } + } + + /// + /// This property is overridden and hidden from statement completion + /// on controls that are based on Win32 Native Controls. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override bool DoubleBuffered + { + get + { + return base.DoubleBuffered; + } + set + { + base.DoubleBuffered = value; + } + } + + /// + /// Gets or sets the docking behavior of the control. + /// + [ + Localizable(true), + DefaultValue(DockStyle.Bottom) + ] + public override DockStyle Dock + { + get + { + return base.Dock; + } + set + { + base.Dock = value; + } + } + + /// + /// Gets or sets the font the + /// control will use to display + /// information. + /// + [ + Localizable(true) + ] + public override Font Font + { + get { return base.Font; } + set + { + base.Font = value; + SetPanelContentsWidths(false); + } + } + + /// + /// Gets or sets + /// the forecolor for the control. + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler ForeColorChanged + { + add => base.ForeColorChanged += value; + remove => base.ForeColorChanged -= value; + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public ImeMode ImeMode + { + get + { + return base.ImeMode; + } + set + { + base.ImeMode = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public new event EventHandler ImeModeChanged + { + add => base.ImeModeChanged += value; + remove => base.ImeModeChanged -= value; + } + + /// + /// Gets the collection of + /// panels contained within the + /// control. + /// + [ + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), + SRDescription(nameof(SR.StatusBarPanelsDescr)), + Localizable(true), + SRCategory(nameof(SR.CatAppearance)), + MergableProperty(false) + ] + public StatusBarPanelCollection Panels + { + get + { + if (panelsCollection == null) + { + panelsCollection = new StatusBarPanelCollection(this); + } + + return panelsCollection; + } + } + + /// + /// The status bar text. + /// + [ + Localizable(true) + ] + public override string Text + { + get + { + if (simpleText == null) + { + return ""; + } + else + { + return simpleText; + } + } + set + { + SetSimpleText(value); + if (simpleText != value) + { + simpleText = value; + OnTextChanged(EventArgs.Empty); + } + } + } + + /// + /// Gets or sets a value indicating whether panels should be shown. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(false), + SRDescription(nameof(SR.StatusBarShowPanelsDescr)) + ] + public bool ShowPanels + { + get + { + return showPanels; + } + set + { + if (showPanels != value) + { + showPanels = value; + + layoutDirty = true; + if (IsHandleCreated) + { + int bShowPanels = (!showPanels) ? 1 : 0; + + SendMessage(NativeMethods.SB_SIMPLE, bShowPanels, 0); + + if (showPanels) + { + PerformLayout(); + RealizePanels(); + } + else if (tooltips != null) + { + for (int i = 0; i < panels.Count; i++) + { + tooltips.SetTool(panels[i], null); + } + } + + SetSimpleText(simpleText); + } + } + } + } + + /// + /// Gets or sets a value indicating whether a sizing grip + /// will be rendered on the corner of the + /// control. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(true), + SRDescription(nameof(SR.StatusBarSizingGripDescr)) + ] + public bool SizingGrip + { + get + { + return sizeGrip; + } + set + { + if (value != sizeGrip) + { + sizeGrip = value; + RecreateHandle(); + } + } + } + + /// + /// Gets or sets a value indicating whether the user will be able to tab to the + /// . + /// + [DefaultValue(false)] + new public bool TabStop + { + get + { + return base.TabStop; + } + set + { + base.TabStop = value; + } + } + + internal bool ToolTipSet + { + get + { + return toolTipSet; + } + } + + internal ToolTip MainToolTip + { + get + { + return mainToolTip; + } + } + + /// + /// Occurs when a visual aspect of an owner-drawn status bar changes. + /// + [SRCategory(nameof(SR.CatBehavior)), SRDescription(nameof(SR.StatusBarDrawItem))] + public event StatusBarDrawItemEventHandler DrawItem + { + add => Events.AddHandler(EVENT_SBDRAWITEM, value); + remove => Events.RemoveHandler(EVENT_SBDRAWITEM, value); + } + + /// + /// Occurs when a panel on the status bar is clicked. + /// + [SRCategory(nameof(SR.CatMouse)), SRDescription(nameof(SR.StatusBarOnPanelClickDescr))] + public event StatusBarPanelClickEventHandler PanelClick + { + add => Events.AddHandler(EVENT_PANELCLICK, value); + remove => Events.RemoveHandler(EVENT_PANELCLICK, value); + } + + /// + /// StatusBar Onpaint. + /// + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public new event PaintEventHandler Paint + { + add => base.Paint += value; + remove => base.Paint -= value; + } + + /// + /// Tells whether the panels have been realized. + /// + internal bool ArePanelsRealized() + { + return showPanels && IsHandleCreated; + } + + internal void DirtyLayout() + { + layoutDirty = true; + } + + /// + /// Makes the panel according to the sizes in the panel list. + /// + private void ApplyPanelWidths() + { + // This forces handle creation every time any time the StatusBar + // has to be re-laidout. + if (!IsHandleCreated) + { + return; + } + + StatusBarPanel panel = null; + int length = panels.Count; + + if (length == 0) + { + Size sz = Size; + int[] offsets = new int[1]; + offsets[0] = sz.Width; + if (sizeGrip) + { + offsets[0] -= SizeGripWidth; + } + + UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.SB_SETPARTS, 1, offsets); + SendMessage(NativeMethods.SB_SETICON, 0, (int)IntPtr.Zero); + + return; + } + + int[] offsets2 = new int[length]; + int currentOffset = 0; + for (int i = 0; i < length; i++) + { + panel = (StatusBarPanel)panels[i]; + currentOffset += panel.Width; + offsets2[i] = currentOffset; + panel.Right = offsets2[i]; + } + + UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.SB_SETPARTS, length, offsets2); + + // Tooltip setup... + for (int i = 0; i < length; i++) + { + panel = (StatusBarPanel)panels[i]; + UpdateTooltip(panel); + } + + layoutDirty = false; + } + + protected override void CreateHandle() + { + if (!RecreatingHandle) + { + IntPtr userCookie = UnsafeNativeMethodsCore.ThemingScope.Activate(); + + try + { + NativeMethods.INITCOMMONCONTROLSEX icc = new NativeMethods.INITCOMMONCONTROLSEX + { + dwICC = NativeMethods.ICC_BAR_CLASSES + }; + SafeNativeMethods.InitCommonControlsEx(icc); + } + finally + { + UnsafeNativeMethodsCore.ThemingScope.Deactivate(userCookie); + } + } + + base.CreateHandle(); + } + + /// + /// Disposes this control + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (panelsCollection != null) + { + StatusBarPanel[] panelCopy = new StatusBarPanel[panelsCollection.Count]; + ((ICollection)panelsCollection).CopyTo(panelCopy, 0); + panelsCollection.Clear(); + + foreach (StatusBarPanel p in panelCopy) + { + p.Dispose(); + } + } + } + + base.Dispose(disposing); + } + + /// + /// Forces the panels to be updated, location, repainting, etc. + /// + private void ForcePanelUpdate() + { + if (ArePanelsRealized()) + { + layoutDirty = true; + SetPanelContentsWidths(true); + PerformLayout(); + RealizePanels(); + } + } + + /// + /// Raises the + /// event. + /// + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + if (!DesignMode) + { + tooltips = new ControlToolTip(this); + } + + if (!showPanels) + { + SendMessage(NativeMethods.SB_SIMPLE, 1, 0); + SetSimpleText(simpleText); + } + else + { + ForcePanelUpdate(); + } + } + + /// + /// Raises the event. + /// + protected override void OnHandleDestroyed(EventArgs e) + { + base.OnHandleDestroyed(e); + if (tooltips != null) + { + tooltips.Dispose(); + tooltips = null; + } + } + + /// + /// Raises the event. + /// + protected override void OnMouseDown(MouseEventArgs e) + { + lastClick.X = e.X; + lastClick.Y = e.Y; + base.OnMouseDown(e); + } + + /// + /// Raises the event. + /// + protected virtual void OnPanelClick(StatusBarPanelClickEventArgs e) + { + ((StatusBarPanelClickEventHandler)Events[EVENT_PANELCLICK])?.Invoke(this, e); + } + + protected override void OnLayout(LayoutEventArgs levent) + { + if (showPanels) + { + LayoutPanels(); + if (IsHandleCreated && panelsRealized != panels.Count) + { + RealizePanels(); + } + } + + base.OnLayout(levent); + } + + /// + /// This function sets up all the panel on the status bar according to + /// the internal this.panels List. + /// + internal void RealizePanels() + { + StatusBarPanel panel = null; + int length = panels.Count; + int old = panelsRealized; + + panelsRealized = 0; + + if (length == 0) + { + SendMessage(NativeMethods.SB_SETTEXT, 0, ""); + } + + int i; + for (i = 0; i < length; i++) + { + panel = (StatusBarPanel)panels[i]; + try + { + panel.Realize(); + panelsRealized++; + } + catch + { + } + } + + for (; i < old; i++) + { + SendMessage(NativeMethods.SB_SETTEXT, 0, null); + } + } + + /// + /// Remove the internal list of panels without updating the control. + /// + internal void RemoveAllPanelsWithoutUpdate() + { + int size = panels.Count; + // remove the parent reference + for (int i = 0; i < size; i++) + { + StatusBarPanel sbp = (StatusBarPanel)panels[i]; + sbp.ParentInternal = null; + } + + panels.Clear(); + if (showPanels == true) + { + ApplyPanelWidths(); + ForcePanelUpdate(); + } + + } + + /// + /// Sets the widths of any panels that have the + /// StatusBarPanelAutoSize.CONTENTS property set. + /// + internal void SetPanelContentsWidths(bool newPanels) + { + int size = panels.Count; + bool changed = false; + for (int i = 0; i < size; i++) + { + StatusBarPanel sbp = (StatusBarPanel)panels[i]; + if (sbp.AutoSize == StatusBarPanelAutoSize.Contents) + { + int newWidth = sbp.GetContentsWidth(newPanels); + if (sbp.Width != newWidth) + { + sbp.Width = newWidth; + changed = true; + } + } + } + + if (changed) + { + DirtyLayout(); + PerformLayout(); + } + } + + private void SetSimpleText(string simpleText) + { + if (!showPanels && IsHandleCreated) + { + + int wparam = SIMPLE_INDEX + NativeMethods.SBT_NOBORDERS; + if (RightToLeft == RightToLeft.Yes) + { + wparam |= NativeMethods.SBT_RTLREADING; + } + + SendMessage(NativeMethods.SB_SETTEXT, wparam, simpleText); + } + } + + /// + /// Sizes the the panels appropriately. It looks at the SPRING AutoSize + /// property. + /// + private void LayoutPanels() + { + StatusBarPanel panel = null; + int barPanelWidth = 0; + int springNum = 0; + StatusBarPanel[] pArray = new StatusBarPanel[panels.Count]; + bool changed = false; + + for (int i = 0; i < pArray.Length; i++) + { + panel = (StatusBarPanel)panels[i]; + if (panel.AutoSize == StatusBarPanelAutoSize.Spring) + { + pArray[springNum] = panel; + springNum++; + } + else + { + barPanelWidth += panel.Width; + } + } + + if (springNum > 0) + { + Rectangle rect = Bounds; + int springPanelsLeft = springNum; + int leftoverWidth = rect.Width - barPanelWidth; + if (sizeGrip) + { + leftoverWidth -= SizeGripWidth; + } + + int copyOfLeftoverWidth = unchecked((int)0x80000000); + while (springPanelsLeft > 0) + { + + int widthOfSpringPanel = (leftoverWidth) / springPanelsLeft; + if (leftoverWidth == copyOfLeftoverWidth) + { + break; + } + + copyOfLeftoverWidth = leftoverWidth; + + for (int i = 0; i < springNum; i++) + { + panel = pArray[i]; + if (panel == null) + { + continue; + } + + if (widthOfSpringPanel < panel.MinWidth) + { + if (panel.Width != panel.MinWidth) + { + changed = true; + } + + panel.Width = panel.MinWidth; + pArray[i] = null; + springPanelsLeft--; + leftoverWidth -= panel.MinWidth; + } + else + { + if (panel.Width != widthOfSpringPanel) + { + changed = true; + } + + panel.Width = widthOfSpringPanel; + } + } + } + } + + if (changed || layoutDirty) + { + ApplyPanelWidths(); + } + } + + /// + /// Raises the + /// event. + /// + protected virtual void OnDrawItem(StatusBarDrawItemEventArgs sbdievent) + { + ((StatusBarDrawItemEventHandler)Events[EVENT_SBDRAWITEM])?.Invoke(this, sbdievent); + } + + /// + /// Raises the event. + /// + protected override void OnResize(EventArgs e) + { + Invalidate(); + base.OnResize(e); + } + + /// + /// Returns a string representation for this control. + /// + public override string ToString() + { + string s = base.ToString(); + if (Panels != null) + { + s += ", Panels.Count: " + Panels.Count.ToString(CultureInfo.CurrentCulture); + if (Panels.Count > 0) + { + s += ", Panels[0]: " + Panels[0].ToString(); + } + } + + return s; + } + + // call this when System.Windows.forms.toolTip is Associated with Statusbar.... + internal void SetToolTip(ToolTip t) + { + mainToolTip = t; + toolTipSet = true; + + } + + internal void UpdateTooltip(StatusBarPanel panel) + { + if (tooltips == null) + { + if (IsHandleCreated && !DesignMode) + { + //This shouldn't happen: tooltips should've already been set. The best we can + //do here is reset it. + tooltips = new ControlToolTip(this); + } + else + { + return; + } + } + + if (panel.Parent == this && panel.ToolTipText.Length > 0) + { + int border = SystemInformation.Border3DSize.Width; + ControlToolTip.Tool t = tooltips.GetTool(panel); + if (t == null) + { + t = new ControlToolTip.Tool(); + } + + t.text = panel.ToolTipText; + t.rect = new Rectangle(panel.Right - panel.Width + border, 0, panel.Width - border, Height); + tooltips.SetTool(panel, t); + } + else + { + tooltips.SetTool(panel, null); + } + } + + private void UpdatePanelIndex() + { + int length = panels.Count; + for (int i = 0; i < length; i++) + { + ((StatusBarPanel)panels[i]).Index = i; + } + } + + /// + /// Processes messages for ownerdraw panels. + /// + private void WmDrawItem(ref Message m) + { + NativeMethods.DRAWITEMSTRUCT dis = (NativeMethods.DRAWITEMSTRUCT)m.GetLParam(typeof(NativeMethods.DRAWITEMSTRUCT)); + + int length = panels.Count; + if (dis.itemID < 0 || dis.itemID >= length) + { + Debug.Fail("OwnerDraw item out of range"); + } + + StatusBarPanel panel = (StatusBarPanel) + panels[dis.itemID]; + + Graphics g = Graphics.FromHdcInternal(dis.hDC); + Rectangle r = Rectangle.FromLTRB(dis.rcItem.left, dis.rcItem.top, dis.rcItem.right, dis.rcItem.bottom); + + //The itemstate is not defined for a statusbar control + OnDrawItem(new StatusBarDrawItemEventArgs(g, Font, r, dis.itemID, DrawItemState.None, panel, ForeColor, BackColor)); + g.Dispose(); + } + + private void WmNotifyNMClick(NativeMethods.NMHDR note) + { + if (!showPanels) + { + return; + } + + int size = panels.Count; + int currentOffset = 0; + int index = -1; + for (int i = 0; i < size; i++) + { + StatusBarPanel panel = (StatusBarPanel)panels[i]; + currentOffset += panel.Width; + if (lastClick.X < currentOffset) + { + // this is where the mouse was clicked. + index = i; + break; + } + } + + if (index != -1) + { + MouseButtons button = MouseButtons.Left; + int clicks = 0; + switch (note.code) + { + case NativeMethods.NM_CLICK: + button = MouseButtons.Left; + clicks = 1; + break; + case NativeMethods.NM_RCLICK: + button = MouseButtons.Right; + clicks = 1; + break; + case NativeMethods.NM_DBLCLK: + button = MouseButtons.Left; + clicks = 2; + break; + case NativeMethods.NM_RDBLCLK: + button = MouseButtons.Right; + clicks = 2; + break; + } + + Point pt = lastClick; + StatusBarPanel panel = (StatusBarPanel)panels[index]; + + StatusBarPanelClickEventArgs sbpce = new StatusBarPanelClickEventArgs(panel, + button, clicks, pt.X, pt.Y); + OnPanelClick(sbpce); + } + } + + private void WmNCHitTest(ref Message m) + { + int x = NativeMethods.Util.LOWORD(m.LParam); + Rectangle bounds = Bounds; + bool callSuper = true; + + // The default implementation of the statusbar + // will let you size the form when it is docked on the bottom, + // but when it is anywhere else, the statusbar will be resized. + // to prevent that we provide a little bit a sanity to only + // allow resizing, when it would resize the form. + if (x > bounds.X + bounds.Width - SizeGripWidth) + { + Control parent = ParentInternal; + if (parent != null && parent is Form) + { + FormBorderStyle bs = ((Form)parent).FormBorderStyle; + + if (bs != FormBorderStyle.Sizable + && bs != FormBorderStyle.SizableToolWindow) + { + callSuper = false; + } + + if (!((Form)parent).TopLevel + || Dock != DockStyle.Bottom) + { + + callSuper = false; + } + + if (callSuper) + { + ControlCollection children = parent.Controls; + int c = children.Count; + for (int i = 0; i < c; i++) + { + Control ctl = children[i]; + if (ctl != this && ctl.Dock == DockStyle.Bottom) + { + if (ctl.Top > Top) + { + callSuper = false; + break; + } + } + } + } + } + else + { + callSuper = false; + } + } + + if (callSuper) + { + base.WndProc(ref m); + } + else + { + m.Result = (IntPtr)NativeMethods.HTCLIENT; + } + } + + /// + /// Base wndProc. All messages are sent to wndProc after getting filtered through + /// the preProcessMessage function. Inheriting controls should call base.wndProc + /// for any messages that they don't handle. + /// + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case WindowMessages.WM_NCHITTEST: + WmNCHitTest(ref m); + break; + case WindowMessages.WM_REFLECT + WindowMessages.WM_DRAWITEM: + WmDrawItem(ref m); + break; + case WindowMessages.WM_NOTIFY: + case WindowMessages.WM_NOTIFY + WindowMessages.WM_REFLECT: + NativeMethods.NMHDR note = (NativeMethods.NMHDR)m.GetLParam(typeof(NativeMethods.NMHDR)); + switch (note.code) + { + case NativeMethods.NM_CLICK: + case NativeMethods.NM_RCLICK: + case NativeMethods.NM_DBLCLK: + case NativeMethods.NM_RDBLCLK: + WmNotifyNMClick(note); + break; + default: + base.WndProc(ref m); + break; + } + + break; + + default: + base.WndProc(ref m); + break; + } + } + + /// + /// The collection of StatusBarPanels that the StatusBar manages. + /// event. + /// + [ListBindable(false)] + public class StatusBarPanelCollection : IList + { + private readonly StatusBar owner; + + // A caching mechanism for key accessor + // We use an index here rather than control so that we don't have lifetime + // issues by holding on to extra references. + private int lastAccessedIndex = -1; + + /// + /// Constructor for the StatusBarPanelCollection class + /// + public StatusBarPanelCollection(StatusBar owner) + { + this.owner = owner; + } + + /// + /// This method will return an individual StatusBarPanel with the appropriate index. + /// + public virtual StatusBarPanel this[int index] + { + get + { + return (StatusBarPanel)owner.panels[index]; + } + set + { + + if (value == null) + { + throw new ArgumentNullException(nameof(StatusBarPanel)); + } + + owner.layoutDirty = true; + + if (value.Parent != null) + { + throw new ArgumentException(SR.ObjectHasParent, "value"); + } + + int length = owner.panels.Count; + + if (index < 0 || index >= length) + { + throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(SR.InvalidArgument, nameof(index), index)); + } + + StatusBarPanel oldPanel = (StatusBarPanel)owner.panels[index]; + oldPanel.ParentInternal = null; + value.ParentInternal = owner; + if (value.AutoSize == StatusBarPanelAutoSize.Contents) + { + value.Width = value.GetContentsWidth(true); + } + + owner.panels[index] = value; + value.Index = index; + + if (owner.ArePanelsRealized()) + { + owner.PerformLayout(); + value.Realize(); + } + } + } + + object IList.this[int index] + { + get + { + return this[index]; + } + set + { + if (value is StatusBarPanel) + { + this[index] = (StatusBarPanel)value; + } + else + { + throw new ArgumentException(SR.StatusBarBadStatusBarPanel, "value"); + } + } + } + + /// + /// Retrieves the child control with the specified key. + /// + public virtual StatusBarPanel this[string key] + { + get + { + // We do not support null and empty string as valid keys. + if (string.IsNullOrEmpty(key)) + { + return null; + } + + // Search for the key in our collection + int index = IndexOfKey(key); + if (IsValidIndex(index)) + { + return this[index]; + } + else + { + return null; + } + + } + } + + /// + /// Returns an integer representing the number of StatusBarPanels + /// in this collection. + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public int Count + { + get + { + return owner.panels.Count; + } + } + + object ICollection.SyncRoot + { + get + { + return this; + } + } + + bool ICollection.IsSynchronized + { + get + { + return false; + } + } + + bool IList.IsFixedSize + { + get + { + return false; + } + } + + public bool IsReadOnly + { + get + { + return false; + } + } + + /// + /// Adds a StatusBarPanel to the collection. + /// + public virtual StatusBarPanel Add(string text) + { + StatusBarPanel panel = new StatusBarPanel + { + Text = text + }; + Add(panel); + return panel; + } + + /// + /// Adds a StatusBarPanel to the collection. + /// + public virtual int Add(StatusBarPanel value) + { + int index = owner.panels.Count; + Insert(index, value); + return index; + } + + int IList.Add(object value) + { + if (value is StatusBarPanel) + { + return Add((StatusBarPanel)value); + } + else + { + throw new ArgumentException(SR.StatusBarBadStatusBarPanel, "value"); + } + } + + public virtual void AddRange(StatusBarPanel[] panels) + { + if (panels == null) + { + throw new ArgumentNullException(nameof(panels)); + } + + foreach (StatusBarPanel panel in panels) + { + Add(panel); + } + } + + public bool Contains(StatusBarPanel panel) + { + return IndexOf(panel) != -1; + } + + bool IList.Contains(object panel) + { + if (panel is StatusBarPanel) + { + return Contains((StatusBarPanel)panel); + } + else + { + return false; + } + } + + /// + /// Returns true if the collection contains an item with the specified key, false otherwise. + /// + public virtual bool ContainsKey(string key) + { + return IsValidIndex(IndexOfKey(key)); + } + + public int IndexOf(StatusBarPanel panel) + { + for (int index = 0; index < Count; ++index) + { + if (this[index] == panel) + { + return index; + } + } + + return -1; + } + + int IList.IndexOf(object panel) + { + if (panel is StatusBarPanel) + { + return IndexOf((StatusBarPanel)panel); + } + else + { + return -1; + } + } + + /// + /// The zero-based index of the first occurrence of value within the entire CollectionBase, if found; otherwise, -1. + /// + public virtual int IndexOfKey(string key) + { + // Step 0 - Arg validation + if (string.IsNullOrEmpty(key)) + { + return -1; // we dont support empty or null keys. + } + + // step 1 - check the last cached item + if (IsValidIndex(lastAccessedIndex)) + { + if (WindowsFormsUtils.SafeCompareStrings(this[lastAccessedIndex].Name, key, /* ignoreCase = */ true)) + { + return lastAccessedIndex; + } + } + + // step 2 - search for the item + for (int i = 0; i < Count; i++) + { + if (WindowsFormsUtils.SafeCompareStrings(this[i].Name, key, /* ignoreCase = */ true)) + { + lastAccessedIndex = i; + return i; + } + } + + // step 3 - we didn't find it. Invalidate the last accessed index and return -1. + lastAccessedIndex = -1; + return -1; + } + + /// + /// Inserts a StatusBarPanel in the collection. + /// + public virtual void Insert(int index, StatusBarPanel value) + { + + //check for the value not to be null + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + //end check + + owner.layoutDirty = true; + if (value.Parent != owner && value.Parent != null) + { + throw new ArgumentException(SR.ObjectHasParent, "value"); + } + + int length = owner.panels.Count; + + if (index < 0 || index > length) + { + throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(SR.InvalidArgument, nameof(index), index)); + } + + value.ParentInternal = owner; + + switch (value.AutoSize) + { + case StatusBarPanelAutoSize.None: + case StatusBarPanelAutoSize.Spring: + break; + case StatusBarPanelAutoSize.Contents: + value.Width = value.GetContentsWidth(true); + break; + } + + owner.panels.Insert(index, value); + owner.UpdatePanelIndex(); + + owner.ForcePanelUpdate(); + } + + void IList.Insert(int index, object value) + { + if (value is StatusBarPanel) + { + Insert(index, (StatusBarPanel)value); + } + else + { + throw new ArgumentException(SR.StatusBarBadStatusBarPanel, "value"); + } + } + + /// + /// Determines if the index is valid for the collection. + /// + private bool IsValidIndex(int index) + { + return ((index >= 0) && (index < Count)); + } + + /// + /// Removes all the StatusBarPanels in the collection. + /// + public virtual void Clear() + { + owner.RemoveAllPanelsWithoutUpdate(); + owner.PerformLayout(); + + } + + /// + /// Removes an individual StatusBarPanel in the collection. + /// + public virtual void Remove(StatusBarPanel value) + { + + //check for the value not to be null + if (value == null) + { + throw new ArgumentNullException(nameof(StatusBarPanel)); + } + + if (value.Parent != owner) + { + return; + } + + RemoveAt(value.Index); + } + + void IList.Remove(object value) + { + if (value is StatusBarPanel) + { + Remove((StatusBarPanel)value); + } + } + + /// + /// Removes an individual StatusBarPanel in the collection at the given index. + /// + public virtual void RemoveAt(int index) + { + int length = Count; + if (index < 0 || index >= length) + { + throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(SR.InvalidArgument, nameof(index), index)); + } + + // clear any tooltip + // + StatusBarPanel panel = (StatusBarPanel)owner.panels[index]; + + owner.panels.RemoveAt(index); + panel.ParentInternal = null; + + // this will cause the panels tooltip to be removed since it's no longer a child + // of this StatusBar. + owner.UpdateTooltip(panel); + + // We must reindex the panels after a removal... + owner.UpdatePanelIndex(); + owner.ForcePanelUpdate(); + } + + /// + /// Removes the child control with the specified key. + /// + public virtual void RemoveByKey(string key) + { + int index = IndexOfKey(key); + if (IsValidIndex(index)) + { + RemoveAt(index); + } + } + + void ICollection.CopyTo(Array dest, int index) + { + owner.panels.CopyTo(dest, index); + } + + /// + /// Returns the Enumerator for this collection. + /// + public IEnumerator GetEnumerator() + { + if (owner.panels != null) + { + return owner.panels.GetEnumerator(); + } + else + { + return Array.Empty().GetEnumerator(); + } + } + } + + /// + /// This is a tooltip control that provides tips for a single + /// control. Each "tool" region is defined by a rectangle and + /// the string that should be displayed. This implementation + /// is based on System.Windows.Forms.ToolTip, but this control + /// is lighter weight and provides less functionality... however + /// this control binds to rectangular regions, instead of + /// full controls. + /// + private class ControlToolTip : IHandle + { + public class Tool + { + public Rectangle rect = Rectangle.Empty; + public string text; + internal IntPtr id = new IntPtr(-1); + } + + private readonly Hashtable tools = new Hashtable(); + private readonly ToolTipNativeWindow window = null; + private readonly Control parent = null; + private int nextId = 0; + + /// + /// Creates a new ControlToolTip. + /// + public ControlToolTip(Control parent) + { + window = new ToolTipNativeWindow(this); + this.parent = parent; + } + + /// + /// Returns the createParams to create the window. + /// + protected CreateParams CreateParams + { + get + { + NativeMethods.INITCOMMONCONTROLSEX icc = new NativeMethods.INITCOMMONCONTROLSEX + { + dwICC = NativeMethods.ICC_TAB_CLASSES + }; + SafeNativeMethods.InitCommonControlsEx(icc); + CreateParams cp = new CreateParams + { + Parent = IntPtr.Zero, + ClassName = NativeMethods.TOOLTIPS_CLASS + }; + cp.Style |= NativeMethods.TTS_ALWAYSTIP; + cp.ExStyle = 0; + cp.Caption = null; + return cp; + } + } + + public HWND Handle + { + get + { + if (window.Handle == IntPtr.Zero) + { + CreateHandle(); + } + + return (HWND)window.Handle; + } + } + + private bool IsHandleCreated + { + get { return window.Handle != IntPtr.Zero; } + } + + private void AssignId(Tool tool) + { + tool.id = (IntPtr)nextId; + nextId++; + } + + /// + /// Sets the tool for the specified key. Keep in mind + /// that as soon as setTool is called, the handle for + /// the ControlToolTip is created, and the handle for + /// the parent control is also created. If the parent + /// handle is recreated in the future, all tools must + /// be re-added. The old tool for the specified key + /// will be removed. Passing null in for the + /// tool parameter will result in the tool + /// region being removed. + /// + public void SetTool(object key, Tool tool) + { + bool remove = false; + bool add = false; + bool update = false; + + Tool toRemove = null; + if (tools.ContainsKey(key)) + { + toRemove = (Tool)tools[key]; + } + + if (toRemove != null) + { + remove = true; + } + + if (tool != null) + { + add = true; + } + + if (tool != null && toRemove != null + && tool.id == toRemove.id) + { + update = true; + } + + if (update) + { + UpdateTool(tool); + } + else + { + if (remove) + { + RemoveTool(toRemove); + } + + if (add) + { + AddTool(tool); + } + } + + if (tool != null) + { + tools[key] = tool; + } + else + { + tools.Remove(key); + } + + } + + /// + /// Returns the tool associated with the specified key, + /// or null if there is no area. + /// + public Tool GetTool(object key) + { + return (Tool)tools[key]; + } + + private void AddTool(Tool tool) + { + if (tool != null && tool.text != null && tool.text.Length > 0) + { + StatusBar p = (StatusBar)parent; + + ComCtl32.ToolInfoWrapper info = GetTOOLINFO(tool); + if (info.SendMessage(p.ToolTipSet ? (IHandle)p.mainToolTip : this, WindowMessages.TTM_ADDTOOLW) == IntPtr.Zero) + { + throw new InvalidOperationException(SR.StatusBarAddFailed); + } + } + } + + private void RemoveTool(Tool tool) + { + if (tool != null && tool.text != null && tool.text.Length > 0 && (int)tool.id >= 0) + { + ComCtl32.ToolInfoWrapper info = GetMinTOOLINFO(tool); + info.SendMessage(this, WindowMessages.TTM_DELTOOLW); + } + } + + private void UpdateTool(Tool tool) + { + if (tool != null && tool.text != null && tool.text.Length > 0 && (int)tool.id >= 0) + { + ComCtl32.ToolInfoWrapper info = GetTOOLINFO(tool); + info.SendMessage(this, WindowMessages.TTM_SETTOOLINFOW); + } + } + + /// + /// Creates the handle for the control. + /// + protected void CreateHandle() + { + if (IsHandleCreated) + { + return; + } + + window.CreateHandle(CreateParams); + SafeNativeMethods.SetWindowPos(new HandleRef(this, Handle), NativeMethods.HWND_TOPMOST, + 0, 0, 0, 0, + NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOSIZE | + NativeMethods.SWP_NOACTIVATE); + + // Setting the max width has the added benefit of enabling multiline tool tips + User32.SendMessageW(this, (User32.WM)WindowMessages.TTM_SETMAXTIPWIDTH, IntPtr.Zero, (IntPtr)SystemInformation.MaxWindowTrackSize.Width); + } + + /// + /// Destroys the handle for this control. + /// + protected void DestroyHandle() + { + if (IsHandleCreated) + { + window.DestroyHandle(); + tools.Clear(); + } + } + + /// + /// Disposes of the component. Call dispose when the component is no longer needed. + /// This method removes the component from its container (if the component has a site) + /// and triggers the dispose event. + /// + public void Dispose() + { + DestroyHandle(); + } + + /// + /// Returns a new instance of the TOOLINFO_T structure with the minimum + /// required data to uniquely identify a region. This is used primarily + /// for delete operations. NOTE: This cannot force the creation of a handle. + /// + private ComCtl32.ToolInfoWrapper GetMinTOOLINFO(Tool tool) + { + if ((int)tool.id < 0) + { + AssignId(tool); + } + + return new ComCtl32.ToolInfoWrapper( + parent, + id: parent is StatusBar sb ? sb.Handle : tool.id); + } + + /// + /// Returns a detailed TOOLINFO_T structure that represents the specified + /// region. NOTE: This may force the creation of a handle. + /// + private ComCtl32.ToolInfoWrapper GetTOOLINFO(Tool tool) + { + ComCtl32.ToolInfoWrapper ti = GetMinTOOLINFO(tool); + ti.Info.uFlags |= (TOOLTIP_FLAGS)(ComCtl32.TTF.TRANSPARENT | ComCtl32.TTF.SUBCLASS); + + // RightToLeft reading order + Control richParent = parent; + if (richParent != null && richParent.RightToLeft == RightToLeft.Yes) + { + ti.Info.uFlags |= (TOOLTIP_FLAGS)ComCtl32.TTF.RTLREADING; + } + + ti.Text = tool.text; + ti.Info.rect = tool.rect; + return ti; + } + + ~ControlToolTip() + { + DestroyHandle(); + } + + protected void WndProc(ref Message msg) + { + switch (msg.Msg) + { + case WindowMessages.WM_SETFOCUS: + return; + default: + window.DefWndProc(ref msg); + break; + } + } + + private class ToolTipNativeWindow : NativeWindow + { + readonly ControlToolTip control; + + internal ToolTipNativeWindow(ControlToolTip control) + { + this.control = control; + } + + protected override void WndProc(ref Message m) + { + if (control != null) + { + control.WndProc(ref m); + } + } + } + } + } +} + diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarDrawItemEventArgs.cs b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarDrawItemEventArgs.cs new file mode 100644 index 00000000000..5d0e2ff0066 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarDrawItemEventArgs.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Drawing; + +namespace System.Windows.Forms +{ + /// + /// Provides data for the + /// event. + /// + public class StatusBarDrawItemEventArgs : DrawItemEventArgs + { + /// + /// Initializes a new instance of the + /// class. + /// + public StatusBarDrawItemEventArgs(Graphics g, Font font, Rectangle r, int itemId, + DrawItemState itemState, StatusBarPanel panel) + : base(g, font, r, itemId, itemState) + { + Panel = panel; + } + + /// + /// Initializes a new instance of the + /// class using the Forecolor and Backcolor. + /// + public StatusBarDrawItemEventArgs(Graphics g, Font font, Rectangle r, int itemId, + DrawItemState itemState, StatusBarPanel panel, + Color foreColor, Color backColor) + : base(g, font, r, itemId, itemState, foreColor, backColor) + { + Panel = panel; + } + + /// + /// Specifies the to draw. + /// + public StatusBarPanel Panel { get; } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarDrawItemEventHandler.cs b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarDrawItemEventHandler.cs new file mode 100644 index 00000000000..dea78084975 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarDrawItemEventHandler.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Represents a method that will handle the + /// event of a . + /// + public delegate void StatusBarDrawItemEventHandler(object sender, StatusBarDrawItemEventArgs sbdevent); +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanel.cs b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanel.cs new file mode 100644 index 00000000000..224dc8d9285 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanel.cs @@ -0,0 +1,735 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace System.Windows.Forms +{ + /// + /// Stores the + /// control panel's information. + /// + [ + ToolboxItem(false), + DesignTimeVisible(false), + DefaultProperty(nameof(Text)) + ] + public class StatusBarPanel : Component, ISupportInitialize + { + private const int DEFAULTWIDTH = 100; + private const int DEFAULTMINWIDTH = 10; + private const int PANELTEXTINSET = 3; + private const int PANELGAP = 2; + + private string text = string.Empty; + private string name = string.Empty; + private string toolTipText = string.Empty; + private Icon icon = null; + + private HorizontalAlignment alignment = HorizontalAlignment.Left; + private StatusBarPanelBorderStyle borderStyle = System.Windows.Forms.StatusBarPanelBorderStyle.Sunken; + private StatusBarPanelStyle style = StatusBarPanelStyle.Text; + + // these are package scope so the parent can get at them. + // + private StatusBar parent = null; + private int width = DEFAULTWIDTH; + private int right = 0; + private int minWidth = DEFAULTMINWIDTH; + private int index = 0; + private StatusBarPanelAutoSize autoSize = StatusBarPanelAutoSize.None; + + private bool initializing = false; + + private object userData; + + /// + /// Initializes a new default instance of the class. + /// + public StatusBarPanel() + { + } + + /// + /// Gets or sets the + /// property. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(HorizontalAlignment.Left), + Localizable(true), + SRDescription(nameof(SR.StatusBarPanelAlignmentDescr)) + ] + public HorizontalAlignment Alignment + { + get + { + return alignment; + } + + set + { + //valid values are 0x0 to 0x2 + if (!ClientUtils.IsEnumValid(value, (int)value, (int)HorizontalAlignment.Left, (int)HorizontalAlignment.Center)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(HorizontalAlignment)); + } + + if (alignment != value) + { + alignment = value; + Realize(); + } + } + } + + /// + /// Gets or sets the + /// property. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(StatusBarPanelAutoSize.None), + RefreshProperties(RefreshProperties.All), + SRDescription(nameof(SR.StatusBarPanelAutoSizeDescr)) + ] + public StatusBarPanelAutoSize AutoSize + { + get + { + return autoSize; + } + + set + { + //valid values are 0x1 to 0x3 + if (!ClientUtils.IsEnumValid(value, (int)value, (int)StatusBarPanelAutoSize.None, (int)StatusBarPanelAutoSize.Contents)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(StatusBarPanelAutoSize)); + } + + if (autoSize != value) + { + autoSize = value; + UpdateSize(); + } + } + } + + /// + /// Gets or sets the + /// + /// property. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(System.Windows.Forms.StatusBarPanelBorderStyle.Sunken), + DispId(NativeMethods.ActiveX.DISPID_BORDERSTYLE), + SRDescription(nameof(SR.StatusBarPanelBorderStyleDescr)) + ] + public StatusBarPanelBorderStyle BorderStyle + { + get + { + return borderStyle; + } + + set + { + //valid values are 0x1 to 0x3 + if (!ClientUtils.IsEnumValid(value, (int)value, (int)StatusBarPanelBorderStyle.None, (int)StatusBarPanelBorderStyle.Sunken)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(StatusBarPanelBorderStyle)); + } + + if (borderStyle != value) + { + borderStyle = value; + Realize(); + if (Created) + { + parent.Invalidate(); + } + } + } + } + + internal bool Created + { + get + { + return parent != null && parent.ArePanelsRealized(); + } + } + + /// + /// Gets or sets the + /// property. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(null), + Localizable(true), + SRDescription(nameof(SR.StatusBarPanelIconDescr)) + ] + public Icon Icon + { + get + { + // unfortunately we have no way of getting the icon from the control. + return icon; + } + + set + { + + if (value != null && (((Icon)value).Height > SystemInformation.SmallIconSize.Height || ((Icon)value).Width > SystemInformation.SmallIconSize.Width)) + { + icon = new Icon(value, SystemInformation.SmallIconSize); + } + else + { + icon = value; + } + + if (Created) + { + IntPtr handle = (icon == null) ? IntPtr.Zero : icon.Handle; + parent.SendMessage(NativeMethods.SB_SETICON, (IntPtr)GetIndex(), handle); + + } + + UpdateSize(); + if (Created) + { + parent.Invalidate(); + } + } + } + + /// + /// Expose index internally + /// + internal int Index + { + get + { + return index; + } + set + { + index = value; + } + } + + /// + /// Gets or sets the minimum width the can be within the + /// control. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(DEFAULTMINWIDTH), + Localizable(true), + RefreshProperties(RefreshProperties.All), + SRDescription(nameof(SR.StatusBarPanelMinWidthDescr)) + ] + public int MinWidth + { + get + { + return minWidth; + } + set + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), value, string.Format(SR.InvalidLowBoundArgumentEx, nameof(MinWidth), value, 0)); + } + + if (value != minWidth) + { + minWidth = value; + + UpdateSize(); + if (minWidth > Width) + { + Width = value; + } + } + } + } + + /// + /// Gets or sets the name of the panel. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + Localizable(true), + SRDescription(nameof(SR.StatusBarPanelNameDescr)) + ] + public string Name + { + get + { + return WindowsFormsUtils.GetComponentName(this, name); + } + set + { + name = value; + if (Site != null) + { + Site.Name = name; + } + } + } + + /// + /// Represents the + /// control which hosts the + /// panel. + /// + [Browsable(false)] + public StatusBar Parent + { + get + { + return parent; + } + } + + /// + /// Expose a direct setter for parent internally + /// + internal StatusBar ParentInternal + { + set + { + parent = value; + } + } + + /// + /// Expose right internally + /// + internal int Right + { + get + { + return right; + } + set + { + right = value; + } + } + + /// + /// Gets or sets the style of the panel. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(StatusBarPanelStyle.Text), + SRDescription(nameof(SR.StatusBarPanelStyleDescr)) + ] + public StatusBarPanelStyle Style + { + get { return style; } + set + { + //valid values are 0x1 to 0x2 + if (!ClientUtils.IsEnumValid(value, (int)value, (int)StatusBarPanelStyle.Text, (int)StatusBarPanelStyle.OwnerDraw)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(StatusBarPanelStyle)); + } + + if (style != value) + { + style = value; + Realize(); + if (Created) + { + parent.Invalidate(); + } + } + } + } + + [ + SRCategory(nameof(SR.CatData)), + Localizable(false), + Bindable(true), + SRDescription(nameof(SR.ControlTagDescr)), + DefaultValue(null), + TypeConverter(typeof(StringConverter)), + ] + public object Tag + { + get + { + return userData; + } + set + { + userData = value; + } + } + + /// + /// Gets or sets the text of the panel. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + Localizable(true), + DefaultValue(""), + SRDescription(nameof(SR.StatusBarPanelTextDescr)) + ] + public string Text + { + get + { + if (text == null) + { + return ""; + } + else + { + return text; + } + } + set + { + if (value == null) + { + value = string.Empty; + } + + if (!Text.Equals(value)) + { + + if (value.Length == 0) + { + text = null; + } + else + { + text = value; + } + + Realize(); + UpdateSize(); + } + } + } + + /// + /// Gets + /// or sets the panel's tool tip text. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + Localizable(true), + DefaultValue(""), + SRDescription(nameof(SR.StatusBarPanelToolTipTextDescr)) + ] + public string ToolTipText + { + get + { + if (toolTipText == null) + { + return ""; + } + else + { + return toolTipText; + } + } + set + { + if (value == null) + { + value = string.Empty; + } + + if (!ToolTipText.Equals(value)) + { + + if (value.Length == 0) + { + toolTipText = null; + } + else + { + toolTipText = value; + } + + if (Created) + { + parent.UpdateTooltip(this); + } + } + } + } + + /// + /// Gets or sets the width of the within the + /// control. + /// + [ + Localizable(true), + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(DEFAULTWIDTH), + SRDescription(nameof(SR.StatusBarPanelWidthDescr)) + ] + public int Width + { + get + { + return width; + } + set + { + if (!initializing && value < minWidth) + { + throw new ArgumentOutOfRangeException(nameof(Width), SR.WidthGreaterThanMinWidth); + } + + width = value; + UpdateSize(); + } + } + + /// + /// Handles tasks required when the control is being initialized. + /// + public void BeginInit() + { + initializing = true; + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (parent != null) + { + int index = GetIndex(); + if (index != -1) + { + parent.Panels.RemoveAt(index); + } + } + } + + base.Dispose(disposing); + } + + /// + /// Called when initialization of the control is complete. + /// + public void EndInit() + { + initializing = false; + + if (Width < MinWidth) + { + Width = MinWidth; + } + } + + /// + /// Gets the width of the contents of the panel + /// + internal int GetContentsWidth(bool newPanel) + { + string text; + if (newPanel) + { + if (this.text == null) + { + text = string.Empty; + } + else + { + text = this.text; + } + } + else + { + text = Text; + } + + Graphics g = parent.CreateGraphicsInternal(); + Size sz = Size.Ceiling(g.MeasureString(text, parent.Font)); + if (icon != null) + { + sz.Width += icon.Size.Width + 5; + } + + g.Dispose(); + + int width = sz.Width + SystemInformation.BorderSize.Width * 2 + PANELTEXTINSET * 2 + PANELGAP; + return Math.Max(width, minWidth); + } + + /// + /// Returns the index of the panel by making the parent control search + /// for it within its list. + /// + private int GetIndex() + { + return index; + } + + /// + /// Sets all the properties for this panel. + /// + internal void Realize() + { + if (Created) + { + string text; + string sendText; + int border = 0; + + if (this.text == null) + { + text = string.Empty; + } + else + { + text = this.text; + } + + HorizontalAlignment align = alignment; + // Translate the alignment for Rtl apps + // + if (parent.RightToLeft == RightToLeft.Yes) + { + switch (align) + { + case HorizontalAlignment.Left: + align = HorizontalAlignment.Right; + break; + case HorizontalAlignment.Right: + align = HorizontalAlignment.Left; + break; + } + } + + switch (align) + { + case HorizontalAlignment.Center: + sendText = "\t" + text; + break; + case HorizontalAlignment.Right: + sendText = "\t\t" + text; + break; + default: + sendText = text; + break; + } + + switch (borderStyle) + { + case StatusBarPanelBorderStyle.None: + border |= NativeMethods.SBT_NOBORDERS; + break; + case StatusBarPanelBorderStyle.Sunken: + break; + case StatusBarPanelBorderStyle.Raised: + border |= NativeMethods.SBT_POPOUT; + break; + } + + switch (style) + { + case StatusBarPanelStyle.Text: + break; + case StatusBarPanelStyle.OwnerDraw: + border |= NativeMethods.SBT_OWNERDRAW; + break; + } + + int wparam = GetIndex() | border; + if (parent.RightToLeft == RightToLeft.Yes) + { + wparam |= NativeMethods.SBT_RTLREADING; + } + + int result = (int)UnsafeNativeMethods.SendMessage(new HandleRef(parent, parent.Handle), NativeMethods.SB_SETTEXT, (IntPtr)wparam, sendText); + + if (result == 0) + { + throw new InvalidOperationException(SR.UnableToSetPanelText); + } + + if (icon != null && style != StatusBarPanelStyle.OwnerDraw) + { + parent.SendMessage(NativeMethods.SB_SETICON, (IntPtr)GetIndex(), icon.Handle); + } + else + { + parent.SendMessage(NativeMethods.SB_SETICON, (IntPtr)GetIndex(), IntPtr.Zero); + } + + if (style == StatusBarPanelStyle.OwnerDraw) + { + RECT rect = new RECT(); + result = (int)UnsafeNativeMethods.SendMessage(new HandleRef(parent, parent.Handle), NativeMethods.SB_GETRECT, (IntPtr)GetIndex(), ref rect); + + if (result != 0) + { + parent.Invalidate(Rectangle.FromLTRB(rect.left, rect.top, rect.right, rect.bottom)); + } + } + } + } + + private void UpdateSize() + { + if (autoSize == StatusBarPanelAutoSize.Contents) + { + ApplyContentSizing(); + } + else + { + if (Created) + { + parent.DirtyLayout(); + parent.PerformLayout(); + } + } + } + + private void ApplyContentSizing() + { + if (autoSize == StatusBarPanelAutoSize.Contents && + parent != null) + { + int newWidth = GetContentsWidth(false); + if (newWidth != Width) + { + Width = newWidth; + if (Created) + { + parent.DirtyLayout(); + parent.PerformLayout(); + } + } + } + } + + /// + /// Retrieves a string that contains information about the + /// panel. + /// + public override string ToString() + { + return "StatusBarPanel: {" + Text + "}"; + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelAutoSize.cs b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelAutoSize.cs new file mode 100644 index 00000000000..329b982eb20 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelAutoSize.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Specifies how a panel on a status bar changes when the status bar resizes. + /// + public enum StatusBarPanelAutoSize + { + /// + /// The panel does not change its size when the status bar resizes. + /// + None = 1, + + /// + /// The panel shares the available status bar space (the space not taken + /// up by panels with the and + /// settings) with other panels that have the setting. + /// + Spring = 2, + + /// + /// The width of the panel is determined by its contents. + /// + Contents = 3, + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelBorderStyle.cs b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelBorderStyle.cs new file mode 100644 index 00000000000..d339f8f2d99 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelBorderStyle.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Specifies the border style of a panel on the . + /// + public enum StatusBarPanelBorderStyle + { + /// + /// No border. + /// + None = 1, + + /// + /// A raised border. + /// + Raised = 2, + + /// + /// A sunken border. + /// + Sunken = 3, + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelClickEventArgs.cs b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelClickEventArgs.cs new file mode 100644 index 00000000000..bc7de6d276d --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelClickEventArgs.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Provides data for the + /// event. + /// + public class StatusBarPanelClickEventArgs : MouseEventArgs + { + /// + /// Initializes a new instance of the + /// class. + /// + public StatusBarPanelClickEventArgs(StatusBarPanel statusBarPanel, MouseButtons button, int clicks, int x, int y) : base(button, clicks, x, y, 0) + { + StatusBarPanel = statusBarPanel; + } + + /// + /// Specifies the that represents the clicked panel. + /// + public StatusBarPanel StatusBarPanel { get; } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelClickEventHandler.cs b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelClickEventHandler.cs new file mode 100644 index 00000000000..c20ea1a5a81 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelClickEventHandler.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Represents a method that will handle the + /// event of a . + /// + public delegate void StatusBarPanelClickEventHandler(object sender, StatusBarPanelClickEventArgs e); +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelStyle.cs b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelStyle.cs new file mode 100644 index 00000000000..577bd23650f --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/StatusBarPanelStyle.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Specifies whether a panel on a status bar is owner drawn or system drawn. + /// + public enum StatusBarPanelStyle + { + /// + /// The panel is drawn by the system. + /// + Text = 1, + + /// + /// The panel is drawn by the owner. + /// + OwnerDraw = 2, + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/TabControl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/TabControl.cs index f4d034a0a4c..9752d11e556 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/TabControl.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/TabControl.cs @@ -9,6 +9,7 @@ using System.Windows.Forms.Layout; using static Interop; using static Interop.ComCtl32; +using INITCOMMONCONTROLSEX = Windows.Win32.UI.Controls.INITCOMMONCONTROLSEX; namespace System.Windows.Forms; @@ -1968,7 +1969,14 @@ private bool WmSelChange() if (IsAccessibilityObjectCreated && SelectedTab?.ParentInternal is TabControl) { SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.SelectionItem_ElementSelectedEventId); - BeginInvoke((MethodInvoker)(() => SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId))); + BeginInvoke((MethodInvoker)(() => + { + if (IsAccessibilityObjectCreated && SelectedTab?.ParentInternal is TabControl && + !SelectedTab.IsDisposed && SelectedTab.TabAccessibilityObject is not null) + { + SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId); + } + })); } } else diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/TextRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/TextRenderer.cs index 7a0e7b69ba4..5704b6ab95e 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/TextRenderer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/TextRenderer.cs @@ -630,7 +630,7 @@ internal static ApplyGraphicsProperties GetApplyStateFlags(IDeviceContext device // translation (rotation for example), and this likely impacted the decision to only have a translation // flag when this was originally written. - Debug.Assert(apply.HasFlag(ApplyGraphicsProperties.Clipping) +/* Debug.Assert(apply.HasFlag(ApplyGraphicsProperties.Clipping) || graphics.Clip is null || graphics.Clip.GetHrgn(graphics) == IntPtr.Zero, "Must preserve Graphics clipping region!"); @@ -638,7 +638,7 @@ internal static ApplyGraphicsProperties GetApplyStateFlags(IDeviceContext device Debug.Assert(apply.HasFlag(ApplyGraphicsProperties.TranslateTransform) || graphics.Transform is null || graphics.Transform.IsIdentity, - "Must preserve Graphics transformation!"); + "Must preserve Graphics transformation!");*/ } #endif diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolBar.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBar.cs new file mode 100644 index 00000000000..8e25db545e5 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBar.cs @@ -0,0 +1,2243 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.Runtime.InteropServices; +using static Interop; + +namespace System.Windows.Forms +{ + /// + /// Represents a Windows toolbar. + /// + [ + ComVisible(true), + ClassInterface(ClassInterfaceType.AutoDispatch), + DefaultEvent(nameof(ButtonClick)), + Designer("System.Windows.Forms.Design.ToolBarDesigner, " + AssemblyRef.SystemDesign), + DefaultProperty(nameof(Buttons)) + ] + public class ToolBar : Control + { + private readonly ToolBarButtonCollection buttonsCollection; + + /// + /// The size of a button in the ToolBar + /// + internal Size buttonSize = System.Drawing.Size.Empty; + + /// + /// This is used by our autoSizing support. + /// + private int requestedSize; + /// + /// This represents the width of the drop down arrow we have if the + /// DropDownArrows property is true. this value is used by the ToolBarButton + /// objects to compute their size + /// + internal const int DDARROW_WIDTH = 15; + + /// + /// Indicates what our appearance will be. This will either be normal + /// or flat. + /// + private ToolBarAppearance appearance = ToolBarAppearance.Normal; + + /// + /// Indicates whether or not we have a border + /// + private BorderStyle borderStyle = System.Windows.Forms.BorderStyle.None; + + /// + /// The array of buttons we're working with. + /// + private ToolBarButton[] buttons; + + /// + /// The number of buttons we're working with + /// + private int buttonCount = 0; + + /// + /// Indicates if text captions should go underneath images in buttons or + /// to the right of them + /// + private ToolBarTextAlign textAlign = ToolBarTextAlign.Underneath; + + /// + /// The ImageList object that contains the main images for our control. + /// + private ImageList imageList = null; + + /// + /// The maximum width of buttons currently being displayed. This is needed + /// by our autoSizing code. If this value is -1, it needs to be recomputed. + /// + private int maxWidth = -1; + private int hotItem = -1; + + // Track the current scale factor so we can scale our buttons + private float currentScaleDX = 1.0F; + private float currentScaleDY = 1.0F; + + private const int TOOLBARSTATE_wrappable = 0x00000001; + private const int TOOLBARSTATE_dropDownArrows = 0x00000002; + private const int TOOLBARSTATE_divider = 0x00000004; + private const int TOOLBARSTATE_showToolTips = 0x00000008; + private const int TOOLBARSTATE_autoSize = 0x00000010; + + // PERF: take all the bools and put them into a state variable + private Collections.Specialized.BitVector32 toolBarState; // see TOOLBARSTATE_ consts above + + // event handlers + // + private ToolBarButtonClickEventHandler onButtonClick = null; + private ToolBarButtonClickEventHandler onButtonDropDown = null; + + /// + /// Initializes a new instance of the class. + /// + public ToolBar() + : base() + { + // Set this BEFORE calling any other methods so that these defaults will be propagated + toolBarState = new Collections.Specialized.BitVector32(TOOLBARSTATE_autoSize | + TOOLBARSTATE_showToolTips | + TOOLBARSTATE_divider | + TOOLBARSTATE_dropDownArrows | + TOOLBARSTATE_wrappable); + + SetStyle(ControlStyles.UserPaint, false); + SetStyle(ControlStyles.FixedHeight, AutoSize); + SetStyle(ControlStyles.FixedWidth, false); + TabStop = false; + Dock = DockStyle.Top; + buttonsCollection = new ToolBarButtonCollection(this); + } + + /// + /// Gets or sets the appearance of the toolbar + /// control and its buttons. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(ToolBarAppearance.Normal), + Localizable(true), + SRDescription(nameof(SR.ToolBarAppearanceDescr)) + ] + public ToolBarAppearance Appearance + { + get + { + return appearance; + } + + set + { + //valid values are 0x0 to 0x1 + if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolBarAppearance.Normal, (int)ToolBarAppearance.Flat)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(ToolBarAppearance)); + } + + if (value != appearance) + { + appearance = value; + RecreateHandle(); + } + } + } + + /// + /// Indicates whether the toolbar + /// adjusts its size automatically based on the size of the buttons and the + /// dock style. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(true), + Localizable(true), + SRDescription(nameof(SR.ToolBarAutoSizeDescr)), + Browsable(true), + EditorBrowsable(EditorBrowsableState.Always), + DesignerSerializationVisibility(DesignerSerializationVisibility.Visible) + ] + public override bool AutoSize + { + get + { + return toolBarState[TOOLBARSTATE_autoSize]; + } + + set + { + // Note that we intentionally do not call base. Toolbars size themselves by + // overriding SetBoundsCore (old RTM code). We let CommonProperties.GetAutoSize + // continue to return false to keep our LayoutEngines from messing with TextBoxes. + // This is done for backwards compatibility since the new AutoSize behavior differs. + if (AutoSize != value) + { + toolBarState[TOOLBARSTATE_autoSize] = value; + if (Dock == DockStyle.Left || Dock == DockStyle.Right) + { + SetStyle(ControlStyles.FixedWidth, AutoSize); + SetStyle(ControlStyles.FixedHeight, false); + } + else + { + SetStyle(ControlStyles.FixedHeight, AutoSize); + SetStyle(ControlStyles.FixedWidth, false); + } + + AdjustSize(Dock); + OnAutoSizeChanged(EventArgs.Empty); + } + } + } + + [SRCategory(nameof(SR.CatPropertyChanged)), SRDescription(nameof(SR.ControlOnAutoSizeChangedDescr))] + [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)] + new public event EventHandler AutoSizeChanged + { + add => base.AutoSizeChanged += value; + remove => base.AutoSizeChanged -= value; + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler BackColorChanged + { + add => base.BackColorChanged += value; + remove => base.BackColorChanged -= value; + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override Image BackgroundImage + { + get + { + return base.BackgroundImage; + } + set + { + base.BackgroundImage = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler BackgroundImageChanged + { + add => base.BackgroundImageChanged += value; + remove => base.BackgroundImageChanged -= value; + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override ImageLayout BackgroundImageLayout + { + get + { + return base.BackgroundImageLayout; + } + set + { + base.BackgroundImageLayout = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler BackgroundImageLayoutChanged + { + add => base.BackgroundImageLayoutChanged += value; + remove => base.BackgroundImageLayoutChanged -= value; + } + + /// + /// Gets or sets + /// the border style of the toolbar control. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(BorderStyle.None), + DispId(PInvoke.DISPID_BORDERSTYLE), + SRDescription(nameof(SR.ToolBarBorderStyleDescr)) + ] + public BorderStyle BorderStyle + { + get + { + return borderStyle; + } + + set + { + //valid values are 0x0 to 0x2 + if (!ClientUtils.IsEnumValid(value, (int)value, (int)BorderStyle.None, (int)BorderStyle.Fixed3D)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(BorderStyle)); + } + + if (borderStyle != value) + { + borderStyle = value; + + //UpdateStyles(); + RecreateHandle(); // Looks like we need to recreate the handle to avoid painting glitches + } + } + } + + /// + /// A collection of controls assigned to the + /// toolbar control. The property is read-only. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), + Localizable(true), + SRDescription(nameof(SR.ToolBarButtonsDescr)), + MergableProperty(false) + ] + public ToolBarButtonCollection Buttons + { + get + { + return buttonsCollection; + } + } + + /// + /// Gets or sets + /// the size of the buttons on the toolbar control. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + RefreshProperties(RefreshProperties.All), + Localizable(true), + SRDescription(nameof(SR.ToolBarButtonSizeDescr)) + ] + public Size ButtonSize + { + get + { + if (buttonSize.IsEmpty) + { + + // Obtain the current buttonsize of the first button from the winctl control + // + if (IsHandleCreated && buttons != null && buttonCount > 0) + { + int result = (int)PInvoke.SendMessage(this, PInvoke.TB_GETBUTTONSIZE, 0, 0); + if (result > 0) + { + return new Size(NativeMethods.Util.LOWORD(result), NativeMethods.Util.HIWORD(result)); + } + } + + if (TextAlign == ToolBarTextAlign.Underneath) + { + return new Size(39, 36); // Default button size + } + else + { + return new Size(23, 22); // Default button size + } + } + else + { + return buttonSize; + } + } + + set + { + + if (value.Width < 0 || value.Height < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), value, string.Format(SR.InvalidArgument, nameof(ButtonSize), value)); + } + + if (buttonSize != value) + { + buttonSize = value; + maxWidth = -1; // Force recompute of maxWidth + RecreateHandle(); + AdjustSize(Dock); + } + } + } + + /// + /// Returns the parameters needed to create the handle. Inheriting classes + /// can override this to provide extra functionality. They should not, + /// however, forget to get base.CreateParams first to get the struct + /// filled up with the basic info. + /// + protected override CreateParams CreateParams + { + get + { + CreateParams cp = base.CreateParams; + cp.ClassName = ComCtl32.WindowClasses.WC_TOOLBAR; + + // windows forms has it's own docking code. + // + cp.Style |= PInvoke.CCS_NOPARENTALIGN + | PInvoke.CCS_NORESIZE; + // | NativeMethods.WS_CHILD was commented out since setTopLevel should be able to work. + + if (!Divider) + { + cp.Style |= PInvoke.CCS_NODIVIDER; + } + + if (Wrappable) + { + cp.Style |= (int)PInvoke.TBSTYLE_WRAPABLE; + } + + if (ShowToolTips && !DesignMode) + { + cp.Style |= (int)PInvoke.TBSTYLE_TOOLTIPS; + } + + cp.ExStyle &= (~(int)WINDOW_EX_STYLE.WS_EX_CLIENTEDGE); + cp.Style &= (~(int)WINDOW_STYLE.WS_BORDER); + switch (borderStyle) + { + case BorderStyle.Fixed3D: + cp.ExStyle |= (int)WINDOW_EX_STYLE.WS_EX_CLIENTEDGE; + break; + case BorderStyle.FixedSingle: + cp.Style |= (int)WINDOW_STYLE.WS_BORDER; + break; + } + + switch (appearance) + { + case ToolBarAppearance.Normal: + break; + case ToolBarAppearance.Flat: + cp.Style |= (int)PInvoke.TBSTYLE_FLAT; + break; + } + + switch (textAlign) + { + case ToolBarTextAlign.Underneath: + break; + case ToolBarTextAlign.Right: + cp.Style |= (int)PInvoke.TBSTYLE_LIST; + break; + } + + return cp; + } + } + + protected override ImeMode DefaultImeMode + { + get + { + return ImeMode.Disable; + } + } + + /// + /// Deriving classes can override this to configure a default size for their control. + /// This is more efficient than setting the size in the control's constructor. + /// + protected override Size DefaultSize + { + get + { + return new Size(100, 22); + } + } + + /// + /// Gets or sets a value indicating + /// whether the toolbar displays a divider. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(true), + SRDescription(nameof(SR.ToolBarDividerDescr)) + ] + public bool Divider + { + get + { + return toolBarState[TOOLBARSTATE_divider]; + } + + set + { + if (Divider != value) + { + + toolBarState[TOOLBARSTATE_divider] = value; + RecreateHandle(); + } + } + } + + /// + /// Sets the way in which this ToolBar is docked to its parent. We need to + /// override this to ensure autoSizing works correctly + /// + [ + Localizable(true), + DefaultValue(DockStyle.Top) + ] + public override DockStyle Dock + { + get { return base.Dock; } + + set + { + //valid values are 0x0 to 0x5 + if (!ClientUtils.IsEnumValid(value, (int)value, (int)DockStyle.None, (int)DockStyle.Fill)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(DockStyle)); + } + + if (Dock != value) + { + if (value == DockStyle.Left || value == DockStyle.Right) + { + SetStyle(ControlStyles.FixedWidth, AutoSize); + SetStyle(ControlStyles.FixedHeight, false); + } + else + { + SetStyle(ControlStyles.FixedHeight, AutoSize); + SetStyle(ControlStyles.FixedWidth, false); + } + + AdjustSize(value); + base.Dock = value; + } + } + } + + /// + /// This property is overridden and hidden from statement completion + /// on controls that are based on Win32 Native Controls. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override bool DoubleBuffered + { + get + { + return base.DoubleBuffered; + } + set + { + base.DoubleBuffered = value; + } + } + + /// + /// Gets or sets a value indicating whether drop-down buttons on a + /// toolbar display down arrows. + /// + [ + DefaultValue(false), + SRCategory(nameof(SR.CatAppearance)), + Localizable(true), + SRDescription(nameof(SR.ToolBarDropDownArrowsDescr)) + ] + public bool DropDownArrows + { + get + { + return toolBarState[TOOLBARSTATE_dropDownArrows]; + } + + set + { + + if (DropDownArrows != value) + { + toolBarState[TOOLBARSTATE_dropDownArrows] = value; + RecreateHandle(); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler ForeColorChanged + { + add => base.ForeColorChanged += value; + remove => base.ForeColorChanged -= value; + } + + /// + /// Gets or sets the collection of images available to the toolbar button + /// controls. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(null), + SRDescription(nameof(SR.ToolBarImageListDescr)) + ] + public ImageList ImageList + { + get + { + return imageList; + } + set + { + if (value != imageList) + { + EventHandler recreateHandler = new EventHandler(ImageListRecreateHandle); + EventHandler disposedHandler = new EventHandler(DetachImageList); + + if (imageList != null) + { + imageList.Disposed -= disposedHandler; + imageList.RecreateHandle -= recreateHandler; + } + + imageList = value; + + if (value != null) + { + value.Disposed += disposedHandler; + value.RecreateHandle += recreateHandler; + } + + if (IsHandleCreated) + { + RecreateHandle(); + } + } + } + } + + /// + /// Gets the size of the images in the image list assigned to the + /// toolbar. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SRDescription(nameof(SR.ToolBarImageSizeDescr)) + ] + public Size ImageSize + { + get + { + if (imageList != null) + { + return imageList.ImageSize; + } + else + { + return new Size(0, 0); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public ImeMode ImeMode + { + get + { + return base.ImeMode; + } + set + { + base.ImeMode = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public new event EventHandler ImeModeChanged + { + add => base.ImeModeChanged += value; + remove => base.ImeModeChanged -= value; + } + + /// + /// The preferred height for this ToolBar control. This is + /// used by the AutoSizing code. + /// + internal int PreferredHeight + { + get + { + int height = 0; + + if (buttons == null || buttonCount == 0 || !IsHandleCreated) + { + height = ButtonSize.Height; + } + else + { + // get the first visible button and get it's height + // + RECT rect = new RECT(); + int firstVisible; + + for (firstVisible = 0; firstVisible < buttons.Length; firstVisible++) + { + if (buttons[firstVisible] != null && buttons[firstVisible].Visible) + { + break; + } + } + + if (firstVisible == buttons.Length) + { + firstVisible = 0; + } + + PInvoke.SendMessage(this, PInvoke.TB_GETRECT, (WPARAM)firstVisible, ref rect); + + // height is the button's height plus some extra goo + // + height = rect.bottom - rect.top; + } + + // if the ToolBar is wrappable, and there is more than one row, make + // sure the height is correctly adjusted + // + if (Wrappable && IsHandleCreated) + { + height *= unchecked((int)PInvoke.SendMessage(this, PInvoke.TB_GETROWS, 0, 0)); + } + + height = (height > 0) ? height : 1; + + switch (borderStyle) + { + case BorderStyle.FixedSingle: + height += SystemInformation.BorderSize.Height; + break; + case BorderStyle.Fixed3D: + height += SystemInformation.Border3DSize.Height; + break; + } + + if (Divider) + { + height += 2; + } + + height += 4; + + return height; + } + + } + + /// + /// The preferred width for this ToolBar control. This is + /// used by AutoSizing code. + /// NOTE!!!!!!!!! This function assumes it's only going to get called + /// if the control is docked left or right [ie, it really + /// just returns a max width] + /// + internal int PreferredWidth + { + get + { + int width; + + // fortunately, we compute this value sometimes, so we can just + // use it if we have it. + // + if (maxWidth == -1) + { + // don't have it, have to recompute + // + if (!IsHandleCreated || buttons == null) + { + maxWidth = ButtonSize.Width; + } + else + { + + RECT rect = new RECT(); + + for (int x = 0; x < buttonCount; x++) + { + PInvoke.SendMessage(this, PInvoke.TB_GETRECT, 0, ref rect); + if ((rect.right - rect.left) > maxWidth) + { + maxWidth = rect.right - rect.left; + } + } + } + } + + width = maxWidth; + + if (borderStyle != BorderStyle.None) + { + width += SystemInformation.BorderSize.Height * 4 + 3; + } + + return width; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override RightToLeft RightToLeft + { + get + { + return base.RightToLeft; + } + set + { + base.RightToLeft = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public new event EventHandler RightToLeftChanged + { + add => base.RightToLeftChanged += value; + remove => base.RightToLeftChanged -= value; + } + + /// + /// We need to track the current scale factor so that we can tell the + /// unmanaged control how to scale its buttons. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void ScaleCore(float dx, float dy) + { + currentScaleDX = dx; + currentScaleDY = dy; + base.ScaleCore(dx, dy); + UpdateButtons(); + } + + /// + /// We need to track the current scale factor so that we can tell the + /// unmanaged control how to scale its buttons. + /// + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + currentScaleDX = factor.Width; + currentScaleDY = factor.Height; + base.ScaleControl(factor, specified); + } + + /// + /// Gets or sets a value indicating whether the toolbar displays a + /// tool tip for each button. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(false), + Localizable(true), + SRDescription(nameof(SR.ToolBarShowToolTipsDescr)) + ] + public bool ShowToolTips + { + get + { + return toolBarState[TOOLBARSTATE_showToolTips]; + } + set + { + if (ShowToolTips != value) + { + + toolBarState[TOOLBARSTATE_showToolTips] = value; + RecreateHandle(); + } + } + } + + [DefaultValue(false)] + new public bool TabStop + { + get + { + return base.TabStop; + } + set + { + base.TabStop = value; + } + } + + [ + Browsable(false), EditorBrowsable(EditorBrowsableState.Never), + Bindable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) + ] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + new public event EventHandler TextChanged + { + add => base.TextChanged += value; + remove => base.TextChanged -= value; + } + + /// + /// Gets or sets the alignment of text in relation to each + /// image displayed on + /// the toolbar button controls. + /// + [ + SRCategory(nameof(SR.CatAppearance)), + DefaultValue(ToolBarTextAlign.Underneath), + Localizable(true), + SRDescription(nameof(SR.ToolBarTextAlignDescr)) + ] + public ToolBarTextAlign TextAlign + { + get + { + return textAlign; + } + set + { + //valid values are 0x0 to 0x1 + if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolBarTextAlign.Underneath, (int)ToolBarTextAlign.Right)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(ToolBarTextAlign)); + } + + if (textAlign == value) + { + return; + } + + textAlign = value; + RecreateHandle(); + } + } + + /// + /// Gets + /// or sets a value + /// indicating whether the toolbar buttons wrap to the next line if the + /// toolbar becomes too small to display all the buttons + /// on the same line. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(true), + Localizable(true), + SRDescription(nameof(SR.ToolBarWrappableDescr)) + ] + public bool Wrappable + { + get + { + return toolBarState[TOOLBARSTATE_wrappable]; + } + set + { + if (Wrappable != value) + { + toolBarState[TOOLBARSTATE_wrappable] = value; + RecreateHandle(); + } + } + } + + /// + /// Occurs when a on the is clicked. + /// + [SRCategory(nameof(SR.CatBehavior)), SRDescription(nameof(SR.ToolBarButtonClickDescr))] + public event ToolBarButtonClickEventHandler ButtonClick + { + add => onButtonClick += value; + remove => onButtonClick -= value; + } + + /// + /// Occurs when a drop-down style or its down arrow is clicked. + /// + [SRCategory(nameof(SR.CatBehavior)), SRDescription(nameof(SR.ToolBarButtonDropDownDescr))] + public event ToolBarButtonClickEventHandler ButtonDropDown + { + add => onButtonDropDown += value; + remove => onButtonDropDown -= value; + } + + /// + /// ToolBar Onpaint. + /// + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public new event PaintEventHandler Paint + { + add => base.Paint += value; + remove => base.Paint -= value; + } + + /// + /// Adjusts the height or width of the ToolBar to make sure we have enough + /// room to show the buttons. + /// + // we pass in a value for dock rather than calling Dock ourselves + // because we can't change Dock until the size has been properly adjusted. + private void AdjustSize(DockStyle dock) + { + int saveSize = requestedSize; + try + { + if (dock == DockStyle.Left || dock == DockStyle.Right) + { + Width = AutoSize ? PreferredWidth : saveSize; + } + else + { + Height = AutoSize ? PreferredHeight : saveSize; + } + } + finally + { + requestedSize = saveSize; + } + } + + /// + /// This routine lets us change a bunch of things about the toolbar without + /// having each operation wait for the paint to complete. This must be + /// matched up with a call to endUpdate(). + /// + internal void BeginUpdate() + { + BeginUpdateInternal(); + } + + protected override void CreateHandle() + { + if (!RecreatingHandle) + { + using ThemingScope scope = new(Application.UseVisualStyles); + INITCOMMONCONTROLSEX icc = new INITCOMMONCONTROLSEX + { + dwICC = INITCOMMONCONTROLSEX_ICC.ICC_BAR_CLASSES + }; + PInvoke.InitCommonControlsEx(icc); + } + + base.CreateHandle(); + } + + /// + /// Resets the imageList to null. We wire this method up to the imageList's + /// Dispose event, so that we don't hang onto an imageList that's gone away. + /// + private void DetachImageList(object? sender, EventArgs e) + { + ImageList = null; + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + // + lock (this) + { + // We need to mark the Disposing state here so buttonsCollection won't attempt to update + // the buttons. + bool currentDisposing = GetState(States.Disposing); + + try + { + SetState(States.Disposing, true); + + if (imageList != null) + { + imageList.Disposed -= new EventHandler(DetachImageList); + imageList = null; + } + + if (buttonsCollection != null) + { + ToolBarButton[] buttonCopy = new ToolBarButton[buttonsCollection.Count]; + ((ICollection)buttonsCollection).CopyTo(buttonCopy, 0); + buttonsCollection.Clear(); + + foreach (ToolBarButton b in buttonCopy) + { + b.Dispose(); + } + } + } + finally + { + SetState(States.Disposing, currentDisposing); + } + } + } + + base.Dispose(disposing); + } + + /// + /// This routine lets us change a bunch of things about the toolbar without + /// having each operation wait for the paint to complete. This must be + /// matched up with a call to beginUpdate(). + /// + internal void EndUpdate() + { + EndUpdateInternal(); + } + + /// + /// Forces the button sizes based on various different things. The default + /// ToolBar button sizing rules are pretty primitive and this tends to be + /// a little better, and lets us actually show things like DropDown Arrows + /// for ToolBars + /// + private void ForceButtonWidths() + { + if (buttons != null && buttonSize.IsEmpty && IsHandleCreated) + { + + // force ourselves to re-compute this each time + // + maxWidth = -1; + + for (int x = 0; x < buttonCount; x++) + { + + NativeMethods.TBBUTTONINFO tbbi = new NativeMethods.TBBUTTONINFO + { + cbSize = Marshal.SizeOf(), + cx = buttons[x].Width + }; + + if (tbbi.cx > maxWidth) + { + maxWidth = tbbi.cx; + } + + tbbi.dwMask = NativeMethods.TBIF_SIZE; + PInvoke.SendMessage(this, PInvoke.TB_SETBUTTONINFO, (WPARAM)x, ref tbbi); + } + } + } + + private void ImageListRecreateHandle(object sender, EventArgs e) + { + if (IsHandleCreated) + { + RecreateHandle(); + } + } + + private void Insert(int index, ToolBarButton button) + { + button.parent = this; + + if (buttons == null) + { + buttons = new ToolBarButton[4]; + } + else if (buttons.Length == buttonCount) + { + ToolBarButton[] newButtons = new ToolBarButton[buttonCount + 4]; + System.Array.Copy(buttons, 0, newButtons, 0, buttonCount); + buttons = newButtons; + } + + if (index < buttonCount) + { + System.Array.Copy(buttons, index, buttons, index + 1, buttonCount - index); + } + + buttons[index] = button; + buttonCount++; + } + + /// + /// Inserts a button at a given location on the toolbar control. + /// + private void InsertButton(int index, ToolBarButton value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + if (index < 0 || ((buttons != null) && (index > buttonCount))) + { + throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(SR.InvalidArgument, nameof(index), index)); + } + + // insert the button into our local array, and then into the + // real windows ToolBar control + // + Insert(index, value); + if (IsHandleCreated) + { + NativeMethods.TBBUTTON tbbutton = value.GetTBBUTTON(index); + PInvoke.SendMessage(this, PInvoke.TB_INSERTBUTTON, (WPARAM)index, ref tbbutton); + } + + UpdateButtons(); + } + + /// + /// Adds a button to the ToolBar + /// + private int InternalAddButton(ToolBarButton button) + { + if (button == null) + { + throw new ArgumentNullException(nameof(button)); + } + + int index = buttonCount; + Insert(index, button); + return index; + } + + /// + /// Changes the data for a button in the ToolBar, and then does the appropriate + /// work to update the ToolBar control. + /// + internal void InternalSetButton(int index, ToolBarButton value, bool recreate, bool updateText) + { + // tragically, there doesn't appear to be a way to remove the + // string for the button if it has one, so we just have to leave + // it in there. + // + buttons[index].parent = null; + buttons[index].stringIndex = (IntPtr)(-1); + buttons[index] = value; + buttons[index].parent = this; + + if (IsHandleCreated) + { + NativeMethods.TBBUTTONINFO tbbi = value.GetTBBUTTONINFO(updateText, index); + PInvoke.SendMessage(this, PInvoke.TB_SETBUTTONINFO, (WPARAM)index, ref tbbi); + + if (tbbi.pszText != IntPtr.Zero) + { + Marshal.FreeHGlobal(tbbi.pszText); + } + + if (recreate) + { + UpdateButtons(); + } + else + { + // after doing anything with the comctl ToolBar control, this + // appears to be a good idea. + // + PInvoke.SendMessage(this, PInvoke.TB_AUTOSIZE, 0, 0); + + ForceButtonWidths(); + Invalidate(); + } + } + } + + /// + /// Raises the + /// event. + /// + protected virtual void OnButtonClick(ToolBarButtonClickEventArgs e) + { + onButtonClick?.Invoke(this, e); + } + + /// + /// Raises the + /// event. + /// + protected virtual void OnButtonDropDown(ToolBarButtonClickEventArgs e) + { + onButtonDropDown?.Invoke(this, e); + } + + /// + /// Overridden from the control class so we can add all the buttons + /// and do whatever work needs to be done. + /// Don't forget to call base.OnHandleCreated. + /// + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + + // we have to set the button struct size, because they don't. + // + PInvoke.SendMessage(this, PInvoke.TB_BUTTONSTRUCTSIZE, (WPARAM)Marshal.SizeOf(), 0); + + // set up some extra goo + // + if (DropDownArrows) + { + PInvoke.SendMessage(this, PInvoke.TB_SETEXTENDEDSTYLE, 0, (LPARAM)PInvoke.TBSTYLE_EX_DRAWDDARROWS); + } + + // if we have an imagelist, add it in now. + // + if (imageList != null) + { + PInvoke.SendMessage(this, PInvoke.TB_SETIMAGELIST, 0, imageList.Handle); + } + + RealizeButtons(); + + // Force a repaint, as occasionally the ToolBar border does not paint properly + // (comctl ToolBar is flaky) + // + BeginUpdate(); + try + { + Size size = Size; + Size = new Size(size.Width + 1, size.Height); + Size = size; + } + finally + { + EndUpdate(); + } + } + + /// + /// The control is being resized. Make sure the width/height are correct. + /// + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + if (Wrappable) + { + AdjustSize(Dock); + } + } + + /// + /// Overridden to ensure that the buttons and the control resize properly + /// whenever the font changes. + /// + protected override void OnFontChanged(EventArgs e) + { + base.OnFontChanged(e); + if (IsHandleCreated) + { + if (!buttonSize.IsEmpty) + { + SendToolbarButtonSizeMessage(); + } + else + { + AdjustSize(Dock); + ForceButtonWidths(); + } + } + } + + /// + /// Sets all the button data into the ToolBar control + /// + private void RealizeButtons() + { + if (buttons != null) + { + IntPtr ptbbuttons = IntPtr.Zero; + try + { + BeginUpdate(); + // go and add in all the strings for all of our buttons + // + for (int x = 0; x < buttonCount; x++) + { + if (buttons[x].Text.Length > 0) + { + string addString = buttons[x].Text + '\0'.ToString(); + buttons[x].stringIndex = PInvoke.SendMessage(this, PInvoke.TB_ADDSTRING, 0, addString); + } + else + { + buttons[x].stringIndex = (IntPtr)(-1); + } + } + + // insert the buttons and set their parent pointers + // + int cb = Marshal.SizeOf(); + int count = buttonCount; + ptbbuttons = Marshal.AllocHGlobal(checked(cb * count)); + + for (int x = 0; x < count; x++) + { + + NativeMethods.TBBUTTON tbbutton = buttons[x].GetTBBUTTON(x); + Marshal.StructureToPtr(tbbutton, (IntPtr)(checked((long)ptbbuttons + (cb * x))), true); + buttons[x].parent = this; + } + + PInvoke.SendMessage(this, PInvoke.TB_ADDBUTTONS, (WPARAM)count, ptbbuttons); + + // after doing anything with the comctl ToolBar control, this + // appears to be a good idea. + // + PInvoke.SendMessage(this, PInvoke.TB_AUTOSIZE, 0, 0); + + // The win32 ToolBar control is somewhat unpredictable here. We + // have to set the button size after we've created all the + // buttons. Otherwise, we need to manually set the width of all + // the buttons so they look reasonable + // + if (!buttonSize.IsEmpty) + { + SendToolbarButtonSizeMessage(); + } + else + { + ForceButtonWidths(); + } + + AdjustSize(Dock); + } + finally + { + Marshal.FreeHGlobal(ptbbuttons); + EndUpdate(); + } + } + } + + private void RemoveAt(int index) + { + buttons[index].parent = null; + buttons[index].stringIndex = (IntPtr)(-1); + buttonCount--; + + if (index < buttonCount) + { + System.Array.Copy(buttons, index + 1, buttons, index, buttonCount - index); + } + + buttons[buttonCount] = null; + } + + /// + /// Resets the toolbar buttons to the minimum + /// size. + /// + private void ResetButtonSize() + { + buttonSize = Size.Empty; + RecreateHandle(); + } + + /// Sends a TB_SETBUTTONSIZE message to the unmanaged control, with size arguments properly scaled. + private void SendToolbarButtonSizeMessage() + { + PInvoke.SendMessage(this, PInvoke.TB_SETBUTTONSIZE, 0, NativeMethods.Util.MAKELPARAM((int)(buttonSize.Width * currentScaleDX), (int)(buttonSize.Height * currentScaleDY))); + } + + /// + /// Overrides Control.setBoundsCore to enforce AutoSize. + /// + protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) + { + int originalHeight = height; + int originalWidth = width; + + base.SetBoundsCore(x, y, width, height, specified); + + Rectangle bounds = Bounds; + if (Dock == DockStyle.Left || Dock == DockStyle.Right) + { + if ((specified & BoundsSpecified.Width) != BoundsSpecified.None) + { + requestedSize = width; + } + + if (AutoSize) + { + width = PreferredWidth; + } + + if (width != originalWidth && Dock == DockStyle.Right) + { + int deltaWidth = originalWidth - width; + x += deltaWidth; + } + + } + else + { + if ((specified & BoundsSpecified.Height) != BoundsSpecified.None) + { + requestedSize = height; + } + + if (AutoSize) + { + height = PreferredHeight; + } + + if (height != originalHeight && Dock == DockStyle.Bottom) + { + int deltaHeight = originalHeight - height; + y += deltaHeight; + } + + } + + base.SetBoundsCore(x, y, width, height, specified); + } + + /// + /// Determines if the property needs to be persisted. + /// + private bool ShouldSerializeButtonSize() + { + return !buttonSize.IsEmpty; + } + + /// + /// Called by ToolTip to poke in that Tooltip into this ComCtl so that the Native ChildToolTip is not exposed. + /// + internal void SetToolTip(ToolTip toolTip) + { + PInvoke.SendMessage(this, PInvoke.TB_SETTOOLTIPS, toolTip.HWND, 0); + + } + + /// + /// Returns a string representation for this control. + /// + public override string ToString() + { + string s = base.ToString(); + s += ", Buttons.Count: " + buttonCount.ToString(CultureInfo.CurrentCulture); + if (buttonCount > 0) + { + s += ", Buttons[0]: " + buttons[0].ToString(); + } + + return s; + } + + /// + /// Updates all the information in the ToolBar. Tragically, the win32 + /// control is pretty flakey, and the only real choice here is to recreate + /// the handle and re-realize all the buttons. + /// + internal void UpdateButtons() + { + if (IsHandleCreated) + { + RecreateHandle(); + } + } + + /// + /// The button clicked was a dropdown button. If it has a menu specified, + /// show it now. Otherwise, fire an onButtonDropDown event. + /// + private void WmNotifyDropDown(ref Message m) + { + var lParam = m.GetLParam(typeof(NativeMethods.NMTOOLBAR)) ?? throw new InvalidOperationException("lparam of a received message should not be null"); + + NativeMethods.NMTOOLBAR nmTB = (NativeMethods.NMTOOLBAR)lParam; + + ToolBarButton tbb = buttons[nmTB.iItem]; + if (tbb == null) + { + throw new InvalidOperationException(SR.ToolBarButtonNotFound); + } + + OnButtonDropDown(new ToolBarButtonClickEventArgs(tbb)); + + Menu menu = tbb.DropDownMenu; + if (menu != null) + { + RECT rc = new RECT(); + NativeMethods.TPMPARAMS tpm = new NativeMethods.TPMPARAMS(); + + PInvoke.SendMessage(this, PInvoke.TB_GETRECT, (WPARAM)nmTB.iItem, ref rc); + + if ((menu.GetType()).IsAssignableFrom(typeof(ContextMenu))) + { + ((ContextMenu)menu).Show(this, new Point(rc.left, rc.bottom)); + } + else + { + Menu main = menu.GetMainMenu(); + if (main != null) + { + main.ProcessInitMenuPopup(menu.Handle); + } + + PInvoke.MapWindowPoints((HWND)nmTB.hdr.hwndFrom, HWND.Null, ref rc); + + tpm.rcExclude_left = rc.left; + tpm.rcExclude_top = rc.top; + tpm.rcExclude_right = rc.right; + tpm.rcExclude_bottom = rc.bottom; + + SafeNativeMethods.TrackPopupMenuEx( + new HandleRef(menu, menu.Handle), + NativeMethods.TPM_LEFTALIGN | + NativeMethods.TPM_LEFTBUTTON | + NativeMethods.TPM_VERTICAL, + rc.left, rc.bottom, + new HandleRef(this, Handle), tpm); + } + } + } + + private void WmNotifyNeedText(ref Message m) + { + NativeMethods.TOOLTIPTEXT ttt = (NativeMethods.TOOLTIPTEXT)m.GetLParam(typeof(NativeMethods.TOOLTIPTEXT)); + int commandID = (int)ttt.hdr.idFrom; + ToolBarButton tbb = buttons[commandID]; + + if (tbb != null && tbb.ToolTipText != null) + { + ttt.lpszText = tbb.ToolTipText; + } + else + { + ttt.lpszText = null; + } + + ttt.hinst = IntPtr.Zero; + + // RightToLeft reading order + // + if (RightToLeft == RightToLeft.Yes) + { + ttt.uFlags |= (int)ComCtl32.TTF.RTLREADING; + } + + Marshal.StructureToPtr(ttt, m.LParam, false); + } + + // Track the currently hot item since the user might be using the tab and + // arrow keys to navigate the toolbar and if that's the case, we'll need to know where to re- + // position the tooltip window when the underlying toolbar control attempts to display it. + private void WmNotifyHotItemChange(ref Message m) + { + var lParam = m.GetLParam(typeof(NMTBHOTITEM)) ?? throw new InvalidOperationException("lparam of a received message should not be null"); + + // Should we set the hot item? + NMTBHOTITEM nmTbHotItem = (NMTBHOTITEM)lParam; + if (NMTBHOTITEM_FLAGS.HICF_ENTERING == (nmTbHotItem.dwFlags & NMTBHOTITEM_FLAGS.HICF_ENTERING)) + { + hotItem = nmTbHotItem.idNew; + } + else if (NMTBHOTITEM_FLAGS.HICF_LEAVING == (nmTbHotItem.dwFlags & NMTBHOTITEM_FLAGS.HICF_LEAVING)) + { + hotItem = -1; + } + else if (NMTBHOTITEM_FLAGS.HICF_MOUSE == (nmTbHotItem.dwFlags & NMTBHOTITEM_FLAGS.HICF_MOUSE)) + { + hotItem = nmTbHotItem.idNew; + } + else if (NMTBHOTITEM_FLAGS.HICF_ARROWKEYS == (nmTbHotItem.dwFlags & NMTBHOTITEM_FLAGS.HICF_ARROWKEYS)) + { + hotItem = nmTbHotItem.idNew; + } + else if (NMTBHOTITEM_FLAGS.HICF_ACCELERATOR == (nmTbHotItem.dwFlags & NMTBHOTITEM_FLAGS.HICF_ACCELERATOR)) + { + hotItem = nmTbHotItem.idNew; + } + else if (NMTBHOTITEM_FLAGS.HICF_DUPACCEL == (nmTbHotItem.dwFlags & NMTBHOTITEM_FLAGS.HICF_DUPACCEL)) + { + hotItem = nmTbHotItem.idNew; + } + else if (NMTBHOTITEM_FLAGS.HICF_RESELECT == (nmTbHotItem.dwFlags & NMTBHOTITEM_FLAGS.HICF_RESELECT)) + { + hotItem = nmTbHotItem.idNew; + } + else if (NMTBHOTITEM_FLAGS.HICF_LMOUSE == (nmTbHotItem.dwFlags & NMTBHOTITEM_FLAGS.HICF_LMOUSE)) + { + hotItem = nmTbHotItem.idNew; + } + else if (NMTBHOTITEM_FLAGS.HICF_TOGGLEDROPDOWN == (nmTbHotItem.dwFlags & NMTBHOTITEM_FLAGS.HICF_TOGGLEDROPDOWN)) + { + hotItem = nmTbHotItem.idNew; + } + } + + private void WmReflectCommand(ref Message m) + { + int id = NativeMethods.Util.LOWORD(m.WParam); + ToolBarButton tbb = buttons[id]; + + if (tbb != null) + { + ToolBarButtonClickEventArgs e = new ToolBarButtonClickEventArgs(tbb); + OnButtonClick(e); + } + + base.WndProc(ref m); + + ResetMouseEventArgs(); + } + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case WindowMessages.WM_COMMAND + WindowMessages.WM_REFLECT: + WmReflectCommand(ref m); + break; + + case WindowMessages.WM_NOTIFY: + case WindowMessages.WM_NOTIFY + WindowMessages.WM_REFLECT: + + var lParam = m.GetLParam(typeof(NMHDR)) ?? throw new InvalidOperationException("lparam of a received message should not be null"); + + NMHDR note = (NMHDR)lParam; + switch (note.code) + { + case PInvoke.TTN_NEEDTEXT: + WmNotifyNeedText(ref m); + m.Result = 1; + return; + case PInvoke.TTN_SHOW: + // Prevent the tooltip from displaying in the upper left corner of the + // desktop when the control is nowhere near that location. + WINDOWPLACEMENT wndPlacement = new(); + int nRet = PInvoke.GetWindowPlacement(note.hwndFrom, ref wndPlacement); + + // Is this tooltip going to be positioned in the upper left corner of the display, + // but nowhere near the toolbar button? + if (wndPlacement.rcNormalPosition.left == 0 && + wndPlacement.rcNormalPosition.top == 0 && + hotItem != -1) + { + + // Assume that we're going to vertically center the tooltip on the right edge of the current + // hot item. + + // Where is the right edge of the current hot item? + int buttonRight = 0; + for (int idx = 0; idx <= hotItem; idx++) + { + // How wide is the item at this index? (It could be a separator, and therefore a different width.) + buttonRight += buttonsCollection[idx].GetButtonWidth(); + } + + // Where can we place this tooltip so that it will be completely visible on the current display? + int tooltipWidth = wndPlacement.rcNormalPosition.right - wndPlacement.rcNormalPosition.left; + int tooltipHeight = wndPlacement.rcNormalPosition.bottom - wndPlacement.rcNormalPosition.top; + + // We'll need screen coordinates of this position for setting the tooltip's position + int x = Location.X + buttonRight + 1; + int y = Location.Y + (ButtonSize.Height / 2); + var leftTop = new Point(x, y); + PInvoke.ClientToScreen(HWND, ref leftTop); + + // Will the tooltip bleed off the top? + if (leftTop.Y < SystemInformation.WorkingArea.Y) + { + // Reposition the tooltip to be displayed below the button + leftTop.Y += (ButtonSize.Height / 2) + 1; + } + + // Will the tooltip bleed off the bottom? + if (leftTop.Y + tooltipHeight > SystemInformation.WorkingArea.Height) + { + // Reposition the tooltip to be displayed above the button + leftTop.Y -= ((ButtonSize.Height / 2) + tooltipHeight + 1); + } + + // Will the tooltip bleed off the right edge? + if (leftTop.X + tooltipWidth > SystemInformation.WorkingArea.Right) + { + // Move the tooltip far enough left that it will display in the working area + leftTop.X -= (ButtonSize.Width + tooltipWidth + 2); + } + + PInvoke.SetWindowPos(note.hwndFrom, HWND.Null, leftTop.X, leftTop.Y, 0, 0, SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOZORDER | SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE); + m.Result = (IntPtr)1; + return; + } + + break; + + case PInvoke.TBN_HOTITEMCHANGE: + WmNotifyHotItemChange(ref m); + break; + + case PInvoke.TBN_QUERYINSERT: + m.Result = (IntPtr)1; + break; + + case PInvoke.TBN_DROPDOWN: + WmNotifyDropDown(ref m); + break; + } + + break; + + } + + base.WndProc(ref m); + } + + /// + /// Encapsulates a collection of controls for use by the + /// class. + /// + public class ToolBarButtonCollection : IList + { + private readonly ToolBar owner; + private bool suspendUpdate; + /// A caching mechanism for key accessor + /// We use an index here rather than control so that we don't have lifetime + /// issues by holding on to extra references. + private int lastAccessedIndex = -1; + + /// + /// Initializes a new instance of the class and assigns it to the specified toolbar. + /// + public ToolBarButtonCollection(ToolBar owner) + { + this.owner = owner; + } + + /// + /// Gets or sets the toolbar button at the specified indexed location in the + /// toolbar button collection. + /// + public virtual ToolBarButton this[int index] + { + get + { + if (index < 0 || ((owner.buttons != null) && (index >= owner.buttonCount))) + { + throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(SR.InvalidArgument, nameof(index), index)); + } + + return owner.buttons[index]; + } + set + { + + // Sanity check parameters + // + if (index < 0 || ((owner.buttons != null) && index >= owner.buttonCount)) + { + throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(SR.InvalidArgument, nameof(index), index)); + } + + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + owner.InternalSetButton(index, value, true, true); + } + } + + object IList.this[int index] + { + get + { + return this[index]; + } + set + { + if (value is ToolBarButton) + { + this[index] = (ToolBarButton)value; + } + else + { + throw new ArgumentException(SR.ToolBarBadToolBarButton, "value"); + } + } + } + + /// + /// Retrieves the child control with the specified key. + /// + public virtual ToolBarButton this[string key] + { + get + { + // We do not support null and empty string as valid keys. + if (string.IsNullOrEmpty(key)) + { + return null; + } + + // Search for the key in our collection + int index = IndexOfKey(key); + if (IsValidIndex(index)) + { + return this[index]; + } + else + { + return null; + } + + } + } + + /// + /// Gets the number of buttons in the toolbar button collection. + /// + [Browsable(false)] + public int Count + { + get + { + return owner.buttonCount; + } + } + + object ICollection.SyncRoot + { + get + { + return this; + } + } + + bool ICollection.IsSynchronized + { + get + { + return false; + } + } + + bool IList.IsFixedSize + { + get + { + return false; + } + } + + public bool IsReadOnly + { + get + { + return false; + } + } + + /// + /// Adds a new toolbar button to + /// the end of the toolbar button collection. + /// + public int Add(ToolBarButton button) + { + + int index = owner.InternalAddButton(button); + + if (!suspendUpdate) + { + owner.UpdateButtons(); + } + + return index; + } + + public int Add(string text) + { + ToolBarButton button = new ToolBarButton(text); + return Add(button); + } + + int IList.Add(object button) + { + if (button is ToolBarButton) + { + return Add((ToolBarButton)button); + } + else + { + throw new ArgumentException(SR.ToolBarBadToolBarButton, "button"); + } + } + + public void AddRange(ToolBarButton[] buttons) + { + if (buttons == null) + { + throw new ArgumentNullException(nameof(buttons)); + } + + try + { + suspendUpdate = true; + foreach (ToolBarButton button in buttons) + { + Add(button); + } + } + finally + { + suspendUpdate = false; + owner.UpdateButtons(); + } + } + + /// + /// Removes + /// all buttons from the toolbar button collection. + /// + public void Clear() + { + + if (owner.buttons == null) + { + return; + } + + for (int x = owner.buttonCount; x > 0; x--) + { + if (owner.IsHandleCreated) + { + PInvoke.SendMessage(owner, PInvoke.TB_DELETEBUTTON, (WPARAM)(x - 1), 0); + } + + owner.RemoveAt(x - 1); + } + + owner.buttons = null; + owner.buttonCount = 0; + if (!owner.Disposing) + { + owner.UpdateButtons(); + } + } + + public bool Contains(ToolBarButton button) + { + return IndexOf(button) != -1; + } + + bool IList.Contains(object button) + { + if (button is ToolBarButton) + { + return Contains((ToolBarButton)button); + } + else + { + return false; + } + } + + /// + /// Returns true if the collection contains an item with the specified key, false otherwise. + /// + public virtual bool ContainsKey(string key) + { + return IsValidIndex(IndexOfKey(key)); + } + + void ICollection.CopyTo(Array dest, int index) + { + if (owner.buttonCount > 0) + { + System.Array.Copy(owner.buttons, 0, dest, index, owner.buttonCount); + } + } + + public int IndexOf(ToolBarButton button) + { + for (int index = 0; index < Count; ++index) + { + if (this[index] == button) + { + return index; + } + } + + return -1; + } + + int IList.IndexOf(object button) + { + if (button is ToolBarButton) + { + return IndexOf((ToolBarButton)button); + } + else + { + return -1; + } + } + + /// + /// The zero-based index of the first occurrence of value within the entire CollectionBase, if found; otherwise, -1. + /// + public virtual int IndexOfKey(string key) + { + // Step 0 - Arg validation + if (string.IsNullOrEmpty(key)) + { + return -1; // we dont support empty or null keys. + } + + // step 1 - check the last cached item + if (IsValidIndex(lastAccessedIndex)) + { + if (WindowsFormsUtils.SafeCompareStrings(this[lastAccessedIndex].Name, key, /* ignoreCase = */ true)) + { + return lastAccessedIndex; + } + } + + // step 2 - search for the item + for (int i = 0; i < Count; i++) + { + if (WindowsFormsUtils.SafeCompareStrings(this[i].Name, key, /* ignoreCase = */ true)) + { + lastAccessedIndex = i; + return i; + } + } + + // step 3 - we didn't find it. Invalidate the last accessed index and return -1. + lastAccessedIndex = -1; + return -1; + } + + public void Insert(int index, ToolBarButton button) + { + owner.InsertButton(index, button); + } + + void IList.Insert(int index, object button) + { + if (button is ToolBarButton) + { + Insert(index, (ToolBarButton)button); + } + else + { + throw new ArgumentException(SR.ToolBarBadToolBarButton, "button"); + } + } + + /// + /// Determines if the index is valid for the collection. + /// + private bool IsValidIndex(int index) + { + return ((index >= 0) && (index < Count)); + } + + /// + /// Removes + /// a given button from the toolbar button collection. + /// + public void RemoveAt(int index) + { + int count = (owner.buttons == null) ? 0 : owner.buttonCount; + + if (index < 0 || index >= count) + { + throw new ArgumentOutOfRangeException(nameof(index), string.Format(SR.InvalidArgument, "index", index.ToString(CultureInfo.CurrentCulture))); + } + + if (owner.IsHandleCreated) + { + PInvoke.SendMessage(owner, PInvoke.TB_DELETEBUTTON, (WPARAM)index, 0); + } + + owner.RemoveAt(index); + owner.UpdateButtons(); + + } + + /// + /// Removes the child control with the specified key. + /// + public virtual void RemoveByKey(string key) + { + int index = IndexOfKey(key); + if (IsValidIndex(index)) + { + RemoveAt(index); + } + } + + public void Remove(ToolBarButton button) + { + int index = IndexOf(button); + if (index != -1) + { + RemoveAt(index); + } + } + + void IList.Remove(object button) + { + if (button is ToolBarButton) + { + Remove((ToolBarButton)button); + } + } + + /// + /// Returns an enumerator that can be used to iterate + /// through the toolbar button collection. + /// + public IEnumerator GetEnumerator() + { + return new WindowsFormsUtils.ArraySubsetEnumerator(owner.buttons, owner.buttonCount); + } + } + + } +} + + diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarAppearance.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarAppearance.cs new file mode 100644 index 00000000000..464c456837b --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarAppearance.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Specifies the type of toolbar to display. + /// + public enum ToolBarAppearance + { + /// + /// The toolbar and buttons appear as standard three dimensional controls. + /// + Normal = 0, + + /// + /// The toolbar and buttons appear flat, but the buttons change to three + /// dimensional as the mouse pointer moves over them. + /// + Flat = 1, + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButton.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButton.cs new file mode 100644 index 00000000000..0bbcdcc5bed --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButton.cs @@ -0,0 +1,881 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Text; +using Marshal = System.Runtime.InteropServices.Marshal; + +namespace System.Windows.Forms +{ + /// + /// Represents a Windows toolbar button. + /// + [ + Designer("System.Windows.Forms.Design.ToolBarButtonDesigner, " + AssemblyRef.SystemDesign), + DefaultProperty(nameof(Text)), + ToolboxItem(false), + DesignTimeVisible(false), + ] + public class ToolBarButton : Component + { + string text; + string name = null; + string tooltipText; + bool enabled = true; + bool visible = true; + bool pushed = false; + bool partialPush = false; + private int commandId = -1; // the cached command id of the button. + private ToolBarButtonImageIndexer imageIndexer; + + ToolBarButtonStyle style = ToolBarButtonStyle.PushButton; + + object userData; + + // These variables below are used by the ToolBar control to help + // it manage some information about us. + + /// + /// If this button has a string, what it's index is in the ToolBar's + /// internal list of strings. Needs to be package protected. + /// + internal IntPtr stringIndex = (IntPtr)(-1); + + /// + /// Our parent ToolBar control. + /// + internal ToolBar parent; + + /// + /// For DropDown buttons, we can optionally show a + /// context menu when the button is dropped down. + /// + internal Menu dropDownMenu = null; + + /// + /// Initializes a new instance of the class. + /// + public ToolBarButton() + { + } + + public ToolBarButton(string text) : base() + { + Text = text; + } + + // We need a special way to defer to the ToolBar's image + // list for indexing purposes. + internal class ToolBarButtonImageIndexer : ImageList.Indexer + { + private readonly ToolBarButton owner; + + public ToolBarButtonImageIndexer(ToolBarButton button) + { + owner = button; + } + + public override ImageList ImageList + { + get + { + if ((owner != null) && (owner.parent != null)) + { + return owner.parent.ImageList; + } + + return null; + } + set { Debug.Assert(false, "We should never set the image list"); } + } + } + + internal ToolBarButtonImageIndexer ImageIndexer + { + get + { + return imageIndexer ??= new ToolBarButtonImageIndexer(this); + } + } + + /// + /// + /// Indicates the menu to be displayed in + /// the drop-down toolbar button. + /// + [ + DefaultValue(null), + TypeConverter(typeof(ReferenceConverter)), + SRDescription(nameof(SR.ToolBarButtonMenuDescr)) + ] + public Menu DropDownMenu + { + get + { + return dropDownMenu; + } + + set + { + //The dropdownmenu must be of type ContextMenu, Main & Items are invalid. + // + if (value != null && !(value is ContextMenu)) + { + throw new ArgumentException(SR.ToolBarButtonInvalidDropDownMenuType); + } + + dropDownMenu = value; + } + } + + /// + /// Indicates whether the button is enabled or not. + /// + [ + DefaultValue(true), + Localizable(true), + SRDescription(nameof(SR.ToolBarButtonEnabledDescr)) + ] + public bool Enabled + { + get + { + return enabled; + } + + set + { + if (enabled != value) + { + + enabled = value; + + if (parent != null && parent.IsHandleCreated) + { + PInvoke.SendMessage(parent, PInvoke.TB_ENABLEBUTTON, (WPARAM)FindButtonIndex(), + enabled ? 1 : 0); + } + } + } + } + + /// + /// Indicates the index + /// value of the image assigned to the button. + /// + [ + TypeConverter(typeof(ImageIndexConverter)), + Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), + DefaultValue(-1), + RefreshProperties(RefreshProperties.Repaint), + Localizable(true), + SRDescription(nameof(SR.ToolBarButtonImageIndexDescr)) + ] + public int ImageIndex + { + get + { + return ImageIndexer.Index; + } + set + { + if (ImageIndexer.Index != value) + { + if (value < -1) + { + throw new ArgumentOutOfRangeException(nameof(ImageIndex), string.Format(SR.InvalidLowBoundArgumentEx, nameof(ImageIndex), value, -1)); + } + + ImageIndexer.Index = value; + UpdateButton(false); + } + } + } + + /// + /// Indicates the index + /// value of the image assigned to the button. + /// + [ + TypeConverter(typeof(ImageKeyConverter)), + Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), + DefaultValue(""), + Localizable(true), + RefreshProperties(RefreshProperties.Repaint), + SRDescription(nameof(SR.ToolBarButtonImageIndexDescr)) + ] + public string ImageKey + { + get + { + return ImageIndexer.Key; + } + set + { + if (ImageIndexer.Key != value) + { + ImageIndexer.Key = value; + UpdateButton(false); + } + } + } + + /// + /// Name of this control. The designer will set this to the same + /// as the programatic Id "(name)" of the control - however this + /// property has no bearing on the runtime aspects of this control. + /// + [Browsable(false)] + public string Name + { + get + { + return WindowsFormsUtils.GetComponentName(this, name); + } + set + { + if (value == null || value.Length == 0) + { + name = null; + } + else + { + name = value; + } + + if (Site != null) + { + Site.Name = name; + } + } + } + + /// + /// Indicates the toolbar control that the toolbar button is assigned to. This property is + /// read-only. + /// + [ + Browsable(false), + ] + public ToolBar Parent + { + get + { + return parent; + } + } + + /// + /// + /// Indicates whether a toggle-style toolbar button + /// is partially pushed. + /// + [ + DefaultValue(false), + SRDescription(nameof(SR.ToolBarButtonPartialPushDescr)) + ] + public bool PartialPush + { + get + { + if (parent == null || !parent.IsHandleCreated) + { + return partialPush; + } + else + { + if ((int)PInvoke.SendMessage(parent, PInvoke.TB_ISBUTTONINDETERMINATE, (WPARAM)FindButtonIndex(), 0) != 0) + { + partialPush = true; + } + else + { + partialPush = false; + } + + return partialPush; + } + } + set + { + if (partialPush != value) + { + partialPush = value; + UpdateButton(false); + } + } + } + + /// + /// Indicates whether a toggle-style toolbar button is currently in the pushed state. + /// + [ + DefaultValue(false), + SRDescription(nameof(SR.ToolBarButtonPushedDescr)) + ] + public bool Pushed + { + get + { + if (parent == null || !parent.IsHandleCreated) + { + return pushed; + } + else + { + return GetPushedState(); + } + } + set + { + if (value != Pushed) + { // Getting property Pushed updates pushed member variable + pushed = value; + UpdateButton(false, false, false); + } + } + } + + /// + /// Indicates the bounding rectangle for a toolbar button. This property is + /// read-only. + /// + public Rectangle Rectangle + { + get + { + if (parent != null) + { + RECT rc = new RECT(); + PInvoke.SendMessage(parent, PInvoke.TB_GETRECT, (WPARAM)FindButtonIndex(), ref rc); + return Rectangle.FromLTRB(rc.left, rc.top, rc.right, rc.bottom); + } + + return Rectangle.Empty; + } + } + + /// + /// Indicates the style of the + /// toolbar button. + /// + [ + DefaultValue(ToolBarButtonStyle.PushButton), + SRDescription(nameof(SR.ToolBarButtonStyleDescr)), + RefreshProperties(RefreshProperties.Repaint) + ] + public ToolBarButtonStyle Style + { + get + { + return style; + } + set + { + //valid values are 0x1 to 0x4 + if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolBarButtonStyle.PushButton, (int)ToolBarButtonStyle.DropDownButton)) + { + throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(ToolBarButtonStyle)); + } + + if (style == value) + { + return; + } + + style = value; + UpdateButton(true); + } + } + + [ + SRCategory(nameof(SR.CatData)), + Localizable(false), + Bindable(true), + SRDescription(nameof(SR.ControlTagDescr)), + DefaultValue(null), + TypeConverter(typeof(StringConverter)), + ] + public object Tag + { + get + { + return userData; + } + set + { + userData = value; + } + } + + /// + /// Indicates the text that is displayed on the toolbar button. + /// + [ + Localizable(true), + DefaultValue(""), + SRDescription(nameof(SR.ToolBarButtonTextDescr)) + ] + public string Text + { + get + { + return text ?? ""; + } + set + { + if (string.IsNullOrEmpty(value)) + { + value = null; + } + + if ((value == null && text != null) || + (value != null && (text == null || !text.Equals(value)))) + { + text = value; + // Adding a mnemonic requires a handle recreate. + UpdateButton(WindowsFormsUtils.ContainsMnemonic(text), true, true); + } + } + } + + /// + /// + /// Indicates + /// the text that appears as a tool tip for a control. + /// + [ + Localizable(true), + DefaultValue(""), + SRDescription(nameof(SR.ToolBarButtonToolTipTextDescr)) + ] + public string ToolTipText + { + get + { + return tooltipText ?? ""; + } + set + { + tooltipText = value; + } + } + + /// + /// + /// Indicates whether the toolbar button + /// is visible. + /// + [ + DefaultValue(true), + Localizable(true), + SRDescription(nameof(SR.ToolBarButtonVisibleDescr)) + ] + public bool Visible + { + get + { + return visible; + } + set + { + if (visible != value) + { + visible = value; + UpdateButton(false); + } + } + } + + /// + /// This is somewhat nasty -- by default, the windows ToolBar isn't very + /// clever about setting the width of buttons, and has a very primitive + /// algorithm that doesn't include for things like drop down arrows, etc. + /// We need to do a bunch of work here to get all the widths correct. Ugh. + /// + internal short Width + { + get + { + Debug.Assert(parent != null, "Parent should be non-null when button width is requested"); + + int width = 0; + ToolBarButtonStyle style = Style; + + Size edge = SystemInformation.Border3DSize; + if (style != ToolBarButtonStyle.Separator) + { + + // COMPAT: this will force handle creation. + // we could use the measurement graphics, but it looks like this has been like this since Everett. + using (Graphics g = parent.CreateGraphicsInternal()) + { + + Size buttonSize = parent.buttonSize; + if (!(buttonSize.IsEmpty)) + { + width = buttonSize.Width; + } + else + { + if (parent.ImageList != null || !string.IsNullOrEmpty(Text)) + { + Size imageSize = parent.ImageSize; + Size textSize = Size.Ceiling(g.MeasureString(Text, parent.Font)); + if (parent.TextAlign == ToolBarTextAlign.Right) + { + if (textSize.Width == 0) + { + width = imageSize.Width + edge.Width * 4; + } + else + { + width = imageSize.Width + textSize.Width + edge.Width * 6; + } + } + else + { + if (imageSize.Width > textSize.Width) + { + width = imageSize.Width + edge.Width * 4; + } + else + { + width = textSize.Width + edge.Width * 4; + } + } + + if (style == ToolBarButtonStyle.DropDownButton && parent.DropDownArrows) + { + width += ToolBar.DDARROW_WIDTH; + } + } + else + { + width = parent.ButtonSize.Width; + } + } + } + } + else + { + width = edge.Width * 2; + } + + return (short)width; + } + + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (parent != null) + { + int index = FindButtonIndex(); + if (index != -1) + { + parent.Buttons.RemoveAt(index); + } + } + } + + base.Dispose(disposing); + } + + /// + /// Finds out index in the parent. + /// + private int FindButtonIndex() + { + for (int x = 0; x < parent.Buttons.Count; x++) + { + if (parent.Buttons[x] == this) + { + return x; + } + } + + return -1; + } + + // This is necessary to get the width of the buttons in the toolbar, + // including the width of separators, so that we can accurately position the tooltip adjacent + // to the currently hot button when the user uses keyboard navigation to access the toolbar. + internal int GetButtonWidth() + { + // Assume that this button is the same width as the parent's ButtonSize's Width + int buttonWidth = Parent.ButtonSize.Width; + + NativeMethods.TBBUTTONINFO button = new NativeMethods.TBBUTTONINFO + { + cbSize = Marshal.SizeOf(), + dwMask = NativeMethods.TBIF_SIZE + }; + + int buttonID = (int)PInvoke.SendMessage(Parent, PInvoke.TB_GETBUTTONINFO, (WPARAM)commandId, ref button); + if (buttonID != -1) + { + buttonWidth = button.cx; + } + + return buttonWidth; + } + + private bool GetPushedState() + { + if ((int)PInvoke.SendMessage(parent, PInvoke.TB_ISBUTTONCHECKED, (WPARAM)FindButtonIndex(), 0) != 0) + { + pushed = true; + } + else + { + pushed = false; + } + + return pushed; + } + + /// + /// Returns a TBBUTTON object that represents this ToolBarButton. + /// + internal NativeMethods.TBBUTTON GetTBBUTTON(int commandId) + { + NativeMethods.TBBUTTON button = new NativeMethods.TBBUTTON + { + iBitmap = ImageIndexer.ActualIndex, + + // set up the state of the button + // + fsState = 0 + }; + if (enabled) + { + button.fsState |= (byte)PInvoke.TBSTATE_ENABLED; + } + + if (partialPush && style == ToolBarButtonStyle.ToggleButton) + { + button.fsState |= (byte)PInvoke.TBSTATE_INDETERMINATE; + } + + if (pushed) + { + button.fsState |= (byte)PInvoke.TBSTATE_CHECKED; + } + + if (!visible) + { + button.fsState |= (byte)PInvoke.TBSTATE_HIDDEN; + } + + // set the button style + // + switch (style) + { + case ToolBarButtonStyle.PushButton: + button.fsStyle = (byte)PInvoke.TBSTYLE_BUTTON; + break; + case ToolBarButtonStyle.ToggleButton: + button.fsStyle = (byte)PInvoke.TBSTYLE_CHECK; + break; + case ToolBarButtonStyle.Separator: + button.fsStyle = (byte)PInvoke.TBSTYLE_SEP; + break; + case ToolBarButtonStyle.DropDownButton: + button.fsStyle = (byte)PInvoke.TBSTYLE_DROPDOWN; + break; + + } + + button.dwData = (IntPtr)0; + button.iString = stringIndex; + this.commandId = commandId; + button.idCommand = commandId; + + return button; + } + + /// + /// Returns a TBBUTTONINFO object that represents this ToolBarButton. + /// + internal NativeMethods.TBBUTTONINFO GetTBBUTTONINFO(bool updateText, int newCommandId) + { + NativeMethods.TBBUTTONINFO button = new NativeMethods.TBBUTTONINFO + { + cbSize = Marshal.SizeOf(), + dwMask = NativeMethods.TBIF_IMAGE + | NativeMethods.TBIF_STATE | NativeMethods.TBIF_STYLE + }; + + // Older platforms interpret null strings as empty, which forces the button to + // leave space for text. + // The only workaround is to avoid having comctl update the text. + if (updateText) + { + button.dwMask |= NativeMethods.TBIF_TEXT; + } + + button.iImage = ImageIndexer.ActualIndex; + + if (newCommandId != commandId) + { + commandId = newCommandId; + button.idCommand = newCommandId; + button.dwMask |= NativeMethods.TBIF_COMMAND; + } + + // set up the state of the button + // + button.fsState = 0; + if (enabled) + { + button.fsState |= (byte)PInvoke.TBSTATE_ENABLED; + } + + if (partialPush && style == ToolBarButtonStyle.ToggleButton) + { + button.fsState |= (byte)PInvoke.TBSTATE_INDETERMINATE; + } + + if (pushed) + { + button.fsState |= (byte)PInvoke.TBSTATE_CHECKED; + } + + if (!visible) + { + button.fsState |= (byte)PInvoke.TBSTATE_HIDDEN; + } + + // set the button style + // + switch (style) + { + case ToolBarButtonStyle.PushButton: + button.fsStyle = (byte)PInvoke.TBSTYLE_BUTTON; + break; + case ToolBarButtonStyle.ToggleButton: + button.fsStyle = (byte)PInvoke.TBSTYLE_CHECK; + break; + case ToolBarButtonStyle.Separator: + button.fsStyle = (byte)PInvoke.TBSTYLE_SEP; + break; + } + + if (text == null) + { + button.pszText = Marshal.StringToHGlobalAuto("\0\0"); + } + else + { + string textValue = text; + PrefixAmpersands(ref textValue); + button.pszText = Marshal.StringToHGlobalAuto(textValue); + } + + return button; + } + + private void PrefixAmpersands(ref string value) + { + // Due to a comctl32 problem, ampersands underline the next letter in the + // text string, but the accelerators don't work. + // So in this function, we prefix ampersands with another ampersand + // so that they actually appear as ampersands. + // + + // Sanity check parameter + // + if (value == null || value.Length == 0) + { + return; + } + + // If there are no ampersands, we don't need to do anything here + // + if (value.IndexOf('&') < 0) + { + return; + } + + // Insert extra ampersands + // + StringBuilder newString = new StringBuilder(); + for (int i = 0; i < value.Length; ++i) + { + if (value[i] == '&') + { + if (i < value.Length - 1 && value[i + 1] == '&') + { + ++i; // Skip the second ampersand + } + + newString.Append("&&"); + } + else + { + newString.Append(value[i]); + } + } + + value = newString.ToString(); + } + + public override string ToString() + { + return "ToolBarButton: " + Text + ", Style: " + Style.ToString("G"); + } + + /// + /// When a button property changes and the parent control is created, + /// we need to make sure it gets the new button information. + /// If Text was changed, call the next overload. + /// + internal void UpdateButton(bool recreate) + { + UpdateButton(recreate, false, true); + } + + /// + /// When a button property changes and the parent control is created, + /// we need to make sure it gets the new button information. + /// + private void UpdateButton(bool recreate, bool updateText, bool updatePushedState) + { + // It looks like ToolBarButtons with a DropDownButton tend to + // lose the DropDownButton very easily - so we need to recreate + // the button each time it changes just to be sure. + // + if (style == ToolBarButtonStyle.DropDownButton && parent != null && parent.DropDownArrows) + { + recreate = true; + } + + // we just need to get the Pushed state : this asks the Button its states and sets + // the private member "pushed" to right value.. + + // this member is used in "InternalSetButton" which calls GetTBBUTTONINFO(bool updateText) + // the GetButtonInfo method uses the "pushed" variable.. + + //rather than setting it ourselves .... we asks the button to set it for us.. + if (updatePushedState && parent != null && parent.IsHandleCreated) + { + GetPushedState(); + } + + if (parent != null) + { + int index = FindButtonIndex(); + if (index != -1) + { + parent.InternalSetButton(index, this, recreate, updateText); + } + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButtonClickEventArgs.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButtonClickEventArgs.cs new file mode 100644 index 00000000000..0256dfba763 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButtonClickEventArgs.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Provides data for the + /// event. + /// + public class ToolBarButtonClickEventArgs : EventArgs + { + /// + /// Initializes a new instance of the + /// class. + /// + public ToolBarButtonClickEventArgs(ToolBarButton button) + { + Button = button; + } + + /// + /// Specifies the + /// that was clicked. + /// + public ToolBarButton Button { get; set; } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButtonClickEventHandler.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButtonClickEventHandler.cs new file mode 100644 index 00000000000..e41f8559afa --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButtonClickEventHandler.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Represents a method that will handle the + /// event of a . + /// + public delegate void ToolBarButtonClickEventHandler(object sender, ToolBarButtonClickEventArgs e); +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButtonStyle.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButtonStyle.cs new file mode 100644 index 00000000000..ea4872efb30 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarButtonStyle.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + public enum ToolBarButtonStyle + { + /// + /// A standard, three-dimensional button. + /// + PushButton = 1, + + /// + /// A toggle button that appears sunken when clicked and retains the + /// sunken appearance until clicked again. + /// + ToggleButton = 2, + + /// + /// A space or line between toolbar buttons. The appearance depends on + /// the value of the + /// property. + /// + Separator = 3, + + /// + /// A drop down control that displays a menu or other window when + /// clicked. + /// + DropDownButton = 4, + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarTextAlign.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarTextAlign.cs new file mode 100644 index 00000000000..72dcf8156c9 --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolBarTextAlign.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Windows.Forms +{ + /// + /// Specifies the alignment of text on the toolbar button control. + /// + public enum ToolBarTextAlign + { + /// + /// The text is aligned underneath the toolbar button image. + /// + Underneath = 0, + + /// + /// The text is aligned to the right of the toolbar button image. + /// + Right = 1, + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolStripDropDown.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolStripDropDown.cs index 56356817a6a..ea5ce231c91 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ToolStripDropDown.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolStripDropDown.cs @@ -503,6 +503,14 @@ public override Font Font remove => base.ImeModeChanged -= value; } + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public new ContextMenu ContextMenu + { + get { return base.ContextMenu; } + set { base.ContextMenu = value; } + } + /// /// determines whether this dropdown was autogenerated. /// diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolStripTextBox.ToolStripTextBoxControl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolStripTextBox.ToolStripTextBoxControl.cs index 79f2d9ef73d..168d5a5dbe8 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ToolStripTextBox.ToolStripTextBoxControl.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolStripTextBox.ToolStripTextBoxControl.cs @@ -30,7 +30,7 @@ private RECT AbsoluteClientRECT RECT rect = default; CreateParams cp = CreateParams; - AdjustWindowRectExForControlDpi(ref rect, (WINDOW_STYLE)cp.Style, false, (WINDOW_EX_STYLE)cp.ExStyle); + AdjustWindowRectExForControlDpi(ref rect, (WINDOW_STYLE)cp.Style, HasMenu, (WINDOW_EX_STYLE)cp.ExStyle); // the coordinates we get back are negative, we need to translate this back to positive. int offsetX = -rect.left; // one to get back to 0,0, another to translate diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip.cs index 04cdc38adf7..a7614a9909f 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip.cs @@ -6,6 +6,7 @@ using System.Globalization; using static Interop; using static Interop.ComCtl32; +using INITCOMMONCONTROLSEX = Windows.Win32.UI.Controls.INITCOMMONCONTROLSEX; namespace System.Windows.Forms; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/TreeNode.cs b/src/System.Windows.Forms/src/System/Windows/Forms/TreeNode.cs index 15ed4dde3d8..a56e26f9a55 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/TreeNode.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/TreeNode.cs @@ -54,6 +54,7 @@ public partial class TreeNode : MarshalByRefObject, ICloneable, ISerializable private TreeNodeImageIndexer stateImageIndexer; private string toolTipText = string.Empty; + private ContextMenu contextMenu = null; private ContextMenuStrip _contextMenuStrip; internal bool nodesCleared; @@ -364,6 +365,27 @@ public bool Checked } } + /// + /// The contextMenu associated with this tree node. The contextMenu + /// will be shown when the user right clicks the mouse on the control. + /// + [ + SRCategory(nameof(SR.CatBehavior)), + DefaultValue(null), + SRDescription(nameof(SR.ControlContextMenuDescr)) + ] + public virtual ContextMenu ContextMenu + { + get + { + return contextMenu; + } + set + { + contextMenu = value; + } + } + /// /// The associated with this tree node. This menu /// will be shown when the user right clicks the mouse on the control. @@ -1169,7 +1191,7 @@ public TreeView TreeView } internal TreeNodeAccessibleObject AccessibilityObject - => _accessibleObject ??= new TreeNodeAccessibleObject(this, TreeView); + => _accessibleObject ??= TreeView is null ? null : new TreeNodeAccessibleObject(this, TreeView); /// /// Adds a new child node at the appropriate sorted position @@ -1424,6 +1446,7 @@ public virtual object Clone() node.StateImageIndexer.Index = StateImageIndexer.Index; node.ToolTipText = toolTipText; + node.ContextMenu = contextMenu; node.ContextMenuStrip = _contextMenuStrip; // only set the key if it's set to something useful diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/TreeView.cs b/src/System.Windows.Forms/src/System/Windows/Forms/TreeView.cs index f58067c52c2..c9220033736 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/TreeView.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/TreeView.cs @@ -12,6 +12,7 @@ using System.Windows.Forms.VisualStyles; using static Interop; using static Interop.ComCtl32; +using INITCOMMONCONTROLSEX = Windows.Win32.UI.Controls.INITCOMMONCONTROLSEX; namespace System.Windows.Forms; @@ -1650,6 +1651,11 @@ protected override void Dispose(bool disposing) { if (disposing) { + foreach (TreeNode node in Nodes) + { + node.ContextMenu = null; + } + lock (this) { DetachImageListHandlers(); @@ -2206,9 +2212,9 @@ protected virtual void OnAfterLabelEdit(NodeLabelEditEventArgs e) // Raise an event to highlight & announce the edited node // if editing hasn't been canceled. - if (IsAccessibilityObjectCreated && !e.CancelEdit) + if (IsAccessibilityObjectCreated && !e.CancelEdit && e.Node is not null) { - e.Node.AccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId); + e.Node.AccessibilityObject?.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId); } } @@ -2228,9 +2234,14 @@ protected virtual void OnAfterCheck(TreeViewEventArgs e) onAfterCheck?.Invoke(this, e); // Raise an event to announce a toggle state change. - if (IsAccessibilityObjectCreated) + if (IsAccessibilityObjectCreated && e.Node is not null) { - AccessibleObject nodeAccessibleObject = e.Node.AccessibilityObject; + TreeNode.TreeNodeAccessibleObject nodeAccessibleObject = e.Node.AccessibilityObject; + if (nodeAccessibleObject is null) + { + return; + } + UiaCore.ToggleState newState = nodeAccessibleObject.ToggleState; UiaCore.ToggleState oldState = newState == UiaCore.ToggleState.On ? UiaCore.ToggleState.Off @@ -2259,9 +2270,9 @@ protected internal virtual void OnAfterCollapse(TreeViewEventArgs e) onAfterCollapse?.Invoke(this, e); // Raise an event to announce the expand-collapse state change. - if (IsAccessibilityObjectCreated) + if (IsAccessibilityObjectCreated && e.Node is not null) { - e.Node.AccessibilityObject.RaiseAutomationPropertyChangedEvent( + e.Node.AccessibilityObject?.RaiseAutomationPropertyChangedEvent( UiaCore.UIA.ExpandCollapseExpandCollapseStatePropertyId, oldValue: UiaCore.ExpandCollapseState.Expanded, newValue: UiaCore.ExpandCollapseState.Collapsed); @@ -2283,10 +2294,10 @@ protected virtual void OnAfterExpand(TreeViewEventArgs e) { onAfterExpand?.Invoke(this, e); - // Raise anevent to announce the expand-collapse state change. - if (IsAccessibilityObjectCreated) + // Raise an event to announce the expand-collapse state change. + if (IsAccessibilityObjectCreated && e.Node is not null) { - e.Node.AccessibilityObject.RaiseAutomationPropertyChangedEvent( + e.Node.AccessibilityObject?.RaiseAutomationPropertyChangedEvent( UiaCore.UIA.ExpandCollapseExpandCollapseStatePropertyId, oldValue: UiaCore.ExpandCollapseState.Collapsed, newValue: UiaCore.ExpandCollapseState.Expanded); @@ -2325,9 +2336,14 @@ protected virtual void OnAfterSelect(TreeViewEventArgs e) onAfterSelect?.Invoke(this, e); // Raise an event to highlight & announce the selected node. - if (IsAccessibilityObjectCreated) + if (IsAccessibilityObjectCreated && e.Node is not null) { - AccessibleObject nodeAccessibleObject = e.Node.AccessibilityObject; + TreeNode.TreeNodeAccessibleObject nodeAccessibleObject = e.Node.AccessibilityObject; + if (nodeAccessibleObject is null) + { + return; + } + nodeAccessibleObject.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId); nodeAccessibleObject.RaiseAutomationEvent(UiaCore.UIA.SelectionItem_ElementSelectedEventId); @@ -2948,14 +2964,14 @@ private unsafe void CustomDraw(ref Message m) { g.FillRectangle(SystemBrushes.Highlight, bounds); ControlPaint.DrawFocusRectangle(g, bounds, color, SystemColors.Highlight); - TextRenderer.DrawText(g, e.Node.Text, font, bounds, color, TextFormatFlags.Default); + TextRenderer.DrawText(g, node.Text, font, bounds, color, TextFormatFlags.Default); } else { using var brush = BackColor.GetCachedSolidBrushScope(); g.FillRectangle(brush, bounds); - TextRenderer.DrawText(g, e.Node.Text, font, bounds, color, TextFormatFlags.Default); + TextRenderer.DrawText(g, node.Text, font, bounds, color, TextFormatFlags.Default); } } } @@ -3155,7 +3171,7 @@ private unsafe void WmNotify(ref Message m) if ((int)nmtv->nmhdr.code == (int)NM.RCLICK) { TreeNode treeNode = NodeFromHandle(hnode); - if (treeNode is not null && treeNode.ContextMenuStrip is not null) + if (treeNode != null && (treeNode.ContextMenu != null || treeNode.ContextMenuStrip != null)) { ShowContextMenu(treeNode); } @@ -3194,7 +3210,7 @@ protected override void OnGotFocus(EventArgs e) // Raise an event to highlight & announce the selected node. if (IsAccessibilityObjectCreated) { - SelectedNode?.AccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId); + SelectedNode?.AccessibilityObject?.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId); } } @@ -3209,14 +3225,39 @@ protected override void OnLostFocus(EventArgs e) /// private void ShowContextMenu(TreeNode treeNode) { - if (treeNode.ContextMenuStrip is not null) + if (treeNode.ContextMenu != null || treeNode.ContextMenuStrip is not null) { + ContextMenu contextMenu = treeNode.ContextMenu; ContextMenuStrip menu = treeNode.ContextMenuStrip; - // Need to send TVM_SELECTITEM to highlight the node while the contextMenuStrip is being shown. - PInvoke.PostMessage(this, PInvoke.TVM_SELECTITEM, (WPARAM)PInvoke.TVGN_DROPHILITE, (LPARAM)treeNode.Handle); - menu.ShowInternal(this, PointToClient(MousePosition), /*keyboardActivated*/false); - menu.Closing += new ToolStripDropDownClosingEventHandler(ContextMenuStripClosing); + if (contextMenu != null) + { + PInvoke.GetCursorPos(out Point pt); + + // Summary: the current window must be made the foreground window + // before calling TrackPopupMenuEx, and a task switch must be + // forced after the call. + PInvoke.SetForegroundWindow(this); + + contextMenu.OnPopup(EventArgs.Empty); + + SafeNativeMethods.TrackPopupMenuEx(new HandleRef(contextMenu, contextMenu.Handle), + NativeMethods.TPM_VERTICAL, + pt.X, + pt.Y, + new HandleRef(this, Handle), + null); + + // Force task switch (see above) + PInvoke.PostMessage(this, PInvoke.WM_NULL, (WPARAM)IntPtr.Zero, IntPtr.Zero); + } + else if (menu is not null) + { + // Need to send TVM_SELECTITEM to highlight the node while the contextMenuStrip is being shown. + PInvoke.PostMessage(this, PInvoke.TVM_SELECTITEM, (WPARAM)PInvoke.TVGN_DROPHILITE, (LPARAM)treeNode.Handle); + menu.ShowInternal(this, PointToClient(MousePosition), /*keyboardActivated*/false); + menu.Closing += new ToolStripDropDownClosingEventHandler(ContextMenuStripClosing); + } } } @@ -3525,15 +3566,22 @@ protected override unsafe void WndProc(ref Message m) { // this is the Shift + F10 Case.... TreeNode treeNode = SelectedNode; - if (treeNode is not null && treeNode.ContextMenuStrip is not null) + if (treeNode is not null && (treeNode.ContextMenu is not null || treeNode.ContextMenuStrip is not null)) { Point client; client = new Point(treeNode.Bounds.X, treeNode.Bounds.Y + treeNode.Bounds.Height / 2); // VisualStudio7 # 156, only show the context menu when clicked in the client area - if (ClientRectangle.Contains(client) && treeNode.ContextMenuStrip is not null) + if (ClientRectangle.Contains(client)) { - bool keyboardActivated = m.LParamInternal == -1; - treeNode.ContextMenuStrip.ShowInternal(this, client, keyboardActivated); + if (treeNode.ContextMenu is not null) + { + treeNode.ContextMenu.Show(this, client); + } + else if (ContextMenuStrip is not null) + { + bool keyboardActivated = m.LParamInternal == -1; + treeNode.ContextMenuStrip.ShowInternal(this, client, keyboardActivated); + } } } else diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/UnsafeNativeMethodsCore.cs b/src/System.Windows.Forms/src/System/Windows/Forms/UnsafeNativeMethodsCore.cs new file mode 100644 index 00000000000..f7f5638a3ba --- /dev/null +++ b/src/System.Windows.Forms/src/System/Windows/Forms/UnsafeNativeMethodsCore.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace WTG.System.Windows.Forms.System.Windows.Forms +{ + internal class UnsafeNativeMethodsCore + { + + /// + /// This class provides static methods to create, activate and deactivate the theming scope. + /// + internal class ThemingScope + { + private static ACTCTX enableThemingActivationContext; + private static IntPtr hActCtx; + private static bool contextCreationSucceeded; + + /// + /// We now use explicitactivate everywhere and use this method to determine if we + /// really need to activate the activationcontext. This should be pretty fast. + /// + private static bool IsContextActive() + { + IntPtr current = IntPtr.Zero; + + if (contextCreationSucceeded && GetCurrentActCtx(out current)) + { + return current == hActCtx; + } + + return false; + } + + /// + /// Activate() does nothing if a theming context is already active on the current thread, which is good + /// for perf reasons. However, in some cases, like in the Timer callback, we need to put another context + /// on the stack even if one is already present. In such cases, this method helps - you get to manage + /// the cookie yourself though. + /// + public static IntPtr Activate() + { + IntPtr userCookie = IntPtr.Zero; + + if (Application.UseVisualStyles && contextCreationSucceeded && OSFeature.Feature.IsPresent(OSFeature.Themes)) + { + if (!IsContextActive()) + { + if (!ActivateActCtx(hActCtx, out userCookie)) + { + // Be sure cookie always zero if activation failed + userCookie = IntPtr.Zero; + } + } + } + + return userCookie; + } + + /// + /// Use this to deactivate a context activated by calling ExplicitActivate. + /// + public static IntPtr Deactivate(IntPtr userCookie) + { + if (userCookie != IntPtr.Zero && OSFeature.Feature.IsPresent(OSFeature.Themes)) + { + if (DeactivateActCtx(0, userCookie)) + { + // deactivation succeeded... + userCookie = IntPtr.Zero; + } + } + + return userCookie; + } + + public static bool CreateActivationContext(string dllPath, int nativeResourceManifestID) + { + lock (typeof(ThemingScope)) + { + if (!contextCreationSucceeded && OSFeature.Feature.IsPresent(OSFeature.Themes)) + { + + enableThemingActivationContext = new ACTCTX + { + cbSize = Marshal.SizeOf(), + lpSource = dllPath, + lpResourceName = (IntPtr)nativeResourceManifestID, + dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID + }; + + hActCtx = CreateActCtx(ref enableThemingActivationContext); + contextCreationSucceeded = (hActCtx != new IntPtr(-1)); + } + + return contextCreationSucceeded; + } + } + + // All the pinvoke goo... + [DllImport(ExternDll.Kernel32)] + + private extern static IntPtr CreateActCtx(ref ACTCTX actctx); + [DllImport(ExternDll.Kernel32)] + + private extern static bool ActivateActCtx(IntPtr hActCtx, out IntPtr lpCookie); + [DllImport(ExternDll.Kernel32)] + + private extern static bool DeactivateActCtx(int dwFlags, IntPtr lpCookie); + [DllImport(ExternDll.Kernel32)] + + private extern static bool GetCurrentActCtx(out IntPtr handle); + + private const int ACTCTX_FLAG_RESOURCE_NAME_VALID = 0x008; + + private struct ACTCTX + { + public int cbSize; + public uint dwFlags; + public string lpSource; + public ushort wProcessorArchitecture; + public ushort wLangId; + public string lpAssemblyDirectory; + public IntPtr lpResourceName; + public string lpApplicationName; + } + } + } +} diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/UpDownBase.UpDownEdit.cs b/src/System.Windows.Forms/src/System/Windows/Forms/UpDownBase.UpDownEdit.cs index e497e297d73..31b19ec4428 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/UpDownBase.UpDownEdit.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/UpDownBase.UpDownEdit.cs @@ -87,7 +87,7 @@ protected override void OnMouseUp(MouseEventArgs e) internal override void WmContextMenu(ref Message m) { // Want to make the SourceControl to be the UpDownBase, not the Edit. - if (ContextMenuStrip is not null) + if (ContextMenuStrip is not null || ContextMenu is not null) { WmContextMenu(ref m, _parent); } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/WebBrowser.WebBrowserEvent.cs b/src/System.Windows.Forms/src/System/Windows/Forms/WebBrowser.WebBrowserEvent.cs index df667609bd2..4c1fbbe6f57 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/WebBrowser.WebBrowserEvent.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/WebBrowser.WebBrowserEvent.cs @@ -13,12 +13,25 @@ public partial class WebBrowser [ClassInterface(ClassInterfaceType.None)] private class WebBrowserEvent : StandardOleMarshalObject, SHDocVw.DWebBrowserEvents2 { - private readonly WebBrowser _parent; + private readonly WeakReference _parent; + private WebBrowser Parent + { + get + { + if (_parent.TryGetTarget(out var target)) + { + return target; + } + + return null; + } + } + private bool _haveNavigated; public WebBrowserEvent(WebBrowser parent) { - _parent = parent; + _parent = new(parent); } public bool AllowNavigation { get; set; } @@ -27,11 +40,11 @@ public void CommandStateChange(SHDocVw.CSC command, bool enable) { if (command == SHDocVw.CSC.NAVIGATEBACK) { - _parent.CanGoBackInternal = enable; + Parent.CanGoBackInternal = enable; } else if (command == SHDocVw.CSC.NAVIGATEFORWARD) { - _parent.CanGoForwardInternal = enable; + Parent.CanGoForwardInternal = enable; } } @@ -44,7 +57,7 @@ public void BeforeNavigate2( ref object? headers, ref bool cancel) { - Debug.Assert(_parent is not null, "Parent should have been set"); + Debug.Assert(Parent is not null, "Parent should have been set"); //Note: we want to allow navigation if we haven't already navigated. if (AllowNavigation || !_haveNavigated) { @@ -62,7 +75,7 @@ public void BeforeNavigate2( string urlString = urlObject is null ? string.Empty : (string)urlObject; WebBrowserNavigatingEventArgs e = new WebBrowserNavigatingEventArgs( new Uri(urlString), targetFrameName is null ? string.Empty : (string)targetFrameName); - _parent.OnNavigating(e); + Parent.OnNavigating(e); cancel = e.Cancel; } else @@ -75,38 +88,38 @@ public unsafe void DocumentComplete(object pDisp, ref object? urlObject) { Debug.Assert(urlObject is null || urlObject is string, "invalid url"); _haveNavigated = true; - if (_parent._documentStreamToSetOnLoad is not null && (string?)urlObject == "about:blank") + if (Parent._documentStreamToSetOnLoad is not null && (string?)urlObject == "about:blank") { - HtmlDocument? htmlDocument = _parent.Document; + HtmlDocument? htmlDocument = Parent.Document; if (htmlDocument is not null) { IPersistStreamInit.Interface? psi = htmlDocument.DomDocument as IPersistStreamInit.Interface; Debug.Assert(psi is not null, "The Document does not implement IPersistStreamInit"); - using var pStream = ComHelpers.GetComScope(new Ole32.GPStream(_parent._documentStreamToSetOnLoad)); + using var pStream = ComHelpers.GetComScope(new Ole32.GPStream(Parent._documentStreamToSetOnLoad)); psi.Load(pStream); htmlDocument.Encoding = "unicode"; } - _parent._documentStreamToSetOnLoad = null; + Parent._documentStreamToSetOnLoad = null; } else { string urlString = urlObject is null ? string.Empty : urlObject.ToString()!; WebBrowserDocumentCompletedEventArgs e = new WebBrowserDocumentCompletedEventArgs( new Uri(urlString)); - _parent.OnDocumentCompleted(e); + Parent.OnDocumentCompleted(e); } } public void TitleChange(string text) { - _parent.OnDocumentTitleChanged(EventArgs.Empty); + Parent.OnDocumentTitleChanged(EventArgs.Empty); } public void SetSecureLockIcon(int secureLockIcon) { - _parent._encryptionLevel = (WebBrowserEncryptionLevel)secureLockIcon; - _parent.OnEncryptionLevelChanged(EventArgs.Empty); + Parent._encryptionLevel = (WebBrowserEncryptionLevel)secureLockIcon; + Parent.OnEncryptionLevelChanged(EventArgs.Empty); } public void NavigateComplete2(object pDisp, ref object? urlObject) @@ -115,29 +128,29 @@ public void NavigateComplete2(object pDisp, ref object? urlObject) string urlString = urlObject is null ? string.Empty : (string)urlObject; WebBrowserNavigatedEventArgs e = new WebBrowserNavigatedEventArgs( new Uri(urlString)); - _parent.OnNavigated(e); + Parent.OnNavigated(e); } public void NewWindow2(ref object ppDisp, ref bool cancel) { CancelEventArgs e = new CancelEventArgs(); - _parent.OnNewWindow(e); + Parent.OnNewWindow(e); cancel = e.Cancel; } public void ProgressChange(int progress, int progressMax) { WebBrowserProgressChangedEventArgs e = new WebBrowserProgressChangedEventArgs(progress, progressMax); - _parent.OnProgressChanged(e); + Parent.OnProgressChanged(e); } public void StatusTextChange(string text) { - _parent._statusText = text ?? string.Empty; - _parent.OnStatusTextChanged(EventArgs.Empty); + Parent._statusText = text ?? string.Empty; + Parent.OnStatusTextChanged(EventArgs.Empty); } - public void DownloadBegin() => _parent.OnFileDownload(EventArgs.Empty); + public void DownloadBegin() => Parent.OnFileDownload(EventArgs.Empty); public void FileDownload(ref bool cancel) { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/WebBrowserSiteBase.cs b/src/System.Windows.Forms/src/System/Windows/Forms/WebBrowserSiteBase.cs index 8a68e12caaa..ab407d5890c 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/WebBrowserSiteBase.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/WebBrowserSiteBase.cs @@ -30,7 +30,7 @@ public unsafe class WebBrowserSiteBase : IPropertyNotifySink.Interface, IDisposable { - private readonly WebBrowserBase host; + private readonly WeakReference host; private AxHost.ConnectionPointCookie? connectionPoint; // @@ -40,7 +40,7 @@ public unsafe class WebBrowserSiteBase : // internal WebBrowserSiteBase(WebBrowserBase h) { - host = h.OrThrowIfNull(); + host = new(h.OrThrowIfNull()); } /// @@ -65,7 +65,18 @@ protected virtual void Dispose(bool disposing) /// /// Retrieves the WebBrowserBase object set in the constructor. /// - internal WebBrowserBase Host => host; + internal WebBrowserBase Host + { + get + { + if (host.TryGetTarget(out var target)) + { + return target; + } + + return null; + } + } // IOleControlSite methods: HRESULT IOleControlSite.Interface.OnControlInfoChanged() => HRESULT.S_OK; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/WinFormsUtils.cs b/src/System.Windows.Forms/src/System/Windows/Forms/WinFormsUtils.cs index a7f07670528..62358ac4d6a 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/WinFormsUtils.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/WinFormsUtils.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections; using System.ComponentModel; using System.Drawing; using System.Globalization; @@ -11,6 +12,40 @@ namespace System.Windows.Forms; internal sealed partial class WindowsFormsUtils { + public class ArraySubsetEnumerator : IEnumerator + { + private readonly object[] _array; + private readonly int _total; + private int _current; + + public ArraySubsetEnumerator(object[] array, int count) + { + Debug.Assert(count == 0 || array != null, "if array is null, count should be 0"); + Debug.Assert(array == null || count <= array.Length, "Trying to enumerate more than the array contains"); + _array = array; + _total = count; + _current = -1; + } + + public bool MoveNext() + { + if (_current < _total - 1) + { + _current++; + return true; + } + + return false; + } + + public void Reset() + { + _current = -1; + } + + public object Current => _current == -1 ? null : _array[_current]; + } + public const ContentAlignment AnyRightAlign = ContentAlignment.TopRight | ContentAlignment.MiddleRight | ContentAlignment.BottomRight; public const ContentAlignment AnyLeftAlign = ContentAlignment.TopLeft | ContentAlignment.MiddleLeft | ContentAlignment.BottomLeft; public const ContentAlignment AnyTopAlign = ContentAlignment.TopLeft | ContentAlignment.TopCenter | ContentAlignment.TopRight; diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Accessibility_Core_App.csproj b/src/System.Windows.Forms/tests/AccessibilityTests/Accessibility_Core_App.csproj deleted file mode 100644 index 893fee5eac4..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Accessibility_Core_App.csproj +++ /dev/null @@ -1,39 +0,0 @@ - - - - WinExe - Accessibility_Core_App - Accessibility_Core_App - app.manifest - false - false - $(NoWarn);IDE0090 - - - - - - - - - - True - True - Resources.resx - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - - PreserveNewest - - - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Accessibility_Core_App.sln b/src/System.Windows.Forms/tests/AccessibilityTests/Accessibility_Core_App.sln deleted file mode 100644 index f68d55595eb..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Accessibility_Core_App.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.3.32622.301 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Accessibility_Core_App", "Accessibility_Core_App.csproj", "{D7BB93BE-9D7E-407F-85DB-DC8BBB364FFD}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D7BB93BE-9D7E-407F-85DB-DC8BBB364FFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D7BB93BE-9D7E-407F-85DB-DC8BBB364FFD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D7BB93BE-9D7E-407F-85DB-DC8BBB364FFD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D7BB93BE-9D7E-407F-85DB-DC8BBB364FFD}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {1651E338-125D-4AAD-BAA2-00625873964D} - EndGlobalSection -EndGlobal diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl1.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl1.Designer.cs deleted file mode 100644 index 5bd00f214a2..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl1.Designer.cs +++ /dev/null @@ -1,765 +0,0 @@ -namespace Accessibility_Core_App; - -partial class CommonControl1 -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem("1"); - System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem("2"); - System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem("3"); - System.Windows.Forms.ListViewItem listViewItem4 = new System.Windows.Forms.ListViewItem("4"); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.button12 = new System.Windows.Forms.Button(); - this.button1 = new System.Windows.Forms.Button(); - this.button10 = new System.Windows.Forms.Button(); - this.button9 = new System.Windows.Forms.Button(); - this.button8 = new System.Windows.Forms.Button(); - this.button3 = new System.Windows.Forms.Button(); - this.button4 = new System.Windows.Forms.Button(); - this.button5 = new System.Windows.Forms.Button(); - this.button2 = new System.Windows.Forms.Button(); - this.button6 = new System.Windows.Forms.Button(); - this.groupBox2 = new System.Windows.Forms.GroupBox(); - this.checkedListBox1 = new System.Windows.Forms.CheckedListBox(); - this.label7 = new System.Windows.Forms.Label(); - this.checkBox3 = new System.Windows.Forms.CheckBox(); - this.checkBox2 = new System.Windows.Forms.CheckBox(); - this.checkBox1 = new System.Windows.Forms.CheckBox(); - this.groupBox3 = new System.Windows.Forms.GroupBox(); - this.comboBox2 = new System.Windows.Forms.ComboBox(); - this.label11 = new System.Windows.Forms.Label(); - this.comboBox1 = new System.Windows.Forms.ComboBox(); - this.label10 = new System.Windows.Forms.Label(); - this.groupBox4 = new System.Windows.Forms.GroupBox(); - this.listView1 = new System.Windows.Forms.ListView(); - this.label8 = new System.Windows.Forms.Label(); - this.groupBox5 = new System.Windows.Forms.GroupBox(); - this.linkLabel6 = new System.Windows.Forms.LinkLabel(); - this.linkLabel5 = new System.Windows.Forms.LinkLabel(); - this.linkLabel4 = new System.Windows.Forms.LinkLabel(); - this.linkLabel3 = new System.Windows.Forms.LinkLabel(); - this.label6 = new System.Windows.Forms.Label(); - this.label5 = new System.Windows.Forms.Label(); - this.label4 = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.linkLabel2 = new System.Windows.Forms.LinkLabel(); - this.linkLabel1 = new System.Windows.Forms.LinkLabel(); - this.label2 = new System.Windows.Forms.Label(); - this.label1 = new System.Windows.Forms.Label(); - this.groupBox6 = new System.Windows.Forms.GroupBox(); - this.listBox1 = new System.Windows.Forms.ListBox(); - this.label12 = new System.Windows.Forms.Label(); - this.groupBox7 = new System.Windows.Forms.GroupBox(); - this.maskedTextBox1 = new System.Windows.Forms.MaskedTextBox(); - this.label9 = new System.Windows.Forms.Label(); - this.groupBox8 = new System.Windows.Forms.GroupBox(); - this.dateTimePicker3 = new System.Windows.Forms.DateTimePicker(); - this.dateTimePicker2 = new System.Windows.Forms.DateTimePicker(); - this.dateTimePicker1 = new System.Windows.Forms.DateTimePicker(); - this.groupBox1.SuspendLayout(); - this.groupBox2.SuspendLayout(); - this.groupBox3.SuspendLayout(); - this.groupBox4.SuspendLayout(); - this.groupBox5.SuspendLayout(); - this.groupBox6.SuspendLayout(); - this.groupBox7.SuspendLayout(); - this.groupBox8.SuspendLayout(); - this.SuspendLayout(); - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.button12); - this.groupBox1.Controls.Add(this.button1); - this.groupBox1.Controls.Add(this.button10); - this.groupBox1.Controls.Add(this.button9); - this.groupBox1.Controls.Add(this.button8); - this.groupBox1.Controls.Add(this.button3); - this.groupBox1.Controls.Add(this.button4); - this.groupBox1.Controls.Add(this.button5); - this.groupBox1.Controls.Add(this.button2); - this.groupBox1.Controls.Add(this.button6); - this.groupBox1.Location = new System.Drawing.Point(32, 4); - this.groupBox1.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Padding = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox1.Size = new System.Drawing.Size(771, 380); - this.groupBox1.TabIndex = 0; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Button"; - // - // button12 - // - this.button12.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.button12.Location = new System.Drawing.Point(15, 309); - this.button12.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.button12.Name = "button12"; - this.button12.Size = new System.Drawing.Size(130, 58); - this.button12.TabIndex = 4; - this.button12.Text = "System"; - this.button12.UseVisualStyleBackColor = true; - // - // button1 - // - this.button1.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.button1.Location = new System.Drawing.Point(240, 245); - this.button1.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(130, 58); - this.button1.TabIndex = 8; - this.button1.Text = "Details"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.button1_Click); - // - // button10 - // - this.button10.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.button10.Location = new System.Drawing.Point(15, 105); - this.button10.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.button10.Name = "button10"; - this.button10.Size = new System.Drawing.Size(130, 58); - this.button10.TabIndex = 1; - this.button10.Text = "Flat"; - this.button10.UseVisualStyleBackColor = true; - // - // button9 - // - this.button9.Location = new System.Drawing.Point(15, 245); - this.button9.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.button9.Name = "button9"; - this.button9.Size = new System.Drawing.Size(130, 58); - this.button9.TabIndex = 3; - this.button9.Text = "Standard"; - this.button9.UseVisualStyleBackColor = true; - // - // button8 - // - this.button8.FlatStyle = System.Windows.Forms.FlatStyle.Popup; - this.button8.Location = new System.Drawing.Point(15, 175); - this.button8.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.button8.Name = "button8"; - this.button8.Size = new System.Drawing.Size(130, 58); - this.button8.TabIndex = 2; - this.button8.Text = "PopUp"; - this.button8.UseVisualStyleBackColor = true; - // - // button3 - // - this.button3.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.button3.Location = new System.Drawing.Point(15, 34); - this.button3.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.button3.Name = "button3"; - this.button3.Size = new System.Drawing.Size(130, 58); - this.button3.TabIndex = 0; - this.button3.Text = "List"; - this.button3.UseVisualStyleBackColor = false; - this.button3.Click += new System.EventHandler(this.button3_Click); - // - // button4 - // - this.button4.Anchor = System.Windows.Forms.AnchorStyles.Bottom; - this.button4.Location = new System.Drawing.Point(240, 309); - this.button4.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.button4.Name = "button4"; - this.button4.Size = new System.Drawing.Size(156, 58); - this.button4.TabIndex = 9; - this.button4.Text = "SmallIcon"; - this.button4.UseVisualStyleBackColor = true; - this.button4.Click += new System.EventHandler(this.button4_Click); - // - // button5 - // - this.button5.AutoSize = true; - this.button5.Location = new System.Drawing.Point(240, 100); - this.button5.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.button5.Name = "button5"; - this.button5.Size = new System.Drawing.Size(175, 63); - this.button5.TabIndex = 6; - this.button5.Text = "AutoSizeTrue"; - this.button5.UseVisualStyleBackColor = true; - // - // button2 - // - this.button2.Anchor = System.Windows.Forms.AnchorStyles.Top; - this.button2.Location = new System.Drawing.Point(241, 34); - this.button2.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(156, 58); - this.button2.TabIndex = 5; - this.button2.Text = "LargeIcon"; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.button2_Click); - // - // button6 - // - this.button6.Location = new System.Drawing.Point(240, 175); - this.button6.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.button6.Name = "button6"; - this.button6.Size = new System.Drawing.Size(175, 58); - this.button6.TabIndex = 7; - this.button6.Text = "AutoSizeFalse"; - this.button6.UseVisualStyleBackColor = true; - // - // groupBox2 - // - this.groupBox2.Controls.Add(this.checkedListBox1); - this.groupBox2.Controls.Add(this.label7); - this.groupBox2.Controls.Add(this.checkBox3); - this.groupBox2.Controls.Add(this.checkBox2); - this.groupBox2.Controls.Add(this.checkBox1); - this.groupBox2.Location = new System.Drawing.Point(32, 397); - this.groupBox2.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox2.Name = "groupBox2"; - this.groupBox2.Padding = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox2.Size = new System.Drawing.Size(771, 269); - this.groupBox2.TabIndex = 1; - this.groupBox2.TabStop = false; - this.groupBox2.Text = "CheckedBox"; - // - // checkedListBox1 - // - this.checkedListBox1.FormattingEnabled = true; - this.checkedListBox1.Items.AddRange(new object[] { - "Winforms1", - "Winforms2", - "Winforms3"}); - this.checkedListBox1.Location = new System.Drawing.Point(299, 83); - this.checkedListBox1.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.checkedListBox1.Name = "checkedListBox1"; - this.checkedListBox1.Size = new System.Drawing.Size(255, 148); - this.checkedListBox1.TabIndex = 4; - // - // label7 - // - this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(301, 32); - this.label7.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(180, 32); - this.label7.TabIndex = 3; - this.label7.Text = "CheckedListBox"; - // - // checkBox3 - // - this.checkBox3.AutoSize = true; - this.checkBox3.Location = new System.Drawing.Point(15, 137); - this.checkBox3.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.checkBox3.Name = "checkBox3"; - this.checkBox3.Size = new System.Drawing.Size(160, 36); - this.checkBox3.TabIndex = 2; - this.checkBox3.Text = "ThreeState"; - this.checkBox3.ThreeState = true; - this.checkBox3.UseVisualStyleBackColor = true; - // - // checkBox2 - // - this.checkBox2.AutoSize = true; - this.checkBox2.Location = new System.Drawing.Point(15, 83); - this.checkBox2.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.checkBox2.Name = "checkBox2"; - this.checkBox2.Size = new System.Drawing.Size(168, 36); - this.checkBox2.TabIndex = 1; - this.checkBox2.Text = "UnChecked"; - this.checkBox2.UseVisualStyleBackColor = true; - // - // checkBox1 - // - this.checkBox1.AutoSize = true; - this.checkBox1.Checked = true; - this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox1.Location = new System.Drawing.Point(15, 30); - this.checkBox1.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.checkBox1.Name = "checkBox1"; - this.checkBox1.Size = new System.Drawing.Size(138, 36); - this.checkBox1.TabIndex = 0; - this.checkBox1.Text = "Checked"; - this.checkBox1.UseVisualStyleBackColor = true; - // - // groupBox3 - // - this.groupBox3.Controls.Add(this.comboBox2); - this.groupBox3.Controls.Add(this.label11); - this.groupBox3.Controls.Add(this.comboBox1); - this.groupBox3.Controls.Add(this.label10); - this.groupBox3.Location = new System.Drawing.Point(839, 4); - this.groupBox3.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox3.Name = "groupBox3"; - this.groupBox3.Padding = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox3.Size = new System.Drawing.Size(600, 380); - this.groupBox3.TabIndex = 4; - this.groupBox3.TabStop = false; - this.groupBox3.Text = "ComboBox"; - // - // comboBox2 - // - this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.Simple; - this.comboBox2.FormattingEnabled = true; - this.comboBox2.Items.AddRange(new object[] { - "1", - "2", - "3", - "4", - "5"}); - this.comboBox2.Location = new System.Drawing.Point(314, 85); - this.comboBox2.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.comboBox2.Name = "comboBox2"; - this.comboBox2.Size = new System.Drawing.Size(257, 266); - this.comboBox2.TabIndex = 3; - // - // label11 - // - this.label11.AutoSize = true; - this.label11.Location = new System.Drawing.Point(371, 34); - this.label11.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label11.Name = "label11"; - this.label11.Size = new System.Drawing.Size(138, 32); - this.label11.TabIndex = 2; - this.label11.Text = "SimpleStyle"; - // - // comboBox1 - // - this.comboBox1.FormattingEnabled = true; - this.comboBox1.Items.AddRange(new object[] { - "1", - "2", - "3", - "4", - "5"}); - this.comboBox1.Location = new System.Drawing.Point(15, 90); - this.comboBox1.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.comboBox1.Name = "comboBox1"; - this.comboBox1.Size = new System.Drawing.Size(257, 40); - this.comboBox1.TabIndex = 1; - // - // label10 - // - this.label10.AutoSize = true; - this.label10.Location = new System.Drawing.Point(15, 41); - this.label10.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label10.Name = "label10"; - this.label10.Size = new System.Drawing.Size(180, 32); - this.label10.TabIndex = 0; - this.label10.Text = "DropDownStyle"; - // - // groupBox4 - // - this.groupBox4.Controls.Add(this.listView1); - this.groupBox4.Controls.Add(this.label8); - this.groupBox4.Location = new System.Drawing.Point(839, 397); - this.groupBox4.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox4.Name = "groupBox4"; - this.groupBox4.Padding = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox4.Size = new System.Drawing.Size(598, 269); - this.groupBox4.TabIndex = 5; - this.groupBox4.TabStop = false; - this.groupBox4.Text = "ListView"; - // - // listView1 - // - this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] { - listViewItem1, - listViewItem2, - listViewItem3, - listViewItem4}); - this.listView1.Location = new System.Drawing.Point(149, 83); - this.listView1.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.listView1.Name = "listView1"; - this.listView1.Size = new System.Drawing.Size(257, 151); - this.listView1.TabIndex = 1; - this.listView1.UseCompatibleStateImageBehavior = false; - // - // label8 - // - this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(223, 30); - this.label8.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(100, 32); - this.label8.TabIndex = 0; - this.label8.Text = "ListView"; - // - // groupBox5 - // - this.groupBox5.Controls.Add(this.linkLabel6); - this.groupBox5.Controls.Add(this.linkLabel5); - this.groupBox5.Controls.Add(this.linkLabel4); - this.groupBox5.Controls.Add(this.linkLabel3); - this.groupBox5.Controls.Add(this.label6); - this.groupBox5.Controls.Add(this.label5); - this.groupBox5.Controls.Add(this.label4); - this.groupBox5.Controls.Add(this.label3); - this.groupBox5.Controls.Add(this.linkLabel2); - this.groupBox5.Controls.Add(this.linkLabel1); - this.groupBox5.Controls.Add(this.label2); - this.groupBox5.Controls.Add(this.label1); - this.groupBox5.Location = new System.Drawing.Point(33, 678); - this.groupBox5.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox5.Name = "groupBox5"; - this.groupBox5.Padding = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox5.Size = new System.Drawing.Size(769, 271); - this.groupBox5.TabIndex = 2; - this.groupBox5.TabStop = false; - this.groupBox5.Text = "Label"; - // - // linkLabel6 - // - this.linkLabel6.Anchor = System.Windows.Forms.AnchorStyles.Top; - this.linkLabel6.AutoSize = true; - this.linkLabel6.Location = new System.Drawing.Point(386, 38); - this.linkLabel6.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.linkLabel6.Name = "linkLabel6"; - this.linkLabel6.Size = new System.Drawing.Size(44, 32); - this.linkLabel6.TabIndex = 5; - this.linkLabel6.TabStop = true; - this.linkLabel6.Text = "Up"; - // - // linkLabel5 - // - this.linkLabel5.Anchor = System.Windows.Forms.AnchorStyles.Bottom; - this.linkLabel5.AutoSize = true; - this.linkLabel5.Location = new System.Drawing.Point(340, 207); - this.linkLabel5.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.linkLabel5.Name = "linkLabel5"; - this.linkLabel5.Size = new System.Drawing.Size(93, 32); - this.linkLabel5.TabIndex = 9; - this.linkLabel5.TabStop = true; - this.linkLabel5.Text = "Bottom"; - // - // linkLabel4 - // - this.linkLabel4.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.linkLabel4.AutoSize = true; - this.linkLabel4.Location = new System.Drawing.Point(598, 143); - this.linkLabel4.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.linkLabel4.Name = "linkLabel4"; - this.linkLabel4.Size = new System.Drawing.Size(70, 32); - this.linkLabel4.TabIndex = 11; - this.linkLabel4.TabStop = true; - this.linkLabel4.Text = "Right"; - // - // linkLabel3 - // - this.linkLabel3.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.linkLabel3.AutoSize = true; - this.linkLabel3.Location = new System.Drawing.Point(17, 143); - this.linkLabel3.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.linkLabel3.Name = "linkLabel3"; - this.linkLabel3.Size = new System.Drawing.Size(54, 32); - this.linkLabel3.TabIndex = 1; - this.linkLabel3.TabStop = true; - this.linkLabel3.Text = "Left"; - // - // label6 - // - this.label6.Anchor = System.Windows.Forms.AnchorStyles.Bottom; - this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(154, 207); - this.label6.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(93, 32); - this.label6.TabIndex = 8; - this.label6.Text = "Bottom"; - // - // label5 - // - this.label5.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(15, 87); - this.label5.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(54, 32); - this.label5.TabIndex = 0; - this.label5.Text = "Left"; - // - // label4 - // - this.label4.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(598, 87); - this.label4.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(70, 32); - this.label4.TabIndex = 10; - this.label4.Text = "Right"; - // - // label3 - // - this.label3.Anchor = System.Windows.Forms.AnchorStyles.Top; - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(171, 41); - this.label3.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(44, 32); - this.label3.TabIndex = 4; - this.label3.Text = "Up"; - // - // linkLabel2 - // - this.linkLabel2.Location = new System.Drawing.Point(340, 143); - this.linkLabel2.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.linkLabel2.Name = "linkLabel2"; - this.linkLabel2.Size = new System.Drawing.Size(217, 58); - this.linkLabel2.TabIndex = 7; - this.linkLabel2.TabStop = true; - this.linkLabel2.Text = "AutoSizeFalse"; - // - // linkLabel1 - // - this.linkLabel1.AutoSize = true; - this.linkLabel1.Location = new System.Drawing.Point(340, 87); - this.linkLabel1.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.linkLabel1.Name = "linkLabel1"; - this.linkLabel1.Size = new System.Drawing.Size(154, 32); - this.linkLabel1.TabIndex = 6; - this.linkLabel1.TabStop = true; - this.linkLabel1.Text = "AutoSizeTrue"; - // - // label2 - // - this.label2.Location = new System.Drawing.Point(121, 143); - this.label2.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(217, 58); - this.label2.TabIndex = 3; - this.label2.Text = "AutoSizeFalse"; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(121, 87); - this.label1.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(154, 32); - this.label1.TabIndex = 2; - this.label1.Text = "AutoSizeTrue"; - // - // groupBox6 - // - this.groupBox6.Controls.Add(this.listBox1); - this.groupBox6.Controls.Add(this.label12); - this.groupBox6.Location = new System.Drawing.Point(839, 678); - this.groupBox6.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox6.Name = "groupBox6"; - this.groupBox6.Padding = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox6.Size = new System.Drawing.Size(598, 271); - this.groupBox6.TabIndex = 6; - this.groupBox6.TabStop = false; - this.groupBox6.Text = "ListBox"; - // - // listBox1 - // - this.listBox1.FormattingEnabled = true; - this.listBox1.ItemHeight = 32; - this.listBox1.Items.AddRange(new object[] { - "1", - "2", - "3", - "4"}); - this.listBox1.Location = new System.Drawing.Point(150, 77); - this.listBox1.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.listBox1.Name = "listBox1"; - this.listBox1.Size = new System.Drawing.Size(255, 164); - this.listBox1.TabIndex = 1; - // - // label12 - // - this.label12.AutoSize = true; - this.label12.Location = new System.Drawing.Point(223, 38); - this.label12.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label12.Name = "label12"; - this.label12.Size = new System.Drawing.Size(83, 32); - this.label12.TabIndex = 0; - this.label12.Text = "listbox"; - // - // groupBox7 - // - this.groupBox7.Controls.Add(this.maskedTextBox1); - this.groupBox7.Controls.Add(this.label9); - this.groupBox7.Location = new System.Drawing.Point(702, 983); - this.groupBox7.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox7.Name = "groupBox7"; - this.groupBox7.Padding = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox7.Size = new System.Drawing.Size(735, 277); - this.groupBox7.TabIndex = 7; - this.groupBox7.TabStop = false; - this.groupBox7.Text = "MaskedTextBox"; - // - // maskedTextBox1 - // - this.maskedTextBox1.Location = new System.Drawing.Point(288, 119); - this.maskedTextBox1.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.maskedTextBox1.Name = "maskedTextBox1"; - this.maskedTextBox1.Size = new System.Drawing.Size(212, 39); - this.maskedTextBox1.TabIndex = 1; - // - // label9 - // - this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(15, 126); - this.label9.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(171, 32); - this.label9.TabIndex = 0; - this.label9.Text = "MaskedTextBix"; - // - // groupBox8 - // - this.groupBox8.Controls.Add(this.dateTimePicker3); - this.groupBox8.Controls.Add(this.dateTimePicker2); - this.groupBox8.Controls.Add(this.dateTimePicker1); - this.groupBox8.Location = new System.Drawing.Point(33, 983); - this.groupBox8.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox8.Name = "groupBox8"; - this.groupBox8.Padding = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.groupBox8.Size = new System.Drawing.Size(570, 277); - this.groupBox8.TabIndex = 3; - this.groupBox8.TabStop = false; - this.groupBox8.Text = "DataTimerPicker"; - // - // dateTimePicker3 - // - this.dateTimePicker3.AccessibleName = "DTP2"; - this.dateTimePicker3.Location = new System.Drawing.Point(37, 126); - this.dateTimePicker3.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.dateTimePicker3.Name = "dateTimePicker3"; - this.dateTimePicker3.Size = new System.Drawing.Size(429, 39); - this.dateTimePicker3.TabIndex = 1; - // - // dateTimePicker2 - // - this.dateTimePicker2.AccessibleName = "DTP3"; - this.dateTimePicker2.Anchor = System.Windows.Forms.AnchorStyles.Bottom; - this.dateTimePicker2.Location = new System.Drawing.Point(37, 205); - this.dateTimePicker2.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.dateTimePicker2.Name = "dateTimePicker2"; - this.dateTimePicker2.RightToLeft = System.Windows.Forms.RightToLeft.Yes; - this.dateTimePicker2.Size = new System.Drawing.Size(429, 39); - this.dateTimePicker2.TabIndex = 2; - // - // dateTimePicker1 - // - this.dateTimePicker1.AccessibleName = "DTP1"; - this.dateTimePicker1.CalendarForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128))))); - this.dateTimePicker1.CalendarMonthBackground = System.Drawing.Color.Yellow; - this.dateTimePicker1.CalendarTitleBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(255))))); - this.dateTimePicker1.CalendarTitleForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(224)))), ((int)(((byte)(192))))); - this.dateTimePicker1.CalendarTrailingForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(255))))); - this.dateTimePicker1.Location = new System.Drawing.Point(37, 47); - this.dateTimePicker1.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.dateTimePicker1.Name = "dateTimePicker1"; - this.dateTimePicker1.ShowCheckBox = true; - this.dateTimePicker1.Size = new System.Drawing.Size(457, 39); - this.dateTimePicker1.TabIndex = 0; - // - // CommonControl1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(13F, 32F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoScroll = true; - this.ClientSize = new System.Drawing.Size(1482, 1291); - this.Controls.Add(this.groupBox8); - this.Controls.Add(this.groupBox7); - this.Controls.Add(this.groupBox6); - this.Controls.Add(this.groupBox5); - this.Controls.Add(this.groupBox4); - this.Controls.Add(this.groupBox3); - this.Controls.Add(this.groupBox2); - this.Controls.Add(this.groupBox1); - this.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); - this.Name = "CommonControl1"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "CommonControl1"; - this.Load += new System.EventHandler(this.MainForm_Load); - this.groupBox1.ResumeLayout(false); - this.groupBox1.PerformLayout(); - this.groupBox2.ResumeLayout(false); - this.groupBox2.PerformLayout(); - this.groupBox3.ResumeLayout(false); - this.groupBox3.PerformLayout(); - this.groupBox4.ResumeLayout(false); - this.groupBox4.PerformLayout(); - this.groupBox5.ResumeLayout(false); - this.groupBox5.PerformLayout(); - this.groupBox6.ResumeLayout(false); - this.groupBox6.PerformLayout(); - this.groupBox7.ResumeLayout(false); - this.groupBox7.PerformLayout(); - this.groupBox8.ResumeLayout(false); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.GroupBox groupBox1; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.Button button3; - private System.Windows.Forms.Button button4; - private System.Windows.Forms.Button button5; - private System.Windows.Forms.Button button6; - private System.Windows.Forms.Button button12; - private System.Windows.Forms.Button button10; - private System.Windows.Forms.Button button9; - private System.Windows.Forms.Button button8; - private System.Windows.Forms.Button button2; - private System.Windows.Forms.GroupBox groupBox2; - private System.Windows.Forms.CheckBox checkBox3; - private System.Windows.Forms.CheckBox checkBox2; - private System.Windows.Forms.CheckBox checkBox1; - private System.Windows.Forms.GroupBox groupBox3; - private System.Windows.Forms.GroupBox groupBox4; - private System.Windows.Forms.GroupBox groupBox5; - private System.Windows.Forms.LinkLabel linkLabel2; - private System.Windows.Forms.LinkLabel linkLabel1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.LinkLabel linkLabel6; - private System.Windows.Forms.LinkLabel linkLabel5; - private System.Windows.Forms.LinkLabel linkLabel4; - private System.Windows.Forms.LinkLabel linkLabel3; - private System.Windows.Forms.Label label6; - private System.Windows.Forms.Label label5; - private System.Windows.Forms.Label label4; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.GroupBox groupBox6; - private System.Windows.Forms.GroupBox groupBox7; - private System.Windows.Forms.GroupBox groupBox8; - private System.Windows.Forms.DateTimePicker dateTimePicker2; - private System.Windows.Forms.DateTimePicker dateTimePicker1; - private System.Windows.Forms.DateTimePicker dateTimePicker3; - private System.Windows.Forms.CheckedListBox checkedListBox1; - private System.Windows.Forms.Label label7; - private System.Windows.Forms.ListView listView1; - private System.Windows.Forms.Label label8; - private System.Windows.Forms.MaskedTextBox maskedTextBox1; - private System.Windows.Forms.Label label9; - private System.Windows.Forms.ComboBox comboBox1; - private System.Windows.Forms.Label label10; - private System.Windows.Forms.ComboBox comboBox2; - private System.Windows.Forms.Label label11; - private System.Windows.Forms.ListBox listBox1; - private System.Windows.Forms.Label label12; -} \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl1.cs b/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl1.cs deleted file mode 100644 index e3a4138981d..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl1.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class CommonControl1 : Form -{ - public CommonControl1() - { - InitializeComponent(); - } - - private void MainForm_Load(object sender, EventArgs e) - { - ImageList imageListSmall = new ImageList(); - ImageList imageListLarge = new ImageList(); - listView1.LargeImageList = imageListLarge; - listView1.SmallImageList = imageListSmall; - } - - private void button2_Click(object sender, EventArgs e) - { - listView1.View = View.LargeIcon; - } - - private void button4_Click(object sender, EventArgs e) - { - listView1.View = View.SmallIcon; - } - - private void button1_Click(object sender, EventArgs e) - { - listView1.View = View.Details; - } - - private void button3_Click(object sender, EventArgs e) - { - listView1.View = View.List; - } - - private void button11_Click(object sender, EventArgs e) - { - listView1.ShowGroups = true; - listView1.Groups[0].Items.Add(listView1.Items[0]); - listView1.Groups[1].Items.AddRange(new ListViewItem[] { listView1.Items[1], listView1.Items[2] }); - } - - private void button7_Click(object sender, EventArgs e) - { - listView1.ShowGroups = false; - } - - private void maskedTextBox1_MaskInputRejected(object sender, MaskInputRejectedEventArgs e) - { - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl1.resx b/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl1.resx deleted file mode 100644 index f298a7be809..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl1.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl2.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl2.Designer.cs deleted file mode 100644 index b473b799111..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl2.Designer.cs +++ /dev/null @@ -1,308 +0,0 @@ -namespace Accessibility_Core_App; - -partial class CommonControl2 -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("Node10WinformsTeam"); - System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("Node11"); - System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("Node1", new System.Windows.Forms.TreeNode[] { - treeNode1, - treeNode2}); - System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("Node20"); - System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode("Node2", new System.Windows.Forms.TreeNode[] { - treeNode4}); - System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode("Node0", new System.Windows.Forms.TreeNode[] { - treeNode3, - treeNode5}); - System.Windows.Forms.TreeNode treeNode7 = new System.Windows.Forms.TreeNode("Node4"); - System.Windows.Forms.TreeNode treeNode8 = new System.Windows.Forms.TreeNode("Node3", new System.Windows.Forms.TreeNode[] { - treeNode7}); - this.label3 = new System.Windows.Forms.Label(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.label4 = new System.Windows.Forms.Label(); - this.progressBar1 = new System.Windows.Forms.ProgressBar(); - this.radioButton1 = new System.Windows.Forms.RadioButton(); - this.label5 = new System.Windows.Forms.Label(); - this.richTextBox1 = new System.Windows.Forms.RichTextBox(); - this.label6 = new System.Windows.Forms.Label(); - this.textBox1 = new System.Windows.Forms.TextBox(); - this.label7 = new System.Windows.Forms.Label(); - this.treeView1 = new System.Windows.Forms.TreeView(); - this.label8 = new System.Windows.Forms.Label(); - this.webBrowser1 = new System.Windows.Forms.WebBrowser(); - this.label1 = new System.Windows.Forms.Label(); - this.monthCalendar1 = new System.Windows.Forms.MonthCalendar(); - this.label2 = new System.Windows.Forms.Label(); - this.numericUpDown1 = new System.Windows.Forms.NumericUpDown(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit(); - this.SuspendLayout(); - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(18, 278); - this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(64, 15); - this.label3.TabIndex = 4; - this.label3.Text = "PictureBox"; - // - // pictureBox1 - // - this.pictureBox1.Image = global::Accessibility_Core_App.Properties.Resources.TestResult; - this.pictureBox1.Location = new System.Drawing.Point(18, 301); - this.pictureBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(231, 141); - this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; - this.pictureBox1.TabIndex = 5; - this.pictureBox1.TabStop = false; - // - // label4 - // - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(517, 153); - this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(81, 15); - this.label4.TabIndex = 6; - this.label4.Text = "ProgressBar01"; - // - // progressBar1 - // - this.progressBar1.BackColor = System.Drawing.Color.Lime; - this.progressBar1.Location = new System.Drawing.Point(517, 175); - this.progressBar1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(223, 27); - this.progressBar1.TabIndex = 7; - this.progressBar1.Value = 60; - // - // radioButton1 - // - this.radioButton1.AutoSize = true; - this.radioButton1.Checked = true; - this.radioButton1.Location = new System.Drawing.Point(18, 459); - this.radioButton1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.radioButton1.Name = "radioButton1"; - this.radioButton1.Size = new System.Drawing.Size(94, 19); - this.radioButton1.TabIndex = 8; - this.radioButton1.TabStop = true; - this.radioButton1.Text = "radioButton1"; - this.radioButton1.UseVisualStyleBackColor = true; - // - // label5 - // - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(309, 10); - this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(71, 15); - this.label5.TabIndex = 9; - this.label5.Text = "RichTextBox"; - // - // richTextBox1 - // - this.richTextBox1.BackColor = System.Drawing.SystemColors.Window; - this.richTextBox1.Location = new System.Drawing.Point(313, 36); - this.richTextBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.richTextBox1.Name = "richTextBox1"; - this.richTextBox1.Size = new System.Drawing.Size(130, 104); - this.richTextBox1.TabIndex = 10; - this.richTextBox1.Text = "winforms\nclickonce\ncontrols\nteam\nwinforms1\nwinforms2\nwinforms3"; - // - // label6 - // - this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(313, 153); - this.label6.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(48, 15); - this.label6.TabIndex = 11; - this.label6.Text = "TextBox"; - // - // textBox1 - // - this.textBox1.AutoCompleteCustomSource.AddRange(new string[] { - "winforms", - "Team", - "MTP", - "FXBVT"}); - this.textBox1.Location = new System.Drawing.Point(313, 175); - this.textBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.textBox1.Name = "textBox1"; - this.textBox1.Size = new System.Drawing.Size(116, 23); - this.textBox1.TabIndex = 12; - // - // label7 - // - this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(517, 10); - this.label7.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(53, 15); - this.label7.TabIndex = 13; - this.label7.Text = "TreeView"; - // - // treeView1 - // - this.treeView1.Location = new System.Drawing.Point(517, 36); - this.treeView1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.treeView1.Name = "treeView1"; - treeNode1.Name = "Node10"; - treeNode1.Text = "Node10WinformsTeam"; - treeNode2.Name = "Node11"; - treeNode2.Text = "Node11"; - treeNode3.Name = "Node1"; - treeNode3.Text = "Node1"; - treeNode4.Name = "Node20"; - treeNode4.Text = "Node20"; - treeNode5.Name = "Node2"; - treeNode5.Text = "Node2"; - treeNode6.Name = "Node0"; - treeNode6.Text = "Node0"; - treeNode7.Name = "Node4"; - treeNode7.Text = "Node4"; - treeNode8.Name = "Node3"; - treeNode8.Text = "Node3"; - this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] { - treeNode6, - treeNode8}); - this.treeView1.Size = new System.Drawing.Size(220, 104); - this.treeView1.TabIndex = 14; - // - // label8 - // - this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(313, 218); - this.label8.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(73, 15); - this.label8.TabIndex = 15; - this.label8.Text = "WebBrowser"; - // - // webBrowser1 - // - this.webBrowser1.Location = new System.Drawing.Point(313, 236); - this.webBrowser1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.webBrowser1.MinimumSize = new System.Drawing.Size(23, 23); - this.webBrowser1.Name = "webBrowser1"; - this.webBrowser1.ScriptErrorsSuppressed = true; - this.webBrowser1.Size = new System.Drawing.Size(512, 242); - this.webBrowser1.TabIndex = 16; - //this.webBrowser1.Url = new System.Uri("https://www.bing.com/", System.UriKind.Absolute); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(14, 10); - this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(90, 15); - this.label1.TabIndex = 0; - this.label1.Text = "MonthCalendar"; - // - // monthCalendar1 - // - this.monthCalendar1.Location = new System.Drawing.Point(18, 36); - this.monthCalendar1.Margin = new System.Windows.Forms.Padding(10); - this.monthCalendar1.Name = "monthCalendar1"; - this.monthCalendar1.TabIndex = 1; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(18, 218); - this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(102, 15); - this.label2.TabIndex = 2; - this.label2.Text = "numericUpdown"; - // - // numericUpDown1 - // - this.numericUpDown1.Location = new System.Drawing.Point(18, 236); - this.numericUpDown1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.numericUpDown1.Name = "numericUpDown1"; - this.numericUpDown1.Size = new System.Drawing.Size(140, 23); - this.numericUpDown1.TabIndex = 3; - // - // CommonControl2 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoScroll = true; - this.ClientSize = new System.Drawing.Size(850, 501); - this.Controls.Add(this.label1); - this.Controls.Add(this.monthCalendar1); - this.Controls.Add(this.label2); - this.Controls.Add(this.numericUpDown1); - this.Controls.Add(this.label3); - this.Controls.Add(this.pictureBox1); - this.Controls.Add(this.label4); - this.Controls.Add(this.progressBar1); - this.Controls.Add(this.radioButton1); - this.Controls.Add(this.label5); - this.Controls.Add(this.richTextBox1); - this.Controls.Add(this.label6); - this.Controls.Add(this.textBox1); - this.Controls.Add(this.label7); - this.Controls.Add(this.treeView1); - this.Controls.Add(this.label8); - this.Controls.Add(this.webBrowser1); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "CommonControl2"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "CommonControl2"; - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - private System.Windows.Forms.Label label3; - private System.Windows.Forms.PictureBox pictureBox1; - private System.Windows.Forms.Label label4; - private System.Windows.Forms.ProgressBar progressBar1; - private System.Windows.Forms.RadioButton radioButton1; - private System.Windows.Forms.Label label5; - private System.Windows.Forms.RichTextBox richTextBox1; - private System.Windows.Forms.Label label6; - private System.Windows.Forms.TextBox textBox1; - private System.Windows.Forms.Label label7; - private System.Windows.Forms.TreeView treeView1; - private System.Windows.Forms.Label label8; - private System.Windows.Forms.WebBrowser webBrowser1; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.MonthCalendar monthCalendar1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.NumericUpDown numericUpDown1; -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl2.cs b/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl2.cs deleted file mode 100644 index c8a0cdd8eda..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl2.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class CommonControl2 : Form -{ - public CommonControl2() - { - InitializeComponent(); - - string executable = Environment.ProcessPath; - string executablePath = Path.GetDirectoryName(executable); - var page = Path.Combine(executablePath, "HTMLPage1.html"); - this.webBrowser1.Url = new System.Uri($"file://{page}", System.UriKind.Absolute); - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl2.resx b/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl2.resx deleted file mode 100644 index f298a7be809..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/CommonControl2.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls.Designer.cs deleted file mode 100644 index bd86222eaae..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls.Designer.cs +++ /dev/null @@ -1,919 +0,0 @@ -namespace Accessibility_Core_App; - -partial class ContainerControls -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); - this.button2 = new System.Windows.Forms.Button(); - this.button5 = new System.Windows.Forms.Button(); - this.button6 = new System.Windows.Forms.Button(); - this.label2 = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.label4 = new System.Windows.Forms.Label(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.button7 = new System.Windows.Forms.Button(); - this.groupBox2 = new System.Windows.Forms.GroupBox(); - this.button8 = new System.Windows.Forms.Button(); - this.groupBox3 = new System.Windows.Forms.GroupBox(); - this.button9 = new System.Windows.Forms.Button(); - this.groupBox4 = new System.Windows.Forms.GroupBox(); - this.button10 = new System.Windows.Forms.Button(); - this.label6 = new System.Windows.Forms.Label(); - this.label7 = new System.Windows.Forms.Label(); - this.radioButton6 = new System.Windows.Forms.RadioButton(); - this.radioButton5 = new System.Windows.Forms.RadioButton(); - this.radioButton4 = new System.Windows.Forms.RadioButton(); - this.checkBox2 = new System.Windows.Forms.CheckBox(); - this.radioButton3 = new System.Windows.Forms.RadioButton(); - this.radioButton2 = new System.Windows.Forms.RadioButton(); - this.button18 = new System.Windows.Forms.Button(); - this.button17 = new System.Windows.Forms.Button(); - this.radioButton1 = new System.Windows.Forms.RadioButton(); - this.checkBox1 = new System.Windows.Forms.CheckBox(); - this.label10 = new System.Windows.Forms.Label(); - this.tabControl5 = new System.Windows.Forms.TabControl(); - this.tabPage9 = new System.Windows.Forms.TabPage(); - this.button19 = new System.Windows.Forms.Button(); - this.tabPage10 = new System.Windows.Forms.TabPage(); - this.tabControl6 = new System.Windows.Forms.TabControl(); - this.tabPage11 = new System.Windows.Forms.TabPage(); - this.button20 = new System.Windows.Forms.Button(); - this.tabPage12 = new System.Windows.Forms.TabPage(); - this.button21 = new System.Windows.Forms.Button(); - this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); - this.button4 = new System.Windows.Forms.Button(); - this.button1 = new System.Windows.Forms.Button(); - this.button3 = new System.Windows.Forms.Button(); - this.label1 = new System.Windows.Forms.Label(); - this.panel2 = new System.Windows.Forms.Panel(); - this.tabControl2 = new System.Windows.Forms.TabControl(); - this.tabPage1 = new System.Windows.Forms.TabPage(); - this.tabPage2 = new System.Windows.Forms.TabPage(); - this.button12 = new System.Windows.Forms.Button(); - this.label5 = new System.Windows.Forms.Label(); - this.panel1 = new System.Windows.Forms.Panel(); - this.tabControl1 = new System.Windows.Forms.TabControl(); - this.tabPage3 = new System.Windows.Forms.TabPage(); - this.button11 = new System.Windows.Forms.Button(); - this.tabPage4 = new System.Windows.Forms.TabPage(); - this.button13 = new System.Windows.Forms.Button(); - this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel(); - this.button14 = new System.Windows.Forms.Button(); - this.button22 = new System.Windows.Forms.Button(); - this.button23 = new System.Windows.Forms.Button(); - this.panel3 = new System.Windows.Forms.Panel(); - this.tabControl3 = new System.Windows.Forms.TabControl(); - this.tabPage5 = new System.Windows.Forms.TabPage(); - this.tabPage6 = new System.Windows.Forms.TabPage(); - this.button24 = new System.Windows.Forms.Button(); - this.flowLayoutPanel2.SuspendLayout(); - this.groupBox1.SuspendLayout(); - this.groupBox2.SuspendLayout(); - this.groupBox3.SuspendLayout(); - this.groupBox4.SuspendLayout(); - this.tabControl5.SuspendLayout(); - this.tabPage9.SuspendLayout(); - this.tabPage10.SuspendLayout(); - this.tabControl6.SuspendLayout(); - this.tabPage11.SuspendLayout(); - this.tabPage12.SuspendLayout(); - this.flowLayoutPanel1.SuspendLayout(); - this.panel2.SuspendLayout(); - this.tabControl2.SuspendLayout(); - this.tabPage2.SuspendLayout(); - this.panel1.SuspendLayout(); - this.tabControl1.SuspendLayout(); - this.tabPage3.SuspendLayout(); - this.tabPage4.SuspendLayout(); - this.flowLayoutPanel3.SuspendLayout(); - this.panel3.SuspendLayout(); - this.tabControl3.SuspendLayout(); - this.tabPage6.SuspendLayout(); - this.SuspendLayout(); - // - // flowLayoutPanel2 - // - this.flowLayoutPanel2.AutoScroll = true; - this.flowLayoutPanel2.BackColor = System.Drawing.Color.White; - this.flowLayoutPanel2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.flowLayoutPanel2.Controls.Add(this.button2); - this.flowLayoutPanel2.Controls.Add(this.button5); - this.flowLayoutPanel2.Controls.Add(this.button6); - this.flowLayoutPanel2.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; - this.flowLayoutPanel2.Location = new System.Drawing.Point(26, 31); - this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.flowLayoutPanel2.Name = "flowLayoutPanel2"; - this.flowLayoutPanel2.Size = new System.Drawing.Size(186, 106); - this.flowLayoutPanel2.TabIndex = 1; - // - // button2 - // - this.button2.Location = new System.Drawing.Point(90, 3); - this.button2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(88, 27); - this.button2.TabIndex = 0; - this.button2.Text = "button2"; - this.button2.UseVisualStyleBackColor = true; - // - // button5 - // - this.button5.Location = new System.Drawing.Point(90, 36); - this.button5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button5.Name = "button5"; - this.button5.Size = new System.Drawing.Size(88, 27); - this.button5.TabIndex = 1; - this.button5.Text = "button5"; - this.button5.UseVisualStyleBackColor = true; - // - // button6 - // - this.button6.Location = new System.Drawing.Point(90, 69); - this.button6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button6.Name = "button6"; - this.button6.Size = new System.Drawing.Size(88, 27); - this.button6.TabIndex = 2; - this.button6.Text = "button6"; - this.button6.UseVisualStyleBackColor = true; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(26, 172); - this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(203, 15); - this.label2.TabIndex = 6; - this.label2.Text = "Fixed3D_RightToLeft_AutoScroll:False"; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(26, 10); - this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(97, 15); - this.label3.TabIndex = 0; - this.label3.Text = "FlowLayoutPanel"; - // - // label4 - // - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(28, 427); - this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(60, 15); - this.label4.TabIndex = 14; - this.label4.Text = "GroupBox"; - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.button7); - this.groupBox1.Location = new System.Drawing.Point(194, 445); - this.groupBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox1.Size = new System.Drawing.Size(130, 69); - this.groupBox1.TabIndex = 16; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "FlatStyle=Standard"; - // - // button7 - // - this.button7.Location = new System.Drawing.Point(12, 22); - this.button7.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button7.Name = "button7"; - this.button7.Size = new System.Drawing.Size(88, 27); - this.button7.TabIndex = 0; - this.button7.Text = "button7"; - this.button7.UseVisualStyleBackColor = true; - // - // groupBox2 - // - this.groupBox2.Controls.Add(this.button8); - this.groupBox2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.groupBox2.Location = new System.Drawing.Point(33, 445); - this.groupBox2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox2.Name = "groupBox2"; - this.groupBox2.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox2.Size = new System.Drawing.Size(130, 69); - this.groupBox2.TabIndex = 15; - this.groupBox2.TabStop = false; - this.groupBox2.Text = "FlatStyle=Flat"; - // - // button8 - // - this.button8.Location = new System.Drawing.Point(12, 22); - this.button8.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button8.Name = "button8"; - this.button8.Size = new System.Drawing.Size(88, 27); - this.button8.TabIndex = 0; - this.button8.Text = "button8"; - this.button8.UseVisualStyleBackColor = true; - // - // groupBox3 - // - this.groupBox3.Controls.Add(this.button9); - this.groupBox3.FlatStyle = System.Windows.Forms.FlatStyle.Popup; - this.groupBox3.Location = new System.Drawing.Point(522, 445); - this.groupBox3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox3.Name = "groupBox3"; - this.groupBox3.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox3.Size = new System.Drawing.Size(130, 69); - this.groupBox3.TabIndex = 18; - this.groupBox3.TabStop = false; - this.groupBox3.Text = "FlatStyle=Popup"; - // - // button9 - // - this.button9.Location = new System.Drawing.Point(12, 22); - this.button9.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button9.Name = "button9"; - this.button9.Size = new System.Drawing.Size(88, 27); - this.button9.TabIndex = 0; - this.button9.Text = "button9"; - this.button9.UseVisualStyleBackColor = true; - // - // groupBox4 - // - this.groupBox4.Controls.Add(this.button10); - this.groupBox4.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.groupBox4.Location = new System.Drawing.Point(350, 445); - this.groupBox4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox4.Name = "groupBox4"; - this.groupBox4.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox4.Size = new System.Drawing.Size(130, 69); - this.groupBox4.TabIndex = 17; - this.groupBox4.TabStop = false; - this.groupBox4.Text = "FlatStyle=System"; - // - // button10 - // - this.button10.Location = new System.Drawing.Point(12, 22); - this.button10.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button10.Name = "button10"; - this.button10.Size = new System.Drawing.Size(88, 27); - this.button10.TabIndex = 0; - this.button10.Text = "button10"; - this.button10.UseVisualStyleBackColor = true; - // - // label6 - // - this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(285, 172); - this.label6.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(186, 15); - this.label6.TabIndex = 8; - this.label6.Text = "Panel_FixedSingle_AutoScroll:True"; - // - // label7 - // - this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(561, 172); - this.label7.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(172, 15); - this.label7.TabIndex = 10; - this.label7.Text = "Panel_Fixed3D_AutoScroll:False"; - // - // radioButton6 - // - this.radioButton6.AutoSize = true; - this.radioButton6.Location = new System.Drawing.Point(223, 72); - this.radioButton6.Name = "radioButton6"; - this.radioButton6.Size = new System.Drawing.Size(15, 17); - this.radioButton6.TabIndex = 9; - this.radioButton6.Text = "radioButton6"; - this.radioButton6.UseVisualStyleBackColor = true; - // - // radioButton5 - // - this.radioButton5.AutoSize = true; - this.radioButton5.Location = new System.Drawing.Point(203, 72); - this.radioButton5.Name = "radioButton5"; - this.radioButton5.Size = new System.Drawing.Size(14, 17); - this.radioButton5.TabIndex = 8; - this.radioButton5.Text = "radioButton5"; - this.radioButton5.UseVisualStyleBackColor = true; - // - // radioButton4 - // - this.radioButton4.AutoSize = true; - this.radioButton4.Location = new System.Drawing.Point(183, 72); - this.radioButton4.Name = "radioButton4"; - this.radioButton4.Size = new System.Drawing.Size(14, 17); - this.radioButton4.TabIndex = 7; - this.radioButton4.Text = "radioButton4"; - this.radioButton4.UseVisualStyleBackColor = true; - // - // checkBox2 - // - this.checkBox2.AutoSize = true; - this.checkBox2.Checked = true; - this.checkBox2.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox2.Location = new System.Drawing.Point(93, 72); - this.checkBox2.Name = "checkBox2"; - this.checkBox2.Size = new System.Drawing.Size(80, 17); - this.checkBox2.TabIndex = 6; - this.checkBox2.Text = "checkBox2"; - this.checkBox2.UseVisualStyleBackColor = true; - // - // radioButton3 - // - this.radioButton3.AutoSize = true; - this.radioButton3.Checked = true; - this.radioButton3.Location = new System.Drawing.Point(223, 3); - this.radioButton3.Name = "radioButton3"; - this.radioButton3.Size = new System.Drawing.Size(15, 17); - this.radioButton3.TabIndex = 4; - this.radioButton3.TabStop = true; - this.radioButton3.Text = "radioButton3"; - this.radioButton3.UseVisualStyleBackColor = true; - // - // radioButton2 - // - this.radioButton2.AutoSize = true; - this.radioButton2.Location = new System.Drawing.Point(203, 3); - this.radioButton2.Name = "radioButton2"; - this.radioButton2.Size = new System.Drawing.Size(14, 17); - this.radioButton2.TabIndex = 3; - this.radioButton2.Text = "radioButton2"; - this.radioButton2.UseVisualStyleBackColor = true; - // - // button18 - // - this.button18.Location = new System.Drawing.Point(93, 3); - this.button18.Name = "button18"; - this.button18.Size = new System.Drawing.Size(75, 23); - this.button18.TabIndex = 1; - this.button18.Text = "button18"; - this.button18.UseVisualStyleBackColor = true; - // - // button17 - // - this.button17.Location = new System.Drawing.Point(3, 3); - this.button17.Name = "button17"; - this.button17.Size = new System.Drawing.Size(75, 23); - this.button17.TabIndex = 0; - this.button17.Text = "button17"; - this.button17.UseVisualStyleBackColor = true; - // - // radioButton1 - // - this.radioButton1.AutoSize = true; - this.radioButton1.Location = new System.Drawing.Point(183, 3); - this.radioButton1.Name = "radioButton1"; - this.radioButton1.Size = new System.Drawing.Size(14, 17); - this.radioButton1.TabIndex = 2; - this.radioButton1.Text = "radioButton1"; - this.radioButton1.UseVisualStyleBackColor = true; - // - // checkBox1 - // - this.checkBox1.AutoSize = true; - this.checkBox1.Location = new System.Drawing.Point(3, 72); - this.checkBox1.Name = "checkBox1"; - this.checkBox1.Size = new System.Drawing.Size(80, 17); - this.checkBox1.TabIndex = 5; - this.checkBox1.Text = "checkBox1"; - this.checkBox1.UseVisualStyleBackColor = true; - // - // label10 - // - this.label10.AutoSize = true; - this.label10.Location = new System.Drawing.Point(561, 10); - this.label10.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label10.Name = "label10"; - this.label10.Size = new System.Drawing.Size(70, 15); - this.label10.TabIndex = 4; - this.label10.Text = "Tab_Control"; - // - // tabControl5 - // - this.tabControl5.Controls.Add(this.tabPage9); - this.tabControl5.Controls.Add(this.tabPage10); - this.tabControl5.Location = new System.Drawing.Point(561, 31); - this.tabControl5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabControl5.Name = "tabControl5"; - this.tabControl5.SelectedIndex = 0; - this.tabControl5.Size = new System.Drawing.Size(219, 138); - this.tabControl5.TabIndex = 5; - // - // tabPage9 - // - this.tabPage9.Controls.Add(this.button19); - this.tabPage9.Location = new System.Drawing.Point(4, 24); - this.tabPage9.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage9.Name = "tabPage9"; - this.tabPage9.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage9.Size = new System.Drawing.Size(211, 110); - this.tabPage9.TabIndex = 0; - this.tabPage9.Text = "tabPage9"; - this.tabPage9.UseVisualStyleBackColor = true; - // - // button19 - // - this.button19.Location = new System.Drawing.Point(16, 24); - this.button19.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button19.Name = "button19"; - this.button19.Size = new System.Drawing.Size(88, 27); - this.button19.TabIndex = 0; - this.button19.Text = "button19"; - this.button19.UseVisualStyleBackColor = true; - // - // tabPage10 - // - this.tabPage10.Controls.Add(this.tabControl6); - this.tabPage10.Location = new System.Drawing.Point(4, 24); - this.tabPage10.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage10.Name = "tabPage10"; - this.tabPage10.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage10.Size = new System.Drawing.Size(211, 110); - this.tabPage10.TabIndex = 1; - this.tabPage10.Text = "tabPage10"; - this.tabPage10.UseVisualStyleBackColor = true; - // - // tabControl6 - // - this.tabControl6.Controls.Add(this.tabPage11); - this.tabControl6.Controls.Add(this.tabPage12); - this.tabControl6.Dock = System.Windows.Forms.DockStyle.Fill; - this.tabControl6.Location = new System.Drawing.Point(4, 3); - this.tabControl6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabControl6.Name = "tabControl6"; - this.tabControl6.SelectedIndex = 0; - this.tabControl6.Size = new System.Drawing.Size(203, 104); - this.tabControl6.TabIndex = 0; - // - // tabPage11 - // - this.tabPage11.Controls.Add(this.button20); - this.tabPage11.Location = new System.Drawing.Point(4, 24); - this.tabPage11.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage11.Name = "tabPage11"; - this.tabPage11.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage11.Size = new System.Drawing.Size(195, 76); - this.tabPage11.TabIndex = 0; - this.tabPage11.Text = "tabPage11"; - this.tabPage11.UseVisualStyleBackColor = true; - // - // button20 - // - this.button20.Location = new System.Drawing.Point(0, 0); - this.button20.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button20.Name = "button20"; - this.button20.Size = new System.Drawing.Size(88, 27); - this.button20.TabIndex = 0; - this.button20.Text = "button20"; - this.button20.UseVisualStyleBackColor = true; - // - // tabPage12 - // - this.tabPage12.Controls.Add(this.button21); - this.tabPage12.Location = new System.Drawing.Point(4, 24); - this.tabPage12.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage12.Name = "tabPage12"; - this.tabPage12.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage12.Size = new System.Drawing.Size(195, 76); - this.tabPage12.TabIndex = 1; - this.tabPage12.Text = "tabPage12"; - this.tabPage12.UseVisualStyleBackColor = true; - // - // button21 - // - this.button21.Location = new System.Drawing.Point(9, 9); - this.button21.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button21.Name = "button21"; - this.button21.Size = new System.Drawing.Size(88, 27); - this.button21.TabIndex = 0; - this.button21.Text = "button21"; - this.button21.UseVisualStyleBackColor = true; - // - // flowLayoutPanel1 - // - this.flowLayoutPanel1.AutoScroll = true; - this.flowLayoutPanel1.BackColor = System.Drawing.Color.White; - this.flowLayoutPanel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.flowLayoutPanel1.Controls.Add(this.button4); - this.flowLayoutPanel1.Controls.Add(this.button1); - this.flowLayoutPanel1.Controls.Add(this.button3); - this.flowLayoutPanel1.Location = new System.Drawing.Point(26, 192); - this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.flowLayoutPanel1.Name = "flowLayoutPanel1"; - this.flowLayoutPanel1.Size = new System.Drawing.Size(203, 102); - this.flowLayoutPanel1.TabIndex = 7; - // - // button4 - // - this.button4.Location = new System.Drawing.Point(4, 3); - this.button4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button4.Name = "button4"; - this.button4.Size = new System.Drawing.Size(88, 27); - this.button4.TabIndex = 0; - this.button4.Text = "button4"; - this.button4.UseVisualStyleBackColor = true; - // - // button1 - // - this.button1.Location = new System.Drawing.Point(100, 3); - this.button1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(88, 27); - this.button1.TabIndex = 1; - this.button1.Text = "button1"; - this.button1.UseVisualStyleBackColor = true; - // - // button3 - // - this.button3.Location = new System.Drawing.Point(4, 36); - this.button3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button3.Name = "button3"; - this.button3.Size = new System.Drawing.Size(88, 27); - this.button3.TabIndex = 2; - this.button3.Text = "button3"; - this.button3.UseVisualStyleBackColor = true; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(26, 308); - this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(217, 15); - this.label1.TabIndex = 12; - this.label1.Text = "FixedSingle_LeftToRight_AutoScroll:True"; - // - // panel2 - // - this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.panel2.Controls.Add(this.tabControl2); - this.panel2.Location = new System.Drawing.Point(285, 199); - this.panel2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(204, 144); - this.panel2.TabIndex = 9; - // - // tabControl2 - // - this.tabControl2.Controls.Add(this.tabPage1); - this.tabControl2.Controls.Add(this.tabPage2); - this.tabControl2.Location = new System.Drawing.Point(8, 12); - this.tabControl2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabControl2.Name = "tabControl2"; - this.tabControl2.SelectedIndex = 0; - this.tabControl2.Size = new System.Drawing.Size(172, 122); - this.tabControl2.TabIndex = 1; - // - // tabPage1 - // - this.tabPage1.Location = new System.Drawing.Point(4, 24); - this.tabPage1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage1.Name = "tabPage1"; - this.tabPage1.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage1.Size = new System.Drawing.Size(164, 94); - this.tabPage1.TabIndex = 2; - this.tabPage1.Text = "tabPage1"; - this.tabPage1.UseVisualStyleBackColor = true; - // - // tabPage2 - // - this.tabPage2.Controls.Add(this.button12); - this.tabPage2.Location = new System.Drawing.Point(4, 24); - this.tabPage2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage2.Name = "tabPage2"; - this.tabPage2.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage2.Size = new System.Drawing.Size(164, 94); - this.tabPage2.TabIndex = 3; - this.tabPage2.Text = "tabPage2"; - this.tabPage2.UseVisualStyleBackColor = true; - // - // button12 - // - this.button12.Location = new System.Drawing.Point(17, 24); - this.button12.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button12.Name = "button12"; - this.button12.Size = new System.Drawing.Size(88, 27); - this.button12.TabIndex = 0; - this.button12.Text = "button12"; - this.button12.UseVisualStyleBackColor = true; - // - // label5 - // - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(286, 9); - this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(36, 15); - this.label5.TabIndex = 2; - this.label5.Text = "Panel"; - // - // panel1 - // - this.panel1.AutoScroll = true; - this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.panel1.Controls.Add(this.tabControl1); - this.panel1.Location = new System.Drawing.Point(286, 30); - this.panel1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(192, 128); - this.panel1.TabIndex = 3; - // - // tabControl1 - // - this.tabControl1.Controls.Add(this.tabPage3); - this.tabControl1.Controls.Add(this.tabPage4); - this.tabControl1.Location = new System.Drawing.Point(5, 4); - this.tabControl1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(156, 102); - this.tabControl1.TabIndex = 0; - // - // tabPage3 - // - this.tabPage3.Controls.Add(this.button11); - this.tabPage3.Location = new System.Drawing.Point(4, 24); - this.tabPage3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage3.Name = "tabPage3"; - this.tabPage3.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage3.Size = new System.Drawing.Size(148, 74); - this.tabPage3.TabIndex = 0; - this.tabPage3.Text = "tabPage3"; - this.tabPage3.UseVisualStyleBackColor = true; - // - // button11 - // - this.button11.Location = new System.Drawing.Point(9, 9); - this.button11.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button11.Name = "button11"; - this.button11.Size = new System.Drawing.Size(88, 27); - this.button11.TabIndex = 0; - this.button11.Text = "button11"; - this.button11.UseVisualStyleBackColor = true; - // - // tabPage4 - // - this.tabPage4.Controls.Add(this.button13); - this.tabPage4.Location = new System.Drawing.Point(4, 24); - this.tabPage4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage4.Name = "tabPage4"; - this.tabPage4.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage4.Size = new System.Drawing.Size(148, 74); - this.tabPage4.TabIndex = 1; - this.tabPage4.Text = "tabPage4"; - this.tabPage4.UseVisualStyleBackColor = true; - // - // button13 - // - this.button13.Location = new System.Drawing.Point(9, 9); - this.button13.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button13.Name = "button13"; - this.button13.Size = new System.Drawing.Size(88, 27); - this.button13.TabIndex = 0; - this.button13.Text = "button13"; - this.button13.UseVisualStyleBackColor = true; - // - // flowLayoutPanel3 - // - this.flowLayoutPanel3.AutoScroll = true; - this.flowLayoutPanel3.BackColor = System.Drawing.Color.White; - this.flowLayoutPanel3.Controls.Add(this.button14); - this.flowLayoutPanel3.Controls.Add(this.button22); - this.flowLayoutPanel3.Controls.Add(this.button23); - this.flowLayoutPanel3.Location = new System.Drawing.Point(26, 326); - this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.flowLayoutPanel3.Name = "flowLayoutPanel3"; - this.flowLayoutPanel3.Size = new System.Drawing.Size(180, 98); - this.flowLayoutPanel3.TabIndex = 13; - // - // button14 - // - this.button14.Location = new System.Drawing.Point(4, 3); - this.button14.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button14.Name = "button14"; - this.button14.Size = new System.Drawing.Size(88, 27); - this.button14.TabIndex = 0; - this.button14.Text = "button14"; - this.button14.UseVisualStyleBackColor = true; - // - // button22 - // - this.button22.Location = new System.Drawing.Point(4, 36); - this.button22.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button22.Name = "button22"; - this.button22.Size = new System.Drawing.Size(88, 27); - this.button22.TabIndex = 1; - this.button22.Text = "button22"; - this.button22.UseVisualStyleBackColor = true; - // - // button23 - // - this.button23.Location = new System.Drawing.Point(4, 69); - this.button23.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button23.Name = "button23"; - this.button23.Size = new System.Drawing.Size(88, 27); - this.button23.TabIndex = 2; - this.button23.Text = "button23"; - this.button23.UseVisualStyleBackColor = true; - // - // panel3 - // - this.panel3.Controls.Add(this.tabControl3); - this.panel3.Location = new System.Drawing.Point(561, 199); - this.panel3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.panel3.Name = "panel3"; - this.panel3.Size = new System.Drawing.Size(211, 136); - this.panel3.TabIndex = 11; - // - // tabControl3 - // - this.tabControl3.Controls.Add(this.tabPage5); - this.tabControl3.Controls.Add(this.tabPage6); - this.tabControl3.Location = new System.Drawing.Point(12, 14); - this.tabControl3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabControl3.Name = "tabControl3"; - this.tabControl3.SelectedIndex = 0; - this.tabControl3.Size = new System.Drawing.Size(187, 118); - this.tabControl3.TabIndex = 1; - // - // tabPage5 - // - this.tabPage5.Location = new System.Drawing.Point(4, 24); - this.tabPage5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage5.Name = "tabPage5"; - this.tabPage5.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage5.Size = new System.Drawing.Size(179, 90); - this.tabPage5.TabIndex = 2; - this.tabPage5.Text = "tabPage5"; - this.tabPage5.UseVisualStyleBackColor = true; - // - // tabPage6 - // - this.tabPage6.Controls.Add(this.button24); - this.tabPage6.Location = new System.Drawing.Point(4, 24); - this.tabPage6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage6.Name = "tabPage6"; - this.tabPage6.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage6.Size = new System.Drawing.Size(179, 90); - this.tabPage6.TabIndex = 3; - this.tabPage6.Text = "tabPage6"; - this.tabPage6.UseVisualStyleBackColor = true; - // - // button24 - // - this.button24.Location = new System.Drawing.Point(19, 23); - this.button24.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button24.Name = "button24"; - this.button24.Size = new System.Drawing.Size(88, 27); - this.button24.TabIndex = 0; - this.button24.Text = "button24"; - this.button24.UseVisualStyleBackColor = true; - // - // ContainerControls - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoScroll = true; - this.ClientSize = new System.Drawing.Size(795, 523); - this.Controls.Add(this.panel3); - this.Controls.Add(this.flowLayoutPanel3); - this.Controls.Add(this.panel1); - this.Controls.Add(this.label5); - this.Controls.Add(this.label1); - this.Controls.Add(this.flowLayoutPanel1); - this.Controls.Add(this.tabControl5); - this.Controls.Add(this.label10); - this.Controls.Add(this.label7); - this.Controls.Add(this.label6); - this.Controls.Add(this.panel2); - this.Controls.Add(this.groupBox4); - this.Controls.Add(this.groupBox3); - this.Controls.Add(this.groupBox2); - this.Controls.Add(this.groupBox1); - this.Controls.Add(this.label4); - this.Controls.Add(this.label2); - this.Controls.Add(this.label3); - this.Controls.Add(this.flowLayoutPanel2); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "ContainerControls"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Winforms_Containers"; - this.flowLayoutPanel2.ResumeLayout(false); - this.groupBox1.ResumeLayout(false); - this.groupBox2.ResumeLayout(false); - this.groupBox3.ResumeLayout(false); - this.groupBox4.ResumeLayout(false); - this.tabControl5.ResumeLayout(false); - this.tabPage9.ResumeLayout(false); - this.tabPage10.ResumeLayout(false); - this.tabControl6.ResumeLayout(false); - this.tabPage11.ResumeLayout(false); - this.tabPage12.ResumeLayout(false); - this.flowLayoutPanel1.ResumeLayout(false); - this.panel2.ResumeLayout(false); - this.tabControl2.ResumeLayout(false); - this.tabPage2.ResumeLayout(false); - this.panel1.ResumeLayout(false); - this.tabControl1.ResumeLayout(false); - this.tabPage3.ResumeLayout(false); - this.tabPage4.ResumeLayout(false); - this.flowLayoutPanel3.ResumeLayout(false); - this.panel3.ResumeLayout(false); - this.tabControl3.ResumeLayout(false); - this.tabPage6.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; - private System.Windows.Forms.Button button2; - private System.Windows.Forms.Button button5; - private System.Windows.Forms.Button button6; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.Label label4; - private System.Windows.Forms.GroupBox groupBox1; - private System.Windows.Forms.Button button7; - private System.Windows.Forms.GroupBox groupBox2; - private System.Windows.Forms.Button button8; - private System.Windows.Forms.GroupBox groupBox3; - private System.Windows.Forms.Button button9; - private System.Windows.Forms.GroupBox groupBox4; - private System.Windows.Forms.Button button10; - private System.Windows.Forms.Label label6; - private System.Windows.Forms.Label label7; - private System.Windows.Forms.RadioButton radioButton6; - private System.Windows.Forms.RadioButton radioButton5; - private System.Windows.Forms.RadioButton radioButton4; - private System.Windows.Forms.CheckBox checkBox2; - private System.Windows.Forms.RadioButton radioButton3; - private System.Windows.Forms.RadioButton radioButton2; - private System.Windows.Forms.Button button18; - private System.Windows.Forms.Button button17; - private System.Windows.Forms.RadioButton radioButton1; - private System.Windows.Forms.CheckBox checkBox1; - private System.Windows.Forms.Label label10; - private System.Windows.Forms.TabControl tabControl5; - private System.Windows.Forms.TabPage tabPage9; - private System.Windows.Forms.Button button19; - private System.Windows.Forms.TabPage tabPage10; - private System.Windows.Forms.TabControl tabControl6; - private System.Windows.Forms.TabPage tabPage11; - private System.Windows.Forms.Button button20; - private System.Windows.Forms.TabPage tabPage12; - private System.Windows.Forms.Button button21; - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.Button button3; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Panel panel2; - private System.Windows.Forms.TabControl tabControl2; - private System.Windows.Forms.TabPage tabPage1; - private System.Windows.Forms.TabPage tabPage2; - private System.Windows.Forms.Button button12; - private System.Windows.Forms.Label label5; - private System.Windows.Forms.Panel panel1; - private System.Windows.Forms.TabControl tabControl1; - private System.Windows.Forms.TabPage tabPage3; - private System.Windows.Forms.Button button11; - private System.Windows.Forms.TabPage tabPage4; - private System.Windows.Forms.Button button13; - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3; - private System.Windows.Forms.Button button14; - private System.Windows.Forms.Button button22; - private System.Windows.Forms.Button button23; - private System.Windows.Forms.Panel panel3; - private System.Windows.Forms.TabControl tabControl3; - private System.Windows.Forms.TabPage tabPage5; - private System.Windows.Forms.TabPage tabPage6; - private System.Windows.Forms.Button button24; - private System.Windows.Forms.Button button4; -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls.cs b/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls.cs deleted file mode 100644 index 66b8c7f6ef6..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class ContainerControls : Form -{ - public ContainerControls() - { - InitializeComponent(); - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls.resx b/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls.resx deleted file mode 100644 index f298a7be809..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls2.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls2.Designer.cs deleted file mode 100644 index 77fb285f681..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls2.Designer.cs +++ /dev/null @@ -1,482 +0,0 @@ -namespace Accessibility_Core_App; - -partial class ContainerControls2 -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.label8 = new System.Windows.Forms.Label(); - this.splitContainer1 = new System.Windows.Forms.SplitContainer(); - this.button15 = new System.Windows.Forms.Button(); - this.button16 = new System.Windows.Forms.Button(); - this.label9 = new System.Windows.Forms.Label(); - this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.radioButton6 = new System.Windows.Forms.RadioButton(); - this.radioButton5 = new System.Windows.Forms.RadioButton(); - this.radioButton4 = new System.Windows.Forms.RadioButton(); - this.checkBox2 = new System.Windows.Forms.CheckBox(); - this.radioButton3 = new System.Windows.Forms.RadioButton(); - this.radioButton2 = new System.Windows.Forms.RadioButton(); - this.button18 = new System.Windows.Forms.Button(); - this.button17 = new System.Windows.Forms.Button(); - this.radioButton1 = new System.Windows.Forms.RadioButton(); - this.checkBox1 = new System.Windows.Forms.CheckBox(); - this.label13 = new System.Windows.Forms.Label(); - this.flowLayoutPanel4 = new System.Windows.Forms.FlowLayoutPanel(); - this.label14 = new System.Windows.Forms.Label(); - this.groupBox5 = new System.Windows.Forms.GroupBox(); - this.label15 = new System.Windows.Forms.Label(); - this.panel4 = new System.Windows.Forms.Panel(); - this.label16 = new System.Windows.Forms.Label(); - this.splitContainer2 = new System.Windows.Forms.SplitContainer(); - this.label17 = new System.Windows.Forms.Label(); - this.tabControl4 = new System.Windows.Forms.TabControl(); - this.tabPage7 = new System.Windows.Forms.TabPage(); - this.tabPage8 = new System.Windows.Forms.TabPage(); - this.label18 = new System.Windows.Forms.Label(); - this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); - this.splitContainer1.Panel1.SuspendLayout(); - this.splitContainer1.Panel2.SuspendLayout(); - this.splitContainer1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit(); - this.splitContainer2.SuspendLayout(); - this.tabControl4.SuspendLayout(); - this.SuspendLayout(); - // - // label8 - // - this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(13, 21); - this.label8.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(295, 15); - this.label8.TabIndex = 0; - this.label8.Text = "SplitContainer_SetBackColor_Panel1_Silver_Panel2_Red"; - // - // splitContainer1 - // - this.splitContainer1.Location = new System.Drawing.Point(13, 45); - this.splitContainer1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.splitContainer1.Name = "splitContainer1"; - // - // splitContainer1.Panel1 - // - this.splitContainer1.Panel1.BackColor = System.Drawing.Color.Silver; - this.splitContainer1.Panel1.Controls.Add(this.button15); - this.splitContainer1.Panel1.RightToLeft = System.Windows.Forms.RightToLeft.No; - // - // splitContainer1.Panel2 - // - this.splitContainer1.Panel2.BackColor = System.Drawing.Color.Red; - this.splitContainer1.Panel2.Controls.Add(this.button16); - this.splitContainer1.Panel2.RightToLeft = System.Windows.Forms.RightToLeft.No; - this.splitContainer1.RightToLeft = System.Windows.Forms.RightToLeft.No; - this.splitContainer1.Size = new System.Drawing.Size(273, 142); - this.splitContainer1.SplitterDistance = 98; - this.splitContainer1.SplitterWidth = 5; - this.splitContainer1.TabIndex = 1; - // - // button15 - // - this.button15.Location = new System.Drawing.Point(10, 57); - this.button15.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button15.Name = "button15"; - this.button15.Size = new System.Drawing.Size(74, 27); - this.button15.TabIndex = 0; - this.button15.Text = "button15"; - this.button15.UseVisualStyleBackColor = true; - // - // button16 - // - this.button16.Location = new System.Drawing.Point(21, 57); - this.button16.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button16.Name = "button16"; - this.button16.Size = new System.Drawing.Size(88, 27); - this.button16.TabIndex = 0; - this.button16.Text = "button16"; - this.button16.UseVisualStyleBackColor = true; - // - // label9 - // - this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(27, 294); - this.label9.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(199, 15); - this.label9.TabIndex = 10; - this.label9.Text = "TableLayoutPanel_SetBackColor_Red"; - // - // tableLayoutPanel1 - // - this.tableLayoutPanel1.BackColor = System.Drawing.Color.Red; - this.tableLayoutPanel1.ColumnCount = 5; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 23F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 23F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25F)); - this.tableLayoutPanel1.Location = new System.Drawing.Point(27, 329); - this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 2; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(259, 103); - this.tableLayoutPanel1.TabIndex = 11; - // - // radioButton6 - // - this.radioButton6.AutoSize = true; - this.radioButton6.Location = new System.Drawing.Point(223, 72); - this.radioButton6.Name = "radioButton6"; - this.radioButton6.Size = new System.Drawing.Size(15, 17); - this.radioButton6.TabIndex = 9; - this.radioButton6.Text = "radioButton6"; - this.radioButton6.UseVisualStyleBackColor = true; - // - // radioButton5 - // - this.radioButton5.AutoSize = true; - this.radioButton5.Location = new System.Drawing.Point(203, 72); - this.radioButton5.Name = "radioButton5"; - this.radioButton5.Size = new System.Drawing.Size(14, 17); - this.radioButton5.TabIndex = 8; - this.radioButton5.Text = "radioButton5"; - this.radioButton5.UseVisualStyleBackColor = true; - // - // radioButton4 - // - this.radioButton4.AutoSize = true; - this.radioButton4.Location = new System.Drawing.Point(183, 72); - this.radioButton4.Name = "radioButton4"; - this.radioButton4.Size = new System.Drawing.Size(14, 17); - this.radioButton4.TabIndex = 7; - this.radioButton4.Text = "radioButton4"; - this.radioButton4.UseVisualStyleBackColor = true; - // - // checkBox2 - // - this.checkBox2.AutoSize = true; - this.checkBox2.Checked = true; - this.checkBox2.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox2.Location = new System.Drawing.Point(93, 72); - this.checkBox2.Name = "checkBox2"; - this.checkBox2.Size = new System.Drawing.Size(80, 17); - this.checkBox2.TabIndex = 6; - this.checkBox2.Text = "checkBox2"; - this.checkBox2.UseVisualStyleBackColor = true; - // - // radioButton3 - // - this.radioButton3.AutoSize = true; - this.radioButton3.Checked = true; - this.radioButton3.Location = new System.Drawing.Point(223, 3); - this.radioButton3.Name = "radioButton3"; - this.radioButton3.Size = new System.Drawing.Size(15, 17); - this.radioButton3.TabIndex = 4; - this.radioButton3.TabStop = true; - this.radioButton3.Text = "radioButton3"; - this.radioButton3.UseVisualStyleBackColor = true; - // - // radioButton2 - // - this.radioButton2.AutoSize = true; - this.radioButton2.Location = new System.Drawing.Point(203, 3); - this.radioButton2.Name = "radioButton2"; - this.radioButton2.Size = new System.Drawing.Size(14, 17); - this.radioButton2.TabIndex = 3; - this.radioButton2.Text = "radioButton2"; - this.radioButton2.UseVisualStyleBackColor = true; - // - // button18 - // - this.button18.Location = new System.Drawing.Point(93, 3); - this.button18.Name = "button18"; - this.button18.Size = new System.Drawing.Size(75, 23); - this.button18.TabIndex = 1; - this.button18.Text = "button18"; - this.button18.UseVisualStyleBackColor = true; - // - // button17 - // - this.button17.Location = new System.Drawing.Point(3, 3); - this.button17.Name = "button17"; - this.button17.Size = new System.Drawing.Size(75, 23); - this.button17.TabIndex = 0; - this.button17.Text = "button17"; - this.button17.UseVisualStyleBackColor = true; - // - // radioButton1 - // - this.radioButton1.AutoSize = true; - this.radioButton1.Location = new System.Drawing.Point(183, 3); - this.radioButton1.Name = "radioButton1"; - this.radioButton1.Size = new System.Drawing.Size(14, 17); - this.radioButton1.TabIndex = 2; - this.radioButton1.Text = "radioButton1"; - this.radioButton1.UseVisualStyleBackColor = true; - // - // checkBox1 - // - this.checkBox1.AutoSize = true; - this.checkBox1.Location = new System.Drawing.Point(3, 72); - this.checkBox1.Name = "checkBox1"; - this.checkBox1.Size = new System.Drawing.Size(80, 17); - this.checkBox1.TabIndex = 5; - this.checkBox1.Text = "checkBox1"; - this.checkBox1.UseVisualStyleBackColor = true; - // - // label13 - // - this.label13.AutoSize = true; - this.label13.Location = new System.Drawing.Point(337, 21); - this.label13.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label13.Name = "label13"; - this.label13.Size = new System.Drawing.Size(218, 15); - this.label13.TabIndex = 2; - this.label13.Text = "Empty_FlowLayout_SetBackColor_Green"; - // - // flowLayoutPanel4 - // - this.flowLayoutPanel4.BackColor = System.Drawing.Color.Green; - this.flowLayoutPanel4.Location = new System.Drawing.Point(337, 45); - this.flowLayoutPanel4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.flowLayoutPanel4.Name = "flowLayoutPanel4"; - this.flowLayoutPanel4.Size = new System.Drawing.Size(153, 84); - this.flowLayoutPanel4.TabIndex = 3; - // - // label14 - // - this.label14.AutoSize = true; - this.label14.Location = new System.Drawing.Point(337, 157); - this.label14.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label14.Name = "label14"; - this.label14.Size = new System.Drawing.Size(210, 15); - this.label14.TabIndex = 6; - this.label14.Text = "Empty_GroupBox_SetBackColor_Green"; - // - // groupBox5 - // - this.groupBox5.BackColor = System.Drawing.Color.Green; - this.groupBox5.Location = new System.Drawing.Point(337, 182); - this.groupBox5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox5.Name = "groupBox5"; - this.groupBox5.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox5.Size = new System.Drawing.Size(153, 88); - this.groupBox5.TabIndex = 7; - this.groupBox5.TabStop = false; - this.groupBox5.Text = "groupBox5"; - // - // label15 - // - this.label15.AutoSize = true; - this.label15.Location = new System.Drawing.Point(337, 294); - this.label15.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label15.Name = "label15"; - this.label15.Size = new System.Drawing.Size(186, 15); - this.label15.TabIndex = 12; - this.label15.Text = "Empty_Panel_SetBackColor_Green"; - // - // panel4 - // - this.panel4.BackColor = System.Drawing.Color.Green; - this.panel4.Location = new System.Drawing.Point(337, 329); - this.panel4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.panel4.Name = "panel4"; - this.panel4.Size = new System.Drawing.Size(164, 103); - this.panel4.TabIndex = 13; - // - // label16 - // - this.label16.AutoSize = true; - this.label16.Location = new System.Drawing.Point(582, 21); - this.label16.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label16.Name = "label16"; - this.label16.Size = new System.Drawing.Size(337, 15); - this.label16.TabIndex = 4; - this.label16.Text = "Empty_SplitContainer_SetBackColor_Panel1_Green_Panel2_Red"; - // - // splitContainer2 - // - this.splitContainer2.Location = new System.Drawing.Point(586, 39); - this.splitContainer2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.splitContainer2.Name = "splitContainer2"; - // - // splitContainer2.Panel1 - // - this.splitContainer2.Panel1.BackColor = System.Drawing.Color.Green; - // - // splitContainer2.Panel2 - // - this.splitContainer2.Panel2.BackColor = System.Drawing.Color.Red; - this.splitContainer2.Size = new System.Drawing.Size(262, 90); - this.splitContainer2.SplitterDistance = 83; - this.splitContainer2.SplitterWidth = 5; - this.splitContainer2.TabIndex = 5; - // - // label17 - // - this.label17.AutoSize = true; - this.label17.Location = new System.Drawing.Point(582, 157); - this.label17.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label17.Name = "label17"; - this.label17.Size = new System.Drawing.Size(350, 15); - this.label17.TabIndex = 8; - this.label17.Text = "Empty_TabControl_SetBackColor_TabPage7_Green_TabPage8_Red"; - // - // tabControl4 - // - this.tabControl4.Controls.Add(this.tabPage7); - this.tabControl4.Controls.Add(this.tabPage8); - this.tabControl4.Location = new System.Drawing.Point(582, 182); - this.tabControl4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabControl4.Name = "tabControl4"; - this.tabControl4.SelectedIndex = 0; - this.tabControl4.Size = new System.Drawing.Size(262, 88); - this.tabControl4.TabIndex = 9; - // - // tabPage7 - // - this.tabPage7.BackColor = System.Drawing.Color.Green; - this.tabPage7.Location = new System.Drawing.Point(4, 24); - this.tabPage7.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage7.Name = "tabPage7"; - this.tabPage7.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage7.Size = new System.Drawing.Size(254, 60); - this.tabPage7.TabIndex = 0; - this.tabPage7.Text = "tabPage7"; - // - // tabPage8 - // - this.tabPage8.BackColor = System.Drawing.Color.Red; - this.tabPage8.Location = new System.Drawing.Point(4, 24); - this.tabPage8.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage8.Name = "tabPage8"; - this.tabPage8.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage8.Size = new System.Drawing.Size(254, 60); - this.tabPage8.TabIndex = 1; - this.tabPage8.Text = "tabPage8"; - // - // label18 - // - this.label18.AutoSize = true; - this.label18.Location = new System.Drawing.Point(582, 294); - this.label18.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label18.Name = "label18"; - this.label18.Size = new System.Drawing.Size(211, 15); - this.label18.TabIndex = 14; - this.label18.Text = "Empty_TabLayout_SetBackColor_Green"; - // - // tableLayoutPanel2 - // - this.tableLayoutPanel2.BackColor = System.Drawing.Color.Green; - this.tableLayoutPanel2.ColumnCount = 2; - this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel2.Location = new System.Drawing.Point(582, 329); - this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tableLayoutPanel2.Name = "tableLayoutPanel2"; - this.tableLayoutPanel2.RowCount = 2; - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel2.Size = new System.Drawing.Size(258, 103); - this.tableLayoutPanel2.TabIndex = 15; - // - // ContainerControls2 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoScroll = true; - this.ClientSize = new System.Drawing.Size(945, 464); - this.Controls.Add(this.tableLayoutPanel2); - this.Controls.Add(this.label18); - this.Controls.Add(this.tabControl4); - this.Controls.Add(this.label17); - this.Controls.Add(this.splitContainer2); - this.Controls.Add(this.label16); - this.Controls.Add(this.panel4); - this.Controls.Add(this.label15); - this.Controls.Add(this.groupBox5); - this.Controls.Add(this.label14); - this.Controls.Add(this.flowLayoutPanel4); - this.Controls.Add(this.label13); - this.Controls.Add(this.tableLayoutPanel1); - this.Controls.Add(this.label9); - this.Controls.Add(this.splitContainer1); - this.Controls.Add(this.label8); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "ContainerControls2"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Winforms_Containers"; - this.Load += new System.EventHandler(this.ContainerControls2_Load); - this.splitContainer1.Panel1.ResumeLayout(false); - this.splitContainer1.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); - this.splitContainer1.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit(); - this.splitContainer2.ResumeLayout(false); - this.tabControl4.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - private System.Windows.Forms.Label label8; - private System.Windows.Forms.SplitContainer splitContainer1; - private System.Windows.Forms.Button button15; - private System.Windows.Forms.Button button16; - private System.Windows.Forms.Label label9; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.RadioButton radioButton6; - private System.Windows.Forms.RadioButton radioButton5; - private System.Windows.Forms.RadioButton radioButton4; - private System.Windows.Forms.CheckBox checkBox2; - private System.Windows.Forms.RadioButton radioButton3; - private System.Windows.Forms.RadioButton radioButton2; - private System.Windows.Forms.Button button18; - private System.Windows.Forms.Button button17; - private System.Windows.Forms.RadioButton radioButton1; - private System.Windows.Forms.CheckBox checkBox1; - private System.Windows.Forms.Label label13; - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel4; - private System.Windows.Forms.Label label14; - private System.Windows.Forms.GroupBox groupBox5; - private System.Windows.Forms.Label label15; - private System.Windows.Forms.Panel panel4; - private System.Windows.Forms.Label label16; - private System.Windows.Forms.SplitContainer splitContainer2; - private System.Windows.Forms.Label label17; - private System.Windows.Forms.TabControl tabControl4; - private System.Windows.Forms.TabPage tabPage7; - private System.Windows.Forms.TabPage tabPage8; - private System.Windows.Forms.Label label18; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls2.cs b/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls2.cs deleted file mode 100644 index 500d5f99976..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls2.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class ContainerControls2 : Form -{ - public ContainerControls2() - { - InitializeComponent(); - } - - private void ContainerControls2_Load(object sender, EventArgs e) - { - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls2.resx b/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls2.resx deleted file mode 100644 index f298a7be809..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/ContainerControls2.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/CustomAccessiblePropertiesForm.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/CustomAccessiblePropertiesForm.Designer.cs deleted file mode 100644 index d20f05440b4..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/CustomAccessiblePropertiesForm.Designer.cs +++ /dev/null @@ -1,1234 +0,0 @@ -namespace Accessibility_Core_App; - -partial class CustomAccessiblePropertiesForm -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomAccessiblePropertiesForm)); - this.button1 = new System.Windows.Forms.Button(); - this.checkBox1 = new System.Windows.Forms.CheckBox(); - this.checkedListBox1 = new System.Windows.Forms.CheckedListBox(); - this.comboBox1 = new System.Windows.Forms.ComboBox(); - this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); - this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripComboBox1 = new System.Windows.Forms.ToolStripComboBox(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.toolStripTextBox1 = new System.Windows.Forms.ToolStripTextBox(); - this.dateTimePicker1 = new System.Windows.Forms.DateTimePicker(); - this.linkLabel1 = new System.Windows.Forms.LinkLabel(); - this.label1 = new System.Windows.Forms.Label(); - this.hScrollBar1 = new System.Windows.Forms.HScrollBar(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); - this.domainUpDown1 = new System.Windows.Forms.DomainUpDown(); - this.numericUpDown1 = new System.Windows.Forms.NumericUpDown(); - this.monthCalendar1 = new System.Windows.Forms.MonthCalendar(); - this.maskedTextBox1 = new System.Windows.Forms.MaskedTextBox(); - this.listView1 = new System.Windows.Forms.ListView(); - this.listBox1 = new System.Windows.Forms.ListBox(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.panel1 = new System.Windows.Forms.Panel(); - this.menuStrip1 = new System.Windows.Forms.MenuStrip(); - this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator(); - this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this.printToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.printPreviewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); - this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.undoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.redoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); - this.cutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.pasteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); - this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.customizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.indexToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); - this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripComboBox2 = new System.Windows.Forms.ToolStripComboBox(); - this.toolStripTextBox2 = new System.Windows.Forms.ToolStripTextBox(); - this.vScrollBar1 = new System.Windows.Forms.VScrollBar(); - this.treeView1 = new System.Windows.Forms.TreeView(); - this.trackBar1 = new System.Windows.Forms.TrackBar(); - this.textBox1 = new System.Windows.Forms.TextBox(); - this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.tabControl1 = new System.Windows.Forms.TabControl(); - this.tabPage1 = new System.Windows.Forms.TabPage(); - this.tabPage2 = new System.Windows.Forms.TabPage(); - this.toolStrip1 = new System.Windows.Forms.ToolStrip(); - this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); - this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel(); - this.toolStripSplitButton2 = new System.Windows.Forms.ToolStripSplitButton(); - this.toolStripDropDownButton2 = new System.Windows.Forms.ToolStripDropDownButton(); - this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); - this.toolStripComboBox3 = new System.Windows.Forms.ToolStripComboBox(); - this.toolStripTextBox3 = new System.Windows.Forms.ToolStripTextBox(); - this.toolStripProgressBar2 = new System.Windows.Forms.ToolStripProgressBar(); - this.webBrowser1 = new System.Windows.Forms.WebBrowser(); - this.splitContainer1 = new System.Windows.Forms.SplitContainer(); - this.radioButton1 = new System.Windows.Forms.RadioButton(); - this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); - this.progressBar1 = new System.Windows.Forms.ProgressBar(); - this.printPreviewControl1 = new System.Windows.Forms.PrintPreviewControl(); - this.splitter1 = new System.Windows.Forms.Splitter(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); - this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); - this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar(); - this.toolStripDropDownButton1 = new System.Windows.Forms.ToolStripDropDownButton(); - this.toolStripSplitButton1 = new System.Windows.Forms.ToolStripSplitButton(); - this.dataGridView1 = new System.Windows.Forms.DataGridView(); - this.Column1 = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.Column2 = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.Column3 = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.Column4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer(); - this.richTextBox1 = new System.Windows.Forms.RichTextBox(); - this.contextMenuStrip1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - this.menuStrip1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit(); - this.tabControl1.SuspendLayout(); - this.toolStrip1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); - this.splitContainer1.SuspendLayout(); - this.statusStrip1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); - this.SuspendLayout(); - // - // button1 - // - this.button1.AccessibleDescription = "This is Button1"; - this.button1.AccessibleName = "TestButton"; - this.button1.AccessibleRole = System.Windows.Forms.AccessibleRole.MenuBar; - this.button1.Location = new System.Drawing.Point(6, 61); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(120, 33); - this.button1.TabIndex = 1; - this.button1.Text = "button1"; - this.button1.UseVisualStyleBackColor = true; - // - // checkBox1 - // - this.checkBox1.AccessibleDescription = "This is CheckBox1"; - this.checkBox1.AccessibleName = "TestCheckBox"; - this.checkBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.ScrollBar; - this.checkBox1.AutoSize = true; - this.checkBox1.Location = new System.Drawing.Point(9, 105); - this.checkBox1.Name = "checkBox1"; - this.checkBox1.Size = new System.Drawing.Size(83, 19); - this.checkBox1.TabIndex = 2; - this.checkBox1.Text = "checkBox1"; - this.checkBox1.UseVisualStyleBackColor = true; - // - // checkedListBox1 - // - this.checkedListBox1.AccessibleDescription = "This is CheckedListBox1"; - this.checkedListBox1.AccessibleName = "TestCheckedListBox"; - this.checkedListBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.Grip; - this.checkedListBox1.FormattingEnabled = true; - this.checkedListBox1.Location = new System.Drawing.Point(6, 131); - this.checkedListBox1.Name = "checkedListBox1"; - this.checkedListBox1.Size = new System.Drawing.Size(120, 94); - this.checkedListBox1.TabIndex = 3; - // - // comboBox1 - // - this.comboBox1.AccessibleDescription = "This is ComboBox1"; - this.comboBox1.AccessibleName = "TestComboBox"; - this.comboBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; - this.comboBox1.FormattingEnabled = true; - this.comboBox1.Location = new System.Drawing.Point(6, 232); - this.comboBox1.Name = "comboBox1"; - this.comboBox1.Size = new System.Drawing.Size(121, 23); - this.comboBox1.TabIndex = 4; - // - // contextMenuStrip1 - // - this.contextMenuStrip1.AccessibleDescription = "This is ContextMenuStrip"; - this.contextMenuStrip1.AccessibleName = "TestContextMenuStrip"; - this.contextMenuStrip1.AccessibleRole = System.Windows.Forms.AccessibleRole.Cursor; - this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripMenuItem1, - this.toolStripComboBox1, - this.toolStripSeparator1, - this.toolStripTextBox1}); - this.contextMenuStrip1.Name = "contextMenuStrip1"; - this.contextMenuStrip1.Size = new System.Drawing.Size(182, 84); - // - // toolStripMenuItem1 - // - this.toolStripMenuItem1.AccessibleDescription = "This is toolStripMenuItem"; - this.toolStripMenuItem1.AccessibleName = "TestToolStripMenuItem"; - this.toolStripMenuItem1.AccessibleRole = System.Windows.Forms.AccessibleRole.Sound; - this.toolStripMenuItem1.Name = "toolStripMenuItem1"; - this.toolStripMenuItem1.Size = new System.Drawing.Size(181, 22); - this.toolStripMenuItem1.Text = "toolStripMenuItem1"; - // - // toolStripComboBox1 - // - this.toolStripComboBox1.AccessibleDescription = "This is toolStripComboBox"; - this.toolStripComboBox1.AccessibleName = "TestToolStripComboBox"; - this.toolStripComboBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.Alert; - this.toolStripComboBox1.Name = "toolStripComboBox1"; - this.toolStripComboBox1.Size = new System.Drawing.Size(121, 23); - // - // toolStripSeparator1 - // - this.toolStripSeparator1.AccessibleDescription = "This is toolStripSeparator"; - this.toolStripSeparator1.AccessibleName = "TestToolStripSeparator"; - this.toolStripSeparator1.AccessibleRole = System.Windows.Forms.AccessibleRole.Client; - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(178, 6); - // - // toolStripTextBox1 - // - this.toolStripTextBox1.AccessibleDescription = "This is toolStripTextBox"; - this.toolStripTextBox1.AccessibleName = "TestToolStripTextBox"; - this.toolStripTextBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.MenuPopup; - this.toolStripTextBox1.Name = "toolStripTextBox1"; - this.toolStripTextBox1.Size = new System.Drawing.Size(100, 23); - // - // dateTimePicker1 - // - this.dateTimePicker1.AccessibleDescription = "This is DateTimePicker1"; - this.dateTimePicker1.AccessibleName = "TestDateTimePicker"; - this.dateTimePicker1.AccessibleRole = System.Windows.Forms.AccessibleRole.Caret; - this.dateTimePicker1.Location = new System.Drawing.Point(6, 266); - this.dateTimePicker1.Name = "dateTimePicker1"; - this.dateTimePicker1.Size = new System.Drawing.Size(200, 23); - this.dateTimePicker1.TabIndex = 7; - // - // linkLabel1 - // - this.linkLabel1.AccessibleDescription = "This is LinkLabel"; - this.linkLabel1.AccessibleName = "TestLinkLabel"; - this.linkLabel1.AccessibleRole = System.Windows.Forms.AccessibleRole.MenuPopup; - this.linkLabel1.AutoSize = true; - this.linkLabel1.Location = new System.Drawing.Point(209, 299); - this.linkLabel1.Name = "linkLabel1"; - this.linkLabel1.Size = new System.Drawing.Size(60, 15); - this.linkLabel1.TabIndex = 13; - this.linkLabel1.TabStop = true; - this.linkLabel1.Text = "linkLabel1"; - // - // label1 - // - this.label1.AccessibleDescription = "This is Label"; - this.label1.AccessibleName = "TestLabel"; - this.label1.AccessibleRole = System.Windows.Forms.AccessibleRole.PageTab; - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(143, 299); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(38, 15); - this.label1.TabIndex = 12; - this.label1.Text = "label1"; - // - // hScrollBar1 - // - this.hScrollBar1.AccessibleDescription = "This is HScrollBar"; - this.hScrollBar1.AccessibleName = "TestHScrollBar"; - this.hScrollBar1.AccessibleRole = System.Windows.Forms.AccessibleRole.Sound; - this.hScrollBar1.Location = new System.Drawing.Point(9, 547); - this.hScrollBar1.Name = "hScrollBar1"; - this.hScrollBar1.Size = new System.Drawing.Size(198, 17); - this.hScrollBar1.TabIndex = 11; - // - // groupBox1 - // - this.groupBox1.AccessibleDescription = "This is GroupBox"; - this.groupBox1.AccessibleName = "TestGroupBox"; - this.groupBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.Border; - this.groupBox1.Location = new System.Drawing.Point(7, 435); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(200, 100); - this.groupBox1.TabIndex = 10; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "groupBox1"; - // - // flowLayoutPanel1 - // - this.flowLayoutPanel1.AccessibleDescription = "This is FlowLayoutPanel"; - this.flowLayoutPanel1.AccessibleName = "TestFlowLayoutPanel"; - this.flowLayoutPanel1.AccessibleRole = System.Windows.Forms.AccessibleRole.Document; - this.flowLayoutPanel1.BackColor = System.Drawing.SystemColors.ActiveCaption; - this.flowLayoutPanel1.Location = new System.Drawing.Point(7, 329); - this.flowLayoutPanel1.Name = "flowLayoutPanel1"; - this.flowLayoutPanel1.Size = new System.Drawing.Size(200, 100); - this.flowLayoutPanel1.TabIndex = 9; - // - // domainUpDown1 - // - this.domainUpDown1.AccessibleDescription = "This is DomainUpDown"; - this.domainUpDown1.AccessibleName = "TestDomainUpDown"; - this.domainUpDown1.AccessibleRole = System.Windows.Forms.AccessibleRole.Indicator; - this.domainUpDown1.Location = new System.Drawing.Point(7, 299); - this.domainUpDown1.Name = "domainUpDown1"; - this.domainUpDown1.Size = new System.Drawing.Size(120, 23); - this.domainUpDown1.TabIndex = 8; - this.domainUpDown1.Text = "domainUpDown1"; - // - // numericUpDown1 - // - this.numericUpDown1.AccessibleDescription = "This is a test numericUpDown."; - this.numericUpDown1.AccessibleName = "numericUpDownTestControl"; - this.numericUpDown1.AccessibleRole = System.Windows.Forms.AccessibleRole.Sound; - this.numericUpDown1.Location = new System.Drawing.Point(214, 570); - this.numericUpDown1.Name = "numericUpDown1"; - this.numericUpDown1.Size = new System.Drawing.Size(120, 23); - this.numericUpDown1.TabIndex = 18; - // - // monthCalendar1 - // - this.monthCalendar1.AccessibleDescription = "This is a test MonthCalendar."; - this.monthCalendar1.AccessibleName = "monthCalendarTestControl"; - this.monthCalendar1.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; - this.monthCalendar1.Location = new System.Drawing.Point(345, 252); - this.monthCalendar1.Name = "monthCalendar1"; - this.monthCalendar1.TabIndex = 17; - // - // maskedTextBox1 - // - this.maskedTextBox1.AccessibleDescription = "This is a maskedTextBox control to test Accessibility."; - this.maskedTextBox1.AccessibleName = "maskedTextBoxTestControl"; - this.maskedTextBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.Grip; - this.maskedTextBox1.Location = new System.Drawing.Point(214, 541); - this.maskedTextBox1.Name = "maskedTextBox1"; - this.maskedTextBox1.Size = new System.Drawing.Size(121, 23); - this.maskedTextBox1.TabIndex = 16; - // - // listView1 - // - this.listView1.AccessibleDescription = "This is a listView control to test Accessibility."; - this.listView1.AccessibleName = "listViewTestControl"; - this.listView1.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; - this.listView1.HideSelection = false; - this.listView1.Location = new System.Drawing.Point(214, 438); - this.listView1.Name = "listView1"; - this.listView1.Size = new System.Drawing.Size(121, 97); - this.listView1.TabIndex = 15; - this.listView1.UseCompatibleStateImageBehavior = false; - // - // listBox1 - // - this.listBox1.AccessibleDescription = "This is a listBox control to test Accessibility."; - this.listBox1.AccessibleName = "listBoxTestControl"; - this.listBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.TitleBar; - this.listBox1.FormattingEnabled = true; - this.listBox1.ItemHeight = 15; - this.listBox1.Location = new System.Drawing.Point(214, 329); - this.listBox1.Name = "listBox1"; - this.listBox1.Size = new System.Drawing.Size(120, 94); - this.listBox1.TabIndex = 14; - // - // pictureBox1 - // - this.pictureBox1.AccessibleDescription = "This is a test PictureBox."; - this.pictureBox1.AccessibleName = "pictureBoxTestControl"; - this.pictureBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.Chart; - this.pictureBox1.BackColor = System.Drawing.SystemColors.ActiveBorder; - this.pictureBox1.Location = new System.Drawing.Point(350, 438); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(211, 155); - this.pictureBox1.TabIndex = 20; - this.pictureBox1.TabStop = false; - // - // panel1 - // - this.panel1.AccessibleDescription = "This is a test Panel."; - this.panel1.AccessibleName = "panelTestControl"; - this.panel1.AccessibleRole = System.Windows.Forms.AccessibleRole.Application; - this.panel1.BackColor = System.Drawing.SystemColors.ActiveCaption; - this.panel1.Location = new System.Drawing.Point(464, 62); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(183, 174); - this.panel1.TabIndex = 19; - // - // menuStrip1 - // - this.menuStrip1.AccessibleDescription = "MenuStrip to test Accessibility."; - this.menuStrip1.AccessibleName = "menuStripTestControl"; - this.menuStrip1.AccessibleRole = System.Windows.Forms.AccessibleRole.Caret; - this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.fileToolStripMenuItem, - this.editToolStripMenuItem, - this.toolsToolStripMenuItem, - this.helpToolStripMenuItem, - this.toolStripComboBox2, - this.toolStripTextBox2}); - this.menuStrip1.Location = new System.Drawing.Point(0, 0); - this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(914, 27); - this.menuStrip1.TabIndex = 21; - this.menuStrip1.Text = "menuStrip1"; - // - // fileToolStripMenuItem - // - this.fileToolStripMenuItem.AccessibleDescription = "This is a test item in MenuStrip."; - this.fileToolStripMenuItem.AccessibleName = "fileTestItem"; - this.fileToolStripMenuItem.AccessibleRole = System.Windows.Forms.AccessibleRole.Border; - this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.newToolStripMenuItem, - this.openToolStripMenuItem, - this.toolStripSeparator, - this.saveToolStripMenuItem, - this.saveAsToolStripMenuItem, - this.toolStripSeparator2, - this.printToolStripMenuItem, - this.printPreviewToolStripMenuItem, - this.toolStripSeparator3, - this.exitToolStripMenuItem}); - this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; - this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 23); - this.fileToolStripMenuItem.Text = "&File"; - // - // newToolStripMenuItem - // - this.newToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.newToolStripMenuItem.Name = "newToolStripMenuItem"; - this.newToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N))); - this.newToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.newToolStripMenuItem.Text = "&New"; - // - // openToolStripMenuItem - // - this.openToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.openToolStripMenuItem.Name = "openToolStripMenuItem"; - this.openToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); - this.openToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.openToolStripMenuItem.Text = "&Open"; - // - // toolStripSeparator - // - this.toolStripSeparator.Name = "toolStripSeparator"; - this.toolStripSeparator.Size = new System.Drawing.Size(143, 6); - // - // saveToolStripMenuItem - // - this.saveToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; - this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); - this.saveToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.saveToolStripMenuItem.Text = "&Save"; - // - // saveAsToolStripMenuItem - // - this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; - this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.saveAsToolStripMenuItem.Text = "Save &As"; - // - // toolStripSeparator2 - // - this.toolStripSeparator2.Name = "toolStripSeparator2"; - this.toolStripSeparator2.Size = new System.Drawing.Size(143, 6); - // - // printToolStripMenuItem - // - this.printToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.printToolStripMenuItem.Name = "printToolStripMenuItem"; - this.printToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.P))); - this.printToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.printToolStripMenuItem.Text = "&Print"; - // - // printPreviewToolStripMenuItem - // - this.printPreviewToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.printPreviewToolStripMenuItem.Name = "printPreviewToolStripMenuItem"; - this.printPreviewToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.printPreviewToolStripMenuItem.Text = "Print Pre&view"; - // - // toolStripSeparator3 - // - this.toolStripSeparator3.Name = "toolStripSeparator3"; - this.toolStripSeparator3.Size = new System.Drawing.Size(143, 6); - // - // exitToolStripMenuItem - // - this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; - this.exitToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.exitToolStripMenuItem.Text = "E&xit"; - // - // editToolStripMenuItem - // - this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.undoToolStripMenuItem, - this.redoToolStripMenuItem, - this.toolStripSeparator4, - this.cutToolStripMenuItem, - this.copyToolStripMenuItem, - this.pasteToolStripMenuItem, - this.toolStripSeparator5, - this.selectAllToolStripMenuItem}); - this.editToolStripMenuItem.Name = "editToolStripMenuItem"; - this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 23); - this.editToolStripMenuItem.Text = "&Edit"; - // - // undoToolStripMenuItem - // - this.undoToolStripMenuItem.Name = "undoToolStripMenuItem"; - this.undoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); - this.undoToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.undoToolStripMenuItem.Text = "&Undo"; - // - // redoToolStripMenuItem - // - this.redoToolStripMenuItem.Name = "redoToolStripMenuItem"; - this.redoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); - this.redoToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.redoToolStripMenuItem.Text = "&Redo"; - // - // toolStripSeparator4 - // - this.toolStripSeparator4.Name = "toolStripSeparator4"; - this.toolStripSeparator4.Size = new System.Drawing.Size(141, 6); - // - // cutToolStripMenuItem - // - this.cutToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.cutToolStripMenuItem.Name = "cutToolStripMenuItem"; - this.cutToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); - this.cutToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.cutToolStripMenuItem.Text = "Cu&t"; - // - // copyToolStripMenuItem - // - this.copyToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.copyToolStripMenuItem.Name = "copyToolStripMenuItem"; - this.copyToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); - this.copyToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.copyToolStripMenuItem.Text = "&Copy"; - // - // pasteToolStripMenuItem - // - this.pasteToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.pasteToolStripMenuItem.Name = "pasteToolStripMenuItem"; - this.pasteToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); - this.pasteToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.pasteToolStripMenuItem.Text = "&Paste"; - // - // toolStripSeparator5 - // - this.toolStripSeparator5.Name = "toolStripSeparator5"; - this.toolStripSeparator5.Size = new System.Drawing.Size(141, 6); - // - // selectAllToolStripMenuItem - // - this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem"; - this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.selectAllToolStripMenuItem.Text = "Select &All"; - // - // toolsToolStripMenuItem - // - this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.customizeToolStripMenuItem, - this.optionsToolStripMenuItem}); - this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; - this.toolsToolStripMenuItem.Size = new System.Drawing.Size(46, 23); - this.toolsToolStripMenuItem.Text = "&Tools"; - // - // customizeToolStripMenuItem - // - this.customizeToolStripMenuItem.Name = "customizeToolStripMenuItem"; - this.customizeToolStripMenuItem.Size = new System.Drawing.Size(130, 22); - this.customizeToolStripMenuItem.Text = "&Customize"; - // - // optionsToolStripMenuItem - // - this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; - this.optionsToolStripMenuItem.Size = new System.Drawing.Size(130, 22); - this.optionsToolStripMenuItem.Text = "&Options"; - // - // helpToolStripMenuItem - // - this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.contentsToolStripMenuItem, - this.indexToolStripMenuItem, - this.searchToolStripMenuItem, - this.toolStripSeparator6, - this.aboutToolStripMenuItem}); - this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 23); - this.helpToolStripMenuItem.Text = "&Help"; - // - // contentsToolStripMenuItem - // - this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; - this.contentsToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.contentsToolStripMenuItem.Text = "&Contents"; - // - // indexToolStripMenuItem - // - this.indexToolStripMenuItem.Name = "indexToolStripMenuItem"; - this.indexToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.indexToolStripMenuItem.Text = "&Index"; - // - // searchToolStripMenuItem - // - this.searchToolStripMenuItem.Name = "searchToolStripMenuItem"; - this.searchToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.searchToolStripMenuItem.Text = "&Search"; - // - // toolStripSeparator6 - // - this.toolStripSeparator6.Name = "toolStripSeparator6"; - this.toolStripSeparator6.Size = new System.Drawing.Size(119, 6); - // - // aboutToolStripMenuItem - // - this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; - this.aboutToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.aboutToolStripMenuItem.Text = "&About..."; - // - // toolStripComboBox2 - // - this.toolStripComboBox2.AccessibleDescription = "This is a combobox item in MenuStrip."; - this.toolStripComboBox2.AccessibleName = "comboBoxTestItem"; - this.toolStripComboBox2.AccessibleRole = System.Windows.Forms.AccessibleRole.Pane; - this.toolStripComboBox2.Items.AddRange(new object[] { - "A", - "B", - "C", - "D"}); - this.toolStripComboBox2.Name = "toolStripComboBox2"; - this.toolStripComboBox2.Size = new System.Drawing.Size(121, 23); - this.toolStripComboBox2.Text = "A"; - // - // toolStripTextBox2 - // - this.toolStripTextBox2.AccessibleDescription = "This is a textBox item in MenuStrip."; - this.toolStripTextBox2.AccessibleName = "textBoxItem"; - this.toolStripTextBox2.AccessibleRole = System.Windows.Forms.AccessibleRole.Row; - this.toolStripTextBox2.Name = "toolStripTextBox2"; - this.toolStripTextBox2.Size = new System.Drawing.Size(100, 23); - this.toolStripTextBox2.Text = "TextBox"; - // - // vScrollBar1 - // - this.vScrollBar1.AccessibleDescription = "This is a VScrollBar"; - this.vScrollBar1.AccessibleName = "TestVScrollBar"; - this.vScrollBar1.AccessibleRole = System.Windows.Forms.AccessibleRole.Equation; - this.vScrollBar1.Location = new System.Drawing.Point(585, 252); - this.vScrollBar1.Name = "vScrollBar1"; - this.vScrollBar1.Size = new System.Drawing.Size(17, 220); - this.vScrollBar1.TabIndex = 27; - // - // treeView1 - // - this.treeView1.AccessibleDescription = "This is a TreeView"; - this.treeView1.AccessibleName = "TestTreeView"; - this.treeView1.AccessibleRole = System.Windows.Forms.AccessibleRole.ButtonDropDown; - this.treeView1.Location = new System.Drawing.Point(613, 363); - this.treeView1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.treeView1.Name = "treeView1"; - this.treeView1.Size = new System.Drawing.Size(233, 112); - this.treeView1.TabIndex = 26; - // - // trackBar1 - // - this.trackBar1.AccessibleDescription = "This is a TrackBar"; - this.trackBar1.AccessibleName = "TestTrackBar"; - this.trackBar1.AccessibleRole = System.Windows.Forms.AccessibleRole.ButtonMenu; - this.trackBar1.Location = new System.Drawing.Point(613, 510); - this.trackBar1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.trackBar1.Name = "trackBar1"; - this.trackBar1.Size = new System.Drawing.Size(194, 45); - this.trackBar1.TabIndex = 25; - // - // textBox1 - // - this.textBox1.AccessibleDescription = "This is a TextBox"; - this.textBox1.AccessibleName = "TestTextBox"; - this.textBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.SplitButton; - this.textBox1.Location = new System.Drawing.Point(613, 481); - this.textBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.textBox1.Name = "textBox1"; - this.textBox1.Size = new System.Drawing.Size(233, 23); - this.textBox1.TabIndex = 24; - // - // tableLayoutPanel1 - // - this.tableLayoutPanel1.AccessibleDescription = "This is a TableLayoutPanel"; - this.tableLayoutPanel1.AccessibleName = "TestTableLayoutPanel"; - this.tableLayoutPanel1.AccessibleRole = System.Windows.Forms.AccessibleRole.IpAddress; - this.tableLayoutPanel1.BackColor = System.Drawing.SystemColors.ControlDark; - this.tableLayoutPanel1.ColumnCount = 2; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.Location = new System.Drawing.Point(613, 242); - this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 2; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(233, 115); - this.tableLayoutPanel1.TabIndex = 23; - // - // tabControl1 - // - this.tabControl1.AccessibleDescription = "This is a TabControl"; - this.tabControl1.AccessibleName = "TestTabControl"; - this.tabControl1.AccessibleRole = System.Windows.Forms.AccessibleRole.OutlineButton; - this.tabControl1.Controls.Add(this.tabPage1); - this.tabControl1.Controls.Add(this.tabPage2); - this.tabControl1.Location = new System.Drawing.Point(657, 62); - this.tabControl1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(222, 174); - this.tabControl1.TabIndex = 22; - // - // tabPage1 - // - this.tabPage1.Location = new System.Drawing.Point(4, 24); - this.tabPage1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage1.Name = "tabPage1"; - this.tabPage1.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage1.Size = new System.Drawing.Size(214, 146); - this.tabPage1.TabIndex = 0; - this.tabPage1.Text = "tabPage1"; - this.tabPage1.UseVisualStyleBackColor = true; - // - // tabPage2 - // - this.tabPage2.Location = new System.Drawing.Point(4, 24); - this.tabPage2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage2.Name = "tabPage2"; - this.tabPage2.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.tabPage2.Size = new System.Drawing.Size(214, 146); - this.tabPage2.TabIndex = 1; - this.tabPage2.Text = "tabPage2"; - this.tabPage2.UseVisualStyleBackColor = true; - // - // toolStrip1 - // - this.toolStrip1.AccessibleDescription = "This is a ToolStrip"; - this.toolStrip1.AccessibleName = "TestToolStrip"; - this.toolStrip1.AccessibleRole = System.Windows.Forms.AccessibleRole.Clock; - this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripButton1, - this.toolStripLabel1, - this.toolStripSplitButton2, - this.toolStripDropDownButton2, - this.toolStripSeparator7, - this.toolStripComboBox3, - this.toolStripTextBox3, - this.toolStripProgressBar2}); - this.toolStrip1.Location = new System.Drawing.Point(0, 27); - this.toolStrip1.Name = "toolStrip1"; - this.toolStrip1.Size = new System.Drawing.Size(914, 25); - this.toolStrip1.TabIndex = 28; - this.toolStrip1.Text = "toolStrip1"; - // - // toolStripButton1 - // - this.toolStripButton1.AccessibleDescription = "This is toolStripButton"; - this.toolStripButton1.AccessibleName = "TestToolStripButton"; - this.toolStripButton1.AccessibleRole = System.Windows.Forms.AccessibleRole.TitleBar; - this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image"))); - this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButton1.Name = "toolStripButton1"; - this.toolStripButton1.Size = new System.Drawing.Size(23, 22); - this.toolStripButton1.Text = "toolStripButton1"; - // - // toolStripLabel1 - // - this.toolStripLabel1.AccessibleDescription = "This is toolStripLabel"; - this.toolStripLabel1.AccessibleName = "TestToolStripLabel"; - this.toolStripLabel1.AccessibleRole = System.Windows.Forms.AccessibleRole.MenuBar; - this.toolStripLabel1.Name = "toolStripLabel1"; - this.toolStripLabel1.Size = new System.Drawing.Size(86, 22); - this.toolStripLabel1.Text = "toolStripLabel1"; - // - // toolStripSplitButton2 - // - this.toolStripSplitButton2.AccessibleDescription = "This is toolStripSplitButton"; - this.toolStripSplitButton2.AccessibleName = "TestToolStripSplitButton"; - this.toolStripSplitButton2.AccessibleRole = System.Windows.Forms.AccessibleRole.ScrollBar; - this.toolStripSplitButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripSplitButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripSplitButton2.Image"))); - this.toolStripSplitButton2.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripSplitButton2.Name = "toolStripSplitButton2"; - this.toolStripSplitButton2.Size = new System.Drawing.Size(32, 22); - this.toolStripSplitButton2.Text = "toolStripSplitButton2"; - // - // toolStripDropDownButton2 - // - this.toolStripDropDownButton2.AccessibleDescription = "This is toolStripDropDownButton"; - this.toolStripDropDownButton2.AccessibleName = "TestToolStripDropDownButton"; - this.toolStripDropDownButton2.AccessibleRole = System.Windows.Forms.AccessibleRole.Grip; - this.toolStripDropDownButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripDropDownButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripDropDownButton2.Image"))); - this.toolStripDropDownButton2.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripDropDownButton2.Name = "toolStripDropDownButton2"; - this.toolStripDropDownButton2.Size = new System.Drawing.Size(29, 22); - this.toolStripDropDownButton2.Text = "toolStripDropDownButton2"; - // - // toolStripSeparator7 - // - this.toolStripSeparator7.AccessibleDescription = "This is toolStripSeparator"; - this.toolStripSeparator7.AccessibleName = "TestToolStripSeparator"; - this.toolStripSeparator7.AccessibleRole = System.Windows.Forms.AccessibleRole.Sound; - this.toolStripSeparator7.Name = "toolStripSeparator7"; - this.toolStripSeparator7.Size = new System.Drawing.Size(6, 25); - // - // toolStripComboBox3 - // - this.toolStripComboBox3.AccessibleDescription = "This is toolStripComboBox"; - this.toolStripComboBox3.AccessibleName = "TestToolStripComboBox"; - this.toolStripComboBox3.AccessibleRole = System.Windows.Forms.AccessibleRole.Cursor; - this.toolStripComboBox3.Name = "toolStripComboBox3"; - this.toolStripComboBox3.Size = new System.Drawing.Size(121, 25); - // - // toolStripTextBox3 - // - this.toolStripTextBox3.AccessibleDescription = "This is toolStripTextBox"; - this.toolStripTextBox3.AccessibleName = "TestToolStripTextBox"; - this.toolStripTextBox3.AccessibleRole = System.Windows.Forms.AccessibleRole.Caret; - this.toolStripTextBox3.Name = "toolStripTextBox3"; - this.toolStripTextBox3.Size = new System.Drawing.Size(100, 25); - // - // toolStripProgressBar2 - // - this.toolStripProgressBar2.AccessibleDescription = "This is toolStripProgressBar"; - this.toolStripProgressBar2.AccessibleName = "TestToolStripProgressBar"; - this.toolStripProgressBar2.AccessibleRole = System.Windows.Forms.AccessibleRole.Client; - this.toolStripProgressBar2.Name = "toolStripProgressBar2"; - this.toolStripProgressBar2.Size = new System.Drawing.Size(100, 22); - // - // webBrowser1 - // - this.webBrowser1.AccessibleDescription = "This is a WebBrowser"; - this.webBrowser1.AccessibleName = "TestWebBrowser"; - this.webBrowser1.AccessibleRole = System.Windows.Forms.AccessibleRole.Animation; - this.webBrowser1.Location = new System.Drawing.Point(350, 620); - this.webBrowser1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.webBrowser1.MinimumSize = new System.Drawing.Size(23, 23); - this.webBrowser1.Name = "webBrowser1"; - this.webBrowser1.Size = new System.Drawing.Size(200, 165); - this.webBrowser1.TabIndex = 8; - // - // splitContainer1 - // - this.splitContainer1.AccessibleDescription = "This is a splitContainer"; - this.splitContainer1.AccessibleName = "splitContainerTest"; - this.splitContainer1.AccessibleRole = System.Windows.Forms.AccessibleRole.SplitButton; - this.splitContainer1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(128))))); - this.splitContainer1.Location = new System.Drawing.Point(613, 554); - this.splitContainer1.Name = "splitContainer1"; - this.splitContainer1.Size = new System.Drawing.Size(179,99); - this.splitContainer1.SplitterDistance = 69; - this.splitContainer1.TabIndex = 34; - // - // radioButton1 - // - this.radioButton1.AccessibleDescription = "This is a radioButton"; - this.radioButton1.AccessibleName = "radioButtonTest"; - this.radioButton1.AccessibleRole = System.Windows.Forms.AccessibleRole.Grouping; - this.radioButton1.AutoSize = true; - this.radioButton1.Location = new System.Drawing.Point(15, 606); - this.radioButton1.Name = "radioButton1"; - this.radioButton1.Size = new System.Drawing.Size(94, 19); - this.radioButton1.TabIndex = 32; - this.radioButton1.TabStop = true; - this.radioButton1.Text = "radioButton1"; - this.radioButton1.UseVisualStyleBackColor = true; - // - // propertyGrid1 - // - this.propertyGrid1.AccessibleDescription = "This is a propertyGrid"; - this.propertyGrid1.AccessibleName = "propertyGridTest"; - this.propertyGrid1.AccessibleRole = System.Windows.Forms.AccessibleRole.PropertyPage; - this.propertyGrid1.Location = new System.Drawing.Point(159, 610); - this.propertyGrid1.Name = "propertyGrid1"; - this.propertyGrid1.Size = new System.Drawing.Size(176, 174); - this.propertyGrid1.TabIndex = 31; - // - // progressBar1 - // - this.progressBar1.AccessibleDescription = "This is a progressBar"; - this.progressBar1.AccessibleName = "progressBarTest"; - this.progressBar1.AccessibleRole = System.Windows.Forms.AccessibleRole.ProgressBar; - this.progressBar1.Location = new System.Drawing.Point(15, 572); - this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(100, 23); - this.progressBar1.TabIndex = 30; - // - // printPreviewControl1 - // - this.printPreviewControl1.AccessibleDescription = "This is a printPreviewControl"; - this.printPreviewControl1.AccessibleName = "printPreviewControlTest"; - this.printPreviewControl1.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; - this.printPreviewControl1.Location = new System.Drawing.Point(15, 640); - this.printPreviewControl1.Name = "printPreviewControl1"; - this.printPreviewControl1.Size = new System.Drawing.Size(133, 140); - this.printPreviewControl1.TabIndex = 29; - // - // splitter1 - // - this.splitter1.AccessibleDescription = "This is a splitter"; - this.splitter1.AccessibleName = "splitterTest"; - this.splitter1.AccessibleRole = System.Windows.Forms.AccessibleRole.SplitButton; - this.splitter1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128))))); - this.splitter1.Dock = System.Windows.Forms.DockStyle.Right; - this.splitter1.Location = new System.Drawing.Point(883, 52); - this.splitter1.Name = "splitter1"; - this.splitter1.Size = new System.Drawing.Size(31, 765); - this.splitter1.TabIndex = 35; - this.splitter1.TabStop = false; - // - // statusStrip1 - // - this.statusStrip1.AccessibleDescription = "This is a statusStrip"; - this.statusStrip1.AccessibleName = "statusStripTest"; - this.statusStrip1.AccessibleRole = System.Windows.Forms.AccessibleRole.StatusBar; - this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripStatusLabel1, - this.toolStripProgressBar1, - this.toolStripDropDownButton1, - this.toolStripSplitButton1}); - this.statusStrip1.Location = new System.Drawing.Point(0, 795); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Size = new System.Drawing.Size(883, 22); - this.statusStrip1.TabIndex = 36; - this.statusStrip1.Text = "statusStrip1"; - // - // toolStripStatusLabel1 - // - this.toolStripStatusLabel1.AccessibleDescription = "This is toolStripStatusLabel"; - this.toolStripStatusLabel1.AccessibleName = "TestToolStripStatusLabel"; - this.toolStripStatusLabel1.AccessibleRole = System.Windows.Forms.AccessibleRole.MenuBar; - this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; - this.toolStripStatusLabel1.Size = new System.Drawing.Size(118, 17); - this.toolStripStatusLabel1.Text = "toolStripStatusLabel1"; - // - // toolStripProgressBar1 - // - this.toolStripProgressBar1.AccessibleDescription = "This is toolStripProgressBar"; - this.toolStripProgressBar1.AccessibleName = "TestToolStripProgressBar"; - this.toolStripProgressBar1.AccessibleRole = System.Windows.Forms.AccessibleRole.ScrollBar; - this.toolStripProgressBar1.Name = "toolStripProgressBar1"; - this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16); - // - // toolStripDropDownButton1 - // - this.toolStripDropDownButton1.AccessibleDescription = "This is toolStripDropDownButton"; - this.toolStripDropDownButton1.AccessibleName = "TestToolStripDropDownButton"; - this.toolStripDropDownButton1.AccessibleRole = System.Windows.Forms.AccessibleRole.Grip; - this.toolStripDropDownButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripDropDownButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripDropDownButton1.Image"))); - this.toolStripDropDownButton1.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripDropDownButton1.Name = "toolStripDropDownButton1"; - this.toolStripDropDownButton1.Size = new System.Drawing.Size(29, 20); - this.toolStripDropDownButton1.Text = "toolStripDropDownButton1"; - // - // toolStripSplitButton1 - // - this.toolStripSplitButton1.AccessibleDescription = "This is toolStripSplitButton"; - this.toolStripSplitButton1.AccessibleName = "TestToolStripSplitButton"; - this.toolStripSplitButton1.AccessibleRole = System.Windows.Forms.AccessibleRole.Sound; - this.toolStripSplitButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripSplitButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripSplitButton1.Image"))); - this.toolStripSplitButton1.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripSplitButton1.Name = "toolStripSplitButton1"; - this.toolStripSplitButton1.Size = new System.Drawing.Size(32, 20); - this.toolStripSplitButton1.Text = "toolStripSplitButton1"; - // - // dataGridView1 - // - this.dataGridView1.AccessibleDescription = "This is dataGridView1"; - this.dataGridView1.AccessibleName = "TestDataGridView"; - this.dataGridView1.AccessibleRole = System.Windows.Forms.AccessibleRole.Alert; - this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.Column1, - this.Column2, - this.Column3, - this.Column4}); - this.dataGridView1.Location = new System.Drawing.Point(133, 62); - this.dataGridView1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.dataGridView1.Name = "dataGridView1"; - this.dataGridView1.Size = new System.Drawing.Size(324, 174); - this.dataGridView1.TabIndex = 37; - // - // Column1 - // - this.Column1.DisplayStyle = System.Windows.Forms.DataGridViewComboBoxDisplayStyle.ComboBox; - this.Column1.HeaderText = "CBColumn1"; - this.Column1.Name = "Column1"; - // - // Column2 - // - this.Column2.HeaderText = "CBColumn2"; - this.Column2.Name = "Column2"; - // - // Column3 - // - this.Column3.DisplayStyle = System.Windows.Forms.DataGridViewComboBoxDisplayStyle.Nothing; - this.Column3.HeaderText = "CBColumn3"; - this.Column3.Name = "Column3"; - // - // Column4 - // - this.Column4.HeaderText = "TBColumn"; - this.Column4.Name = "Column4"; - // - // toolStripContainer1 - // - this.toolStripContainer1.AccessibleDescription = "This is a ToolStripContainer"; - this.toolStripContainer1.AccessibleName = "TestToolStripContainer"; - this.toolStripContainer1.AccessibleRole = System.Windows.Forms.AccessibleRole.PageTabList; - // - // - // - this.toolStripContainer1.BottomToolStripPanel.Location = new System.Drawing.Point(0, 0); - this.toolStripContainer1.BottomToolStripPanel.Name = ""; - this.toolStripContainer1.BottomToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; - this.toolStripContainer1.BottomToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); - // - // - // - this.toolStripContainer1.ContentPanel.AccessibleDescription = "This is a ToolStripContainer.ContentPanel"; - this.toolStripContainer1.ContentPanel.AccessibleName = "TestToolStripContainer.ContentPanel"; - this.toolStripContainer1.ContentPanel.AccessibleRole = System.Windows.Forms.AccessibleRole.WhiteSpace; - this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(202, 123); - // - // - // - this.toolStripContainer1.LeftToolStripPanel.Location = new System.Drawing.Point(0, 0); - this.toolStripContainer1.LeftToolStripPanel.Name = ""; - this.toolStripContainer1.LeftToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; - this.toolStripContainer1.LeftToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); - this.toolStripContainer1.Location = new System.Drawing.Point(613, 670); - this.toolStripContainer1.Name = "toolStripContainer1"; - // - // - // - this.toolStripContainer1.RightToolStripPanel.Location = new System.Drawing.Point(0, 0); - this.toolStripContainer1.RightToolStripPanel.Name = ""; - this.toolStripContainer1.RightToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; - this.toolStripContainer1.RightToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); - this.toolStripContainer1.Size = new System.Drawing.Size(202, 123); - this.toolStripContainer1.TabIndex = 0; - this.toolStripContainer1.Text = "toolStripContainer1"; - // - // - // - this.toolStripContainer1.TopToolStripPanel.Location = new System.Drawing.Point(0, 0); - this.toolStripContainer1.TopToolStripPanel.Name = ""; - this.toolStripContainer1.TopToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; - this.toolStripContainer1.TopToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); - // - // richTextBox1 - // - this.richTextBox1.AccessibleDescription = "This is RichTextBox"; - this.richTextBox1.AccessibleName = "TestRichTextBox"; - this.richTextBox1.AccessibleRole = System.Windows.Forms.AccessibleRole.Border; - this.richTextBox1.Location = new System.Drawing.Point(799, 554); - this.richTextBox1.Name = "richTextBox1"; - this.richTextBox1.Size = new System.Drawing.Size(100, 96); - this.richTextBox1.TabIndex = 38; - this.richTextBox1.Text = ""; - // - // CustomAccessiblePropertiesForm - // - this.AccessibleDescription = "This is customAccessiblePropertiesForm"; - this.AccessibleName = "testForm"; - this.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(944, 817); - this.ContextMenuStrip = this.contextMenuStrip1; - this.Controls.Add(this.richTextBox1); - this.Controls.Add(this.dataGridView1); - this.Controls.Add(this.toolStripContainer1); - this.Controls.Add(this.statusStrip1); - this.Controls.Add(this.splitter1); - this.Controls.Add(this.splitContainer1); - this.Controls.Add(this.radioButton1); - this.Controls.Add(this.propertyGrid1); - this.Controls.Add(this.progressBar1); - this.Controls.Add(this.printPreviewControl1); - this.Controls.Add(this.webBrowser1); - this.Controls.Add(this.toolStrip1); - this.Controls.Add(this.vScrollBar1); - this.Controls.Add(this.treeView1); - this.Controls.Add(this.trackBar1); - this.Controls.Add(this.textBox1); - this.Controls.Add(this.tableLayoutPanel1); - this.Controls.Add(this.tabControl1); - this.Controls.Add(this.menuStrip1); - this.Controls.Add(this.pictureBox1); - this.Controls.Add(this.panel1); - this.Controls.Add(this.numericUpDown1); - this.Controls.Add(this.monthCalendar1); - this.Controls.Add(this.maskedTextBox1); - this.Controls.Add(this.listView1); - this.Controls.Add(this.listBox1); - this.Controls.Add(this.linkLabel1); - this.Controls.Add(this.label1); - this.Controls.Add(this.hScrollBar1); - this.Controls.Add(this.groupBox1); - this.Controls.Add(this.flowLayoutPanel1); - this.Controls.Add(this.domainUpDown1); - this.Controls.Add(this.dateTimePicker1); - this.Controls.Add(this.comboBox1); - this.Controls.Add(this.checkedListBox1); - this.Controls.Add(this.checkBox1); - this.Controls.Add(this.button1); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "CustomAccessiblePropertiesForm"; - this.Text = "CustomAccessiblePropertiesForm"; - this.contextMenuStrip1.ResumeLayout(false); - this.contextMenuStrip1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - this.menuStrip1.ResumeLayout(false); - this.menuStrip1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit(); - this.tabControl1.ResumeLayout(false); - this.toolStrip1.ResumeLayout(false); - this.toolStrip1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); - this.splitContainer1.ResumeLayout(false); - this.statusStrip1.ResumeLayout(false); - this.statusStrip1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button button1; - private System.Windows.Forms.CheckBox checkBox1; - private System.Windows.Forms.CheckedListBox checkedListBox1; - private System.Windows.Forms.ComboBox comboBox1; - private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; - private System.Windows.Forms.DateTimePicker dateTimePicker1; - private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1; - private System.Windows.Forms.ToolStripComboBox toolStripComboBox1; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.ToolStripTextBox toolStripTextBox1; - private System.Windows.Forms.LinkLabel linkLabel1; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.HScrollBar hScrollBar1; - private System.Windows.Forms.GroupBox groupBox1; - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; - private System.Windows.Forms.DomainUpDown domainUpDown1; - private System.Windows.Forms.NumericUpDown numericUpDown1; - private System.Windows.Forms.MonthCalendar monthCalendar1; - private System.Windows.Forms.MaskedTextBox maskedTextBox1; - private System.Windows.Forms.ListView listView1; - private System.Windows.Forms.ListBox listBox1; - private System.Windows.Forms.PictureBox pictureBox1; - private System.Windows.Forms.Panel panel1; - private System.Windows.Forms.MenuStrip menuStrip1; - private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator; - private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; - private System.Windows.Forms.ToolStripMenuItem printToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem printPreviewToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; - private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem undoToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem redoToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; - private System.Windows.Forms.ToolStripMenuItem cutToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem copyToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem pasteToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; - private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem customizeToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem indexToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem searchToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; - private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; - private System.Windows.Forms.ToolStripComboBox toolStripComboBox2; - private System.Windows.Forms.ToolStripTextBox toolStripTextBox2; - private System.Windows.Forms.VScrollBar vScrollBar1; - private System.Windows.Forms.TreeView treeView1; - private System.Windows.Forms.TrackBar trackBar1; - private System.Windows.Forms.TextBox textBox1; - private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.TabControl tabControl1; - private System.Windows.Forms.TabPage tabPage1; - private System.Windows.Forms.TabPage tabPage2; - private System.Windows.Forms.ToolStrip toolStrip1; - private System.Windows.Forms.WebBrowser webBrowser1; - private System.Windows.Forms.SplitContainer splitContainer1; - private System.Windows.Forms.RadioButton radioButton1; - private System.Windows.Forms.PropertyGrid propertyGrid1; - private System.Windows.Forms.ProgressBar progressBar1; - private System.Windows.Forms.PrintPreviewControl printPreviewControl1; - private System.Windows.Forms.Splitter splitter1; - private System.Windows.Forms.StatusStrip statusStrip1; - private System.Windows.Forms.DataGridView dataGridView1; - private System.Windows.Forms.DataGridViewComboBoxColumn Column1; - private System.Windows.Forms.DataGridViewComboBoxColumn Column2; - private System.Windows.Forms.DataGridViewComboBoxColumn Column3; - private System.Windows.Forms.DataGridViewTextBoxColumn Column4; - private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; - private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1; - private System.Windows.Forms.ToolStripDropDownButton toolStripDropDownButton1; - private System.Windows.Forms.ToolStripSplitButton toolStripSplitButton1; - private System.Windows.Forms.ToolStripButton toolStripButton1; - private System.Windows.Forms.ToolStripLabel toolStripLabel1; - private System.Windows.Forms.ToolStripSplitButton toolStripSplitButton2; - private System.Windows.Forms.ToolStripDropDownButton toolStripDropDownButton2; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; - private System.Windows.Forms.ToolStripComboBox toolStripComboBox3; - private System.Windows.Forms.ToolStripTextBox toolStripTextBox3; - private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar2; - private System.Windows.Forms.ToolStripContainer toolStripContainer1; - private System.Windows.Forms.RichTextBox richTextBox1; -} - - diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/CustomAccessiblePropertiesForm.cs b/src/System.Windows.Forms/tests/AccessibilityTests/CustomAccessiblePropertiesForm.cs deleted file mode 100644 index d70cdcc799b..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/CustomAccessiblePropertiesForm.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class CustomAccessiblePropertiesForm : Form -{ - public CustomAccessiblePropertiesForm() - { - InitializeComponent(); - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/CustomAccessiblePropertiesForm.resx b/src/System.Windows.Forms/tests/AccessibilityTests/CustomAccessiblePropertiesForm.resx deleted file mode 100644 index bfcbcbe074c..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/CustomAccessiblePropertiesForm.resx +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACRSURBVDhPY/j27dt/SjDYACcnJ7IwigEf3n8kCZNswPNb - J/+f6DYF0yA+yQac6Db5f6hWCmwIiE+mC0wIu2DS2Vf/F1x6DefjwlgNyNr34r/0wkdgTMgQDAOQNRNj - CIoBOg0rMTTDMLIhIHbriZeYBmDTiIxBGkEYxge5liQDsGGQqykyAISpZwAlmIEywMAAAAc1/Jwvt6sN - AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACRSURBVDhPY/j27dt/SjDYACcnJ7IwigEf3n8kCZNswPNb - J/+f6DYF0yA+yQac6Db5f6hWCmwIiE+mC0wIu2DS2Vf/F1x6DefjwlgNyNr34r/0wkdgTMgQDAOQNRNj - CIoBOg0rMTTDMLIhIHbriZeYBmDTiIxBGkEYxge5liQDsGGQqykyAISpZwAlmIEywMAAAAc1/Jwvt6sN - AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACRSURBVDhPY/j27dt/SjDYACcnJ7IwigEf3n8kCZNswPNb - J/+f6DYF0yA+yQac6Db5f6hWCmwIiE+mC0wIu2DS2Vf/F1x6DefjwlgNyNr34r/0wkdgTMgQDAOQNRNj - CIoBOg0rMTTDMLIhIHbriZeYBmDTiIxBGkEYxge5liQDsGGQqykyAISpZwAlmIEywMAAAAc1/Jwvt6sN - AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACRSURBVDhPY/j27dt/SjDYACcnJ7IwigEf3n8kCZNswPNb - J/+f6DYF0yA+yQac6Db5f6hWCmwIiE+mC0wIu2DS2Vf/F1x6DefjwlgNyNr34r/0wkdgTMgQDAOQNRNj - CIoBOg0rMTTDMLIhIHbriZeYBmDTiIxBGkEYxge5liQDsGGQqykyAISpZwAlmIEywMAAAAc1/Jwvt6sN - AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACRSURBVDhPY/j27dt/SjDYACcnJ7IwigEf3n8kCZNswPNb - J/+f6DYF0yA+yQac6Db5f6hWCmwIiE+mC0wIu2DS2Vf/F1x6DefjwlgNyNr34r/0wkdgTMgQDAOQNRNj - CIoBOg0rMTTDMLIhIHbriZeYBmDTiIxBGkEYxge5liQDsGGQqykyAISpZwAlmIEywMAAAAc1/Jwvt6sN - AAAAAElFTkSuQmCC - - - - 74 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/DataBindingExample.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/DataBindingExample.Designer.cs deleted file mode 100644 index 8b42763598b..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/DataBindingExample.Designer.cs +++ /dev/null @@ -1,312 +0,0 @@ -namespace Accessibility_Core_App; - -partial class DataBindingExample -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - #region Windows Form Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.dataGridView1 = new System.Windows.Forms.DataGridView(); - this.panel1 = new System.Windows.Forms.Panel(); - this.comboBox1 = new System.Windows.Forms.ComboBox(); - this.label1 = new System.Windows.Forms.Label(); - this.textBox1 = new System.Windows.Forms.TextBox(); - this.button1 = new System.Windows.Forms.Button(); - this.linkLabel1 = new System.Windows.Forms.LinkLabel(); - this.maskedTextBox1 = new System.Windows.Forms.MaskedTextBox(); - this.checkBox1 = new System.Windows.Forms.CheckBox(); - this.richTextBox1 = new System.Windows.Forms.RichTextBox(); - this.domainUpDown1 = new System.Windows.Forms.DomainUpDown(); - this.numericUpDown1 = new System.Windows.Forms.NumericUpDown(); - this.radioButton1 = new System.Windows.Forms.RadioButton(); - this.label2 = new System.Windows.Forms.Label(); - this.treeView1 = new System.Windows.Forms.TreeView(); - this.label3 = new System.Windows.Forms.Label(); - this.listView1 = new System.Windows.Forms.ListView(); - this.label4 = new System.Windows.Forms.Label(); - this.listBox1 = new System.Windows.Forms.ListBox(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); - this.panel1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit(); - this.SuspendLayout(); - // - // comboBox1 - // - this.comboBox1.AccessibleDescription = "CB1"; - this.comboBox1.AccessibleName = "CB1"; - this.comboBox1.FormattingEnabled = true; - this.comboBox1.Location = new System.Drawing.Point(10, 9); - this.comboBox1.Name = "comboBox1"; - this.comboBox1.Size = new System.Drawing.Size(121, 23); - this.comboBox1.TabIndex = 2; - this.comboBox1.Text = "ComboBox_DropDown"; - // - // dataGridView1 - // - this.dataGridView1.AccessibleDescription = "DGV1"; - this.dataGridView1.AccessibleName = "DGV1"; - this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView1.Location = new System.Drawing.Point(12, 21); - this.dataGridView1.Name = "dataGridView1"; - this.dataGridView1.Size = new System.Drawing.Size(240, 150); - this.dataGridView1.TabIndex = 0; - this.dataGridView1.StandardTab = true; - this.dataGridView1.Text = "dataGridView1"; - // - // label1 - // - this.label1.AccessibleDescription = "L1"; - this.label1.AccessibleName = "L1"; - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(10, 48); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(109, 15); - this.label1.TabIndex = 3; - this.label1.Text = "StudentPhoneNum"; - // - // textBox1 - // - this.textBox1.AccessibleDescription = "TB1"; - this.textBox1.AccessibleName = "TB1"; - this.textBox1.Location = new System.Drawing.Point(10, 77); - this.textBox1.Name = "textBox1"; - this.textBox1.Size = new System.Drawing.Size(142, 23); - this.textBox1.TabIndex = 4; - this.textBox1.Text = "TextBox"; - // - // button1 - // - this.button1.AccessibleDescription = "BT1"; - this.button1.AccessibleName = "BT1"; - this.button1.Location = new System.Drawing.Point(10, 136); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(75, 23); - this.button1.TabIndex = 5; - this.button1.Text = "button1"; - this.button1.UseVisualStyleBackColor = true; - // - // panel1 - // - this.panel1.AccessibleDescription = "Pane1"; - this.panel1.AccessibleName = "Panel1"; - this.panel1.Controls.Add(this.comboBox1); - this.panel1.Controls.Add(this.label1); - this.panel1.Controls.Add(this.textBox1); - this.panel1.Controls.Add(this.button1); - this.panel1.Controls.Add(this.linkLabel1); - this.panel1.Controls.Add(this.maskedTextBox1); - this.panel1.Controls.Add(this.checkBox1); - this.panel1.Controls.Add(this.richTextBox1); - this.panel1.Controls.Add(this.domainUpDown1); - this.panel1.Controls.Add(this.numericUpDown1); - this.panel1.Controls.Add(this.radioButton1); - this.panel1.Location = new System.Drawing.Point(272, 12); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(479, 198); - this.panel1.TabIndex = 1; - // - // radioButton1 - // - this.radioButton1.AccessibleDescription = "RB1"; - this.radioButton1.AccessibleName = "RB1"; - this.radioButton1.AutoSize = true; - this.radioButton1.Location = new System.Drawing.Point(336, 77); - this.radioButton1.Name = "radioButton1"; - this.radioButton1.Size = new System.Drawing.Size(84, 19); - this.radioButton1.TabIndex = 12; - this.radioButton1.TabStop = true; - this.radioButton1.Text = "Agreement"; - this.radioButton1.UseVisualStyleBackColor = true; - // - // numericUpDown1 - // - this.numericUpDown1.AccessibleDescription = "NUO1"; - this.numericUpDown1.AccessibleName = "NUO1"; - this.numericUpDown1.Location = new System.Drawing.Point(336, 39); - this.numericUpDown1.Name = "numericUpDown1"; - this.numericUpDown1.Size = new System.Drawing.Size(120, 23); - this.numericUpDown1.TabIndex = 11; - // - // domainUpDown1 - // - this.domainUpDown1.AccessibleDescription = "DUO1"; - this.domainUpDown1.AccessibleName = "DUO1"; - this.domainUpDown1.Location = new System.Drawing.Point(336, 10); - this.domainUpDown1.Name = "domainUpDown1"; - this.domainUpDown1.Size = new System.Drawing.Size(120, 23); - this.domainUpDown1.TabIndex = 10; - this.domainUpDown1.Text = "Student count"; - // - // richTextBox1 - // - this.richTextBox1.AccessibleDescription = "RT1"; - this.richTextBox1.AccessibleName = "RT1"; - this.richTextBox1.Location = new System.Drawing.Point(169, 102); - this.richTextBox1.Name = "richTextBox1"; - this.richTextBox1.Size = new System.Drawing.Size(151, 85); - this.richTextBox1.TabIndex = 9; - this.richTextBox1.Text = "RichTestBox"; - this.richTextBox1.BackColor = System.Drawing.SystemColors.Window; - // - // checkBox1 - // - this.checkBox1.AccessibleDescription = "CB2"; - this.checkBox1.AccessibleName = "CB2"; - this.checkBox1.AutoSize = true; - this.checkBox1.Location = new System.Drawing.Point(169, 77); - this.checkBox1.Name = "checkBox1"; - this.checkBox1.Size = new System.Drawing.Size(80, 19); - this.checkBox1.TabIndex = 8; - this.checkBox1.Text = "Is_Student"; - this.checkBox1.UseVisualStyleBackColor = true; - // - // maskedTextBox1 - // - this.maskedTextBox1.AccessibleDescription = "MT1"; - this.maskedTextBox1.AccessibleName = "MT1"; - this.maskedTextBox1.Location = new System.Drawing.Point(169, 45); - this.maskedTextBox1.Name = "maskedTextBox1"; - this.maskedTextBox1.Size = new System.Drawing.Size(142, 23); - this.maskedTextBox1.TabIndex = 7; - this.maskedTextBox1.Text = "MaskedTextBox"; - // - // linkLabel1 - // - this.linkLabel1.AccessibleDescription = "IL1"; - this.linkLabel1.AccessibleName = "IL1"; - this.linkLabel1.AutoSize = true; - this.linkLabel1.Location = new System.Drawing.Point(169, 12); - this.linkLabel1.Name = "linkLabel1"; - this.linkLabel1.Size = new System.Drawing.Size(84, 15); - this.linkLabel1.TabIndex = 6; - this.linkLabel1.TabStop = true; - this.linkLabel1.Text = "HomeNumber"; - // - // label2 - // - this.label2.AccessibleDescription = "L2"; - this.label2.AccessibleName = "L2"; - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(37, 224); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(53, 15); - this.label2.TabIndex = 13; - this.label2.Text = "TreeView"; - // - // treeView1 - // - this.treeView1.AccessibleDescription = "TV1"; - this.treeView1.AccessibleName = "TV1"; - this.treeView1.Location = new System.Drawing.Point(12, 242); - this.treeView1.Name = "treeView1"; - this.treeView1.Size = new System.Drawing.Size(129, 101); - this.treeView1.TabIndex = 14; - // - // label3 - // - this.label3.AccessibleDescription = "L3"; - this.label3.AccessibleName = "L3"; - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(244, 225); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(50, 15); - this.label3.TabIndex = 15; - this.label3.Text = "ListView"; - // - // listView1 - // - this.listView1.AccessibleDescription = "LV1"; - this.listView1.AccessibleName = "LV1"; - this.listView1.HideSelection = false; - this.listView1.Location = new System.Drawing.Point(162, 246); - this.listView1.Name = "listView1"; - this.listView1.Size = new System.Drawing.Size(203, 97); - this.listView1.TabIndex = 16; - this.listView1.UseCompatibleStateImageBehavior = false; - this.listView1.View = System.Windows.Forms.View.Details; - // - // label4 - // - this.label4.AccessibleDescription = "L5"; - this.label4.AccessibleName = "L5"; - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(476, 225); - this.label4.Name = "label5"; - this.label4.Size = new System.Drawing.Size(45, 15); - this.label4.TabIndex = 17; - this.label4.Text = "ListBox"; - // - // listBox1 - // - this.listBox1.AccessibleDescription = "LB5"; - this.listBox1.AccessibleName = "LB5"; - this.listBox1.FormattingEnabled = true; - this.listBox1.ItemHeight = 15; - this.listBox1.Location = new System.Drawing.Point(453, 249); - this.listBox1.Name = "listBox1"; - this.listBox1.Size = new System.Drawing.Size(120, 94); - this.listBox1.TabIndex = 18; - // - // DataBindingExample - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(785, 383); - this.Controls.Add(this.dataGridView1); - this.Controls.Add(this.panel1); - this.Controls.Add(this.label2); - this.Controls.Add(this.treeView1); - this.Controls.Add(this.listBox1); - this.Controls.Add(this.label3); - this.Controls.Add(this.listView1); - this.Controls.Add(this.label4); - this.Name = "DataBindingExample"; - this.Text = "DataBindingExampleForControls"; - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); - this.panel1.ResumeLayout(false); - this.panel1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - } - #endregion - private System.Windows.Forms.DataGridView dataGridView1; - private System.Windows.Forms.Panel panel1; - private System.Windows.Forms.ComboBox comboBox1; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.TextBox textBox1; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.LinkLabel linkLabel1; - private System.Windows.Forms.MaskedTextBox maskedTextBox1; - private System.Windows.Forms.CheckBox checkBox1; - private System.Windows.Forms.RichTextBox richTextBox1; - private System.Windows.Forms.DomainUpDown domainUpDown1; - private System.Windows.Forms.NumericUpDown numericUpDown1; - private System.Windows.Forms.RadioButton radioButton1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.TreeView treeView1; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.ListView listView1; - private System.Windows.Forms.Label label4; - private System.Windows.Forms.ListBox listBox1; -} - diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/DataBindingExample.cs b/src/System.Windows.Forms/tests/AccessibilityTests/DataBindingExample.cs deleted file mode 100644 index 9eb2dd5a1fb..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/DataBindingExample.cs +++ /dev/null @@ -1,141 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Data; -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class DataBindingExample : Form -{ - private readonly List _studentA = new(); - private readonly List _studentB = new(); - - public DataBindingExample() - { - InitializeComponent(); - } - - protected override void OnLoad(EventArgs e) - { - BindingData(); - } - - private void BindingData() - { - for (int i = 0; i < 6; i++) - { - _studentA.Add(new Student(i, $"Name 1{i}", "Male")); - _studentB.Add(new Student(i * 2, $"Name 11{i * 2}", "Female")); - } - - // Binding Data For ListBox & ComboBox & CheckedListBox controls by using DataSource property - listBox1.DataSource = _studentA; - comboBox1.DataSource = _studentB; - - listBox1.DisplayMember = nameof(Student.Name); - comboBox1.DisplayMember = nameof(Student.Name); - - // Binding Data For DataGridView control by using DadSource property - dataGridView1.DataSource = new List - { - new Student(1, "StudentA", "Female", 12121, "1001", "Basketball", false, 10, 11), - new Student(2, "StudentB", "Male", 12122, "1002", "Basketball", true, 10, 11), - new Student(3, "StudentC", "Female", 12123, "1003", "Football", false, 10, 11), - new Student(4, "StudentD", "Male", 12124, "1004", "Football", true, 10, 11), - }; - - // Binding Data For TextBox/Label/DomainUpDown/NumericUpDown/LinkLabel/CheckBox/RadioButton/RichTextBox/MaskedTextBox/Button controls by using DadaBindings property - Student stu = new Student(1, "StudentNumber", "Female", 12121, "HomeNumber", "Habits\nBasketball\nFootball", true, 10, 11); - textBox1.DataBindings.Add("Text", stu, "StudentNumber"); - domainUpDown1.DataBindings.Add("Text", stu, "LuckyNumber"); - numericUpDown1.DataBindings.Add("Text", stu, "Count"); - label1.DataBindings.Add("Text", stu, "Name"); - button1.DataBindings.Add("Text", stu, "Sex"); - maskedTextBox1.DataBindings.Add("Text", stu, "PhoneNumber"); - linkLabel1.DataBindings.Add("Text", stu, "HomeNumber"); - richTextBox1.DataBindings.Add("Text", stu, "Hobby"); - checkBox1.DataBindings.Add("Checked", stu, "IsStudent"); - radioButton1.DataBindings.Add("Checked", stu, "IsStudent"); - - // Binding Data For TreeView control by using DataSet - BindTreeView(); - - // Binding Data For ListView control by using DataSet - BindListView(); - } - - private void BindTreeView() - { - using DataSet dataSet = CreateDataSet(); - - if (dataSet.Tables[0].Rows.Count > 0) - { - for (int i = 0; i < dataSet.Tables[0].Rows.Count; i++) - { - TreeNode node = new TreeNode(); - node.Text = dataSet.Tables[0].Rows[i]["StuName"].ToString(); - treeView1.Nodes.Add(node); - } - } - } - - private void BindListView() - { - listView1.View = View.Details; - using DataSet dataSet = CreateDataSet(); - - int row_Count = dataSet.Tables[0].Rows.Count; - int col_Count = dataSet.Tables[0].Columns.Count; - - for (int j = 0; j < col_Count; j++) - { - string colName = dataSet.Tables[0].Columns[j].ColumnName; - listView1.Columns.Add(colName); - } - - for (int i = 0; i < row_Count; i++) - { - string itemName = dataSet.Tables[0].Rows[i][0].ToString(); - ListViewItem item = new ListViewItem(itemName, i); - listView1.Items.Add(item); - - for (int j = 1; j < col_Count; j++) - { - item.SubItems.Add(dataSet.Tables[0].Rows[i][j].ToString()); - } - } - } - - // Create DataSet - public DataSet CreateDataSet() - { - DataSet stuDS = new DataSet(); - DataTable stuTable = new DataTable("Students"); - - stuTable.Columns.Add("StuName", typeof(string)); - stuTable.Columns.Add("StuSex", typeof(string)); - stuTable.Columns.Add("StuAge", typeof(int)); - - DataRow stuRow = stuTable.NewRow(); - stuRow["StuName"] = "sofie"; - stuRow["StuSex"] = "male"; - stuRow["StuAge"] = 21; - stuTable.Rows.Add(stuRow); - - stuRow = stuTable.NewRow(); - stuRow["StuName"] = "Jrain"; - stuRow["StuSex"] = "Female"; - stuRow["StuAge"] = 21; - stuTable.Rows.Add(stuRow); - - stuRow = stuTable.NewRow(); - stuRow["StuName"] = "Lida"; - stuRow["StuSex"] = "male"; - stuRow["StuAge"] = 21; - stuTable.Rows.Add(stuRow); - stuDS.Tables.Add(stuTable); - - return stuDS; - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/DataBindingExample.resx b/src/System.Windows.Forms/tests/AccessibilityTests/DataBindingExample.resx deleted file mode 100644 index da834e20291..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/DataBindingExample.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/DataControls.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/DataControls.Designer.cs deleted file mode 100644 index 76afdf7fb37..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/DataControls.Designer.cs +++ /dev/null @@ -1,405 +0,0 @@ -namespace Accessibility_Core_App; - -partial class DataControls -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DataControls)); - this.bindingNavigator1 = new System.Windows.Forms.BindingNavigator(this.components); - this.bindingNavigatorAddNewItem = new System.Windows.Forms.ToolStripButton(); - this.bindingNavigatorCountItem = new System.Windows.Forms.ToolStripLabel(); - this.bindingNavigatorDeleteItem = new System.Windows.Forms.ToolStripButton(); - this.bindingNavigatorMoveFirstItem = new System.Windows.Forms.ToolStripButton(); - this.bindingNavigatorMovePreviousItem = new System.Windows.Forms.ToolStripButton(); - this.bindingNavigatorSeparator = new System.Windows.Forms.ToolStripSeparator(); - this.bindingNavigatorPositionItem = new System.Windows.Forms.ToolStripTextBox(); - this.bindingNavigatorSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.bindingNavigatorMoveNextItem = new System.Windows.Forms.ToolStripButton(); - this.bindingNavigatorMoveLastItem = new System.Windows.Forms.ToolStripButton(); - this.bindingNavigatorSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); - this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel(); - this.toolStripSplitButton1 = new System.Windows.Forms.ToolStripSplitButton(); - this.toolStripDropDownButton1 = new System.Windows.Forms.ToolStripDropDownButton(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.toolStripComboBox1 = new System.Windows.Forms.ToolStripComboBox(); - this.toolStripTextBox1 = new System.Windows.Forms.ToolStripTextBox(); - this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar(); - this.toolStripLabel2 = new System.Windows.Forms.ToolStripLabel(); - this.dataGridView1 = new System.Windows.Forms.DataGridView(); - this.Column1 = new System.Windows.Forms.DataGridViewButtonColumn(); - this.Column2 = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.Column3 = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.Column4 = new System.Windows.Forms.DataGridViewCheckBoxColumn(); - this.Column5 = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.Column6 = new System.Windows.Forms.DataGridViewImageColumn(); - this.Column7 = new System.Windows.Forms.DataGridViewLinkColumn(); - this.Column8 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridView2 = new System.Windows.Forms.DataGridView(); - this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components); - ((System.ComponentModel.ISupportInitialize)(this.bindingNavigator1)).BeginInit(); - this.bindingNavigator1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).BeginInit(); - this.SuspendLayout(); - // - // bindingNavigator1 - // - this.bindingNavigator1.AddNewItem = this.bindingNavigatorAddNewItem; - this.bindingNavigator1.CountItem = this.bindingNavigatorCountItem; - this.bindingNavigator1.DeleteItem = this.bindingNavigatorDeleteItem; - this.bindingNavigator1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.bindingNavigatorMoveFirstItem, - this.bindingNavigatorMovePreviousItem, - this.bindingNavigatorSeparator, - this.bindingNavigatorPositionItem, - this.bindingNavigatorCountItem, - this.bindingNavigatorSeparator1, - this.bindingNavigatorMoveNextItem, - this.bindingNavigatorMoveLastItem, - this.bindingNavigatorSeparator2, - this.bindingNavigatorAddNewItem, - this.bindingNavigatorDeleteItem, - this.toolStripButton1, - this.toolStripLabel1, - this.toolStripSplitButton1, - this.toolStripDropDownButton1, - this.toolStripSeparator1, - this.toolStripComboBox1, - this.toolStripTextBox1, - this.toolStripProgressBar1, - this.toolStripLabel2}); - this.bindingNavigator1.Location = new System.Drawing.Point(0, 0); - this.bindingNavigator1.MoveFirstItem = this.bindingNavigatorMoveFirstItem; - this.bindingNavigator1.MoveLastItem = this.bindingNavigatorMoveLastItem; - this.bindingNavigator1.MoveNextItem = this.bindingNavigatorMoveNextItem; - this.bindingNavigator1.MovePreviousItem = this.bindingNavigatorMovePreviousItem; - this.bindingNavigator1.Name = "bindingNavigator1"; - this.bindingNavigator1.PositionItem = this.bindingNavigatorPositionItem; - this.bindingNavigator1.Size = new System.Drawing.Size(868, 28); - this.bindingNavigator1.TabIndex = 0; - this.bindingNavigator1.TabStop = true; - this.bindingNavigator1.Text = "bindingNavigator1"; - // - // bindingNavigatorAddNewItem - // - this.bindingNavigatorAddNewItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.bindingNavigatorAddNewItem.Image = ((System.Drawing.Image)(resources.GetObject("bindingNavigatorAddNewItem.Image"))); - this.bindingNavigatorAddNewItem.Name = "bindingNavigatorAddNewItem"; - this.bindingNavigatorAddNewItem.RightToLeftAutoMirrorImage = true; - this.bindingNavigatorAddNewItem.Size = new System.Drawing.Size(23, 25); - this.bindingNavigatorAddNewItem.Text = "Add new"; - this.bindingNavigatorAddNewItem.Click += new System.EventHandler(this.bindingNavigatorAddNewItem_Click); - // - // bindingNavigatorCountItem - // - this.bindingNavigatorCountItem.Name = "bindingNavigatorCountItem"; - this.bindingNavigatorCountItem.Size = new System.Drawing.Size(35, 25); - this.bindingNavigatorCountItem.Text = "of {0}"; - this.bindingNavigatorCountItem.ToolTipText = "Total number of items"; - // - // bindingNavigatorDeleteItem - // - this.bindingNavigatorDeleteItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.bindingNavigatorDeleteItem.Image = ((System.Drawing.Image)(resources.GetObject("bindingNavigatorDeleteItem.Image"))); - this.bindingNavigatorDeleteItem.Name = "bindingNavigatorDeleteItem"; - this.bindingNavigatorDeleteItem.RightToLeftAutoMirrorImage = true; - this.bindingNavigatorDeleteItem.Size = new System.Drawing.Size(23, 25); - this.bindingNavigatorDeleteItem.Text = "Delete"; - // - // bindingNavigatorMoveFirstItem - // - this.bindingNavigatorMoveFirstItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.bindingNavigatorMoveFirstItem.Image = ((System.Drawing.Image)(resources.GetObject("bindingNavigatorMoveFirstItem.Image"))); - this.bindingNavigatorMoveFirstItem.Name = "bindingNavigatorMoveFirstItem"; - this.bindingNavigatorMoveFirstItem.RightToLeftAutoMirrorImage = true; - this.bindingNavigatorMoveFirstItem.Size = new System.Drawing.Size(23, 25); - this.bindingNavigatorMoveFirstItem.Text = "Move first"; - // - // bindingNavigatorMovePreviousItem - // - this.bindingNavigatorMovePreviousItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.bindingNavigatorMovePreviousItem.Image = ((System.Drawing.Image)(resources.GetObject("bindingNavigatorMovePreviousItem.Image"))); - this.bindingNavigatorMovePreviousItem.Name = "bindingNavigatorMovePreviousItem"; - this.bindingNavigatorMovePreviousItem.RightToLeftAutoMirrorImage = true; - this.bindingNavigatorMovePreviousItem.Size = new System.Drawing.Size(23, 25); - this.bindingNavigatorMovePreviousItem.Text = "Move previous"; - // - // bindingNavigatorSeparator - // - this.bindingNavigatorSeparator.Name = "bindingNavigatorSeparator"; - this.bindingNavigatorSeparator.Size = new System.Drawing.Size(6, 28); - // - // bindingNavigatorPositionItem - // - this.bindingNavigatorPositionItem.AccessibleName = "Position"; - this.bindingNavigatorPositionItem.AutoSize = false; - this.bindingNavigatorPositionItem.Name = "bindingNavigatorPositionItem"; - this.bindingNavigatorPositionItem.Size = new System.Drawing.Size(58, 23); - this.bindingNavigatorPositionItem.Text = "0"; - this.bindingNavigatorPositionItem.ToolTipText = "Current position"; - // - // bindingNavigatorSeparator1 - // - this.bindingNavigatorSeparator1.Name = "bindingNavigatorSeparator1"; - this.bindingNavigatorSeparator1.Size = new System.Drawing.Size(6, 28); - // - // bindingNavigatorMoveNextItem - // - this.bindingNavigatorMoveNextItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.bindingNavigatorMoveNextItem.Image = ((System.Drawing.Image)(resources.GetObject("bindingNavigatorMoveNextItem.Image"))); - this.bindingNavigatorMoveNextItem.Name = "bindingNavigatorMoveNextItem"; - this.bindingNavigatorMoveNextItem.RightToLeftAutoMirrorImage = true; - this.bindingNavigatorMoveNextItem.Size = new System.Drawing.Size(23, 25); - this.bindingNavigatorMoveNextItem.Text = "Move next"; - // - // bindingNavigatorMoveLastItem - // - this.bindingNavigatorMoveLastItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.bindingNavigatorMoveLastItem.Image = ((System.Drawing.Image)(resources.GetObject("bindingNavigatorMoveLastItem.Image"))); - this.bindingNavigatorMoveLastItem.Name = "bindingNavigatorMoveLastItem"; - this.bindingNavigatorMoveLastItem.RightToLeftAutoMirrorImage = true; - this.bindingNavigatorMoveLastItem.Size = new System.Drawing.Size(23, 25); - this.bindingNavigatorMoveLastItem.Text = "Move last"; - // - // bindingNavigatorSeparator2 - // - this.bindingNavigatorSeparator2.Name = "bindingNavigatorSeparator2"; - this.bindingNavigatorSeparator2.Size = new System.Drawing.Size(6, 28); - // - // toolStripButton1 - // - this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image"))); - this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButton1.Name = "toolStripButton1"; - this.toolStripButton1.Size = new System.Drawing.Size(114, 25); - this.toolStripButton1.Text = "toolStripButton1"; - // - // toolStripLabel1 - // - this.toolStripLabel1.Name = "toolStripLabel1"; - this.toolStripLabel1.Size = new System.Drawing.Size(86, 25); - this.toolStripLabel1.Text = "toolStripLabel1"; - // - // toolStripSplitButton1 - // - this.toolStripSplitButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripSplitButton1.Image"))); - this.toolStripSplitButton1.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripSplitButton1.Name = "toolStripSplitButton1"; - this.toolStripSplitButton1.Size = new System.Drawing.Size(149, 25); - this.toolStripSplitButton1.Text = "toolStripSplitButton1"; - // - // toolStripDropDownButton1 - // - this.toolStripDropDownButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripDropDownButton1.Image"))); - this.toolStripDropDownButton1.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripDropDownButton1.Name = "toolStripDropDownButton1"; - this.toolStripDropDownButton1.Size = new System.Drawing.Size(180, 25); - this.toolStripDropDownButton1.Text = "toolStripDropDownButton1"; - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(6, 28); - // - // toolStripComboBox1 - // - this.toolStripComboBox1.AccessibleName = "CB1"; - this.toolStripComboBox1.Items.AddRange(new object[] { - "Test1", - "Test2"}); - this.toolStripComboBox1.Name = "toolStripComboBox1"; - this.toolStripComboBox1.Size = new System.Drawing.Size(140, 23); - this.toolStripComboBox1.Text = "Test1"; - // - // toolStripTextBox1 - // - this.toolStripTextBox1.Name = "toolStripTextBox1"; - this.toolStripTextBox1.Size = new System.Drawing.Size(116, 23); - this.toolStripTextBox1.Text = "Test1"; - // - // toolStripProgressBar1 - // - this.toolStripProgressBar1.AccessibleDescription = "This is PB"; - this.toolStripProgressBar1.AccessibleName = "PB1"; - this.toolStripProgressBar1.Name = "toolStripProgressBar1"; - this.toolStripProgressBar1.Size = new System.Drawing.Size(117, 25); - this.toolStripProgressBar1.Tag = "PB"; - this.toolStripProgressBar1.ToolTipText = "ProgressBar1"; - this.toolStripProgressBar1.Value = 50; - // - // toolStripLabel2 - // - this.toolStripLabel2.Name = "toolStripLabel2"; - this.toolStripLabel2.Size = new System.Drawing.Size(282, 15); - this.toolStripLabel2.Text = "The current progress percentage of ProgressBar is 50"; - // - // dataGridView1 - // - this.dataGridView1.AccessibleName = "DGV1"; - this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.Column1, - this.Column2, - this.Column3, - this.Column4, - this.Column5, - this.Column6, - this.Column7, - this.Column8}); - this.dataGridView1.Location = new System.Drawing.Point(13, 323); - this.dataGridView1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.dataGridView1.Name = "dataGridView1"; - this.dataGridView1.Size = new System.Drawing.Size(844, 115); - this.dataGridView1.StandardTab = true; - this.dataGridView1.TabIndex = 2; - // - // Column1 - // - this.Column1.HeaderText = "Name"; - this.Column1.Name = "Column1"; - // - // Column2 - // - this.Column2.HeaderText = "City"; - this.Column2.Items.AddRange(new object[] { - "City1", - "City2"}); - this.Column2.Name = "Column2"; - // - // Column3 - // - this.Column3.DisplayStyle = System.Windows.Forms.DataGridViewComboBoxDisplayStyle.ComboBox; - this.Column3.HeaderText = "Country"; - this.Column3.Items.AddRange(new object[] { - "Country1", - "Country2"}); - this.Column3.Name = "Column3"; - // - // Column4 - // - this.Column4.HeaderText = "IsHealthy"; - this.Column4.Name = "Column4"; - // - // Column5 - // - this.Column5.DisplayStyle = System.Windows.Forms.DataGridViewComboBoxDisplayStyle.Nothing; - this.Column5.HeaderText = "Gender"; - this.Column5.Items.AddRange(new object[] { - "Male", - "Female"}); - this.Column5.Name = "Column5"; - // - // Column6 - // - this.Column6.HeaderText = "Photo"; - this.Column6.Name = "Column6"; - // - // Column7 - // - this.Column7.HeaderText = "Address"; - this.Column7.Name = "Column7"; - this.Column7.Text = "Address1"; - this.Column7.UseColumnTextForLinkValue = true; - // - // Column8 - // - this.Column8.HeaderText = "Comment"; - this.Column8.Name = "Column8"; - // - // dataGridView2 - // - this.dataGridView2.AccessibleName = "DGV2"; - this.dataGridView2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView2.Location = new System.Drawing.Point(13, 46); - this.dataGridView2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.dataGridView2.Name = "dataGridView2"; - this.dataGridView2.Size = new System.Drawing.Size(408, 258); - this.dataGridView2.StandardTab = true; - this.dataGridView2.TabIndex = 1; - // - // DataControls - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoScroll = true; - this.ClientSize = new System.Drawing.Size(868, 450); - this.Controls.Add(this.dataGridView2); - this.Controls.Add(this.dataGridView1); - this.Controls.Add(this.bindingNavigator1); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "DataControls"; - this.Text = "DataControls"; - this.Load += new System.EventHandler(this.DataControls_Load); - ((System.ComponentModel.ISupportInitialize)(this.bindingNavigator1)).EndInit(); - this.bindingNavigator1.ResumeLayout(false); - this.bindingNavigator1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.BindingNavigator bindingNavigator1; - private System.Windows.Forms.ToolStripButton bindingNavigatorAddNewItem; - private System.Windows.Forms.ToolStripLabel bindingNavigatorCountItem; - private System.Windows.Forms.ToolStripButton bindingNavigatorDeleteItem; - private System.Windows.Forms.ToolStripButton bindingNavigatorMoveFirstItem; - private System.Windows.Forms.ToolStripButton bindingNavigatorMovePreviousItem; - private System.Windows.Forms.ToolStripSeparator bindingNavigatorSeparator; - private System.Windows.Forms.ToolStripTextBox bindingNavigatorPositionItem; - private System.Windows.Forms.ToolStripSeparator bindingNavigatorSeparator1; - private System.Windows.Forms.ToolStripButton bindingNavigatorMoveNextItem; - private System.Windows.Forms.ToolStripButton bindingNavigatorMoveLastItem; - private System.Windows.Forms.ToolStripSeparator bindingNavigatorSeparator2; - private System.Windows.Forms.DataGridView dataGridView1; - private System.Windows.Forms.DataGridViewButtonColumn Column1; - private System.Windows.Forms.DataGridViewComboBoxColumn Column2; - private System.Windows.Forms.DataGridViewComboBoxColumn Column3; - private System.Windows.Forms.DataGridViewCheckBoxColumn Column4; - private System.Windows.Forms.DataGridViewComboBoxColumn Column5; - private System.Windows.Forms.DataGridViewImageColumn Column6; - private System.Windows.Forms.DataGridViewLinkColumn Column7; - private System.Windows.Forms.DataGridViewTextBoxColumn Column8; - private System.Windows.Forms.ToolStripButton toolStripButton1; - private System.Windows.Forms.ToolStripLabel toolStripLabel1; - private System.Windows.Forms.ToolStripSplitButton toolStripSplitButton1; - private System.Windows.Forms.ToolStripDropDownButton toolStripDropDownButton1; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1; - private System.Windows.Forms.ToolStripTextBox toolStripTextBox1; - private System.Windows.Forms.ToolStripComboBox toolStripComboBox1; - private System.Windows.Forms.DataGridView dataGridView2; - private System.Windows.Forms.BindingSource bindingSource1; - private System.Windows.Forms.ToolStripLabel toolStripLabel2; -} \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/DataControls.cs b/src/System.Windows.Forms/tests/AccessibilityTests/DataControls.cs deleted file mode 100644 index aec77759dc4..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/DataControls.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Data; -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class DataControls : Form -{ - public DataControls() - { - InitializeComponent(); - } - - private void DataControls_Load(object sender, EventArgs e) - { - DataTable dataTable = new DataTable(); - dataTable.Columns.Add("Name"); - dataTable.Columns.Add("Id"); - dataTable.Columns.Add("Desc"); - for (int i = 0; i < 20; i++) - { - DataRow dataRow = dataTable.NewRow(); - dataRow[0] = $"Jack{i}"; - dataRow[1] = i * 10; - dataRow[2] = $"I like{i}"; - dataTable.Rows.Add(dataRow); - } - - bindingSource1.DataSource = dataTable; - dataGridView2.DataSource = bindingSource1; - bindingNavigator1.BindingSource = bindingSource1; - - dataGridView1.Rows[0].Cells[0].Value = "Rose"; - dataGridView1.CurrentCell = dataGridView1.Rows[0].Cells[0]; - dataGridView1.BeginEdit(false); - DataGridViewComboBoxEditingControl cbox = dataGridView1.EditingControl as DataGridViewComboBoxEditingControl; - if (cbox is not null) - cbox.DroppedDown = true; - } - - private void bindingNavigatorAddNewItem_Click(object sender, EventArgs e) - { - dataGridView2.Focus(); - bindingNavigator1.AccessibilityObject.RaiseAutomationNotification( - System.Windows.Forms.Automation.AutomationNotificationKind.Other, - System.Windows.Forms.Automation.AutomationNotificationProcessing.CurrentThenMostRecent, - "Please enter first name now"); - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/DataControls.resx b/src/System.Windows.Forms/tests/AccessibilityTests/DataControls.resx deleted file mode 100644 index 43467020d76..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/DataControls.resx +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAAUpJREFUOE9jGLzg7gL2/7fmcf6/Oofr/8UZvP+hwsSD60CNfx41/v/zsOH/yckC - pBtwfjov3ICDPSKkG3B8kiBQc93/Pw+q/u9oFydswKWZPP/PTuX7fxKo8Ui/0P993SJAzeX//94r+r++ - Qeb/qhq5/0srFf/PL1X+P6tIFdPAU0B//nlYD9RUC8SV///cKwHivP9/72b+/3sn+f/f23H//92MAOKQ - /5NyNDENONQrDHbu3/ulQI0FQI3ZQI2pQI0J///digZqDPv/70bQ/3/X/f53peliGrCzXeL/lmap/+vA - zpX/v6RC8f/fWzFAjeH/p+Zp/J+QpfW/O0P3f3uq/v/mREPCYTIb6E+Qc//dCPjfk6FDWAM6APnz3w1/ - IPb735qsT7oB3em6YP+CcH2cEekGtCQZ/G+IN/xfE2v8vzLahHQD6AQYGAAkI9iedfyIaQAAAABJRU5E - rkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAAW9JREFUOE+1kE0ow2Ecx3dV3krt4oJaOSCTvIRkMqSxyITIzCQHDouEdnFwIOVC - DrhIDiQl5UTiNG/z2ppafy1S2gX/uDwfY6i1v7Hie3nqeb7fz+/7/FR/Ilwn0G0Exw4fV5GJlXlEZxXC - rIet9bAQvB5Ymgn2sLYAvSZEux7RUQFzE4qQt4bCXAYjPaHvnDoCkLpsRGMB2JqCTGLIijDlwqQ9bEMV - i9OIytR3EMNWcJ/BWH8A6j8/bOGFxwXNxYEvGbMQ9XnQ1/K78KfY3/VXzkMY0qFGG2H4RoLGQshJQNbG - 86CNhdrsX9a/uQZTPhQl4rMY4OLofbl3aX7I8uwPC7y/g1YdjyVJuEvT8e1tfwUYteHUxCCfHChDeHmG - QQvokjlOU+PbWA0x3pZnILVVI3uvQyHsbiLnqnGmRCF1NYD8pDhpRxOH7HQoAKZGkFKjceszQbpSrumX - bO+G80MFwKUTxgfgcO/b8D9IpXoFiiMDHIQm0skAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAASpJREFUOE9jGDygcNbz/00Lnv/PnPj4P1QIA4S3P8Apx5A789n/VUfe/8elKL77 - wf/ghmu4DciY8vT/wn0fsCqK73n4f+n+///9qy/gNiCh58n/aVveYyiKaL8P1pw56/9/r9ITuA2I7Hr0 - v3f1BxRFoa33wJpb1wFt7/z73yX/AG4DApsf/q+b/w6uKLjl7v9Fe///7wBqzpjz879d3c//9hnbcRvg - UXX/f/60NyiK7Ipv/0+f8/u/f9e3/zqF7/5bJKzHbYB96d3/2ZNfYyjSTzn/36ToxX+VrE//jSOX4TbA - Iu/O/9T+11gVGSSd+C+b9vW/bvA83AYYZt3+H9byEqci/dTL/zV8p+E2QCftxn+/6od4Fal4TMBtgFPu - lf8gBXgVDULAwAAA8HbAq6XlmnAAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALZJREFUOE9jGDogvP3BfyiTdBDf/eB/cMM18gyI73n4f+n+///9qy+QbkBE+32w - 5sxZ//97lZ4gzYDQ1ntgza3rgLZ3/v3vkn+AeAOCW+7+X7T3//8OoOaMOT//29X9/G+fsZ00F9gV3/6f - Puf3f/+ub/91Ct/9t0hYT3oY6Kec/29S9OK/Stan/8aRy0g3AAQMkk78l037+l83eB55BoCAfurl/xq+ - 08g3AARUPCZQZsBgBQwMANAUYJgEulBVAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAAKNJREFUOE9jGHygcNbz/1AmeSB35rP/Cd33yDckY8rT//P2//6f0HWHPEMSep78 - n73v1//OrX//u5VeJt2QyK5H/6ds+/W/ZOnf/wnT//63yT1LmiGBzQ//t659D9ZsXPLlv3T0tf/GkcuI - N8Sj6v7/krnv4JoVXXpIc4F96d3/gS3PyNMMAhZ5d/7bFFwhTzMIGGbdJl8zCOik3SBf81AEDAwAoH5f - oAc0QjgAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAASxJREFUOE9jGFygcNbz/1AmBgDJNS14/j9z4mOcahhyZz77n9B9D6sCkNyqI+// - h7c/wG1AxpSn/+ft//0/oesOhiKQ3MJ9H/4HN1zDbUBCz5P/s/f9+t+59e9/t9LLKApBctO2vP/vX30B - twGRXY/+T9n263/J0r//E6b//W+TexauGCTXu/rDf6/SE7gNCGx++L917XuwZuOSL/+lo6/9N45cBtYA - kqub/+6/S/4B3AZ4VN3/XzL3HVyzoksPXDFILn/am//2GdtxG2Bfevd/YMszDM0gAJLLnvz6v0XCetwG - WOTd+W9TcAVDMwiA5FL7X8O9hBUYZt3GqhkEQHJhLS//6wbPw22ATtoNnJIgOb/qh/81fKfhNgAfcMq9 - 8l/FYwIYQ4UGBWBgAAC+0b+zuQxOnAAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG - YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 - 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw - bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc - VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 - c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 - Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo - mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ - kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D - TgDQASA1MVpwzwAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG - YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 - 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw - bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc - VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 - c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 - Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo - mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ - kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D - TgDQASA1MVpwzwAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG - YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 - 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw - bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc - VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 - c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 - Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo - mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ - kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D - TgDQASA1MVpwzwAAAABJRU5ErkJggg== - - - - True - - - True - - - True - - - True - - - True - - - True - - - 17, 17 - - - 45 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/DialogControls.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/DialogControls.Designer.cs deleted file mode 100644 index 539f0f8c598..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/DialogControls.Designer.cs +++ /dev/null @@ -1,102 +0,0 @@ -namespace Accessibility_Core_App; - -partial class DialogControls -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.ColorDialog = new System.Windows.Forms.Button(); - this.FolderBrowserDialog = new System.Windows.Forms.Button(); - this.OpenFileDialog = new System.Windows.Forms.Button(); - this.SaveFileDialog = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // ColorDialog - // - this.ColorDialog.Location = new System.Drawing.Point(42, 12); - this.ColorDialog.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.ColorDialog.Name = "ColorDialog"; - this.ColorDialog.Size = new System.Drawing.Size(88, 27); - this.ColorDialog.TabIndex = 0; - this.ColorDialog.Text = "ColorDialog"; - this.ColorDialog.UseVisualStyleBackColor = true; - this.ColorDialog.Click += new System.EventHandler(this.ColorDialog_Click); - // - // FolderBrowserDialog - // - this.FolderBrowserDialog.Location = new System.Drawing.Point(42, 67); - this.FolderBrowserDialog.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.FolderBrowserDialog.Name = "FolderBrowserDialog"; - this.FolderBrowserDialog.Size = new System.Drawing.Size(153, 27); - this.FolderBrowserDialog.TabIndex = 1; - this.FolderBrowserDialog.Text = "FolderBrowserDialog"; - this.FolderBrowserDialog.UseVisualStyleBackColor = true; - this.FolderBrowserDialog.Click += new System.EventHandler(this.FolderBrowserDialog_Click); - // - // OpenFileDialog - // - this.OpenFileDialog.Location = new System.Drawing.Point(42, 125); - this.OpenFileDialog.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.OpenFileDialog.Name = "OpenFileDialog"; - this.OpenFileDialog.Size = new System.Drawing.Size(108, 27); - this.OpenFileDialog.TabIndex = 2; - this.OpenFileDialog.Text = "OpenFileDialog"; - this.OpenFileDialog.UseVisualStyleBackColor = true; - this.OpenFileDialog.Click += new System.EventHandler(this.OpenFileDialog_Click); - // - // SaveFileDialog - // - this.SaveFileDialog.Location = new System.Drawing.Point(42, 181); - this.SaveFileDialog.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.SaveFileDialog.Name = "SaveFileDialog"; - this.SaveFileDialog.Size = new System.Drawing.Size(114, 27); - this.SaveFileDialog.TabIndex = 3; - this.SaveFileDialog.Text = "SaveFileDialog"; - this.SaveFileDialog.UseVisualStyleBackColor = true; - this.SaveFileDialog.Click += new System.EventHandler(this.SaveFileDialog_Click); - // - // DialogControls - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(268, 233); - this.Controls.Add(this.SaveFileDialog); - this.Controls.Add(this.OpenFileDialog); - this.Controls.Add(this.FolderBrowserDialog); - this.Controls.Add(this.ColorDialog); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "DialogControls"; - this.Text = "DialogsTesting"; - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.Button ColorDialog; - private System.Windows.Forms.Button FolderBrowserDialog; - private System.Windows.Forms.Button OpenFileDialog; - private System.Windows.Forms.Button SaveFileDialog; -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/DialogControls.cs b/src/System.Windows.Forms/tests/AccessibilityTests/DialogControls.cs deleted file mode 100644 index 7c46a47388c..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/DialogControls.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class DialogControls : Form -{ - public DialogControls() - { - InitializeComponent(); - } - - private void ColorDialog_Click(object sender, EventArgs e) - { - ColorDialog colorDialog = new ColorDialog(); - colorDialog.ShowDialog(); - } - - private void FolderBrowserDialog_Click(object sender, EventArgs e) - { - FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog(); - folderBrowserDialog.ShowDialog(); - } - - private void OpenFileDialog_Click(object sender, EventArgs e) - { - OpenFileDialog openFileDialog = new OpenFileDialog(); - openFileDialog.ShowDialog(); - } - - private void SaveFileDialog_Click(object sender, EventArgs e) - { - SaveFileDialog saveFileDialog = new SaveFileDialog(); - saveFileDialog.ShowDialog(); - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/DialogControls.resx b/src/System.Windows.Forms/tests/AccessibilityTests/DialogControls.resx deleted file mode 100644 index 1af7de150c9..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/DialogControls.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/HTMLPage1.html b/src/System.Windows.Forms/tests/AccessibilityTests/HTMLPage1.html deleted file mode 100644 index b2cd84084d4..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/HTMLPage1.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - Test Title - - -

This is my HTML Doc

- This is some normal text -
    -
  1. One
  2. -
  3. Two
  4. -
- - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Main.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/Main.Designer.cs deleted file mode 100644 index 209f4f1ba4e..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Main.Designer.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System.Windows.Forms; -namespace Accessibility_Core_App; - -partial class Main -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.button1 = new System.Windows.Forms.Button(); - this.button2 = new System.Windows.Forms.Button(); - this.button3 = new System.Windows.Forms.Button(); - this.button4 = new System.Windows.Forms.Button(); - this.button5 = new System.Windows.Forms.Button(); - this.button6 = new System.Windows.Forms.Button(); - this.button7 = new System.Windows.Forms.Button(); - this.button8 = new System.Windows.Forms.Button(); - this.button9 = new System.Windows.Forms.Button(); - this.button10 = new System.Windows.Forms.Button(); - this.button11 = new System.Windows.Forms.Button(); - this.button12 = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // button1 - // - this.button1.Location = new System.Drawing.Point(14, 14); - this.button1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(531, 27); - this.button1.TabIndex = 0; - this.button1.Text = "Common_Controls1: Testing the controls under the Common_Controls Tab"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.Button1_Click); - // - // button2 - // - this.button2.Location = new System.Drawing.Point(14, 60); - this.button2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(531, 27); - this.button2.TabIndex = 1; - this.button2.Text = "Common_Controls2: Testing the controls under the Common_Controls Tab"; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.Button2_Click); - // - // button3 - // - this.button3.Location = new System.Drawing.Point(13, 105); - this.button3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button3.Name = "button3"; - this.button3.Size = new System.Drawing.Size(531, 27); - this.button3.TabIndex = 2; - this.button3.Text = "Data_Controls: Testing the controls under the Data Tab"; - this.button3.UseVisualStyleBackColor = true; - this.button3.Click += new System.EventHandler(this.Button3_Click); - // - // button4 - // - this.button4.Location = new System.Drawing.Point(13, 152); - this.button4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button4.Name = "button4"; - this.button4.Size = new System.Drawing.Size(531, 27); - this.button4.TabIndex = 3; - this.button4.Text = "Dialogs_Controls: Testing the controls under the Dialogs Tab"; - this.button4.UseVisualStyleBackColor = true; - this.button4.Click += new System.EventHandler(this.Button4_Click); - // - // button5 - // - this.button5.Location = new System.Drawing.Point(13, 199); - this.button5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button5.Name = "button5"; - this.button5.Size = new System.Drawing.Size(531, 27); - this.button5.TabIndex = 4; - this.button5.Text = "MenuToolbars_Controls: Testing the controls under the Menu & Toolbars Tab"; - this.button5.UseVisualStyleBackColor = true; - this.button5.Click += new System.EventHandler(this.Button5_Click); - // - // button6 - // - this.button6.Location = new System.Drawing.Point(14, 247); - this.button6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button6.Name = "button6"; - this.button6.Size = new System.Drawing.Size(531, 27); - this.button6.TabIndex = 5; - this.button6.Text = "Printing_Controls: Testing the controls under the Printing Tab"; - this.button6.UseVisualStyleBackColor = true; - this.button6.Click += new System.EventHandler(this.Button6_Click); - // - // button7 - // - this.button7.Location = new System.Drawing.Point(13, 292); - this.button7.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button7.Name = "button7"; - this.button7.Size = new System.Drawing.Size(531, 27); - this.button7.TabIndex = 6; - this.button7.Text = "Remaining_Controls_Testing"; - this.button7.UseVisualStyleBackColor = true; - this.button7.Click += new System.EventHandler(this.Button7_Click); - // - // button8 - // - this.button8.Location = new System.Drawing.Point(14, 336); - this.button8.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button8.Name = "button8"; - this.button8.Size = new System.Drawing.Size(531, 27); - this.button8.TabIndex = 7; - this.button8.Text = "Containers_Controls: Testing the controls under the Containers Tab"; - this.button8.UseVisualStyleBackColor = true; - this.button8.Click += new System.EventHandler(this.Button8_Click); - // - // button9 - // - this.button9.Location = new System.Drawing.Point(13, 380); - this.button9.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button9.Name = "button9"; - this.button9.Size = new System.Drawing.Size(531, 27); - this.button9.TabIndex = 8; - this.button9.Text = "Containers_Controls_2: Testing the controls under the Containers Tab"; - this.button9.UseVisualStyleBackColor = true; - this.button9.Click += new System.EventHandler(this.button9_Click); - // - // button10 - // - this.button10.Location = new System.Drawing.Point(14, 425); - this.button10.Name = "button10"; - this.button10.Size = new System.Drawing.Size(530, 27); - this.button10.TabIndex = 9; - this.button10.Text = "TaskDialog: Testing the task dialog"; - this.button10.UseVisualStyleBackColor = true; - this.button10.Click += new System.EventHandler(this.button10_Click); - // - // button11 - // - this.button11.Location = new System.Drawing.Point(14, 469); - this.button11.Name = "button11"; - this.button11.Size = new System.Drawing.Size(530, 28); - this.button11.TabIndex = 10; - this.button11.Text = "Accessible properties: Testing controls with custom accessible name, role, and de" + -"scription"; - this.button11.UseVisualStyleBackColor = true; - this.button11.Click += new System.EventHandler(this.button11_Click); - // - // button12 - // - this.button12.Location = new System.Drawing.Point(14, 514); - this.button12.Name = "button12"; - this.button12.Size = new System.Drawing.Size(530, 23); - this.button12.TabIndex = 11; - this.button12.Text = "DataBinding Example"; - this.button12.UseVisualStyleBackColor = true; - this.button12.Click += new System.EventHandler(this.button12_Click); - // - // Main - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(576, 538); - this.Controls.Add(this.button12); - this.Controls.Add(this.button11); - this.Controls.Add(this.button10); - this.Controls.Add(this.button9); - this.Controls.Add(this.button8); - this.Controls.Add(this.button7); - this.Controls.Add(this.button6); - this.Controls.Add(this.button5); - this.Controls.Add(this.button4); - this.Controls.Add(this.button3); - this.Controls.Add(this.button2); - this.Controls.Add(this.button1); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "Main"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "MainForm"; - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.Button button1; - private System.Windows.Forms.Button button2; - private System.Windows.Forms.Button button3; - private System.Windows.Forms.Button button4; - private System.Windows.Forms.Button button5; - private System.Windows.Forms.Button button6; - private System.Windows.Forms.Button button7; - private System.Windows.Forms.Button button8; - private Button button9; - private Button button10; - private Button button11; - private Button button12; -} - diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Main.cs b/src/System.Windows.Forms/tests/AccessibilityTests/Main.cs deleted file mode 100644 index 6655cf4f2e1..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Main.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class Main : Form -{ - public Main() - { - InitializeComponent(); - } - - private void Button1_Click(object sender, EventArgs e) - { - CommonControl1 commonControl1 = new CommonControl1(); - commonControl1.Show(); - } - - private void Button2_Click(object sender, EventArgs e) - { - CommonControl2 commonControl2 = new CommonControl2(); - commonControl2.Show(); - } - - private void Button3_Click(object sender, EventArgs e) - { - DataControls dataControls = new DataControls(); - dataControls.Show(); - } - - private void Button4_Click(object sender, EventArgs e) - { - DialogControls dialogsTesting = new DialogControls(); - dialogsTesting.Show(); - } - - private void Button5_Click(object sender, EventArgs e) - { - MenuForm menuForm = new MenuForm(); - menuForm.Show(); - } - - private void Button6_Click(object sender, EventArgs e) - { - PrintingControls printingTesting = new PrintingControls(); - printingTesting.Show(); - } - - private void Button7_Click(object sender, EventArgs e) - { - RemainingControls remainingControls = new RemainingControls(); - remainingControls.Show(); - } - - private void Button8_Click(object sender, EventArgs e) - { - ContainerControls containerControl = new ContainerControls(); - containerControl.Show(); - } - - private void button9_Click(object sender, EventArgs e) - { - ContainerControls2 containerControl2 = new ContainerControls2(); - containerControl2.Show(); - } - - private void button10_Click(object sender, EventArgs e) - { - TaskDialogTesting taskDialogTesting = new(); - taskDialogTesting.ShowEventsDemoTaskDialog(); - } - - private void button11_Click(object sender, EventArgs e) - { - CustomAccessiblePropertiesForm cusAcccName = new(); - cusAcccName.StartPosition = FormStartPosition.CenterParent; - cusAcccName.Show(); - } - - private void button12_Click(object sender, EventArgs e) - { - DataBindingExample dataBindingExample = new(); - dataBindingExample.Show(); - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Main.resx b/src/System.Windows.Forms/tests/AccessibilityTests/Main.resx deleted file mode 100644 index f298a7be809..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Main.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/MenuForm.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/MenuForm.Designer.cs deleted file mode 100644 index a6beab9d4e0..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/MenuForm.Designer.cs +++ /dev/null @@ -1,75 +0,0 @@ -namespace Accessibility_Core_App; - -partial class MenuForm -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.button1 = new System.Windows.Forms.Button(); - this.button2 = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // button1 - // - this.button1.Location = new System.Drawing.Point(78, 46); - this.button1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(88, 27); - this.button1.TabIndex = 0; - this.button1.Text = "StripControls"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.Button1_Click); - // - // button2 - // - this.button2.Location = new System.Drawing.Point(264, 46); - this.button2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(122, 27); - this.button2.TabIndex = 1; - this.button2.Text = "ToolStripContainer"; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.Button2_Click); - // - // MenuForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(467, 441); - this.Controls.Add(this.button2); - this.Controls.Add(this.button1); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "MenuForm"; - this.Text = "MenuForm"; - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.Button button1; - private System.Windows.Forms.Button button2; -} \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/MenuForm.cs b/src/System.Windows.Forms/tests/AccessibilityTests/MenuForm.cs deleted file mode 100644 index 5b1b8b801df..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/MenuForm.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class MenuForm : Form -{ - public MenuForm() - { - InitializeComponent(); - } - - private void Button1_Click(object sender, EventArgs e) - { - Menu_Toolbars_controls stripControls = new Menu_Toolbars_controls(); - stripControls.Show(); - } - - private void Button2_Click(object sender, EventArgs e) - { - ToolStripContainer toolStripContainer = new ToolStripContainer(); - toolStripContainer.Show(); - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/MenuForm.resx b/src/System.Windows.Forms/tests/AccessibilityTests/MenuForm.resx deleted file mode 100644 index f298a7be809..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/MenuForm.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Menu_Toolbars_controls.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/Menu_Toolbars_controls.Designer.cs deleted file mode 100644 index 6f4690171e5..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Menu_Toolbars_controls.Designer.cs +++ /dev/null @@ -1,679 +0,0 @@ -using System.Drawing; -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -partial class Menu_Toolbars_controls -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - -/// -/// Clean up any resources being used. -/// -/// true if managed resources should be disposed; otherwise, false. -protected override void Dispose(bool disposing) -{ - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); -} - -#region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Menu_Toolbars_controls)); - menuStrip1 = new MenuStrip(); - contextMenuStrip1 = new ContextMenuStrip(components); - menuStripToolStripMenuItem = new ToolStripMenuItem(); - item1ToolStripMenuItem = new ToolStripMenuItem(); - shortCutsToolStripMenuItem = new ToolStripMenuItem(); - item2ToolStripMenuItem = new ToolStripMenuItem(); - fileToolStripMenuItem = new ToolStripMenuItem(); - newToolStripMenuItem = new ToolStripMenuItem(); - openToolStripMenuItem = new ToolStripMenuItem(); - toolStripSeparator = new ToolStripSeparator(); - saveToolStripMenuItem = new ToolStripMenuItem(); - saveAsToolStripMenuItem = new ToolStripMenuItem(); - toolStripSeparator1 = new ToolStripSeparator(); - printToolStripMenuItem = new ToolStripMenuItem(); - printPreviewToolStripMenuItem = new ToolStripMenuItem(); - toolStripSeparator2 = new ToolStripSeparator(); - exitToolStripMenuItem = new ToolStripMenuItem(); - editToolStripMenuItem = new ToolStripMenuItem(); - undoToolStripMenuItem = new ToolStripMenuItem(); - redoToolStripMenuItem = new ToolStripMenuItem(); - toolStripSeparator3 = new ToolStripSeparator(); - cutToolStripMenuItem = new ToolStripMenuItem(); - copyToolStripMenuItem = new ToolStripMenuItem(); - pasteToolStripMenuItem = new ToolStripMenuItem(); - toolStripSeparator4 = new ToolStripSeparator(); - selectAllToolStripMenuItem = new ToolStripMenuItem(); - toolsToolStripMenuItem = new ToolStripMenuItem(); - customizeToolStripMenuItem = new ToolStripMenuItem(); - optionsToolStripMenuItem = new ToolStripMenuItem(); - helpToolStripMenuItem = new ToolStripMenuItem(); - contentsToolStripMenuItem = new ToolStripMenuItem(); - indexToolStripMenuItem = new ToolStripMenuItem(); - searchToolStripMenuItem = new ToolStripMenuItem(); - toolStripSeparator5 = new ToolStripSeparator(); - aboutToolStripMenuItem = new ToolStripMenuItem(); - toolStripMenuItem1 = new ToolStripMenuItem(); - uncheckedCheckOnClickToolStripMenuItem = new ToolStripMenuItem(); - checkCheckOnClickToolStripMenuItem = new ToolStripMenuItem(); - checkedCheckOnClickFToolStripMenuItem = new ToolStripMenuItem(); - indeterminateToolStripMenuItem = new ToolStripMenuItem(); - indeterminateCheckOnClickFToolStripMenuItem = new ToolStripMenuItem(); - toolStripComboBox1 = new ToolStripComboBox(); - toolStripTextBox1 = new ToolStripTextBox(); - statusStrip1 = new StatusStrip(); - toolStripDropDownButton1 = new ToolStripDropDownButton(); - toolStripSeparator9 = new ToolStripSeparator(); - toolStripTextBox3 = new ToolStripTextBox(); - toolStripMenuItem3 = new ToolStripMenuItem(); - toolStripSplitButton1 = new ToolStripSplitButton(); - toolStripTextBox2 = new ToolStripTextBox(); - toolStripSeparator8 = new ToolStripSeparator(); - toolStripComboBox2 = new ToolStripComboBox(); - toolStripMenuItem2 = new ToolStripMenuItem(); - toolStripStatusLabel1 = new ToolStripStatusLabel(); - toolStripProgressBar1 = new ToolStripProgressBar(); - toolStrip1 = new ToolStrip(); - newToolStripButton = new ToolStripButton(); - toolStripSeparator7 = new ToolStripSeparator(); - toolStripButton1 = new ToolStripButton(); - toolStripButton2 = new ToolStripButton(); - toolStripButton3 = new ToolStripButton(); - toolStripButton4 = new ToolStripButton(); - toolStripButton5 = new ToolStripButton(); - toolStripButton6 = new ToolStripButton(); - menuStrip1.SuspendLayout(); - contextMenuStrip1.SuspendLayout(); - statusStrip1.SuspendLayout(); - toolStrip1.SuspendLayout(); - SuspendLayout(); - // - // menuStrip1 - // - menuStrip1.ContextMenuStrip = contextMenuStrip1; - menuStrip1.ImageScalingSize = new Size(20, 20); - menuStrip1.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem, editToolStripMenuItem, toolsToolStripMenuItem, helpToolStripMenuItem, toolStripMenuItem1, toolStripComboBox1, toolStripTextBox1 }); - menuStrip1.Location = new Point(0, 0); - menuStrip1.Name = "menuStrip1"; - menuStrip1.Padding = new Padding(8, 3, 0, 3); - menuStrip1.ShowItemToolTips = true; - menuStrip1.Size = new Size(1287, 34); - menuStrip1.TabIndex = 0; - menuStrip1.TabStop = true; - menuStrip1.Text = "menuStrip1"; - // - // contextMenuStrip1 - // - contextMenuStrip1.ImageScalingSize = new Size(20, 20); - contextMenuStrip1.Items.AddRange(new ToolStripItem[] { menuStripToolStripMenuItem, shortCutsToolStripMenuItem }); - contextMenuStrip1.Name = "contextMenuStrip1"; - contextMenuStrip1.Size = new Size(147, 52); - contextMenuStrip1.TabStop = true; - // - // menuStripToolStripMenuItem - // - menuStripToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { item1ToolStripMenuItem }); - menuStripToolStripMenuItem.Name = "menuStripToolStripMenuItem"; - menuStripToolStripMenuItem.Size = new Size(146, 24); - menuStripToolStripMenuItem.Text = "MenuStrip"; - // - // item1ToolStripMenuItem - // - item1ToolStripMenuItem.Name = "item1ToolStripMenuItem"; - item1ToolStripMenuItem.Size = new Size(130, 26); - item1ToolStripMenuItem.Text = "Item1"; - // - // shortCutsToolStripMenuItem - // - shortCutsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { item2ToolStripMenuItem }); - shortCutsToolStripMenuItem.Name = "shortCutsToolStripMenuItem"; - shortCutsToolStripMenuItem.Size = new Size(146, 24); - shortCutsToolStripMenuItem.Text = "ShortCuts"; - // - // item2ToolStripMenuItem - // - item2ToolStripMenuItem.Name = "item2ToolStripMenuItem"; - item2ToolStripMenuItem.Size = new Size(130, 26); - item2ToolStripMenuItem.Text = "Item2"; - // - // fileToolStripMenuItem - // - fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { newToolStripMenuItem, openToolStripMenuItem, toolStripSeparator, saveToolStripMenuItem, saveAsToolStripMenuItem, toolStripSeparator1, printToolStripMenuItem, printPreviewToolStripMenuItem, toolStripSeparator2, exitToolStripMenuItem }); - fileToolStripMenuItem.Name = "fileToolStripMenuItem"; - fileToolStripMenuItem.Size = new Size(46, 28); - fileToolStripMenuItem.Text = "&File"; - fileToolStripMenuItem.ToolTipText = "File"; - // - // newToolStripMenuItem - // - newToolStripMenuItem.Image = (Image)resources.GetObject("newToolStripMenuItem.Image"); - newToolStripMenuItem.ImageTransparentColor = Color.Magenta; - newToolStripMenuItem.Name = "newToolStripMenuItem"; - newToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.N; - newToolStripMenuItem.Size = new Size(181, 26); - newToolStripMenuItem.Text = "&New"; - // - // openToolStripMenuItem - // - openToolStripMenuItem.Image = (Image)resources.GetObject("openToolStripMenuItem.Image"); - openToolStripMenuItem.ImageTransparentColor = Color.Magenta; - openToolStripMenuItem.Name = "openToolStripMenuItem"; - openToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.O; - openToolStripMenuItem.Size = new Size(181, 26); - openToolStripMenuItem.Text = "&Open"; - // - // toolStripSeparator - // - toolStripSeparator.Name = "toolStripSeparator"; - toolStripSeparator.Size = new Size(178, 6); - // - // saveToolStripMenuItem - // - saveToolStripMenuItem.Image = (Image)resources.GetObject("saveToolStripMenuItem.Image"); - saveToolStripMenuItem.ImageTransparentColor = Color.Magenta; - saveToolStripMenuItem.Name = "saveToolStripMenuItem"; - saveToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.S; - saveToolStripMenuItem.Size = new Size(181, 26); - saveToolStripMenuItem.Text = "&Save"; - // - // saveAsToolStripMenuItem - // - saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; - saveAsToolStripMenuItem.Size = new Size(181, 26); - saveAsToolStripMenuItem.Text = "Save &As"; - // - // toolStripSeparator1 - // - toolStripSeparator1.Name = "toolStripSeparator1"; - toolStripSeparator1.Size = new Size(178, 6); - // - // printToolStripMenuItem - // - printToolStripMenuItem.Image = (Image)resources.GetObject("printToolStripMenuItem.Image"); - printToolStripMenuItem.ImageTransparentColor = Color.Magenta; - printToolStripMenuItem.Name = "printToolStripMenuItem"; - printToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.P; - printToolStripMenuItem.Size = new Size(181, 26); - printToolStripMenuItem.Text = "&Print"; - // - // printPreviewToolStripMenuItem - // - printPreviewToolStripMenuItem.Image = (Image)resources.GetObject("printPreviewToolStripMenuItem.Image"); - printPreviewToolStripMenuItem.ImageTransparentColor = Color.Magenta; - printPreviewToolStripMenuItem.Name = "printPreviewToolStripMenuItem"; - printPreviewToolStripMenuItem.Size = new Size(181, 26); - printPreviewToolStripMenuItem.Text = "Print Pre&view"; - // - // toolStripSeparator2 - // - toolStripSeparator2.Name = "toolStripSeparator2"; - toolStripSeparator2.Size = new Size(178, 6); - // - // exitToolStripMenuItem - // - exitToolStripMenuItem.Name = "exitToolStripMenuItem"; - exitToolStripMenuItem.Size = new Size(181, 26); - exitToolStripMenuItem.Text = "E&xit"; - // - // editToolStripMenuItem - // - editToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { undoToolStripMenuItem, redoToolStripMenuItem, toolStripSeparator3, cutToolStripMenuItem, copyToolStripMenuItem, pasteToolStripMenuItem, toolStripSeparator4, selectAllToolStripMenuItem }); - editToolStripMenuItem.Name = "editToolStripMenuItem"; - editToolStripMenuItem.Size = new Size(49, 28); - editToolStripMenuItem.Text = "&Edit"; - editToolStripMenuItem.ToolTipText = "Edit"; - // - // undoToolStripMenuItem - // - undoToolStripMenuItem.Name = "undoToolStripMenuItem"; - undoToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.Z; - undoToolStripMenuItem.Size = new Size(179, 26); - undoToolStripMenuItem.Text = "&Undo"; - // - // redoToolStripMenuItem - // - redoToolStripMenuItem.Name = "redoToolStripMenuItem"; - redoToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.Y; - redoToolStripMenuItem.Size = new Size(179, 26); - redoToolStripMenuItem.Text = "&Redo"; - // - // toolStripSeparator3 - // - toolStripSeparator3.Name = "toolStripSeparator3"; - toolStripSeparator3.Size = new Size(176, 6); - // - // cutToolStripMenuItem - // - cutToolStripMenuItem.Image = (Image)resources.GetObject("cutToolStripMenuItem.Image"); - cutToolStripMenuItem.ImageTransparentColor = Color.Magenta; - cutToolStripMenuItem.Name = "cutToolStripMenuItem"; - cutToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.X; - cutToolStripMenuItem.Size = new Size(179, 26); - cutToolStripMenuItem.Text = "Cu&t"; - // - // copyToolStripMenuItem - // - copyToolStripMenuItem.Image = (Image)resources.GetObject("copyToolStripMenuItem.Image"); - copyToolStripMenuItem.ImageTransparentColor = Color.Magenta; - copyToolStripMenuItem.Name = "copyToolStripMenuItem"; - copyToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.C; - copyToolStripMenuItem.Size = new Size(179, 26); - copyToolStripMenuItem.Text = "&Copy"; - // - // pasteToolStripMenuItem - // - pasteToolStripMenuItem.Image = (Image)resources.GetObject("pasteToolStripMenuItem.Image"); - pasteToolStripMenuItem.ImageTransparentColor = Color.Magenta; - pasteToolStripMenuItem.Name = "pasteToolStripMenuItem"; - pasteToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.V; - pasteToolStripMenuItem.Size = new Size(179, 26); - pasteToolStripMenuItem.Text = "&Paste"; - // - // toolStripSeparator4 - // - toolStripSeparator4.Name = "toolStripSeparator4"; - toolStripSeparator4.Size = new Size(176, 6); - // - // selectAllToolStripMenuItem - // - selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem"; - selectAllToolStripMenuItem.Size = new Size(179, 26); - selectAllToolStripMenuItem.Text = "Select &All"; - // - // toolsToolStripMenuItem - // - toolsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { customizeToolStripMenuItem, optionsToolStripMenuItem }); - toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; - toolsToolStripMenuItem.Size = new Size(58, 28); - toolsToolStripMenuItem.Text = "&Tools"; - toolsToolStripMenuItem.ToolTipText = "Tools"; - // - // customizeToolStripMenuItem - // - customizeToolStripMenuItem.Name = "customizeToolStripMenuItem"; - customizeToolStripMenuItem.Size = new Size(161, 26); - customizeToolStripMenuItem.Text = "&Customize"; - // - // optionsToolStripMenuItem - // - optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; - optionsToolStripMenuItem.Size = new Size(161, 26); - optionsToolStripMenuItem.Text = "&Options"; - // - // helpToolStripMenuItem - // - helpToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { contentsToolStripMenuItem, indexToolStripMenuItem, searchToolStripMenuItem, toolStripSeparator5, aboutToolStripMenuItem }); - helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - helpToolStripMenuItem.Size = new Size(55, 28); - helpToolStripMenuItem.Text = "&Help"; - helpToolStripMenuItem.ToolTipText = "Help"; - // - // contentsToolStripMenuItem - // - contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; - contentsToolStripMenuItem.Size = new Size(150, 26); - contentsToolStripMenuItem.Text = "&Contents"; - // - // indexToolStripMenuItem - // - indexToolStripMenuItem.Name = "indexToolStripMenuItem"; - indexToolStripMenuItem.Size = new Size(150, 26); - indexToolStripMenuItem.Text = "&Index"; - // - // searchToolStripMenuItem - // - searchToolStripMenuItem.Name = "searchToolStripMenuItem"; - searchToolStripMenuItem.Size = new Size(150, 26); - searchToolStripMenuItem.Text = "&Search"; - // - // toolStripSeparator5 - // - toolStripSeparator5.Name = "toolStripSeparator5"; - toolStripSeparator5.Size = new Size(147, 6); - // - // aboutToolStripMenuItem - // - aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; - aboutToolStripMenuItem.Size = new Size(150, 26); - aboutToolStripMenuItem.Text = "&About..."; - // - // toolStripMenuItem1 - // - toolStripMenuItem1.DropDownItems.AddRange(new ToolStripItem[] { uncheckedCheckOnClickToolStripMenuItem, checkCheckOnClickToolStripMenuItem, checkedCheckOnClickFToolStripMenuItem, indeterminateToolStripMenuItem, indeterminateCheckOnClickFToolStripMenuItem }); - toolStripMenuItem1.Name = "toolStripMenuItem1"; - toolStripMenuItem1.Size = new Size(156, 28); - toolStripMenuItem1.Text = "CheckState Samples"; - toolStripMenuItem1.ToolTipText = "CheckState Samples"; - // - // uncheckedCheckOnClickToolStripMenuItem - // - uncheckedCheckOnClickToolStripMenuItem.CheckOnClick = true; - uncheckedCheckOnClickToolStripMenuItem.Name = "uncheckedCheckOnClickToolStripMenuItem"; - uncheckedCheckOnClickToolStripMenuItem.Size = new Size(298, 26); - uncheckedCheckOnClickToolStripMenuItem.Text = "Unchecked_CheckOnClick(T)"; - // - // checkCheckOnClickToolStripMenuItem - // - checkCheckOnClickToolStripMenuItem.Checked = true; - checkCheckOnClickToolStripMenuItem.CheckOnClick = true; - checkCheckOnClickToolStripMenuItem.CheckState = CheckState.Checked; - checkCheckOnClickToolStripMenuItem.Name = "checkCheckOnClickToolStripMenuItem"; - checkCheckOnClickToolStripMenuItem.Size = new Size(298, 26); - checkCheckOnClickToolStripMenuItem.Text = "Checked_CheckOnClick(T)"; - // - // checkedCheckOnClickFToolStripMenuItem - // - checkedCheckOnClickFToolStripMenuItem.Checked = true; - checkedCheckOnClickFToolStripMenuItem.CheckState = CheckState.Checked; - checkedCheckOnClickFToolStripMenuItem.Name = "checkedCheckOnClickFToolStripMenuItem"; - checkedCheckOnClickFToolStripMenuItem.Size = new Size(298, 26); - checkedCheckOnClickFToolStripMenuItem.Text = "Checked_CheckOnClick(F)"; - // - // indeterminateToolStripMenuItem - // - indeterminateToolStripMenuItem.Checked = true; - indeterminateToolStripMenuItem.CheckOnClick = true; - indeterminateToolStripMenuItem.CheckState = CheckState.Indeterminate; - indeterminateToolStripMenuItem.Name = "indeterminateToolStripMenuItem"; - indeterminateToolStripMenuItem.Size = new Size(298, 26); - indeterminateToolStripMenuItem.Text = "Indeterminate_CheckOnClick(T)"; - // - // indeterminateCheckOnClickFToolStripMenuItem - // - indeterminateCheckOnClickFToolStripMenuItem.Checked = true; - indeterminateCheckOnClickFToolStripMenuItem.CheckState = CheckState.Indeterminate; - indeterminateCheckOnClickFToolStripMenuItem.Name = "indeterminateCheckOnClickFToolStripMenuItem"; - indeterminateCheckOnClickFToolStripMenuItem.Size = new Size(298, 26); - indeterminateCheckOnClickFToolStripMenuItem.Text = "Indeterminate_CheckOnClick(F)"; - // - // toolStripComboBox1 - // - toolStripComboBox1.AccessibleName = "toolStripCombo_Box"; - toolStripComboBox1.Name = "toolStripComboBox1"; - toolStripComboBox1.Size = new Size(159, 28); - toolStripComboBox1.ToolTipText = "toolStripComboBox1"; - // - // toolStripTextBox1 - // - toolStripTextBox1.AccessibleName = "toolStripText_Box1"; - toolStripTextBox1.Name = "toolStripTextBox1"; - toolStripTextBox1.Size = new Size(132, 28); - toolStripTextBox1.Text = "toolStripTextBox1"; - // - // statusStrip1 - // - statusStrip1.ImageScalingSize = new Size(20, 20); - statusStrip1.Items.AddRange(new ToolStripItem[] { toolStripDropDownButton1, toolStripSplitButton1, toolStripStatusLabel1, toolStripProgressBar1 }); - statusStrip1.Location = new Point(0, 520); - statusStrip1.Name = "statusStrip1"; - statusStrip1.Padding = new Padding(1, 0, 18, 0); - statusStrip1.ShowItemToolTips = true; - statusStrip1.Size = new Size(1287, 29); - statusStrip1.TabIndex = 2; - statusStrip1.TabStop = true; - statusStrip1.Text = "statusStrip1"; - // - // toolStripDropDownButton1 - // - toolStripDropDownButton1.DisplayStyle = ToolStripItemDisplayStyle.Image; - toolStripDropDownButton1.DropDownItems.AddRange(new ToolStripItem[] { toolStripSeparator9, toolStripTextBox3, toolStripMenuItem3 }); - toolStripDropDownButton1.Image = (Image)resources.GetObject("toolStripDropDownButton1.Image"); - toolStripDropDownButton1.ImageTransparentColor = Color.Magenta; - toolStripDropDownButton1.Name = "toolStripDropDownButton1"; - toolStripDropDownButton1.Size = new Size(34, 27); - toolStripDropDownButton1.Text = "toolStripDropDownButton1"; - // - // toolStripSeparator9 - // - toolStripSeparator9.Name = "toolStripSeparator9"; - toolStripSeparator9.Size = new Size(222, 6); - // - // toolStripTextBox3 - // - toolStripTextBox3.Name = "toolStripTextBox3"; - toolStripTextBox3.Size = new Size(100, 27); - // - // toolStripMenuItem3 - // - toolStripMenuItem3.Name = "toolStripMenuItem3"; - toolStripMenuItem3.Size = new Size(225, 26); - toolStripMenuItem3.Text = "toolStripMenuItem3"; - // - // toolStripSplitButton1 - // - toolStripSplitButton1.DisplayStyle = ToolStripItemDisplayStyle.Image; - toolStripSplitButton1.DropDownItems.AddRange(new ToolStripItem[] { toolStripTextBox2, toolStripSeparator8, toolStripComboBox2, toolStripMenuItem2 }); - toolStripSplitButton1.Image = (Image)resources.GetObject("toolStripSplitButton1.Image"); - toolStripSplitButton1.ImageTransparentColor = Color.Magenta; - toolStripSplitButton1.Name = "toolStripSplitButton1"; - toolStripSplitButton1.Size = new Size(39, 27); - toolStripSplitButton1.Text = "toolStripSplitButton1"; - // - // toolStripTextBox2 - // - toolStripTextBox2.Name = "toolStripTextBox2"; - toolStripTextBox2.Size = new Size(100, 27); - // - // toolStripSeparator8 - // - toolStripSeparator8.Name = "toolStripSeparator8"; - toolStripSeparator8.Size = new Size(222, 6); - // - // toolStripComboBox2 - // - toolStripComboBox2.Name = "toolStripComboBox2"; - toolStripComboBox2.Size = new Size(121, 28); - // - // toolStripMenuItem2 - // - toolStripMenuItem2.Name = "toolStripMenuItem2"; - toolStripMenuItem2.Size = new Size(225, 26); - toolStripMenuItem2.Text = "toolStripMenuItem2"; - // - // toolStripStatusLabel1 - // - toolStripStatusLabel1.Name = "toolStripStatusLabel1"; - toolStripStatusLabel1.Size = new Size(151, 23); - toolStripStatusLabel1.Text = "toolStripStatusLabel1"; - toolStripStatusLabel1.ToolTipText = "toolStripStatusLabel1"; - // - // toolStripProgressBar1 - // - toolStripProgressBar1.AccessibleName = "Progress_Bar"; - toolStripProgressBar1.Name = "toolStripProgressBar1"; - toolStripProgressBar1.Size = new Size(134, 21); - // - // toolStrip1 - // - toolStrip1.ImageScalingSize = new Size(20, 20); - toolStrip1.Items.AddRange(new ToolStripItem[] { newToolStripButton, toolStripSeparator7, toolStripButton1, toolStripButton2, toolStripButton3, toolStripButton4, toolStripButton5, toolStripButton6 }); - toolStrip1.Location = new Point(0, 34); - toolStrip1.Name = "toolStrip1"; - toolStrip1.Size = new Size(1287, 31); - toolStrip1.TabIndex = 1; - toolStrip1.TabStop = true; - toolStrip1.Text = "toolStrip1"; - // - // newToolStripButton - // - newToolStripButton.Image = (Image)resources.GetObject("newToolStripButton.Image"); - newToolStripButton.ImageTransparentColor = Color.Magenta; - newToolStripButton.Name = "newToolStripButton"; - newToolStripButton.Size = new Size(63, 28); - newToolStripButton.Text = "&New"; - // - // toolStripSeparator7 - // - toolStripSeparator7.Name = "toolStripSeparator7"; - toolStripSeparator7.Size = new Size(6, 31); - // - // toolStripButton1 - // - toolStripButton1.DisplayStyle = ToolStripItemDisplayStyle.Text; - toolStripButton1.Image = (Image)resources.GetObject("toolStripButton1.Image"); - toolStripButton1.ImageTransparentColor = Color.Magenta; - toolStripButton1.Name = "toolStripButton1"; - toolStripButton1.Size = new Size(197, 28); - toolStripButton1.Text = "Unchecked_CheckOnClick(F)"; - // - // toolStripButton2 - // - toolStripButton2.CheckOnClick = true; - toolStripButton2.DisplayStyle = ToolStripItemDisplayStyle.Text; - toolStripButton2.Image = (Image)resources.GetObject("toolStripButton2.Image"); - toolStripButton2.ImageTransparentColor = Color.Magenta; - toolStripButton2.Name = "toolStripButton2"; - toolStripButton2.Size = new Size(198, 28); - toolStripButton2.Text = "Unchecked_CheckOnClick(T)"; - // - // toolStripButton3 - // - toolStripButton3.Checked = true; - toolStripButton3.CheckOnClick = true; - toolStripButton3.CheckState = CheckState.Checked; - toolStripButton3.DisplayStyle = ToolStripItemDisplayStyle.Text; - toolStripButton3.Image = (Image)resources.GetObject("toolStripButton3.Image"); - toolStripButton3.ImageTransparentColor = Color.Magenta; - toolStripButton3.Name = "toolStripButton3"; - toolStripButton3.Size = new Size(182, 28); - toolStripButton3.Text = "Checked_CheckOnClick(T)"; - // - // toolStripButton4 - // - toolStripButton4.Checked = true; - toolStripButton4.CheckState = CheckState.Checked; - toolStripButton4.DisplayStyle = ToolStripItemDisplayStyle.Text; - toolStripButton4.Image = (Image)resources.GetObject("toolStripButton4.Image"); - toolStripButton4.ImageTransparentColor = Color.Magenta; - toolStripButton4.Name = "toolStripButton4"; - toolStripButton4.Size = new Size(181, 28); - toolStripButton4.Text = "Checked_CheckOnClick(F)"; - // - // toolStripButton5 - // - toolStripButton5.Checked = true; - toolStripButton5.CheckOnClick = true; - toolStripButton5.CheckState = CheckState.Indeterminate; - toolStripButton5.DisplayStyle = ToolStripItemDisplayStyle.Text; - toolStripButton5.Image = (Image)resources.GetObject("toolStripButton5.Image"); - toolStripButton5.ImageTransparentColor = Color.Magenta; - toolStripButton5.Name = "toolStripButton5"; - toolStripButton5.Size = new Size(219, 28); - toolStripButton5.Text = "Indeterminate_CheckOnClick(T)"; - // - // toolStripButton6 - // - toolStripButton6.Checked = true; - toolStripButton6.CheckState = CheckState.Indeterminate; - toolStripButton6.DisplayStyle = ToolStripItemDisplayStyle.Text; - toolStripButton6.Image = (Image)resources.GetObject("toolStripButton6.Image"); - toolStripButton6.ImageTransparentColor = Color.Magenta; - toolStripButton6.Name = "toolStripButton6"; - toolStripButton6.Size = new Size(218, 24); - toolStripButton6.Text = "Indeterminate_CheckOnClick(F)"; - // - // Menu_Toolbars_controls - // - AutoScaleDimensions = new SizeF(8F, 20F); - AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(1287, 549); - Controls.Add(toolStrip1); - Controls.Add(statusStrip1); - Controls.Add(menuStrip1); - MainMenuStrip = menuStrip1; - Margin = new Padding(5, 4, 5, 4); - Name = "Menu_Toolbars_controls"; - Text = "StripControls"; - menuStrip1.ResumeLayout(false); - menuStrip1.PerformLayout(); - contextMenuStrip1.ResumeLayout(false); - statusStrip1.ResumeLayout(false); - statusStrip1.PerformLayout(); - toolStrip1.ResumeLayout(false); - toolStrip1.PerformLayout(); - ResumeLayout(false); - PerformLayout(); - } - -#endregion - - private MenuStrip menuStrip1; - private ContextMenuStrip contextMenuStrip1; - private ToolStripMenuItem fileToolStripMenuItem; - private ToolStripMenuItem newToolStripMenuItem; - private ToolStripMenuItem openToolStripMenuItem; - private ToolStripSeparator toolStripSeparator; - private ToolStripMenuItem saveToolStripMenuItem; - private ToolStripMenuItem saveAsToolStripMenuItem; - private ToolStripSeparator toolStripSeparator1; - private ToolStripMenuItem printToolStripMenuItem; - private ToolStripMenuItem printPreviewToolStripMenuItem; - private ToolStripSeparator toolStripSeparator2; - private ToolStripMenuItem exitToolStripMenuItem; - private ToolStripMenuItem editToolStripMenuItem; - private ToolStripMenuItem undoToolStripMenuItem; - private ToolStripMenuItem redoToolStripMenuItem; - private ToolStripSeparator toolStripSeparator3; - private ToolStripMenuItem cutToolStripMenuItem; - private ToolStripMenuItem copyToolStripMenuItem; - private ToolStripMenuItem pasteToolStripMenuItem; - private ToolStripSeparator toolStripSeparator4; - private ToolStripMenuItem selectAllToolStripMenuItem; - private ToolStripMenuItem toolsToolStripMenuItem; - private ToolStripMenuItem customizeToolStripMenuItem; - private ToolStripMenuItem optionsToolStripMenuItem; - private ToolStripMenuItem helpToolStripMenuItem; - private ToolStripMenuItem contentsToolStripMenuItem; - private ToolStripMenuItem indexToolStripMenuItem; - private ToolStripMenuItem searchToolStripMenuItem; - private ToolStripSeparator toolStripSeparator5; - private ToolStripMenuItem aboutToolStripMenuItem; - private StatusStrip statusStrip1; - private ToolStripStatusLabel toolStripStatusLabel1; - private ToolStripDropDownButton toolStripDropDownButton1; - private ToolStripSplitButton toolStripSplitButton1; - private ToolStrip toolStrip1; - private ToolStripButton newToolStripButton; - private ToolStripSeparator toolStripSeparator7; - private ToolStripMenuItem menuStripToolStripMenuItem; - private ToolStripMenuItem shortCutsToolStripMenuItem; - private ToolStripMenuItem toolStripMenuItem1; - private ToolStripComboBox toolStripComboBox1; - private ToolStripMenuItem item1ToolStripMenuItem; - private ToolStripMenuItem item2ToolStripMenuItem; - private ToolStripTextBox toolStripTextBox1; - private ToolStripSeparator toolStripSeparator9; - private ToolStripTextBox toolStripTextBox3; - private ToolStripMenuItem toolStripMenuItem3; - private ToolStripTextBox toolStripTextBox2; - private ToolStripSeparator toolStripSeparator8; - private ToolStripComboBox toolStripComboBox2; - private ToolStripMenuItem toolStripMenuItem2; - private ToolStripProgressBar toolStripProgressBar1; - private ToolStripMenuItem uncheckedCheckOnClickToolStripMenuItem; - private ToolStripMenuItem checkCheckOnClickToolStripMenuItem; - private ToolStripMenuItem checkedCheckOnClickFToolStripMenuItem; - private ToolStripMenuItem indeterminateToolStripMenuItem; - private ToolStripMenuItem indeterminateCheckOnClickFToolStripMenuItem; - private ToolStripButton toolStripButton1; - private ToolStripButton toolStripButton2; - private ToolStripButton toolStripButton3; - private ToolStripButton toolStripButton4; - private ToolStripButton toolStripButton5; - private ToolStripButton toolStripButton6; -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Menu_Toolbars_controls.cs b/src/System.Windows.Forms/tests/AccessibilityTests/Menu_Toolbars_controls.cs deleted file mode 100644 index 51543c0cfb0..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Menu_Toolbars_controls.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class Menu_Toolbars_controls : Form -{ - public Menu_Toolbars_controls() - { - InitializeComponent(); - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Menu_Toolbars_controls.resx b/src/System.Windows.Forms/tests/AccessibilityTests/Menu_Toolbars_controls.resx deleted file mode 100644 index 57a6bde133b..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Menu_Toolbars_controls.resx +++ /dev/null @@ -1,324 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAERSURBVDhPrZDbSgJRGIXnpewd6jXsjSQvIrwoI0RQMChU - 0iiDPCGiE3ZCRkvR8VzTeBhnyR5/ccaZNnPhB4t9sdf6Ln5hb8QeathNJFVFKF5C8DqL4ksDVHWGDf7j - LHyPg6NjviSaFqlu5yQYR+KpupaIkrMknCxT3Y7v/NYYb0ITK1c3BarbWWhLQ7IR0cTKReyZ6lZ0XYei - ztHpK4bAc+h1FgQijzSxMptrGIxVSO0xX3AaStFki7bUMVFmaMm/eJMGfIH/MkGzLep0AXn4h/r3CJV3 - mS9gn2bY4UY/UzQ7E9TqfeTFtnuB+XAfzSHKr11kSl/uBebDiZ89ZCst3OUkdwL28sIVsE83ock+EIQV - 2Mz2wxeg6/UAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJHSURBVDhPxZBdSNNhFMb/F110ZZEVhVBgeeHNICiiuggp - olAUyyxI0oSaH1QYC3N+tKnp5ubm1JUua5uuqdNKMwr7kApFItTUkWZqVhSVYmao5Nevvy7UoYR3HXh4 - 4XCe33nOKyy3lAY7l9RWMo0O/raWXxEyo5spVYTNvOGyfIRPfW+ptOkXqaPl6T83hcRmExSdgzAz3NVm - YWyoYla/B+1M9JtxWLPpaH22JORIjI6gKAMB0jyEimIdo4OlbuaprwVMOOMovammpDADc34qppwUrmnl - 5Kni3aFlFg2j3y1z5mnRTJccnNIltQhwq0jFry+mOXNtpWZWDx1Z1NhV3C3JwGFOw25SYjVe5oYhiUKd - HKMmwQUrMWUw/CF3NnZvvYKqUh1TvUroS3fXe7HXkwidMngTS2t5KLbregSzMY2f3Wr4qKW6LJvGR1rX - 0MLor8OhKYTJBn/GHvvxrliCTBrsOqXIoOBHh5K+hmSq7FqmexTQHuUytkaKxuNMNgYyVneA4Qd7GKjc - hjLaRzxH7gIU6JIZaEvgtk1D8wsxSWecCDgNzWFMvwxm/PkhRmr3Mli1nW9lvjRdWc0Jf+/5jzRmyWmv - S+GOLQu6U6BFjPvqKOP1AYw88WOoZif9DgmfLVtxaj1RSLdwNvrkPCA3M54KqxrnvRia9MKcGrUrqFOt - 5H7qKsqT1mGO9+Lqhc2ELdw+U/r0i+gVZ8hMiCDx3DHORwZyKnQ/hw/uYt9uCTskPvh6e7Fp41rWr/Fg - g6eHO+A/lyD8ARfG3mk9fv1YAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIySURBVDhPrZLfS5NRGMfff6H7boIuuq2pMZyL1eAt11CW - DcOKsB9vpFmaLtNExco0av6CbIVLJ61Wk3BSkT/AFCkRZSpZmrmiJQ41xSaCwdfznL15XEUX0Reem5f3 - 8znnec4j/Zc8fxYGla91CS3eRTx0z6OpMYS7jmnU1X6B/VYA18snUVoyjsKCt8jLHcH5c36ouCQR2NUJ - 1Nas4G9ZXlmFKbULh1Kf8lJxSfI+WeCCyopv6q+/h+DQ/DJ2WV5Ao1FgPegRAveDOS4oLfmq/h6dn/DH - 4AJizD4UXJrCAUuzEDgbZrjgou2DiohshIcnQtgme5GTPYbkJKcQ1N8OckHW2REVi+RXuM8fxGaDG4oy - ALPZIQQ11Z+5QDk1oKJ/hjv7P2FTfCMOH3mFxMQ6IbhROYWOdrCnBI4dfwPr0V4+bRoY9UzXppMjcDdS - rC8hy3YhuFI2gTYf2A4Aza4f7N2/o/zaLB8qDYx6zszwr8P7k1thNFYIweXCMXgeAfedq2xxwjClZUeV - Jd2GtDNFETiJwfs8MBjKhMCWN8pgoLoqzE8miH1GjE7G4PsZjE7OQsm9ij2mFg7rdrug1xcJAa2l4w7W - r00Cgk/n38S7wBwC04u4UGxHrMHF4CbEJtyDLj5fCDIzhljfSxzeavRgyw4Zj9t64GvvQ0d3P3pfD2Kv - 2QqNvgFxDN6urYdWmyMElJMnevh60obRktA701PRtGlg1DOdSkXwzrisaMG/RZLWAE60OMW5fNhvAAAA - AElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIpSURBVDhPtZL/T1JRGMb5p1itrVZbbRpqZbawnBENV1I0 - jGlByTSyJTXJwq2oKZQb1KAv6JCYWSxvBrkkZUq4CeQEiRABFeLL072Xa0zRra31bO8v57zP5znnPYf1 - X+TxhWF6O7VtGYcnwbSWijKPOLzYrPSvLPwLS3huGUMlT7o9wGD9grVUBj+icdid03S9tDmgNxNwTgVQ - J+rA8XNtWwM+uuZATMwxmQVRycuJFNyzIRitDlScugKzjSgFRGJJaIwEsrk8AsHIhnSL/Ssck37UNipQ - I5DjtuYV7uksRYhr2kebhx2eP6nrycFIEh5fBA/1Nvru8q5+PDaOovK0rABwfwugWzcErfkzHhjsePL6 - E7q1VrTdNUDcrgGvSYlDZHN5XTNOnL8BVe8AJAoNDtZfLgDu9L1BPJmikzcrk81hlRwodZJwdBXziwnI - OrVoaOkiT8C8hKLHBPO7CbywOaE1jeC+bhAd6meQdvZC1KoG/5IS3MZ2HObLUHZSggvkWq3wOvbWiAqA - VpWeyStVfCUNf3AZ4zNhfHCFMEDMgye+hYr6FrDLzxQAUuVTpr0ocn74mchg5vsKRt1RcHp2Qv9+kZ78 - UcE17KkWFgHNN/uQzgBkGKLJPBZiecyGchjzrmFwPIF++xJUbDbUQzEacIArLpopSRSP4CUN1Obf1Abz - uqob5KjiXwWH/GVl5HPt5zZh37GL2H1EiF1VZ7GDI6CNW5r/TSzWbwHYL0mKJ5czAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGCSURBVDhPnZK9S0JRGMb9F1xb2gqaq6mhwCGDtvYIIyLI - cJOE1paoIYpMKUjFRDH87lpoakGlIZF9DA2hZJEQhJXl1xPn3HPV29WQfvBwOfA+P95zuDJ39A6/4wyl - YOOSMHvOcHGThuwvSKEVRvsR+pQqWD3R1pK98DUbl7Jm5hA8SfESd6S5xH5wycalrO4E0D8yWQuriLH6 - E2xcSqlcoRJBxCpiTO5TNi4m/ZgDF4nDsOulsfujyGRzUsmWM8YqdcggKbveS3A88bEkslRye58RSzZt - IVarY/FFaPmlwp+fUaESYRNW5Vm3BPmpBpZNvppACDmTLbS6FbGAPFAj5OGI4PALOK/yZfIlAlk4j7n5 - xdaCarWKj0KRXmE2+UklJEJZZ/RCPTPdWvBdLOP1rYD41QNcgRiVkKJQ1mjGsa2VNxeQb2OWDC7sh47p - ddQLeoyOTSFiVAAFvVhChsmv2k6Uvd3Icx1UolMNiDdpl4nhLiohW/xb0tMph2JwCJxjAz9A30JI8zYA - tAAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGDSURBVDhPrZFNSwJRGIX9NYGbFoUlFElY1EJQKEYhCJsi - LaVsERnRF5iCaSZJO1toCDVGFkgoFpWQWWRR2aIvUxm1BKN1wSnHCFw4TOCzue+9nPNw4eVVnav4Izzb - QfxeGZ5TWaxT/rK3irzmC7CsusvC1G4IkbNLboIiDieF4GGUKeTeClDpppF8eeEu2PIfwfrzizSdw3Hk - EnKlFpkMzV2wH77AosOFTV8A+vkl9CiHuJeLJNNZjM8tYWB0FkTvMAwmy/8ERTR6CwjlGAi1Ccence6C - 1NsXzN4PKIxJLLgeIJ2MoXvmFraNBKK3eXZRIveJPvs7FIYniEkXZENOdE+GIZ2Ko10TwLK7tJmKmL0F - EEYarYM+NMnt0C1sQzpx/lcSEnZ2gcKY/gs0dlmZuWvmjjmpwA1qxVp2AWFIMAF/OAGBzMjMI7ZrtJCb - 4Df3o4Zfxy7QrdxDRFKol5khkpR2H4qmIOzUQNBGwrsXYxccnNOQqNbQ0KGGZ+eEPVwdeLxvqqrf4wGh - TNAAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHkSURBVDhPvZHfS1NhHIf3p5QypLr2D4goMwoMCi/qIugH - Xe1Cr7qKDIMkZixwNhfWLGWbnuki0kXKzLU023KubBNPJrbRdOzocm6e2dPOO21mMS+CHvjcvOf9PF++ - 79H9M+7RT2iRRsIi9sEAXe43yAvf2LpSHq28G9uAnytNT4jMLewtcQ2Ht2pF8ps/aOt+gccX5lxD694S - +1BQFD1RkN5DSFa4Z3uONKbgHE3h8KZ4OJTC1J8UiSzmfhd2uf1CoJHbyKOsZokl0kKwm+aeJaov+wjO - rpQkVqdXfOz0bWAcVLghfaXxkUz3y2VxvpMGSwL3uMKh+gHezSSLEnNhX23vtYzKUirDfGyFj/Iy1mdx - UWqR8iKhwtQLxjgH659y4EwvVXWPiwJt3/Ws+muywRrlqvkDdx3zQrCN8l1ldnEd3/QqFmkS/akHJYGS - zjLzOUEwEsMf+sLI2zmaOou/93pPGoM5zvk7UU7fnBKxSBPoT7SXBNW1F/9Io2lKCNTCeomUyrS8xnBA - wfUqyf1eP5U1ptJD/o1LzeNCsHPydtqdr6k4aiwvOHvNSya3ibU/QIdrEkvfhJislc32MfYfuV1eUGPw - FF7bIVJVZ0N/soPK421UHGstlFvYd/hWecF/Qqf7CR0A5wwgSQA2AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJSSURBVDhPtZJrSJNRGMdf6IN9KbpQn/pUEH2JIoLqQ0Zh - FqYZRmJG1iKmUqKyLB2pqSm6vC1Nm5GXoeatEsVJ0RASR3eNzegikRq5lrV3857Fr/d9ddlICoL+8OfA - Oef/e57zcIT/os7WLMw302muSGJ2689qqi7A44q8IzjtNYzarzHQm8tZtT8FmRqu6LToMxN+B8qhCbGR - KVcDE85ajKUaxoaryEuL4UVXIudPB5Ko2oy98xjDptXERuz3hsgAOTzlqqMk6yjdllzE90UM9Wp5azlB - S1kwkeG+1CSv4mmBQPThfd6Ahqq8GYB4A11yBKmaMLQxoZyLDkGjDiZOFUhUuB+FsWsUQFiArzegtlzH - pFjPpMPA2GA2jucx2KqWK7ZWLqO7dBGP9D5KWLbfto3eAKMhi3FHBeP9GYy9PMXos4OIrYvJrzSRbWjm - wuV6EnVG4tLLiEzSExGf4w0oL05nZEDPaK+akceBuO9v4uPtFUrYo6npbzhdE/QPOQmNSiPouHYOUpaf - gvgqA/dDf9wd63G1r2SgUlAqyyq/1anYUGfG2mdXwne7bOwJUc1AinOS+NxzBpd5HWLbUhyNPvRdF5S2 - v05/54tbqvzBifWNHUvPOwLC4/CXwrv2HsB3+w6EwosJOB5ESeElfGpayGD1AmwlArHSm+W2PR1clToo - MrbT0mFTVtlbN6xFuJQar3wQz5Q9VksD+7XyPctrJdx4p5s605M5gKz8lJPSDwtGFbKboJ1blAN52vKb - PdXm80/AfDokTVu+8DfPXv9XCcIPTvjvLQ8YoakAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG - YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 - 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw - bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc - VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 - c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 - Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo - mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ - kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D - TgDQASA1MVpwzwAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG - YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 - 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw - bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc - VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 - c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 - Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo - mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ - kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D - TgDQASA1MVpwzwAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAERSURBVDhPrZDbSgJRGIXnpewd6jXsjSQvIrwoI0RQMChU - 0iiDPCGiE3ZCRkvR8VzTeBhnyR5/ccaZNnPhB4t9sdf6Ln5hb8QeathNJFVFKF5C8DqL4ksDVHWGDf7j - LHyPg6NjviSaFqlu5yQYR+KpupaIkrMknCxT3Y7v/NYYb0ITK1c3BarbWWhLQ7IR0cTKReyZ6lZ0XYei - ztHpK4bAc+h1FgQijzSxMptrGIxVSO0xX3AaStFki7bUMVFmaMm/eJMGfIH/MkGzLep0AXn4h/r3CJV3 - mS9gn2bY4UY/UzQ7E9TqfeTFtnuB+XAfzSHKr11kSl/uBebDiZ89ZCst3OUkdwL28sIVsE83ock+EIQV - 2Mz2wxeg6/UAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJHSURBVDhPxZBdSNNhFMb/F110ZZEVhVBgeeHNICiiuggp - olAUyyxI0oSaH1QYC3N+tKnp5ubm1JUua5uuqdNKMwr7kApFItTUkWZqVhSVYmao5Nevvy7UoYR3HXh4 - 4XCe33nOKyy3lAY7l9RWMo0O/raWXxEyo5spVYTNvOGyfIRPfW+ptOkXqaPl6T83hcRmExSdgzAz3NVm - YWyoYla/B+1M9JtxWLPpaH22JORIjI6gKAMB0jyEimIdo4OlbuaprwVMOOMovammpDADc34qppwUrmnl - 5Kni3aFlFg2j3y1z5mnRTJccnNIltQhwq0jFry+mOXNtpWZWDx1Z1NhV3C3JwGFOw25SYjVe5oYhiUKd - HKMmwQUrMWUw/CF3NnZvvYKqUh1TvUroS3fXe7HXkwidMngTS2t5KLbregSzMY2f3Wr4qKW6LJvGR1rX - 0MLor8OhKYTJBn/GHvvxrliCTBrsOqXIoOBHh5K+hmSq7FqmexTQHuUytkaKxuNMNgYyVneA4Qd7GKjc - hjLaRzxH7gIU6JIZaEvgtk1D8wsxSWecCDgNzWFMvwxm/PkhRmr3Mli1nW9lvjRdWc0Jf+/5jzRmyWmv - S+GOLQu6U6BFjPvqKOP1AYw88WOoZif9DgmfLVtxaj1RSLdwNvrkPCA3M54KqxrnvRia9MKcGrUrqFOt - 5H7qKsqT1mGO9+Lqhc2ELdw+U/r0i+gVZ8hMiCDx3DHORwZyKnQ/hw/uYt9uCTskPvh6e7Fp41rWr/Fg - g6eHO+A/lyD8ARfG3mk9fv1YAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIySURBVDhPrZLfS5NRGMfff6H7boIuuq2pMZyL1eAt11CW - DcOKsB9vpFmaLtNExco0av6CbIVLJ61Wk3BSkT/AFCkRZSpZmrmiJQ41xSaCwdfznL15XEUX0Reem5f3 - 8znnec4j/Zc8fxYGla91CS3eRTx0z6OpMYS7jmnU1X6B/VYA18snUVoyjsKCt8jLHcH5c36ouCQR2NUJ - 1Nas4G9ZXlmFKbULh1Kf8lJxSfI+WeCCyopv6q+/h+DQ/DJ2WV5Ao1FgPegRAveDOS4oLfmq/h6dn/DH - 4AJizD4UXJrCAUuzEDgbZrjgou2DiohshIcnQtgme5GTPYbkJKcQ1N8OckHW2REVi+RXuM8fxGaDG4oy - ALPZIQQ11Z+5QDk1oKJ/hjv7P2FTfCMOH3mFxMQ6IbhROYWOdrCnBI4dfwPr0V4+bRoY9UzXppMjcDdS - rC8hy3YhuFI2gTYf2A4Aza4f7N2/o/zaLB8qDYx6zszwr8P7k1thNFYIweXCMXgeAfedq2xxwjClZUeV - Jd2GtDNFETiJwfs8MBjKhMCWN8pgoLoqzE8miH1GjE7G4PsZjE7OQsm9ij2mFg7rdrug1xcJAa2l4w7W - r00Cgk/n38S7wBwC04u4UGxHrMHF4CbEJtyDLj5fCDIzhljfSxzeavRgyw4Zj9t64GvvQ0d3P3pfD2Kv - 2QqNvgFxDN6urYdWmyMElJMnevh60obRktA701PRtGlg1DOdSkXwzrisaMG/RZLWAE60OMW5fNhvAAAA - AElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIpSURBVDhPtZL/T1JRGMb5p1itrVZbbRpqZbawnBENV1I0 - jGlByTSyJTXJwq2oKZQb1KAv6JCYWSxvBrkkZUq4CeQEiRABFeLL072Xa0zRra31bO8v57zP5znnPYf1 - X+TxhWF6O7VtGYcnwbSWijKPOLzYrPSvLPwLS3huGUMlT7o9wGD9grVUBj+icdid03S9tDmgNxNwTgVQ - J+rA8XNtWwM+uuZATMwxmQVRycuJFNyzIRitDlScugKzjSgFRGJJaIwEsrk8AsHIhnSL/Ssck37UNipQ - I5DjtuYV7uksRYhr2kebhx2eP6nrycFIEh5fBA/1Nvru8q5+PDaOovK0rABwfwugWzcErfkzHhjsePL6 - E7q1VrTdNUDcrgGvSYlDZHN5XTNOnL8BVe8AJAoNDtZfLgDu9L1BPJmikzcrk81hlRwodZJwdBXziwnI - OrVoaOkiT8C8hKLHBPO7CbywOaE1jeC+bhAd6meQdvZC1KoG/5IS3MZ2HObLUHZSggvkWq3wOvbWiAqA - VpWeyStVfCUNf3AZ4zNhfHCFMEDMgye+hYr6FrDLzxQAUuVTpr0ocn74mchg5vsKRt1RcHp2Qv9+kZ78 - UcE17KkWFgHNN/uQzgBkGKLJPBZiecyGchjzrmFwPIF++xJUbDbUQzEacIArLpopSRSP4CUN1Obf1Abz - uqob5KjiXwWH/GVl5HPt5zZh37GL2H1EiF1VZ7GDI6CNW5r/TSzWbwHYL0mKJ5czAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGDSURBVDhPrZFNSwJRGIX9NYGbFoUlFElY1EJQKEYhCJsi - LaVsERnRF5iCaSZJO1toCDVGFkgoFpWQWWRR2aIvUxm1BKN1wSnHCFw4TOCzue+9nPNw4eVVnav4Izzb - QfxeGZ5TWaxT/rK3irzmC7CsusvC1G4IkbNLboIiDieF4GGUKeTeClDpppF8eeEu2PIfwfrzizSdw3Hk - EnKlFpkMzV2wH77AosOFTV8A+vkl9CiHuJeLJNNZjM8tYWB0FkTvMAwmy/8ERTR6CwjlGAi1Ccence6C - 1NsXzN4PKIxJLLgeIJ2MoXvmFraNBKK3eXZRIveJPvs7FIYniEkXZENOdE+GIZ2Ko10TwLK7tJmKmL0F - EEYarYM+NMnt0C1sQzpx/lcSEnZ2gcKY/gs0dlmZuWvmjjmpwA1qxVp2AWFIMAF/OAGBzMjMI7ZrtJCb - 4Df3o4Zfxy7QrdxDRFKol5khkpR2H4qmIOzUQNBGwrsXYxccnNOQqNbQ0KGGZ+eEPVwdeLxvqqrf4wGh - TNAAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHkSURBVDhPvZHfS1NhHIf3p5QypLr2D4goMwoMCi/qIugH - Xe1Cr7qKDIMkZixwNhfWLGWbnuki0kXKzLU023KubBNPJrbRdOzocm6e2dPOO21mMS+CHvjcvOf9PF++ - 79H9M+7RT2iRRsIi9sEAXe43yAvf2LpSHq28G9uAnytNT4jMLewtcQ2Ht2pF8ps/aOt+gccX5lxD694S - +1BQFD1RkN5DSFa4Z3uONKbgHE3h8KZ4OJTC1J8UiSzmfhd2uf1CoJHbyKOsZokl0kKwm+aeJaov+wjO - rpQkVqdXfOz0bWAcVLghfaXxkUz3y2VxvpMGSwL3uMKh+gHezSSLEnNhX23vtYzKUirDfGyFj/Iy1mdx - UWqR8iKhwtQLxjgH659y4EwvVXWPiwJt3/Ws+muywRrlqvkDdx3zQrCN8l1ldnEd3/QqFmkS/akHJYGS - zjLzOUEwEsMf+sLI2zmaOou/93pPGoM5zvk7UU7fnBKxSBPoT7SXBNW1F/9Io2lKCNTCeomUyrS8xnBA - wfUqyf1eP5U1ptJD/o1LzeNCsHPydtqdr6k4aiwvOHvNSya3ibU/QIdrEkvfhJislc32MfYfuV1eUGPw - FF7bIVJVZ0N/soPK421UHGstlFvYd/hWecF/Qqf7CR0A5wwgSQA2AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJSSURBVDhPtZJrSJNRGMdf6IN9KbpQn/pUEH2JIoLqQ0Zh - FqYZRmJG1iKmUqKyLB2pqSm6vC1Nm5GXoeatEsVJ0RASR3eNzegikRq5lrV3857Fr/d9ddlICoL+8OfA - Oef/e57zcIT/os7WLMw302muSGJ2689qqi7A44q8IzjtNYzarzHQm8tZtT8FmRqu6LToMxN+B8qhCbGR - KVcDE85ajKUaxoaryEuL4UVXIudPB5Ko2oy98xjDptXERuz3hsgAOTzlqqMk6yjdllzE90UM9Wp5azlB - S1kwkeG+1CSv4mmBQPThfd6Ahqq8GYB4A11yBKmaMLQxoZyLDkGjDiZOFUhUuB+FsWsUQFiArzegtlzH - pFjPpMPA2GA2jucx2KqWK7ZWLqO7dBGP9D5KWLbfto3eAKMhi3FHBeP9GYy9PMXos4OIrYvJrzSRbWjm - wuV6EnVG4tLLiEzSExGf4w0oL05nZEDPaK+akceBuO9v4uPtFUrYo6npbzhdE/QPOQmNSiPouHYOUpaf - gvgqA/dDf9wd63G1r2SgUlAqyyq/1anYUGfG2mdXwne7bOwJUc1AinOS+NxzBpd5HWLbUhyNPvRdF5S2 - v05/54tbqvzBifWNHUvPOwLC4/CXwrv2HsB3+w6EwosJOB5ESeElfGpayGD1AmwlArHSm+W2PR1clToo - MrbT0mFTVtlbN6xFuJQar3wQz5Q9VksD+7XyPctrJdx4p5s605M5gKz8lJPSDwtGFbKboJ1blAN52vKb - PdXm80/AfDokTVu+8DfPXv9XCcIPTvjvLQ8YoakAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIVSURBVDhPtVJNaxNRFM1PyE+Yn1AUXLjK0uWgDWQZwUUX - KsGFBEEcCkIwqBEpGiydsSo2kupsasdo7Yi2toh0sFZjG5JpiZo20/TpVOmH5njvm8BYahEXHji8+968 - c+55l4n8F0zM+rhVWkHmdg29A/PoK1Yw8uIjOp/3xpvqBgrjLeilZbjNLXxZ34bwt6jexMVCGRndQenl - 0p+NWHzPXoP3rQ3bAbQhQM0E5Np2BKprbZzrm8TIs8puE+68+r0NwwZiacCwALEBCVcAqet8JlAjk1PZ - JzsNJt6u4+FMS3ZmMV9mmFNAMhesbBZLC6oFdOsd8oVXocmdx018Ej9k1FgqiJ0zgS6qlR6BVI4iEFRN - IJlxMF/1cfTMcGiQvbskB6ZqgairJ6BCTJKYu9tlAUW1oSRsNDwfB+JXQ4PzN6s07W0ZPxDS5aSgJEFn - 06Y9CaOqSauJRvMr9qmXQ4P8/RoWvU16eyBUEq5kbigwiKoOMTBQ0zbKlTq6TxihwejkZ1iOJwfEwmiC - BQ49yaW50J7Fh0xJw3IxbM3hwo2x0ICRHZzFgveTunYERK5lgo5YMxx8WPFw5Li+U8wYm66jNz+Naov+ - Beqiao58N5NrPluoryJO0QeKU7sNGKPPazh9aRzGo/eYmVvEMk270fTlmzl2N3XW9xL/jv7iaxw7+wAH - E9ew//AVxE8OItv/9O/Cf0ck8gud2vKswuxNZgAAAABJRU5ErkJggg== - - - - 31 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/PrintingControls.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/PrintingControls.Designer.cs deleted file mode 100644 index e5af969cbd6..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/PrintingControls.Designer.cs +++ /dev/null @@ -1,192 +0,0 @@ -namespace Accessibility_Core_App; - -partial class PrintingControls -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PrintingControls)); - this.pageSetupDialog1 = new System.Windows.Forms.PageSetupDialog(); - this.printDocument1 = new System.Drawing.Printing.PrintDocument(); - this.printDialog1 = new System.Windows.Forms.PrintDialog(); - this.printPreviewDialog1 = new System.Windows.Forms.PrintPreviewDialog(); - this.label1 = new System.Windows.Forms.Label(); - this.txtPrint = new System.Windows.Forms.TextBox(); - this.btnSetting = new System.Windows.Forms.Button(); - this.btnPreView = new System.Windows.Forms.Button(); - this.btnPrint = new System.Windows.Forms.Button(); - this.button1 = new System.Windows.Forms.Button(); - this.label2 = new System.Windows.Forms.Label(); - this.printPreviewControl1 = new System.Windows.Forms.PrintPreviewControl(); - this.SuspendLayout(); - // - // pageSetupDialog1 - // - this.pageSetupDialog1.Document = this.printDocument1; - // - // printDocument1 - // - this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage); - // - // printDialog1 - // - this.printDialog1.Document = this.printDocument1; - this.printDialog1.UseEXDialog = true; - // - // printPreviewDialog1 - // - this.printPreviewDialog1.AutoScrollMargin = new System.Drawing.Size(0, 0); - this.printPreviewDialog1.AutoScrollMinSize = new System.Drawing.Size(0, 0); - this.printPreviewDialog1.ClientSize = new System.Drawing.Size(400, 300); - this.printPreviewDialog1.Document = this.printDocument1; - this.printPreviewDialog1.Enabled = true; - this.printPreviewDialog1.Icon = ((System.Drawing.Icon)(resources.GetObject("printPreviewDialog1.Icon"))); - this.printPreviewDialog1.Name = "printPreviewDialog1"; - this.printPreviewDialog1.Visible = false; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(14, 10); - this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(165, 15); - this.label1.TabIndex = 0; - this.label1.Text = "Please &input text you want to print"; - // - // txtPrint - // - this.txtPrint.Location = new System.Drawing.Point(191, 7); - this.txtPrint.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.txtPrint.Name = "txtPrint"; - this.txtPrint.Size = new System.Drawing.Size(213, 23); - this.txtPrint.TabIndex = 1; - this.txtPrint.Text = "This is the test message."; - // - // btnSetting - // - this.btnSetting.Location = new System.Drawing.Point(18, 43); - this.btnSetting.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.btnSetting.Name = "btnSetting"; - this.btnSetting.Size = new System.Drawing.Size(88, 27); - this.btnSetting.TabIndex = 2; - this.btnSetting.Text = "&Setting"; - this.btnSetting.UseVisualStyleBackColor = true; - this.btnSetting.Click += new System.EventHandler(this.BtnSetting_Click); - // - // btnPreView - // - this.btnPreView.Location = new System.Drawing.Point(112, 43); - this.btnPreView.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.btnPreView.Name = "btnPreView"; - this.btnPreView.Size = new System.Drawing.Size(88, 27); - this.btnPreView.TabIndex = 3; - this.btnPreView.Text = "P&review"; - this.btnPreView.UseVisualStyleBackColor = true; - this.btnPreView.Click += new System.EventHandler(this.BtnPreView_Click); - // - // btnPrint - // - this.btnPrint.Location = new System.Drawing.Point(206, 43); - this.btnPrint.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.btnPrint.Name = "btnPrint"; - this.btnPrint.Size = new System.Drawing.Size(88, 27); - this.btnPrint.TabIndex = 4; - this.btnPrint.Text = "&Print"; - this.btnPrint.UseVisualStyleBackColor = true; - this.btnPrint.Click += new System.EventHandler(this.BtnPrint_Click); - // - // button1 - // - this.button1.Location = new System.Drawing.Point(301, 43); - this.button1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(104, 27); - this.button1.TabIndex = 6; - this.button1.Text = "Preview &Control"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.Button1_Click); - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(18, 86); - this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(91, 15); - this.label2.TabIndex = 7; - this.label2.Text = "View your page:"; - // - // printPreviewControl1 - // - this.printPreviewControl1.AccessibleName = "Image layout ready for printing"; - this.printPreviewControl1.AutoZoom = false; - this.printPreviewControl1.Document = this.printDocument1; - this.printPreviewControl1.Location = new System.Drawing.Point(18, 104); - this.printPreviewControl1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.printPreviewControl1.Name = "printPreviewControl1"; - this.printPreviewControl1.Rows = 24; - this.printPreviewControl1.Size = new System.Drawing.Size(387, 408); - this.printPreviewControl1.TabIndex = 8; - this.printPreviewControl1.TabStop = true; - this.printPreviewControl1.Zoom = 0.36454545454545456D; - // - // PrintingControls - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(426, 522); - this.Controls.Add(this.printPreviewControl1); - this.Controls.Add(this.label2); - this.Controls.Add(this.button1); - this.Controls.Add(this.btnPrint); - this.Controls.Add(this.btnPreView); - this.Controls.Add(this.btnSetting); - this.Controls.Add(this.txtPrint); - this.Controls.Add(this.label1); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "PrintingControls"; - this.Text = "PrintingTesting"; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.PageSetupDialog pageSetupDialog1; - private System.Windows.Forms.PrintDialog printDialog1; - private System.Drawing.Printing.PrintDocument printDocument1; - private System.Windows.Forms.PrintPreviewDialog printPreviewDialog1; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.TextBox txtPrint; - private System.Windows.Forms.Button btnSetting; - private System.Windows.Forms.Button btnPreView; - private System.Windows.Forms.Button btnPrint; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.PrintPreviewControl printPreviewControl1; -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/PrintingControls.cs b/src/System.Windows.Forms/tests/AccessibilityTests/PrintingControls.cs deleted file mode 100644 index 399a6f38002..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/PrintingControls.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing; -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class PrintingControls : Form -{ - public PrintingControls() - { - InitializeComponent(); - } - - int totalNumber;//this is for total number of items of the list or array - int itemPerpage;//this is for no of item per page - private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) - { - float currentY = 50;// declare one variable for height measurement - Font font = new Font("Times New Roman", 30); - Brush brush = Brushes.Blue; - - while (totalNumber <= 500) // check the number of items - { - //print each item - e.Graphics.DrawString($"{txtPrint.Text} {totalNumber}", font, brush, 50, currentY); - currentY += 50; // set a gap between every item - totalNumber += 1; //increment count by 1 - if (itemPerpage < 20) // check whether the number of item(per page) is more than 20 or not - { - itemPerpage += 1; // increment itemperpage by 1 - e.HasMorePages = false; // set the HasMorePages property to false , so that no other page will not be added - } - - else // if the number of item(per page) is more than 20 then add one page - { - itemPerpage = 0; //initiate itemperpage to 0 . - e.HasMorePages = true; //e.HasMorePages raised the PrintPage event once per page . - return;//It will call PrintPage event again - } - } - } - - private void BtnSetting_Click(object sender, EventArgs e) - { - pageSetupDialog1.Document = printDocument1; - pageSetupDialog1.ShowDialog(); - } - - private void BtnPreView_Click(object sender, EventArgs e) - { - //here we are printing 50 numbers sequentially by using loop. - //For each button click event we have to reset below two variables to 0 - // because every time PrintPage event fires automatically. - - itemPerpage = totalNumber = 0; - printPreviewDialog1.Document = printDocument1; - - ((ToolStripButton)((ToolStrip)printPreviewDialog1.Controls[1]).Items[0]).Enabled = false;//disable the direct print from printpreview.as when we click that Print button PrintPage event fires again. - - printPreviewDialog1.ShowDialog(); - } - - private void BtnPrint_Click(object sender, EventArgs e) - { - if (printDialog1.ShowDialog() == DialogResult.OK) - { - printDocument1.Print(); - } - } - - private void Button1_Click(object sender, EventArgs e) - { - printPreviewControl1.Document = printDocument1; - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/PrintingControls.resx b/src/System.Windows.Forms/tests/AccessibilityTests/PrintingControls.resx deleted file mode 100644 index 50a469554a5..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/PrintingControls.resx +++ /dev/null @@ -1,246 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 288, 17 - - - 169, 17 - - - 429, 17 - - - - - AAABAAYAICAQAAAAAADoAgAAZgAAABAQEAAAAAAAKAEAAE4DAAAgIAAAAQAIAKgIAAB2BAAAEBAAAAEA - CABoBQAAHg0AACAgAAABACAAqBAAAIYSAAAQEAAAAQAgAGgEAAAuIwAAKAAAACAAAABAAAAAAQAEAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA - /wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIoiI - iIiIiIiIiIiIiIiIiIiCIigiIiIozMzMzMzMyCIogiIoIiIiKM7m5ubm5sgiKIIiKCIiIijObm5ubm7I - IiiCIigiIiIozubm5ubmyCIogiIoIiIiKM5ubm5ubsgiKIIiKCIiIijO5ubm5ubIIiiIiIiIiIiIzm5u - bm5uyCIogRERERERGM7u7u7u7sgiKIHZWVlZWRjMzMzMzMzIIiiB1ZWVlZUYiIiIiIiIiIiIgdlZWVlZ - GDMzMzMzMzMzOIHVlZWVlRg/uLi4uLi4uDiB2VlZWVkYP7uLi4uLi4s4gdWVlZWVGD+4uLi4uLi4OIHZ - WVlZWRg/u4uLi4uLiziB1ZWVlZUYP7i4uLi4uLg4gdlZWVlZGD+7i4uLi4uLOIHVlZWVlRg/uLi4uLi4 - uDiB3d3d3d0YP7uLi4uLi4s4gRERERERGD+4uLi4uLi4OIiIiIiIiIg/u4uLi4uLiziCIiIiIiIoP7i4 - uLi4uLg4giIiIiIiKD+7i4uLi4uLOIIiIiIiIig/uLi4uLi4uDiCIiIiIiIoP7u7u7u7u7s4giIiIiIi - KD//////////OIIiIiIiIigzMzMzMzMzMziIiIiIiIiIiIiIiIiIiIiIIiIiIiIiIiIiIiIiIiIiIv// - ////////AAAAAHv4AA57+AAOe/gADnv4AA57+AAOe/gADgAAAA4AAAAOAAAADgAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/4AAB/+AAAf/gAAH/4AAB/+AAAf/gAAAAA - AAD/////KAAAABAAAAAgAAAAAQAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAACA - gACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAiIiIiIiIiIoiI - iIiIiIiIgigijMzMyCiCKCKM5mbIKIiIiIzu7sgogRERjMzMyCiB2ZGIiIiIiIHZkYMzMzM4gdmRg/u7 - uziB3dGD+7u7OIEREYP7u7s4iIiIg/u7uziCIiKD+7u7OIIiIoP///84giIigzMzMziIiIiIiIiIiP// - KCIAACjObALm5mwCIigAAoiIAAKIzgAAbm4AACIoAAAREQAAGM4AAO7uAAAiKHwAWVl8ABjMfADMzAAA - IigoAAAAIAAAAEAAAAABAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAA - AACAAIAAgIAAAICAgADA3MAA8MqmAKo/KgD/PyoAAF8qAFVfKgCqXyoA/18qAAB/KgBVfyoAqn8qAP9/ - KgAAnyoAVZ8qAKqfKgD/nyoAAL8qAFW/KgCqvyoA/78qAADfKgBV3yoAqt8qAP/fKgAA/yoAVf8qAKr/ - KgD//yoAAABVAFUAVQCqAFUA/wBVAAAfVQBVH1UAqh9VAP8fVQAAP1UAVT9VAKo/VQD/P1UAAF9VAFVf - VQCqX1UA/19VAAB/VQBVf1UAqn9VAP9/VQAAn1UAVZ9VAKqfVQD/n1UAAL9VAFW/VQCqv1UA/79VAADf - VQBV31UAqt9VAP/fVQAA/1UAVf9VAKr/VQD//1UAAAB/AFUAfwCqAH8A/wB/AAAffwBVH38Aqh9/AP8f - fwAAP38AVT9/AKo/fwD/P38AAF9/AFVffwCqX38A/19/AAB/fwBVf38Aqn9/AP9/fwAAn38AVZ9/AKqf - fwD/n38AAL9/AFW/fwCqv38A/79/AADffwBV338Aqt9/AP/ffwAA/38AVf9/AKr/fwD//38AAACqAFUA - qgCqAKoA/wCqAAAfqgBVH6oAqh+qAP8fqgAAP6oAVT+qAKo/qgD/P6oAAF+qAFVfqgCqX6oA/1+qAAB/ - qgBVf6oAqn+qAP9/qgAAn6oAVZ+qAKqfqgD/n6oAAL+qAFW/qgCqv6oA/7+qAADfqgBV36oAqt+qAP/f - qgAA/6oAVf+qAKr/qgD//6oAAADUAFUA1ACqANQA/wDUAAAf1ABVH9QAqh/UAP8f1AAAP9QAVT/UAKo/ - 1AD/P9QAAF/UAFVf1ACqX9QA/1/UAAB/1ABVf9QAqn/UAP9/1AAAn9QAVZ/UAKqf1AD/n9QAAL/UAFW/ - 1ACqv9QA/7/UAADf1ABV39QAqt/UAP/f1AAA/9QAVf/UAKr/1AD//9QAVQD/AKoA/wAAH/8AVR//AKof - /wD/H/8AAD//AFU//wCqP/8A/z//AABf/wBVX/8Aql//AP9f/wAAf/8AVX//AKp//wD/f/8AAJ//AFWf - /wCqn/8A/5//AAC//wBVv/8Aqr//AP+//wAA3/8AVd//AKrf/wD/3/8AVf//AKr//wD/zMwA/8z/AP// - MwD//2YA//+ZAP//zAAAfwAAVX8AAKp/AAD/fwAAAJ8AAFWfAACqnwAA/58AAAC/AABVvwAAqr8AAP+/ - AAAA3wAAVd8AAKrfAAD/3wAAVf8AAKr/AAAAACoAVQAqAKoAKgD/ACoAAB8qAFUfKgCqHyoA/x8qAAA/ - KgBVPyoA8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAAAAAAD//wAA////AP39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39qoYIqoYIhqoIqgiqCaoIqgiqhqqGhoYIhoYIqv39/f0I/f39 - /ar9/f39/YY2Ng4yDg4ODgoOCgoKCgqG/f39/Yb9/f39CP39/f39qjY7Ozs3Nzc3NjMSMjIOCqr9/f39 - qv39/f2G/f39/f0IN19fOzs3Nzc3NjcODg4KCP39/f0I/f39/ar9/f39/ao6X19fXzs7Ozc3NzY3NgqG - /f39/Yb9/f39CP39/f39hl9jY19jX187Ozs7Nzc3Dqr9/f39qv39/f2G/f39/f0IOodjh19jX19fXztf - OzcOCP39/f0ICAmqCAiqCKoICapfCYdjh2ODY19fXzs7Ow6q/f39/QhITEwoSCUoKSQoqmMJCYcJCWNj - Y2NfY19fNgj9/f39qkyZmZmYmJRwlCmqX19fXl9fX186WzY3Njc2gv39/f0JcJ2dmZmZlJmUJAmqCaoJ - hggIqggICKoIqggI/f39/YZwnp2dnZmZmJVMqnx8fHx8fFR8VHhUVFRUVKr9/f39CHChoZ2dnZ2ZmUwJ - fKSkxqSkxqSkpKSkpKBUCP39/f2qcKLDoqGdnZ2ZTKp8ysakxqSkxqSkxqSkpFSq/f39/QiUpqbDoqHE - nZ1Mq3ykqMakyqSkxqSkpKSkVAj9/f39hpTIyKbHoqGhoXAIfMrLpMqkxqSkxqTGpKRUqv39/f0IlMym - yKbIpcShcAh8y6jKpMqkxsqkpKSkxlQI/f39/aqUzMzMyKbIpqJwqnzLy8qpxsqkpMakxqSkeAj9/f39 - CJSUlJSUlJSUlJQJgMupy8qpysqkyqSkxqRUqv39/f2GCKoIqgiqCKoIhgigrcvPqcuoy8qkxsqkxnyG - /f39/ar9/f39/f39/f39qnzPz6nLy8uoyqnKpKTKVAj9/f39CP39/f39/f39/f0IfNDPz8+py8upyqjG - yqR8hv39/f2G/f39/f39/f39/Qik0K7P0M+ty8vLy6jKpXyq/f39/ar9/f39/f39/f39CHzQ09Ctz8/P - qcupy6jKeAj9/f39CP39/f39/f39/f2qoNPQ0NPQ0M/Qz8vLy6l8CP39/f2G/f39/f39/f39/QmkfKR8 - oHx8fHx8fHx8fHyG/f39/aoIqgiqCKoIqgiqCKoIqgiqCKoIqgiqCKoIqgj9/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f3///////////// - ///AAAAD3vgAA974AAPe+AAD3vgAA974AAPe+AADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA - AAPAAAADwAAAA8AAAAPAAAADwAAAA9/4AAPf+AAD3/gAA9/4AAPf+AAD3/gAA8AAAAP//////////ygA - AAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAA - gACAgAAAgICAAMDcwADwyqYAqj8qAP8/KgAAXyoAVV8qAKpfKgD/XyoAAH8qAFV/KgCqfyoA/38qAACf - KgBVnyoAqp8qAP+fKgAAvyoAVb8qAKq/KgD/vyoAAN8qAFXfKgCq3yoA/98qAAD/KgBV/yoAqv8qAP// - KgAAAFUAVQBVAKoAVQD/AFUAAB9VAFUfVQCqH1UA/x9VAAA/VQBVP1UAqj9VAP8/VQAAX1UAVV9VAKpf - VQD/X1UAAH9VAFV/VQCqf1UA/39VAACfVQBVn1UAqp9VAP+fVQAAv1UAVb9VAKq/VQD/v1UAAN9VAFXf - VQCq31UA/99VAAD/VQBV/1UAqv9VAP//VQAAAH8AVQB/AKoAfwD/AH8AAB9/AFUffwCqH38A/x9/AAA/ - fwBVP38Aqj9/AP8/fwAAX38AVV9/AKpffwD/X38AAH9/AFV/fwCqf38A/39/AACffwBVn38Aqp9/AP+f - fwAAv38AVb9/AKq/fwD/v38AAN9/AFXffwCq338A/99/AAD/fwBV/38Aqv9/AP//fwAAAKoAVQCqAKoA - qgD/AKoAAB+qAFUfqgCqH6oA/x+qAAA/qgBVP6oAqj+qAP8/qgAAX6oAVV+qAKpfqgD/X6oAAH+qAFV/ - qgCqf6oA/3+qAACfqgBVn6oAqp+qAP+fqgAAv6oAVb+qAKq/qgD/v6oAAN+qAFXfqgCq36oA/9+qAAD/ - qgBV/6oAqv+qAP//qgAAANQAVQDUAKoA1AD/ANQAAB/UAFUf1ACqH9QA/x/UAAA/1ABVP9QAqj/UAP8/ - 1AAAX9QAVV/UAKpf1AD/X9QAAH/UAFV/1ACqf9QA/3/UAACf1ABVn9QAqp/UAP+f1AAAv9QAVb/UAKq/ - 1AD/v9QAAN/UAFXf1ACq39QA/9/UAAD/1ABV/9QAqv/UAP//1ABVAP8AqgD/AAAf/wBVH/8Aqh//AP8f - /wAAP/8AVT//AKo//wD/P/8AAF//AFVf/wCqX/8A/1//AAB//wBVf/8Aqn//AP9//wAAn/8AVZ//AKqf - /wD/n/8AAL//AFW//wCqv/8A/7//AADf/wBV3/8Aqt//AP/f/wBV//8Aqv//AP/MzAD/zP8A//8zAP// - ZgD//5kA///MAAB/AABVfwAAqn8AAP9/AAAAnwAAVZ8AAKqfAAD/nwAAAL8AAFW/AACqvwAA/78AAADf - AABV3wAAqt8AAP/fAABV/wAAqv8AAAAAKgBVACoAqgAqAP8AKgAAHyoAVR8qAKofKgD/HyoAAD8qAFU/ - KgDw+/8ApKCgAICAgAAAAP8AAP8AAAD//wD/AAAAAAAAAP//AAD///8A/f39/f39/f39/f39/f39/f0I - hgiqCKoICKoICKaGCP39qv39hv2GNg4ODjII/ar9/Yb9/ar9qjdjXzsOCP2G/f0IhquGCAleCWNfNob9 - qv39qkxMTEgIX19fX18I/Qj9/QhwnZlMqoYIqggIqgiG/f2qcKadcAl8fFQDVFQDqv39CHDMpnCqfMvL - ysrKVAj9/QiUlHBwCYDPy8/LylSG/f2GqoYIqgig0M/Py8t8qv39CP39/f2GpNDQ0M/PfAn9/ar9/f39 - qqT20NDQ0Hyq/f2G/f39/QmkpKSloKR8CP39CKoIhgiqCIYIqgiGCKr9/f39/f39/f39/f39/f39/f// - hv2AAf0ItAX9/bQFX2OABWNfgAU7O4ABNzeAAf39gAGq/YAB/YaAAf39vAE6h7wBX2O8AV9fgAE7N/// - /f0oAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAADCv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/ - wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/ - wf/Cv8H/AAAAAAAAAAAAAAAAAAAAAMK/wf8AAAAAAAAAAAAAAAAAAAAAwr/B/wAAAAAAAAAAAAAAAAAA - AAAAAAAAwr/B/7Z3Sf+zckT/rm0//6toO/+nYjb/pF4y/6BZLv+dVCr/mlEn/5dNI/+VSiH/kkce/5FE - HP+RRBz/kUUb/8K/wf8AAAAAAAAAAAAAAAAAAAAAwr/B/wAAAAAAAAAAAAAAAAAAAADCv8H/AAAAAAAA - AAAAAAAAAAAAAAAAAADCv8H/v4JS//+aZv//lWD/+5Bc//WLV//uh1P/54FO/997S//Wdkb/zXBD/8Vr - QP+9Zj3/tGI5/65dN/+RRRz/wr/B/wAAAAAAAAAAAAAAAAAAAADCv8H/AAAAAAAAAAAAAAAAAAAAAMK/ - wf8AAAAAAAAAAAAAAAAAAAAAAAAAAMK/wf/GjFv//6Rz//+fbf//m2f//5Zh//yRXf/3jVj/8IhV/+mD - UP/hfUz/2HhI/9ByRP/HbED/v2c9/5VJIf/Cv8H/AAAAAAAAAAAAAAAAAAAAAMK/wf8AAAAAAAAAAAAA - AAAAAAAAwr/B/wAAAAAAAAAAAAAAAAAAAAAAAAAAwr/B/86WZP//r4L//6p7//+mdf//oW7//5xo//+X - Yv/9kl7/+I5a//KJVf/rhFH/4n5N/9t4SP/Sc0X/mlEm/8K/wf8AAAAAAAAAAAAAAAAAAAAAwr/B/wAA - AAAAAAAAAAAAAAAAAADCv8H/AAAAAAAAAAAAAAAAAAAAAAAAAADCv8H/1J9s//+4kf//tIv//6+E//+r - ff//p3f//6Jw//+eav//mWT//pRf//qQWv/0i1b/7IVS/+V/Tv+gWC7/wr/B/wAAAAAAAAAAAAAAAAAA - AADCv8H/AAAAAAAAAAAAAAAAAAAAAMK/wf8AAAAAAAAAAAAAAAAAAAAAAAAAAMK/wf/apnP//7+d//+7 - mP//uJL//7WM//+whv//rH///6d4//+jcf//n2v//5ll//+VYP/6kVv/9YxY/6diN//Cv8H/AAAAAAAA - AAAAAAAAAAAAAMK/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/96t - eP//wqL//8Gi//+/nv//vJn//7mT//+2jv//sYj//66A//+pev//pHP//6Bt//+bZ///l2L/r20//8K/ - wf8AAAAAAAAAAAAAAAAAAAAAwr/B/xYXev8XF3b/GBVx/xkUbf8ZFGr/GhNm/xoSY/8bEV//HBFd/xwQ - W//Cv8H/4K96///Cov//wqL//8Ki///Cov//wJ///72b//+6lf//t4///7KJ//+ugv//qnv//6V0//+h - bv+3d0n/wr/B/wAAAAAAAAAAAAAAAAAAAADCv8H/FRqE/0dN1v8/RNL/Nz3Q/y40zv8nLcz/ISfK/xwh - yf8WHMf/GxJh/8K/wf/gr3r/4K96/+Cvev/gr3r/3614/9yqdf/apnL/16Nw/9Sea//Rmmj/zZZk/8qR - X//GjFz/w4dW/7+CUv/Cv8H/AAAAAAAAAAAAAAAAAAAAAMK/wf8SHZD/WF3a/05U1/9FS9X/PUPS/zU7 - 0P8uM83/JyzL/yAmyf8aFGn/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/ - wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf8AAAAAAAAAAAAAAAAAAAAAwr/B/xAfnP9obt7/YGTc/1Zb - 2f9NU9f/RUrU/ztB0v80OdD/LDHO/xgWcv/Cv8H/Dn+n/w18pP8MeqH/DHie/wt1m/8Kc5j/CXGV/wlv - k/8JbJD/CGqN/wdpi/8HZ4j/BmWH/wZkhf8GYoP/wr/B/wAAAAAAAAAAAAAAAAAAAADCv8H/DiKp/3l+ - 4/9vdeH/Zmze/11i2/9UWtn/S1HW/0NI1P86P9H/Fhh9/8K/wf8Ogar/Barp/wGo6P8Apef/AKPm/wCi - 5P8An+L/AJ7h/wCd3/8AnN7/AJnc/wCY2/8AmNn/AJbX/wZjhP/Cv8H/AAAAAAAAAAAAAAAAAAAAAMK/ - wf8MJbX/iI7n/4CF5v93fOP/bnPg/2Vr3f9bYdv/UljY/0lP1v8UGoj/wr/B/w+Erf8Lrur/Bqvq/wOo - 6f8Apuf/AKTm/wCi5f8AoOT/AJ/i/wCd4f8AnN//AJrd/wCZ2/8AmNr/BmWH/8K/wf8AAAAAAAAAAAAA - AAAAAAAAwr/B/wkowP+WnOz/jpTq/4aL6P9+hOX/dXri/2xx4P9jaN3/WV/b/xEek//Cv8H/EIaw/xay - 7P8Or+z/Cavr/wWq6v8Bp+j/AKbn/wCj5f8AoeT/AJ/j/wCe4f8AnOD/AJve/wCa3f8HZ4n/wr/B/wAA - AAAAAAAAAAAAAAAAAADCv8H/CCrK/6Ko7/+coe7/lZrr/42T6f+Fiub/fIHl/3N54v9rcN//ECGg/8K/ - wf8QiLP/I7nu/xq07f8Ssez/C63r/war6v8Cqen/AKbo/wCk5v8AouX/AKHk/wCf4f8AneH/AJzf/who - i//Cv8H/AAAAAAAAAAAAAAAAAAAAAMK/wf8GLNP/q7Hy/6as8P+hpu//mp/u/5OY6/+LkOj/g4nm/3qA - 5P8NI6z/wr/B/xCKtv8xvvD/J7rv/x627f8Vsuz/Dq/s/wmr6/8Equn/Aafo/wCl5/8Ao+X/AKHk/wCf - 4v8AnuH/CGqO/8K/wf8AAAAAAAAAAAAAAAAAAAAAwr/B/wUu2/+vtPP/r7Tz/6qv8v+mq/D/oKXv/5me - 7f+Sl+v/io/p/wsmt//Cv8H/Eo24/0HF8f82wfD/LLzv/yK47v8atO3/EbHs/wut6/8Gq+r/A6np/wCm - 6P8Apeb/AKLl/wCh5P8IbJD/wr/B/wAAAAAAAAAAAAAAAAAAAADCv8H/BC/h/wQv3/8FL9z/BS3Z/wYt - 1v8GLNL/ByvP/wgqy/8IKcb/CSnC/8K/wf8Sjrv/Uszy/0fH8f87w/H/Mb7v/ye67/8et+7/FbPt/w6v - 6/8IrOv/BKnp/wGo6P8Apef/AKPl/wluk//Cv8H/AAAAAAAAAAAAAAAAAAAAAMK/wf/Cv8H/wr/B/8K/ - wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/xKRvf9j0/P/WM/z/0zK8f9BxfH/N8Hw/yy8 - 7/8iuO7/GbTt/xGx7P8Lruv/Bqrq/wOo6f8Apuf/CnGV/8K/wf8AAAAAAAAAAAAAAAAAAAAAwr/B/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCv8H/E5LA/3Ta8/9q1fP/XtHz/1LM - 8v9Hx/H/O8Pw/zG+7/8nu+//Hrbt/xay7f8Or+v/CKzq/wSq6f8Kc5j/wr/B/wAAAAAAAAAAAAAAAAAA - AADCv8H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMK/wf8UlMH/hOD1/3rc - 9f9v2PP/ZNTy/1jO8v9NyvH/Qsbx/zbB8P8svO//I7ju/xm07f8SsOz/C67r/wt2m//Cv8H/AAAAAAAA - AAAAAAAAAAAAAMK/wf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwr/B/xSW - w/+T5vb/iuL1/3/e9P912vT/adbz/13R8/9SzPL/R8jx/zzD8P8xvvD/J7rv/x627v8Vsuz/C3ie/8K/ - wf8AAAAAAAAAAAAAAAAAAAAAwr/B/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AADCv8H/FJbG/57r9/+X6Pb/juT1/4Th9f963fX/b9j0/2PT8/9Yz/L/TMrx/0HF8f83wO//LLzv/yK4 - 7v8MeqH/wr/B/wAAAAAAAAAAAAAAAAAAAADCv8H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAMK/wf8VmMf/qO/3/6Lt9/+b6vb/kub2/4rj9f9/3vX/dNrz/2rV8/9d0fP/Uszy/0fI - 8f88w/D/Mr7v/w19pP/Cv8H/AAAAAAAAAAAAAAAAAAAAAMK/wf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAwr/B/xWZyP8UmMf/FZfF/xSVw/8TlML/E5K//xOQvf8Sjrv/EYy4/xGK - tv8QiLL/D4Ww/w+Erf8Pgar/Dn+n/8K/wf8AAAAAAAAAAAAAAAAAAAAAwr/B/8K/wf/Cv8H/wr/B/8K/ - wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/ - wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/8K/wf/Cv8H/wr/B/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// - /////////////8AAAAPe+AAD3vgAA974AAPe+AAD3vgAA974AAPAAAADwAAAA8AAAAPAAAADwAAAA8AA - AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD3/gAA9/4AAPf+AAD3/gAA9/4AAPf+AADwAAAA/// - ////////KAAAABAAAAAgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDA/8DA - wP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP8AAAAAAAAAAMDA - wP8AAAAAAAAAAMDAwP8AAAAAwMDA/8F2R/+9bj//umc6/7diNf+3YjX/wMDA/wAAAADAwMD/AAAAAAAA - AADAwMD/AAAAAAAAAADAwMD/AAAAAMDAwP/RkmD//7aP//+ldP/8kl3/vW0//8DAwP8AAAAAwMDA/wAA - AAAAAAAAwMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/3ap2///Cov//to7//6V0/8uJWP/AwMD/AAAAAMDA - wP8AAAAAAAAAAMDAwP8THI7/FBqF/xYYfP8XFnP/wMDA/+Cvev/gr3r/4K96/92qdv/ao3D/wMDA/wAA - AADAwMD/AAAAAAAAAADAwMD/ECCd/2Fn3P8zOc//FRmC/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DA - wP/AwMD/wMDA/wAAAAAAAAAAwMDA/w0krP+Pler/YWbd/xIcj//AwMD/DHmf/wpzmP8Ib5L/B2uO/wdq - jf8Gao3/B2qN/8DAwP8AAAAAAAAAAMDAwP8KJrv/r7Tz/5CU6v8PIJ//wMDA/w+Dq/87y/z/Kcb8/xrD - /P8QwPv/EMD7/wdqjf/AwMD/AAAAAAAAAADAwMD/CCrI/woowP8LJrf/DSSu/8DAwP8Sjbj/Zdb9/0/Q - /P88y/v/Kcf7/xrC+/8IbZD/wMDA/wAAAAAAAAAAwMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/FpfG/43h - /f962/3/Zdb8/0/Q/P87zPz/CXSZ/8DAwP8AAAAAAAAAAMDAwP8AAAAAAAAAAAAAAAAAAAAAwMDA/xif - z/+u6f7/n+X9/47h/f953P3/ZNb9/w19pP/AwMD/AAAAAAAAAADAwMD/AAAAAAAAAAAAAAAAAAAAAMDA - wP8apNX/uez+/7ns/v+u6f7/oOX9/43h/f8Rh7H/wMDA/wAAAAAAAAAAwMDA/wAAAAAAAAAAAAAAAAAA - AADAwMD/GqTV/xqk1f8apNX/GaHR/xecy/8WmMb/FJK+/8DAwP8AAAAAAAAAAMDAwP/AwMD/wMDA/8DA - wP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAgAEAALQF - wf+0BQAAgAUAAIAFAACAAQAAgAHB/4ABAACAAQAAgAEAALwBAAC8AQAAvAHB/4ABbP///5H/ - - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Program.cs b/src/System.Windows.Forms/tests/AccessibilityTests/Program.cs deleted file mode 100644 index 2216c860adc..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Program.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -internal static class Program -{ - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - Application.SetHighDpiMode(HighDpiMode.PerMonitorV2); - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Main()); - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Properties/Resources.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/Properties/Resources.Designer.cs deleted file mode 100644 index 098f32ef98d..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Properties/Resources.Designer.cs +++ /dev/null @@ -1,72 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Accessibility_Core_App.Properties; -using System; - - -/// -/// A strongly-typed resource class, for looking up localized strings, etc. -/// -// This class was auto-generated by the StronglyTypedResourceBuilder -// class via a tool like ResGen or Visual Studio. -// To add or remove a member, edit your .ResX file then rerun ResGen -// with the /str option, or rebuild your VS project. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] -[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] -[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] -internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Accessibility_Core_App.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap TestResult { - get { - object obj = ResourceManager.GetObject("TestResult", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Properties/Resources.resx b/src/System.Windows.Forms/tests/AccessibilityTests/Properties/Resources.resx deleted file mode 100644 index e546aadddd1..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Properties/Resources.resx +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Resources\TestResult.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/RemainingControls.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/RemainingControls.Designer.cs deleted file mode 100644 index b86b8cb7adc..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/RemainingControls.Designer.cs +++ /dev/null @@ -1,146 +0,0 @@ -namespace Accessibility_Core_App; - -partial class RemainingControls -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.hScrollBar1 = new System.Windows.Forms.HScrollBar(); - this.vScrollBar1 = new System.Windows.Forms.VScrollBar(); - this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); - this.propertyGrid2 = new System.Windows.Forms.PropertyGrid(); - this.label1 = new System.Windows.Forms.Label(); - this.domainUpDown1 = new System.Windows.Forms.DomainUpDown(); - this.label2 = new System.Windows.Forms.Label(); - this.trackBar1 = new System.Windows.Forms.TrackBar(); - ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit(); - this.SuspendLayout(); - // - // hScrollBar1 - // - this.hScrollBar1.Dock = System.Windows.Forms.DockStyle.Bottom; - this.hScrollBar1.Location = new System.Drawing.Point(0, 406); - this.hScrollBar1.Name = "hScrollBar1"; - this.hScrollBar1.Size = new System.Drawing.Size(593, 17); - this.hScrollBar1.TabIndex = 7; - this.hScrollBar1.TabStop = true; - // - // vScrollBar1 - // - this.vScrollBar1.Dock = System.Windows.Forms.DockStyle.Right; - this.vScrollBar1.Location = new System.Drawing.Point(576, 0); - this.vScrollBar1.Name = "vScrollBar1"; - this.vScrollBar1.Size = new System.Drawing.Size(17, 406); - this.vScrollBar1.TabIndex = 4; - this.vScrollBar1.TabStop = true; - // - // propertyGrid1 - // - this.propertyGrid1.Location = new System.Drawing.Point(19, 80); - this.propertyGrid1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.propertyGrid1.Name = "propertyGrid1"; - this.propertyGrid1.Size = new System.Drawing.Size(266, 282); - this.propertyGrid1.TabIndex = 5; - // - // propertyGrid2 - // - this.propertyGrid2.Location = new System.Drawing.Point(292, 80); - this.propertyGrid2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.propertyGrid2.Name = "propertyGrid2"; - this.propertyGrid2.Size = new System.Drawing.Size(260, 282); - this.propertyGrid2.TabIndex = 6; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(19, 33); - this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(156, 15); - this.label1.TabIndex = 0; - this.label1.Text = "Setting for DomainUpDown:"; - // - // domainUpDown1 - // - this.domainUpDown1.Location = new System.Drawing.Point(192, 31); - this.domainUpDown1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.domainUpDown1.Name = "domainUpDown1"; - this.domainUpDown1.Size = new System.Drawing.Size(140, 23); - this.domainUpDown1.TabIndex = 1; - this.domainUpDown1.Text = "domainUpDown1"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(373, 33); - this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(37, 15); - this.label2.TabIndex = 2; - this.label2.Text = "Track:"; - // - // trackBar1 - // - this.trackBar1.Location = new System.Drawing.Point(431, 29); - this.trackBar1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.trackBar1.Name = "trackBar1"; - this.trackBar1.Size = new System.Drawing.Size(121, 45); - this.trackBar1.TabIndex = 3; - // - // RemainingControls - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(593, 423); - this.Controls.Add(this.trackBar1); - this.Controls.Add(this.label2); - this.Controls.Add(this.domainUpDown1); - this.Controls.Add(this.label1); - this.Controls.Add(this.propertyGrid2); - this.Controls.Add(this.propertyGrid1); - this.Controls.Add(this.vScrollBar1); - this.Controls.Add(this.hScrollBar1); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "RemainingControls"; - this.Text = "RemainingControls"; - this.Load += new System.EventHandler(this.Form1_Load); - ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - private System.Windows.Forms.HScrollBar hScrollBar1; - private System.Windows.Forms.VScrollBar vScrollBar1; - private System.Windows.Forms.PropertyGrid propertyGrid1; - private System.Windows.Forms.PropertyGrid propertyGrid2; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.DomainUpDown domainUpDown1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.TrackBar trackBar1; -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/RemainingControls.cs b/src/System.Windows.Forms/tests/AccessibilityTests/RemainingControls.cs deleted file mode 100644 index e0b0c6b48ff..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/RemainingControls.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class RemainingControls : Form -{ - public RemainingControls() - { - InitializeComponent(); - } - - private void Form1_Load(object sender, EventArgs e) - { - propertyGrid1.SelectedObject = domainUpDown1; - propertyGrid2.SelectedObject = trackBar1; - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/RemainingControls.resx b/src/System.Windows.Forms/tests/AccessibilityTests/RemainingControls.resx deleted file mode 100644 index f298a7be809..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/RemainingControls.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Resources/TestResult.png b/src/System.Windows.Forms/tests/AccessibilityTests/Resources/TestResult.png deleted file mode 100644 index caa694fdb73..00000000000 Binary files a/src/System.Windows.Forms/tests/AccessibilityTests/Resources/TestResult.png and /dev/null differ diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/Student.cs b/src/System.Windows.Forms/tests/AccessibilityTests/Student.cs deleted file mode 100644 index 1379e7ab848..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/Student.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Accessibility_Core_App; - -public class Student -{ - public Student(int studentNumber, string name, string sex) - { - StudentNumber = studentNumber; - Name = name; - Sex = sex; - } - - public Student(int studentNumber, string name, string sex, int phoneNumber, string homeNumber, string hobby, bool isStudent, int count, int luckyNumber) - { - StudentNumber = studentNumber; - Name = name; - Sex = sex; - PhoneNumber = phoneNumber; - HomeNumber = homeNumber; - IsStudent = isStudent; - Hobby = hobby; - Count = count; - LuckyNumber = luckyNumber; - } - - public int StudentNumber { get; set; } - - public string Name { get; set; } - - public string Sex { get; set; } - - public int PhoneNumber { get; set; } - - public string HomeNumber { get; set; } - - public string Hobby { get; set; } - - public bool IsStudent { get; set; } - - public int Count { get; set; } - - public int LuckyNumber { get; set; } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/TaskDialogTesting.cs b/src/System.Windows.Forms/tests/AccessibilityTests/TaskDialogTesting.cs deleted file mode 100644 index 3e3773acaa3..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/TaskDialogTesting.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class TaskDialogTesting -{ - internal void ShowEventsDemoTaskDialog() - { - var page1 = new TaskDialogPage() - { - Caption = nameof(TaskDialogTesting), - Heading = "Event Demo", - Text = "Event Demo...", - }; - - page1.Created += (s, e) => Console.WriteLine("Page1 Created"); - page1.Destroyed += (s, e) => Console.WriteLine("Page1 Destroyed"); - page1.HelpRequest += (s, e) => Console.WriteLine("Page1 HelpRequest"); - - page1.Expander = new TaskDialogExpander("Expander") - { - Position = TaskDialogExpanderPosition.AfterFootnote - }; - - page1.Expander.ExpandedChanged += (s, e) => Console.WriteLine($"Expander ExpandedChanged: {page1.Expander.Expanded}"); - - var buttonOK = TaskDialogButton.OK; - var buttonHelp = TaskDialogButton.Help; - var buttonCancelClose = new TaskDialogCommandLinkButton("C&ancel Close", allowCloseDialog: false); - var buttonShowInnerDialog = new TaskDialogCommandLinkButton("&Show (modeless) Inner Dialog", "(and don't cancel the Close)"); - var buttonNavigate = new TaskDialogCommandLinkButton("&Navigate", allowCloseDialog: false); - - page1.Buttons.Add(buttonOK); - page1.Buttons.Add(buttonHelp); - page1.Buttons.Add(buttonCancelClose); - page1.Buttons.Add(buttonShowInnerDialog); - page1.Buttons.Add(buttonNavigate); - - buttonOK.Click += (s, e) => Console.WriteLine($"Button '{s}' Click"); - buttonHelp.Click += (s, e) => Console.WriteLine($"Button '{s}' Click"); - - buttonCancelClose.Click += (s, e) => - { - Console.WriteLine($"Button '{s}' Click"); - }; - - buttonShowInnerDialog.Click += (s, e) => - { - Console.WriteLine($"Button '{s}' Click"); - TaskDialog.ShowDialog(new TaskDialogPage() - { - Text = "Inner Dialog" - }); - Console.WriteLine($"(returns) Button '{s}' Click"); - }; - - buttonNavigate.Click += (s, e) => - { - Console.WriteLine($"Button '{s}' Click"); - - // Navigate to a new page. - var page2 = new TaskDialogPage() - { - Heading = "AfterNavigation.", - Buttons = - { - TaskDialogButton.Close - } - }; - page2.Created += (s, e) => Console.WriteLine("Page2 Created"); - page2.Destroyed += (s, e) => Console.WriteLine("Page2 Destroyed"); - - page1.Navigate(page2); - }; - - page1.Verification = new TaskDialogVerificationCheckBox("&CheckBox1"); - page1.Verification.CheckedChanged += (s, e) => Console.WriteLine($"CheckBox CheckedChanged: {page1.Verification.Checked}"); - - var radioButton1 = page1.RadioButtons.Add("Radi&oButton1"); - var radioButton2 = page1.RadioButtons.Add("RadioB&utton2"); - - radioButton1.CheckedChanged += (s, e) => Console.WriteLine($"RadioButton1 CheckedChanged: {radioButton1.Checked}"); - radioButton2.CheckedChanged += (s, e) => Console.WriteLine($"RadioButton2 CheckedChanged: {radioButton2.Checked}"); - - var dialogResult = TaskDialog.ShowDialog(page1); - Console.WriteLine($"---> Dialog Result: {dialogResult}"); - } -} - diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/ToolStripContainer.Designer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/ToolStripContainer.Designer.cs deleted file mode 100644 index 6f82e6dd89c..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/ToolStripContainer.Designer.cs +++ /dev/null @@ -1,673 +0,0 @@ -namespace Accessibility_Core_App; - -partial class ToolStripContainer -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ToolStripContainer)); - this.toolStripContainer2 = new System.Windows.Forms.ToolStripContainer(); - this.toolStrip1 = new System.Windows.Forms.ToolStrip(); - this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); - this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); - this.toolStripSplitButton1 = new System.Windows.Forms.ToolStripSplitButton(); - this.toolStripToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.newToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.openToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.saveToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.printToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); - this.cutToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.copyToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.pasteToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); - this.helpToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.toolStripComboBox1 = new System.Windows.Forms.ToolStripComboBox(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); - this.toolStripDropDownButton1 = new System.Windows.Forms.ToolStripDropDownButton(); - this.statusStripToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSplitButton2 = new System.Windows.Forms.ToolStripSplitButton(); - this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); - this.toolStripStatusLabel2 = new System.Windows.Forms.ToolStripStatusLabel(); - this.menuStrip1 = new System.Windows.Forms.MenuStrip(); - this.menuStripToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.menuStripItem1ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator(); - this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.printToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.printPreviewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.undoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.redoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); - this.cutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.pasteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); - this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.customizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.indexToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); - this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.button1 = new System.Windows.Forms.Button(); - this.toolStripContainer2.ContentPanel.SuspendLayout(); - this.toolStripContainer2.TopToolStripPanel.SuspendLayout(); - this.toolStripContainer2.SuspendLayout(); - this.toolStrip1.SuspendLayout(); - this.statusStrip1.SuspendLayout(); - this.menuStrip1.SuspendLayout(); - this.SuspendLayout(); - // - // toolStripContainer2 - // - // - // toolStripContainer2.ContentPanel - // - this.toolStripContainer2.ContentPanel.Controls.Add(this.toolStrip1); - this.toolStripContainer2.ContentPanel.Controls.Add(this.statusStrip1); - this.toolStripContainer2.ContentPanel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.toolStripContainer2.ContentPanel.Size = new System.Drawing.Size(486, 239); - this.toolStripContainer2.Location = new System.Drawing.Point(76, 44); - this.toolStripContainer2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.toolStripContainer2.Name = "toolStripContainer2"; - this.toolStripContainer2.Size = new System.Drawing.Size(486, 263); - this.toolStripContainer2.TabIndex = 2; - this.toolStripContainer2.Text = "toolStripContainer2"; - // - // toolStripContainer2.TopToolStripPanel - // - this.toolStripContainer2.TopToolStripPanel.Controls.Add(this.menuStrip1); - // - // toolStrip1 - // - this.toolStrip1.ContextMenuStrip = this.contextMenuStrip1; - this.toolStrip1.Dock = System.Windows.Forms.DockStyle.Bottom; - this.toolStrip1.ImageScalingSize = new System.Drawing.Size(32, 32); - this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripButton1, - this.toolStripSplitButton1, - this.newToolStripButton, - this.openToolStripButton, - this.saveToolStripButton, - this.printToolStripButton, - this.toolStripSeparator6, - this.cutToolStripButton, - this.copyToolStripButton, - this.pasteToolStripButton, - this.toolStripSeparator7, - this.helpToolStripButton, - this.toolStripComboBox1}); - this.toolStrip1.Location = new System.Drawing.Point(0, 200); - this.toolStrip1.Name = "toolStrip1"; - this.toolStrip1.Padding = new System.Windows.Forms.Padding(0, 0, 2, 0); - this.toolStrip1.Size = new System.Drawing.Size(486, 39); - this.toolStrip1.TabIndex = 1; - this.toolStrip1.TabStop = true; - this.toolStrip1.Text = "toolStrip1"; - // - // contextMenuStrip1 - // - this.contextMenuStrip1.ImageScalingSize = new System.Drawing.Size(32, 32); - this.contextMenuStrip1.Name = "contextMenuStrip1"; - this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); - // - // toolStripButton1 - // - this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image"))); - this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButton1.Name = "toolStripButton1"; - this.toolStripButton1.Size = new System.Drawing.Size(36, 36); - this.toolStripButton1.Text = "toolStrip_Button1"; - // - // toolStripSplitButton1 - // - this.toolStripSplitButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripSplitButton1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripToolStripMenuItem}); - this.toolStripSplitButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripSplitButton1.Image"))); - this.toolStripSplitButton1.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripSplitButton1.Name = "toolStripSplitButton1"; - this.toolStripSplitButton1.Size = new System.Drawing.Size(48, 36); - this.toolStripSplitButton1.Text = "toolStrip_SplitButton1"; - // - // toolStripToolStripMenuItem - // - this.toolStripToolStripMenuItem.Name = "toolStripToolStripMenuItem"; - this.toolStripToolStripMenuItem.Size = new System.Drawing.Size(180, 22); - this.toolStripToolStripMenuItem.Text = "ToolStrip"; - // - // newToolStripButton - // - this.newToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.newToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("newToolStripButton.Image"))); - this.newToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.newToolStripButton.Name = "newToolStripButton"; - this.newToolStripButton.Size = new System.Drawing.Size(36, 36); - this.newToolStripButton.Text = "&New"; - // - // openToolStripButton - // - this.openToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.openToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("openToolStripButton.Image"))); - this.openToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.openToolStripButton.Name = "openToolStripButton"; - this.openToolStripButton.Size = new System.Drawing.Size(36, 36); - this.openToolStripButton.Text = "&Open"; - // - // saveToolStripButton - // - this.saveToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.saveToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripButton.Image"))); - this.saveToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.saveToolStripButton.Name = "saveToolStripButton"; - this.saveToolStripButton.Size = new System.Drawing.Size(36, 36); - this.saveToolStripButton.Text = "&Save"; - // - // printToolStripButton - // - this.printToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.printToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("printToolStripButton.Image"))); - this.printToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.printToolStripButton.Name = "printToolStripButton"; - this.printToolStripButton.Size = new System.Drawing.Size(36, 36); - this.printToolStripButton.Text = "&Print"; - // - // toolStripSeparator6 - // - this.toolStripSeparator6.Name = "toolStripSeparator6"; - this.toolStripSeparator6.Size = new System.Drawing.Size(6, 39); - // - // cutToolStripButton - // - this.cutToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.cutToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("cutToolStripButton.Image"))); - this.cutToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.cutToolStripButton.Name = "cutToolStripButton"; - this.cutToolStripButton.Size = new System.Drawing.Size(36, 36); - this.cutToolStripButton.Text = "C&ut"; - // - // copyToolStripButton - // - this.copyToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.copyToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("copyToolStripButton.Image"))); - this.copyToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.copyToolStripButton.Name = "copyToolStripButton"; - this.copyToolStripButton.Size = new System.Drawing.Size(36, 36); - this.copyToolStripButton.Text = "&Copy"; - // - // pasteToolStripButton - // - this.pasteToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.pasteToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("pasteToolStripButton.Image"))); - this.pasteToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.pasteToolStripButton.Name = "pasteToolStripButton"; - this.pasteToolStripButton.Size = new System.Drawing.Size(36, 36); - this.pasteToolStripButton.Text = "&Paste"; - // - // toolStripSeparator7 - // - this.toolStripSeparator7.Name = "toolStripSeparator7"; - this.toolStripSeparator7.Size = new System.Drawing.Size(6, 39); - // - // helpToolStripButton - // - this.helpToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.helpToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("helpToolStripButton.Image"))); - this.helpToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.helpToolStripButton.Name = "helpToolStripButton"; - this.helpToolStripButton.Size = new System.Drawing.Size(36, 36); - this.helpToolStripButton.Text = "He&lp"; - // - // toolStripComboBox1 - // - this.toolStripComboBox1.AccessibleName = "ComBo_Box"; - this.toolStripComboBox1.Items.AddRange(new object[] { - "1", - "2", - "3", - "4", - "5"}); - this.toolStripComboBox1.Name = "toolStripComboBox1"; - this.toolStripComboBox1.Size = new System.Drawing.Size(106, 23); - // - // statusStrip1 - // - this.statusStrip1.Dock = System.Windows.Forms.DockStyle.Top; - this.statusStrip1.ImageScalingSize = new System.Drawing.Size(32, 32); - this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripDropDownButton1, - this.toolStripSplitButton2, - this.toolStripStatusLabel1, - this.toolStripStatusLabel2}); - this.statusStrip1.Location = new System.Drawing.Point(0, 0); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 16, 0); - this.statusStrip1.ShowItemToolTips = true; - this.statusStrip1.Size = new System.Drawing.Size(486, 38); - this.statusStrip1.TabIndex = 0; - this.statusStrip1.TabStop = true; - this.statusStrip1.Text = "statusStrip1"; - // - // toolStripDropDownButton1 - // - this.toolStripDropDownButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripDropDownButton1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.statusStripToolStripMenuItem}); - this.toolStripDropDownButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripDropDownButton1.Image"))); - this.toolStripDropDownButton1.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripDropDownButton1.Name = "toolStripDropDownButton1"; - this.toolStripDropDownButton1.Size = new System.Drawing.Size(45, 36); - this.toolStripDropDownButton1.Text = "toolStripDropDownButton1"; - // - // statusStripToolStripMenuItem - // - this.statusStripToolStripMenuItem.Name = "statusStripToolStripMenuItem"; - this.statusStripToolStripMenuItem.Size = new System.Drawing.Size(130, 22); - this.statusStripToolStripMenuItem.Text = "StatusStrip"; - // - // toolStripSplitButton2 - // - this.toolStripSplitButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripSplitButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripSplitButton2.Image"))); - this.toolStripSplitButton2.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripSplitButton2.Name = "toolStripSplitButton2"; - this.toolStripSplitButton2.Size = new System.Drawing.Size(48, 36); - this.toolStripSplitButton2.Text = "toolStripSplitButton2"; - // - // toolStripStatusLabel1 - // - this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; - this.toolStripStatusLabel1.Size = new System.Drawing.Size(118, 33); - this.toolStripStatusLabel1.Text = "toolStripStatusLabel1"; - this.toolStripStatusLabel1.ToolTipText = "toolStripStatusLabel1"; - // - // toolStripStatusLabel2 - // - this.toolStripStatusLabel2.Name = "toolStripStatusLabel2"; - this.toolStripStatusLabel2.Size = new System.Drawing.Size(118, 33); - this.toolStripStatusLabel2.Text = "toolStripStatusLabel2"; - this.toolStripStatusLabel2.ToolTipText = "toolStripStatusLabel2"; - // - // menuStrip1 - // - this.menuStrip1.Dock = System.Windows.Forms.DockStyle.None; - this.menuStrip1.ImageScalingSize = new System.Drawing.Size(32, 32); - this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.menuStripToolStripMenuItem, - this.fileToolStripMenuItem, - this.editToolStripMenuItem, - this.toolsToolStripMenuItem, - this.helpToolStripMenuItem}); - this.menuStrip1.Location = new System.Drawing.Point(0, 0); - this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.ShowItemToolTips = true; - this.menuStrip1.Size = new System.Drawing.Size(486, 24); - this.menuStrip1.TabIndex = 0; - this.menuStrip1.TabStop = true; - this.menuStrip1.Text = "menuStrip1"; - // - // menuStripToolStripMenuItem - // - this.menuStripToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.menuStripItem1ToolStripMenuItem}); - this.menuStripToolStripMenuItem.Name = "menuStripToolStripMenuItem"; - this.menuStripToolStripMenuItem.Size = new System.Drawing.Size(74, 20); - this.menuStripToolStripMenuItem.Text = "MenuStrip"; - this.menuStripToolStripMenuItem.ToolTipText = "menuStripToolStripMenuItem"; - // - // menuStripItem1ToolStripMenuItem - // - this.menuStripItem1ToolStripMenuItem.Name = "menuStripItem1ToolStripMenuItem"; - this.menuStripItem1ToolStripMenuItem.Size = new System.Drawing.Size(159, 22); - this.menuStripItem1ToolStripMenuItem.Text = "MenuStripItem1"; - this.menuStripItem1ToolStripMenuItem.ToolTipText = "MenuStripToolStripMenuItem"; - // - // fileToolStripMenuItem - // - this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.newToolStripMenuItem, - this.openToolStripMenuItem, - this.toolStripSeparator, - this.saveToolStripMenuItem, - this.saveAsToolStripMenuItem, - this.toolStripSeparator1, - this.printToolStripMenuItem, - this.printPreviewToolStripMenuItem, - this.toolStripSeparator2, - this.exitToolStripMenuItem}); - this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; - this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); - this.fileToolStripMenuItem.Text = "&File"; - this.fileToolStripMenuItem.ToolTipText = "File"; - // - // newToolStripMenuItem - // - this.newToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("newToolStripMenuItem.Image"))); - this.newToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.newToolStripMenuItem.Name = "newToolStripMenuItem"; - this.newToolStripMenuItem.Size = new System.Drawing.Size(143, 22); - this.newToolStripMenuItem.Text = "&New"; - // - // openToolStripMenuItem - // - this.openToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("openToolStripMenuItem.Image"))); - this.openToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.openToolStripMenuItem.Name = "openToolStripMenuItem"; - this.openToolStripMenuItem.Size = new System.Drawing.Size(143, 22); - this.openToolStripMenuItem.Text = "&Open"; - // - // toolStripSeparator - // - this.toolStripSeparator.Name = "toolStripSeparator"; - this.toolStripSeparator.Size = new System.Drawing.Size(140, 6); - // - // saveToolStripMenuItem - // - this.saveToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem.Image"))); - this.saveToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; - this.saveToolStripMenuItem.Size = new System.Drawing.Size(143, 22); - this.saveToolStripMenuItem.Text = "&Save"; - // - // saveAsToolStripMenuItem - // - this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; - this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(143, 22); - this.saveAsToolStripMenuItem.Text = "Save &As"; - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(140, 6); - // - // printToolStripMenuItem - // - this.printToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("printToolStripMenuItem.Image"))); - this.printToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.printToolStripMenuItem.Name = "printToolStripMenuItem"; - this.printToolStripMenuItem.Size = new System.Drawing.Size(143, 22); - this.printToolStripMenuItem.Text = "&Print"; - // - // printPreviewToolStripMenuItem - // - this.printPreviewToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("printPreviewToolStripMenuItem.Image"))); - this.printPreviewToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.printPreviewToolStripMenuItem.Name = "printPreviewToolStripMenuItem"; - this.printPreviewToolStripMenuItem.Size = new System.Drawing.Size(143, 22); - this.printPreviewToolStripMenuItem.Text = "Print Pre&view"; - // - // toolStripSeparator2 - // - this.toolStripSeparator2.Name = "toolStripSeparator2"; - this.toolStripSeparator2.Size = new System.Drawing.Size(140, 6); - // - // exitToolStripMenuItem - // - this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; - this.exitToolStripMenuItem.Size = new System.Drawing.Size(143, 22); - this.exitToolStripMenuItem.Text = "E&xit"; - // - // editToolStripMenuItem - // - this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.undoToolStripMenuItem, - this.redoToolStripMenuItem, - this.toolStripSeparator3, - this.cutToolStripMenuItem, - this.copyToolStripMenuItem, - this.pasteToolStripMenuItem, - this.toolStripSeparator4, - this.selectAllToolStripMenuItem}); - this.editToolStripMenuItem.Name = "editToolStripMenuItem"; - this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20); - this.editToolStripMenuItem.Text = "&Edit"; - this.editToolStripMenuItem.ToolTipText = "Edit"; - // - // undoToolStripMenuItem - // - this.undoToolStripMenuItem.Name = "undoToolStripMenuItem"; - this.undoToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.undoToolStripMenuItem.Text = "&Undo"; - // - // redoToolStripMenuItem - // - this.redoToolStripMenuItem.Name = "redoToolStripMenuItem"; - this.redoToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.redoToolStripMenuItem.Text = "&Redo"; - // - // toolStripSeparator3 - // - this.toolStripSeparator3.Name = "toolStripSeparator3"; - this.toolStripSeparator3.Size = new System.Drawing.Size(119, 6); - // - // cutToolStripMenuItem - // - this.cutToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("cutToolStripMenuItem.Image"))); - this.cutToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.cutToolStripMenuItem.Name = "cutToolStripMenuItem"; - this.cutToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.cutToolStripMenuItem.Text = "Cu&t"; - // - // copyToolStripMenuItem - // - this.copyToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("copyToolStripMenuItem.Image"))); - this.copyToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.copyToolStripMenuItem.Name = "copyToolStripMenuItem"; - this.copyToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.copyToolStripMenuItem.Text = "&Copy"; - // - // pasteToolStripMenuItem - // - this.pasteToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("pasteToolStripMenuItem.Image"))); - this.pasteToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.pasteToolStripMenuItem.Name = "pasteToolStripMenuItem"; - this.pasteToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.pasteToolStripMenuItem.Text = "&Paste"; - // - // toolStripSeparator4 - // - this.toolStripSeparator4.Name = "toolStripSeparator4"; - this.toolStripSeparator4.Size = new System.Drawing.Size(119, 6); - // - // selectAllToolStripMenuItem - // - this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem"; - this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.selectAllToolStripMenuItem.Text = "Select &All"; - // - // toolsToolStripMenuItem - // - this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.customizeToolStripMenuItem, - this.optionsToolStripMenuItem}); - this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; - this.toolsToolStripMenuItem.Size = new System.Drawing.Size(46, 20); - this.toolsToolStripMenuItem.Text = "&Tools"; - this.toolsToolStripMenuItem.ToolTipText = "Tools"; - // - // customizeToolStripMenuItem - // - this.customizeToolStripMenuItem.Name = "customizeToolStripMenuItem"; - this.customizeToolStripMenuItem.Size = new System.Drawing.Size(130, 22); - this.customizeToolStripMenuItem.Text = "&Customize"; - // - // optionsToolStripMenuItem - // - this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; - this.optionsToolStripMenuItem.Size = new System.Drawing.Size(130, 22); - this.optionsToolStripMenuItem.Text = "&Options"; - // - // helpToolStripMenuItem - // - this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.contentsToolStripMenuItem, - this.indexToolStripMenuItem, - this.searchToolStripMenuItem, - this.toolStripSeparator5, - this.aboutToolStripMenuItem}); - this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); - this.helpToolStripMenuItem.Text = "&Help"; - this.helpToolStripMenuItem.ToolTipText = "Help"; - // - // contentsToolStripMenuItem - // - this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; - this.contentsToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.contentsToolStripMenuItem.Text = "&Contents"; - // - // indexToolStripMenuItem - // - this.indexToolStripMenuItem.Name = "indexToolStripMenuItem"; - this.indexToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.indexToolStripMenuItem.Text = "&Index"; - // - // searchToolStripMenuItem - // - this.searchToolStripMenuItem.Name = "searchToolStripMenuItem"; - this.searchToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.searchToolStripMenuItem.Text = "&Search"; - // - // toolStripSeparator5 - // - this.toolStripSeparator5.Name = "toolStripSeparator5"; - this.toolStripSeparator5.Size = new System.Drawing.Size(119, 6); - // - // aboutToolStripMenuItem - // - this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; - this.aboutToolStripMenuItem.Size = new System.Drawing.Size(122, 22); - this.aboutToolStripMenuItem.Text = "&About..."; - // - // button1 - // - this.button1.Location = new System.Drawing.Point(40, 369); - this.button1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(88, 27); - this.button1.TabIndex = 3; - this.button1.Text = "button1"; - this.button1.UseVisualStyleBackColor = true; - // - // ToolStripContainer - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(627, 362); - this.Controls.Add(this.button1); - this.Controls.Add(this.toolStripContainer2); - this.MainMenuStrip = this.menuStrip1; - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "ToolStripContainer"; - this.Text = "ToolStripContainer"; - this.toolStripContainer2.ContentPanel.ResumeLayout(false); - this.toolStripContainer2.ContentPanel.PerformLayout(); - this.toolStripContainer2.TopToolStripPanel.ResumeLayout(false); - this.toolStripContainer2.TopToolStripPanel.PerformLayout(); - this.toolStripContainer2.ResumeLayout(false); - this.toolStripContainer2.PerformLayout(); - this.toolStrip1.ResumeLayout(false); - this.toolStrip1.PerformLayout(); - this.statusStrip1.ResumeLayout(false); - this.statusStrip1.PerformLayout(); - this.menuStrip1.ResumeLayout(false); - this.menuStrip1.PerformLayout(); - this.ResumeLayout(false); - - } - - #endregion - private System.Windows.Forms.ToolStripContainer toolStripContainer2; - private System.Windows.Forms.ToolStrip toolStrip1; - private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; - private System.Windows.Forms.ToolStripButton toolStripButton1; - private System.Windows.Forms.ToolStripSplitButton toolStripSplitButton1; - private System.Windows.Forms.ToolStripMenuItem toolStripToolStripMenuItem; - private System.Windows.Forms.StatusStrip statusStrip1; - private System.Windows.Forms.ToolStripDropDownButton toolStripDropDownButton1; - private System.Windows.Forms.ToolStripMenuItem statusStripToolStripMenuItem; - private System.Windows.Forms.ToolStripSplitButton toolStripSplitButton2; - private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; - private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel2; - private System.Windows.Forms.MenuStrip menuStrip1; - private System.Windows.Forms.ToolStripMenuItem menuStripToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem menuStripItem1ToolStripMenuItem; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.ToolStripButton newToolStripButton; - private System.Windows.Forms.ToolStripButton openToolStripButton; - private System.Windows.Forms.ToolStripButton saveToolStripButton; - private System.Windows.Forms.ToolStripButton printToolStripButton; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; - private System.Windows.Forms.ToolStripButton cutToolStripButton; - private System.Windows.Forms.ToolStripButton copyToolStripButton; - private System.Windows.Forms.ToolStripButton pasteToolStripButton; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; - private System.Windows.Forms.ToolStripButton helpToolStripButton; - private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator; - private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.ToolStripMenuItem printToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem printPreviewToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; - private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem undoToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem redoToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; - private System.Windows.Forms.ToolStripMenuItem cutToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem copyToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem pasteToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; - private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem customizeToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem indexToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem searchToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; - private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; - private System.Windows.Forms.ToolStripComboBox toolStripComboBox1; -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/ToolStripContainer.cs b/src/System.Windows.Forms/tests/AccessibilityTests/ToolStripContainer.cs deleted file mode 100644 index f43e91ff7ad..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/ToolStripContainer.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Windows.Forms; - -namespace Accessibility_Core_App; - -public partial class ToolStripContainer : Form -{ - public ToolStripContainer() - { - InitializeComponent(); - } -} diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/ToolStripContainer.resx b/src/System.Windows.Forms/tests/AccessibilityTests/ToolStripContainer.resx deleted file mode 100644 index 8eb159e0050..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/ToolStripContainer.resx +++ /dev/null @@ -1,363 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 122, 17 - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG - YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 - 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw - bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc - VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 - c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 - Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo - mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ - kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D - TgDQASA1MVpwzwAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG - YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 - 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw - bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc - VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 - c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 - Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo - mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ - kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D - TgDQASA1MVpwzwAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAERSURBVDhPrZDbSgJRGIXnpewd6jXsjSQvIrwoI0RQMChU - 0iiDPCGiE3ZCRkvR8VzTeBhnyR5/ccaZNnPhB4t9sdf6Ln5hb8QeathNJFVFKF5C8DqL4ksDVHWGDf7j - LHyPg6NjviSaFqlu5yQYR+KpupaIkrMknCxT3Y7v/NYYb0ITK1c3BarbWWhLQ7IR0cTKReyZ6lZ0XYei - ztHpK4bAc+h1FgQijzSxMptrGIxVSO0xX3AaStFki7bUMVFmaMm/eJMGfIH/MkGzLep0AXn4h/r3CJV3 - mS9gn2bY4UY/UzQ7E9TqfeTFtnuB+XAfzSHKr11kSl/uBebDiZ89ZCst3OUkdwL28sIVsE83ock+EIQV - 2Mz2wxeg6/UAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJHSURBVDhPxZBdSNNhFMb/F110ZZEVhVBgeeHNICiiuggp - olAUyyxI0oSaH1QYC3N+tKnp5ubm1JUua5uuqdNKMwr7kApFItTUkWZqVhSVYmao5Nevvy7UoYR3HXh4 - 4XCe33nOKyy3lAY7l9RWMo0O/raWXxEyo5spVYTNvOGyfIRPfW+ptOkXqaPl6T83hcRmExSdgzAz3NVm - YWyoYla/B+1M9JtxWLPpaH22JORIjI6gKAMB0jyEimIdo4OlbuaprwVMOOMovammpDADc34qppwUrmnl - 5Kni3aFlFg2j3y1z5mnRTJccnNIltQhwq0jFry+mOXNtpWZWDx1Z1NhV3C3JwGFOw25SYjVe5oYhiUKd - HKMmwQUrMWUw/CF3NnZvvYKqUh1TvUroS3fXe7HXkwidMngTS2t5KLbregSzMY2f3Wr4qKW6LJvGR1rX - 0MLor8OhKYTJBn/GHvvxrliCTBrsOqXIoOBHh5K+hmSq7FqmexTQHuUytkaKxuNMNgYyVneA4Qd7GKjc - hjLaRzxH7gIU6JIZaEvgtk1D8wsxSWecCDgNzWFMvwxm/PkhRmr3Mli1nW9lvjRdWc0Jf+/5jzRmyWmv - S+GOLQu6U6BFjPvqKOP1AYw88WOoZif9DgmfLVtxaj1RSLdwNvrkPCA3M54KqxrnvRia9MKcGrUrqFOt - 5H7qKsqT1mGO9+Lqhc2ELdw+U/r0i+gVZ8hMiCDx3DHORwZyKnQ/hw/uYt9uCTskPvh6e7Fp41rWr/Fg - g6eHO+A/lyD8ARfG3mk9fv1YAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIySURBVDhPrZLfS5NRGMfff6H7boIuuq2pMZyL1eAt11CW - DcOKsB9vpFmaLtNExco0av6CbIVLJ61Wk3BSkT/AFCkRZSpZmrmiJQ41xSaCwdfznL15XEUX0Reem5f3 - 8znnec4j/Zc8fxYGla91CS3eRTx0z6OpMYS7jmnU1X6B/VYA18snUVoyjsKCt8jLHcH5c36ouCQR2NUJ - 1Nas4G9ZXlmFKbULh1Kf8lJxSfI+WeCCyopv6q+/h+DQ/DJ2WV5Ao1FgPegRAveDOS4oLfmq/h6dn/DH - 4AJizD4UXJrCAUuzEDgbZrjgou2DiohshIcnQtgme5GTPYbkJKcQ1N8OckHW2REVi+RXuM8fxGaDG4oy - ALPZIQQ11Z+5QDk1oKJ/hjv7P2FTfCMOH3mFxMQ6IbhROYWOdrCnBI4dfwPr0V4+bRoY9UzXppMjcDdS - rC8hy3YhuFI2gTYf2A4Aza4f7N2/o/zaLB8qDYx6zszwr8P7k1thNFYIweXCMXgeAfedq2xxwjClZUeV - Jd2GtDNFETiJwfs8MBjKhMCWN8pgoLoqzE8miH1GjE7G4PsZjE7OQsm9ij2mFg7rdrug1xcJAa2l4w7W - r00Cgk/n38S7wBwC04u4UGxHrMHF4CbEJtyDLj5fCDIzhljfSxzeavRgyw4Zj9t64GvvQ0d3P3pfD2Kv - 2QqNvgFxDN6urYdWmyMElJMnevh60obRktA701PRtGlg1DOdSkXwzrisaMG/RZLWAE60OMW5fNhvAAAA - AElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIpSURBVDhPtZL/T1JRGMb5p1itrVZbbRpqZbawnBENV1I0 - jGlByTSyJTXJwq2oKZQb1KAv6JCYWSxvBrkkZUq4CeQEiRABFeLL072Xa0zRra31bO8v57zP5znnPYf1 - X+TxhWF6O7VtGYcnwbSWijKPOLzYrPSvLPwLS3huGUMlT7o9wGD9grVUBj+icdid03S9tDmgNxNwTgVQ - J+rA8XNtWwM+uuZATMwxmQVRycuJFNyzIRitDlScugKzjSgFRGJJaIwEsrk8AsHIhnSL/Ssck37UNipQ - I5DjtuYV7uksRYhr2kebhx2eP6nrycFIEh5fBA/1Nvru8q5+PDaOovK0rABwfwugWzcErfkzHhjsePL6 - E7q1VrTdNUDcrgGvSYlDZHN5XTNOnL8BVe8AJAoNDtZfLgDu9L1BPJmikzcrk81hlRwodZJwdBXziwnI - OrVoaOkiT8C8hKLHBPO7CbywOaE1jeC+bhAd6meQdvZC1KoG/5IS3MZ2HObLUHZSggvkWq3wOvbWiAqA - VpWeyStVfCUNf3AZ4zNhfHCFMEDMgye+hYr6FrDLzxQAUuVTpr0ocn74mchg5vsKRt1RcHp2Qv9+kZ78 - UcE17KkWFgHNN/uQzgBkGKLJPBZiecyGchjzrmFwPIF++xJUbDbUQzEacIArLpopSRSP4CUN1Obf1Abz - uqob5KjiXwWH/GVl5HPt5zZh37GL2H1EiF1VZ7GDI6CNW5r/TSzWbwHYL0mKJ5czAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGDSURBVDhPrZFNSwJRGIX9NYGbFoUlFElY1EJQKEYhCJsi - LaVsERnRF5iCaSZJO1toCDVGFkgoFpWQWWRR2aIvUxm1BKN1wSnHCFw4TOCzue+9nPNw4eVVnav4Izzb - QfxeGZ5TWaxT/rK3irzmC7CsusvC1G4IkbNLboIiDieF4GGUKeTeClDpppF8eeEu2PIfwfrzizSdw3Hk - EnKlFpkMzV2wH77AosOFTV8A+vkl9CiHuJeLJNNZjM8tYWB0FkTvMAwmy/8ERTR6CwjlGAi1Ccence6C - 1NsXzN4PKIxJLLgeIJ2MoXvmFraNBKK3eXZRIveJPvs7FIYniEkXZENOdE+GIZ2Ko10TwLK7tJmKmL0F - EEYarYM+NMnt0C1sQzpx/lcSEnZ2gcKY/gs0dlmZuWvmjjmpwA1qxVp2AWFIMAF/OAGBzMjMI7ZrtJCb - 4Df3o4Zfxy7QrdxDRFKol5khkpR2H4qmIOzUQNBGwrsXYxccnNOQqNbQ0KGGZ+eEPVwdeLxvqqrf4wGh - TNAAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHkSURBVDhPvZHfS1NhHIf3p5QypLr2D4goMwoMCi/qIugH - Xe1Cr7qKDIMkZixwNhfWLGWbnuki0kXKzLU023KubBNPJrbRdOzocm6e2dPOO21mMS+CHvjcvOf9PF++ - 79H9M+7RT2iRRsIi9sEAXe43yAvf2LpSHq28G9uAnytNT4jMLewtcQ2Ht2pF8ps/aOt+gccX5lxD694S - +1BQFD1RkN5DSFa4Z3uONKbgHE3h8KZ4OJTC1J8UiSzmfhd2uf1CoJHbyKOsZokl0kKwm+aeJaov+wjO - rpQkVqdXfOz0bWAcVLghfaXxkUz3y2VxvpMGSwL3uMKh+gHezSSLEnNhX23vtYzKUirDfGyFj/Iy1mdx - UWqR8iKhwtQLxjgH659y4EwvVXWPiwJt3/Ws+muywRrlqvkDdx3zQrCN8l1ldnEd3/QqFmkS/akHJYGS - zjLzOUEwEsMf+sLI2zmaOou/93pPGoM5zvk7UU7fnBKxSBPoT7SXBNW1F/9Io2lKCNTCeomUyrS8xnBA - wfUqyf1eP5U1ptJD/o1LzeNCsHPydtqdr6k4aiwvOHvNSya3ibU/QIdrEkvfhJislc32MfYfuV1eUGPw - FF7bIVJVZ0N/soPK421UHGstlFvYd/hWecF/Qqf7CR0A5wwgSQA2AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJSSURBVDhPtZJrSJNRGMdf6IN9KbpQn/pUEH2JIoLqQ0Zh - FqYZRmJG1iKmUqKyLB2pqSm6vC1Nm5GXoeatEsVJ0RASR3eNzegikRq5lrV3857Fr/d9ddlICoL+8OfA - Oef/e57zcIT/os7WLMw302muSGJ2689qqi7A44q8IzjtNYzarzHQm8tZtT8FmRqu6LToMxN+B8qhCbGR - KVcDE85ajKUaxoaryEuL4UVXIudPB5Ko2oy98xjDptXERuz3hsgAOTzlqqMk6yjdllzE90UM9Wp5azlB - S1kwkeG+1CSv4mmBQPThfd6Ahqq8GYB4A11yBKmaMLQxoZyLDkGjDiZOFUhUuB+FsWsUQFiArzegtlzH - pFjPpMPA2GA2jucx2KqWK7ZWLqO7dBGP9D5KWLbfto3eAKMhi3FHBeP9GYy9PMXos4OIrYvJrzSRbWjm - wuV6EnVG4tLLiEzSExGf4w0oL05nZEDPaK+akceBuO9v4uPtFUrYo6npbzhdE/QPOQmNSiPouHYOUpaf - gvgqA/dDf9wd63G1r2SgUlAqyyq/1anYUGfG2mdXwne7bOwJUc1AinOS+NxzBpd5HWLbUhyNPvRdF5S2 - v05/54tbqvzBifWNHUvPOwLC4/CXwrv2HsB3+w6EwosJOB5ESeElfGpayGD1AmwlArHSm+W2PR1clToo - MrbT0mFTVtlbN6xFuJQar3wQz5Q9VksD+7XyPctrJdx4p5s605M5gKz8lJPSDwtGFbKboJ1blAN52vKb - PdXm80/AfDokTVu+8DfPXv9XCcIPTvjvLQ8YoakAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIVSURBVDhPtVJNaxNRFM1PyE+Yn1AUXLjK0uWgDWQZwUUX - KsGFBEEcCkIwqBEpGiydsSo2kupsasdo7Yi2toh0sFZjG5JpiZo20/TpVOmH5njvm8BYahEXHji8+968 - c+55l4n8F0zM+rhVWkHmdg29A/PoK1Yw8uIjOp/3xpvqBgrjLeilZbjNLXxZ34bwt6jexMVCGRndQenl - 0p+NWHzPXoP3rQ3bAbQhQM0E5Np2BKprbZzrm8TIs8puE+68+r0NwwZiacCwALEBCVcAqet8JlAjk1PZ - JzsNJt6u4+FMS3ZmMV9mmFNAMhesbBZLC6oFdOsd8oVXocmdx018Ej9k1FgqiJ0zgS6qlR6BVI4iEFRN - IJlxMF/1cfTMcGiQvbskB6ZqgairJ6BCTJKYu9tlAUW1oSRsNDwfB+JXQ4PzN6s07W0ZPxDS5aSgJEFn - 06Y9CaOqSauJRvMr9qmXQ4P8/RoWvU16eyBUEq5kbigwiKoOMTBQ0zbKlTq6TxihwejkZ1iOJwfEwmiC - BQ49yaW50J7Fh0xJw3IxbM3hwo2x0ICRHZzFgveTunYERK5lgo5YMxx8WPFw5Li+U8wYm66jNz+Naov+ - Beqiao58N5NrPluoryJO0QeKU7sNGKPPazh9aRzGo/eYmVvEMk270fTlmzl2N3XW9xL/jv7iaxw7+wAH - E9ew//AVxE8OItv/9O/Cf0ck8gud2vKswuxNZgAAAABJRU5ErkJggg== - - - - 277, 17 - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG - YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 - 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw - bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc - VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 - c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 - Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo - mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ - kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D - TgDQASA1MVpwzwAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG - YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 - 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw - bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc - VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 - c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 - Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo - mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ - kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D - TgDQASA1MVpwzwAAAABJRU5ErkJggg== - - - - 393, 17 - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAERSURBVDhPrZDbSgJRGIXnpewd6jXsjSQvIrwoI0RQMChU - 0iiDPCGiE3ZCRkvR8VzTeBhnyR5/ccaZNnPhB4t9sdf6Ln5hb8QeathNJFVFKF5C8DqL4ksDVHWGDf7j - LHyPg6NjviSaFqlu5yQYR+KpupaIkrMknCxT3Y7v/NYYb0ITK1c3BarbWWhLQ7IR0cTKReyZ6lZ0XYei - ztHpK4bAc+h1FgQijzSxMptrGIxVSO0xX3AaStFki7bUMVFmaMm/eJMGfIH/MkGzLep0AXn4h/r3CJV3 - mS9gn2bY4UY/UzQ7E9TqfeTFtnuB+XAfzSHKr11kSl/uBebDiZ89ZCst3OUkdwL28sIVsE83ock+EIQV - 2Mz2wxeg6/UAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJHSURBVDhPxZBdSNNhFMb/F110ZZEVhVBgeeHNICiiuggp - olAUyyxI0oSaH1QYC3N+tKnp5ubm1JUua5uuqdNKMwr7kApFItTUkWZqVhSVYmao5Nevvy7UoYR3HXh4 - 4XCe33nOKyy3lAY7l9RWMo0O/raWXxEyo5spVYTNvOGyfIRPfW+ptOkXqaPl6T83hcRmExSdgzAz3NVm - YWyoYla/B+1M9JtxWLPpaH22JORIjI6gKAMB0jyEimIdo4OlbuaprwVMOOMovammpDADc34qppwUrmnl - 5Kni3aFlFg2j3y1z5mnRTJccnNIltQhwq0jFry+mOXNtpWZWDx1Z1NhV3C3JwGFOw25SYjVe5oYhiUKd - HKMmwQUrMWUw/CF3NnZvvYKqUh1TvUroS3fXe7HXkwidMngTS2t5KLbregSzMY2f3Wr4qKW6LJvGR1rX - 0MLor8OhKYTJBn/GHvvxrliCTBrsOqXIoOBHh5K+hmSq7FqmexTQHuUytkaKxuNMNgYyVneA4Qd7GKjc - hjLaRzxH7gIU6JIZaEvgtk1D8wsxSWecCDgNzWFMvwxm/PkhRmr3Mli1nW9lvjRdWc0Jf+/5jzRmyWmv - S+GOLQu6U6BFjPvqKOP1AYw88WOoZif9DgmfLVtxaj1RSLdwNvrkPCA3M54KqxrnvRia9MKcGrUrqFOt - 5H7qKsqT1mGO9+Lqhc2ELdw+U/r0i+gVZ8hMiCDx3DHORwZyKnQ/hw/uYt9uCTskPvh6e7Fp41rWr/Fg - g6eHO+A/lyD8ARfG3mk9fv1YAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIySURBVDhPrZLfS5NRGMfff6H7boIuuq2pMZyL1eAt11CW - DcOKsB9vpFmaLtNExco0av6CbIVLJ61Wk3BSkT/AFCkRZSpZmrmiJQ41xSaCwdfznL15XEUX0Reem5f3 - 8znnec4j/Zc8fxYGla91CS3eRTx0z6OpMYS7jmnU1X6B/VYA18snUVoyjsKCt8jLHcH5c36ouCQR2NUJ - 1Nas4G9ZXlmFKbULh1Kf8lJxSfI+WeCCyopv6q+/h+DQ/DJ2WV5Ao1FgPegRAveDOS4oLfmq/h6dn/DH - 4AJizD4UXJrCAUuzEDgbZrjgou2DiohshIcnQtgme5GTPYbkJKcQ1N8OckHW2REVi+RXuM8fxGaDG4oy - ALPZIQQ11Z+5QDk1oKJ/hjv7P2FTfCMOH3mFxMQ6IbhROYWOdrCnBI4dfwPr0V4+bRoY9UzXppMjcDdS - rC8hy3YhuFI2gTYf2A4Aza4f7N2/o/zaLB8qDYx6zszwr8P7k1thNFYIweXCMXgeAfedq2xxwjClZUeV - Jd2GtDNFETiJwfs8MBjKhMCWN8pgoLoqzE8miH1GjE7G4PsZjE7OQsm9ij2mFg7rdrug1xcJAa2l4w7W - r00Cgk/n38S7wBwC04u4UGxHrMHF4CbEJtyDLj5fCDIzhljfSxzeavRgyw4Zj9t64GvvQ0d3P3pfD2Kv - 2QqNvgFxDN6urYdWmyMElJMnevh60obRktA701PRtGlg1DOdSkXwzrisaMG/RZLWAE60OMW5fNhvAAAA - AElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIpSURBVDhPtZL/T1JRGMb5p1itrVZbbRpqZbawnBENV1I0 - jGlByTSyJTXJwq2oKZQb1KAv6JCYWSxvBrkkZUq4CeQEiRABFeLL072Xa0zRra31bO8v57zP5znnPYf1 - X+TxhWF6O7VtGYcnwbSWijKPOLzYrPSvLPwLS3huGUMlT7o9wGD9grVUBj+icdid03S9tDmgNxNwTgVQ - J+rA8XNtWwM+uuZATMwxmQVRycuJFNyzIRitDlScugKzjSgFRGJJaIwEsrk8AsHIhnSL/Ssck37UNipQ - I5DjtuYV7uksRYhr2kebhx2eP6nrycFIEh5fBA/1Nvru8q5+PDaOovK0rABwfwugWzcErfkzHhjsePL6 - E7q1VrTdNUDcrgGvSYlDZHN5XTNOnL8BVe8AJAoNDtZfLgDu9L1BPJmikzcrk81hlRwodZJwdBXziwnI - OrVoaOkiT8C8hKLHBPO7CbywOaE1jeC+bhAd6meQdvZC1KoG/5IS3MZ2HObLUHZSggvkWq3wOvbWiAqA - VpWeyStVfCUNf3AZ4zNhfHCFMEDMgye+hYr6FrDLzxQAUuVTpr0ocn74mchg5vsKRt1RcHp2Qv9+kZ78 - UcE17KkWFgHNN/uQzgBkGKLJPBZiecyGchjzrmFwPIF++xJUbDbUQzEacIArLpopSRSP4CUN1Obf1Abz - uqob5KjiXwWH/GVl5HPt5zZh37GL2H1EiF1VZ7GDI6CNW5r/TSzWbwHYL0mKJ5czAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGCSURBVDhPnZK9S0JRGMb9F1xb2gqaq6mhwCGDtvYIIyLI - cJOE1paoIYpMKUjFRDH87lpoakGlIZF9DA2hZJEQhJXl1xPn3HPV29WQfvBwOfA+P95zuDJ39A6/4wyl - YOOSMHvOcHGThuwvSKEVRvsR+pQqWD3R1pK98DUbl7Jm5hA8SfESd6S5xH5wycalrO4E0D8yWQuriLH6 - E2xcSqlcoRJBxCpiTO5TNi4m/ZgDF4nDsOulsfujyGRzUsmWM8YqdcggKbveS3A88bEkslRye58RSzZt - IVarY/FFaPmlwp+fUaESYRNW5Vm3BPmpBpZNvppACDmTLbS6FbGAPFAj5OGI4PALOK/yZfIlAlk4j7n5 - xdaCarWKj0KRXmE2+UklJEJZZ/RCPTPdWvBdLOP1rYD41QNcgRiVkKJQ1mjGsa2VNxeQb2OWDC7sh47p - ddQLeoyOTSFiVAAFvVhChsmv2k6Uvd3Icx1UolMNiDdpl4nhLiohW/xb0tMph2JwCJxjAz9A30JI8zYA - tAAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGDSURBVDhPrZFNSwJRGIX9NYGbFoUlFElY1EJQKEYhCJsi - LaVsERnRF5iCaSZJO1toCDVGFkgoFpWQWWRR2aIvUxm1BKN1wSnHCFw4TOCzue+9nPNw4eVVnav4Izzb - QfxeGZ5TWaxT/rK3irzmC7CsusvC1G4IkbNLboIiDieF4GGUKeTeClDpppF8eeEu2PIfwfrzizSdw3Hk - EnKlFpkMzV2wH77AosOFTV8A+vkl9CiHuJeLJNNZjM8tYWB0FkTvMAwmy/8ERTR6CwjlGAi1Ccence6C - 1NsXzN4PKIxJLLgeIJ2MoXvmFraNBKK3eXZRIveJPvs7FIYniEkXZENOdE+GIZ2Ko10TwLK7tJmKmL0F - EEYarYM+NMnt0C1sQzpx/lcSEnZ2gcKY/gs0dlmZuWvmjjmpwA1qxVp2AWFIMAF/OAGBzMjMI7ZrtJCb - 4Df3o4Zfxy7QrdxDRFKol5khkpR2H4qmIOzUQNBGwrsXYxccnNOQqNbQ0KGGZ+eEPVwdeLxvqqrf4wGh - TNAAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHkSURBVDhPvZHfS1NhHIf3p5QypLr2D4goMwoMCi/qIugH - Xe1Cr7qKDIMkZixwNhfWLGWbnuki0kXKzLU023KubBNPJrbRdOzocm6e2dPOO21mMS+CHvjcvOf9PF++ - 79H9M+7RT2iRRsIi9sEAXe43yAvf2LpSHq28G9uAnytNT4jMLewtcQ2Ht2pF8ps/aOt+gccX5lxD694S - +1BQFD1RkN5DSFa4Z3uONKbgHE3h8KZ4OJTC1J8UiSzmfhd2uf1CoJHbyKOsZokl0kKwm+aeJaov+wjO - rpQkVqdXfOz0bWAcVLghfaXxkUz3y2VxvpMGSwL3uMKh+gHezSSLEnNhX23vtYzKUirDfGyFj/Iy1mdx - UWqR8iKhwtQLxjgH659y4EwvVXWPiwJt3/Ws+muywRrlqvkDdx3zQrCN8l1ldnEd3/QqFmkS/akHJYGS - zjLzOUEwEsMf+sLI2zmaOou/93pPGoM5zvk7UU7fnBKxSBPoT7SXBNW1F/9Io2lKCNTCeomUyrS8xnBA - wfUqyf1eP5U1ptJD/o1LzeNCsHPydtqdr6k4aiwvOHvNSya3ibU/QIdrEkvfhJislc32MfYfuV1eUGPw - FF7bIVJVZ0N/soPK421UHGstlFvYd/hWecF/Qqf7CR0A5wwgSQA2AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJSSURBVDhPtZJrSJNRGMdf6IN9KbpQn/pUEH2JIoLqQ0Zh - FqYZRmJG1iKmUqKyLB2pqSm6vC1Nm5GXoeatEsVJ0RASR3eNzegikRq5lrV3857Fr/d9ddlICoL+8OfA - Oef/e57zcIT/os7WLMw302muSGJ2689qqi7A44q8IzjtNYzarzHQm8tZtT8FmRqu6LToMxN+B8qhCbGR - KVcDE85ajKUaxoaryEuL4UVXIudPB5Ko2oy98xjDptXERuz3hsgAOTzlqqMk6yjdllzE90UM9Wp5azlB - S1kwkeG+1CSv4mmBQPThfd6Ahqq8GYB4A11yBKmaMLQxoZyLDkGjDiZOFUhUuB+FsWsUQFiArzegtlzH - pFjPpMPA2GA2jucx2KqWK7ZWLqO7dBGP9D5KWLbfto3eAKMhi3FHBeP9GYy9PMXos4OIrYvJrzSRbWjm - wuV6EnVG4tLLiEzSExGf4w0oL05nZEDPaK+akceBuO9v4uPtFUrYo6npbzhdE/QPOQmNSiPouHYOUpaf - gvgqA/dDf9wd63G1r2SgUlAqyyq/1anYUGfG2mdXwne7bOwJUc1AinOS+NxzBpd5HWLbUhyNPvRdF5S2 - v05/54tbqvzBifWNHUvPOwLC4/CXwrv2HsB3+w6EwosJOB5ESeElfGpayGD1AmwlArHSm+W2PR1clToo - MrbT0mFTVtlbN6xFuJQar3wQz5Q9VksD+7XyPctrJdx4p5s605M5gKz8lJPSDwtGFbKboJ1blAN52vKb - PdXm80/AfDokTVu+8DfPXv9XCcIPTvjvLQ8YoakAAAAASUVORK5CYII= - - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AccessibilityTests/app.manifest b/src/System.Windows.Forms/tests/AccessibilityTests/app.manifest deleted file mode 100644 index 20b481712bd..00000000000 --- a/src/System.Windows.Forms/tests/AccessibilityTests/app.manifest +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/System.Windows.Forms/tests/AxHosts/AxHosts.Designer.cs b/src/System.Windows.Forms/tests/AxHosts/AxHosts.Designer.cs deleted file mode 100644 index f3937a76949..00000000000 --- a/src/System.Windows.Forms/tests/AxHosts/AxHosts.Designer.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace AxHosts; - -partial class AxHosts -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AxHosts)); - this.axWindowsMediaPlayer1 = new AxWMPLib.AxWindowsMediaPlayer(); - ((System.ComponentModel.ISupportInitialize)(this.axWindowsMediaPlayer1)).BeginInit(); - this.SuspendLayout(); - // - // axWindowsMediaPlayer1 - // - this.axWindowsMediaPlayer1.Dock = System.Windows.Forms.DockStyle.Fill; - this.axWindowsMediaPlayer1.Enabled = true; - this.axWindowsMediaPlayer1.Location = new System.Drawing.Point(0, 0); - this.axWindowsMediaPlayer1.Name = "axWindowsMediaPlayer1"; - this.axWindowsMediaPlayer1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axWindowsMediaPlayer1.OcxState"))); - this.axWindowsMediaPlayer1.Size = new System.Drawing.Size(800, 450); - this.axWindowsMediaPlayer1.TabIndex = 0; - // - // AxHosts - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); - this.Controls.Add(this.axWindowsMediaPlayer1); - this.Name = "AxHosts"; - this.Text = "Form1"; - ((System.ComponentModel.ISupportInitialize)(this.axWindowsMediaPlayer1)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - - private AxWMPLib.AxWindowsMediaPlayer axWindowsMediaPlayer1; -} diff --git a/src/System.Windows.Forms/tests/AxHosts/AxHosts.cs b/src/System.Windows.Forms/tests/AxHosts/AxHosts.cs deleted file mode 100644 index fa2d3595374..00000000000 --- a/src/System.Windows.Forms/tests/AxHosts/AxHosts.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.IO; - -namespace AxHosts; - -public partial class AxHosts : Form -{ - public AxHosts() - { - InitializeComponent(); - axWindowsMediaPlayer1.URL = Path.GetFullPath(@"./Resources/media.mpg"); - } -} diff --git a/src/System.Windows.Forms/tests/AxHosts/AxHosts.csproj b/src/System.Windows.Forms/tests/AxHosts/AxHosts.csproj deleted file mode 100644 index 834adc85d3d..00000000000 --- a/src/System.Windows.Forms/tests/AxHosts/AxHosts.csproj +++ /dev/null @@ -1,62 +0,0 @@ - - - - WinExe - net472 - enable - true - 10 - true - Open - disable - false - AnyCPU - false - false - true - true - - - - - 0 - 1 - 6bf52a50-394a-11d3-b153-00c04f79faa6 - 0 - tlbimp - false - false - - - aximp - 0 - 1 - 6bf52a50-394a-11d3-b153-00c04f79faa6 - 0 - false - false - - - - - - PreserveNewest - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AxHosts/AxHosts.resx b/src/System.Windows.Forms/tests/AxHosts/AxHosts.resx deleted file mode 100644 index e2c3da9bab0..00000000000 --- a/src/System.Windows.Forms/tests/AxHosts/AxHosts.resx +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w - LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACFTeXN0 - ZW0uV2luZG93cy5Gb3Jtcy5BeEhvc3QrU3RhdGUBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAuQAAAAIB - AAAAAQAAAAAAAAAAAAAAAKQAAAABAwAACAACAAAAAAAFAAAAAAAAAPA/AwAAAAAABQAAAAAAAAAAAAgA - AgAAAAAAAwABAAAACwD//wMAAAAAAAsA//8IAAIAAAAAAAMAMgAAAAsAAAAIAAoAAABmAHUAbABsAAAA - CwAAAAsAAAALAP//CwD//wsAAAAIAAIAAAAAAAgAAgAAAAAACAACAAAAAAAIAAIAAAAAAAsAAACvUgAA - gi4AAAs= - - - \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/AxHosts/GlobalUsings.cs b/src/System.Windows.Forms/tests/AxHosts/GlobalUsings.cs deleted file mode 100644 index a9d638d7a43..00000000000 --- a/src/System.Windows.Forms/tests/AxHosts/GlobalUsings.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -global using System; -global using System.Windows.Forms; diff --git a/src/System.Windows.Forms/tests/AxHosts/Program.cs b/src/System.Windows.Forms/tests/AxHosts/Program.cs deleted file mode 100644 index 339c1ee1474..00000000000 --- a/src/System.Windows.Forms/tests/AxHosts/Program.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace AxHosts; - -internal static class Program -{ - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new AxHosts()); - } -} diff --git a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/CustomButton.cs b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/CustomButton.cs deleted file mode 100644 index d9d1c624572..00000000000 --- a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/CustomButton.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Windows.Forms; -using System.ComponentModel; - -namespace TestConsole; - -[Designer(typeof(CustomButtonDesigner), typeof(System.ComponentModel.Design.IDesigner))] -public class CustomButton : Button -{ -} diff --git a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/CustomButtonDesigner.cs b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/CustomButtonDesigner.cs deleted file mode 100644 index 8f1152f4c56..00000000000 --- a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/CustomButtonDesigner.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.ComponentModel.Design; -using System.Windows.Forms.Design; - -namespace TestConsole; - -public class CustomButtonDesigner : ControlDesigner -{ - private DesignerActionListCollection _actionLists; - - public override DesignerActionListCollection ActionLists - { - get - { - _actionLists ??= new DesignerActionListCollection - { - new CustomButtonDesignerActionList(Component) - }; - - return _actionLists; - } - } -} diff --git a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/CustomButtonDesignerActionList.cs b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/CustomButtonDesignerActionList.cs deleted file mode 100644 index 0e430af3661..00000000000 --- a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/CustomButtonDesignerActionList.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.Design; -using System.Drawing; - -namespace TestConsole; - -public class CustomButtonDesignerActionList : DesignerActionList -{ - private readonly IDesignerHost _host; - private readonly CustomButton _control; - private DesignerActionItemCollection _actonListItems; - - public CustomButtonDesignerActionList(IComponent component) - : base(component) - { - _control = component as CustomButton; - _host = GetService(typeof(IDesignerHost)) as IDesignerHost; - } - - public override DesignerActionItemCollection GetSortedActionItems() - { - _actonListItems = new DesignerActionItemCollection(); - _actonListItems.Add(new DesignerActionHeaderItem("Change color")); - _actonListItems.Add(new DesignerActionVerbItem(new DesignerVerb(GetActionName(), OnColorActionClick))); - - return _actonListItems; - } - - public string Name - { - get - { - string name = string.Empty; - if (_control is not null) - { - CustomButton control = _control; - name = control.Name; - } - - return name; - } - set - { - SetValue(nameof(Name), value); - } - } - - private string GetActionName() - { - PropertyDescriptor dockProp = TypeDescriptor.GetProperties(Component)[nameof(CustomButton.BackColor)]; - if (dockProp is not null) - { - Color backColor = (Color)dockProp.GetValue(Component); - if (backColor != Color.Yellow) - { - return "Make Yellow"; - } - else - { - return "Turn Blue"; - } - } - - return null; - } - - private void OnColorActionClick(object sender, EventArgs e) - { - if (_host is null || sender is not DesignerVerb designerVerb) - { - return; - } - - using DesignerTransaction t = _host.CreateTransaction(designerVerb.Text); - - Color backColor = _control.BackColor; - _control.BackColor = backColor != Color.Yellow ? Color.Yellow : Color.Blue; - - t.Commit(); - } - - protected void SetValue(string propertyName, object value) - { - GetProperty(propertyName).SetValue(_control, value); - } - - protected PropertyDescriptor GetProperty(string propertyName) - { - PropertyDescriptor pd = TypeDescriptor.GetProperties(_control)[propertyName]; - if (pd is null) - { - throw new ArgumentException($"Property {propertyName} not found in {nameof(CustomButton)}"); - } - else - { - return pd; - } - } -} diff --git a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/DesignerActionVerbItem.cs b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/DesignerActionVerbItem.cs deleted file mode 100644 index fe0589dc868..00000000000 --- a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/CustomControls/DesignerActionVerbItem.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.ComponentModel.Design; -using System.Diagnostics; - -namespace TestConsole; - -internal class DesignerActionVerbItem : DesignerActionMethodItem -{ - private readonly DesignerVerb _targetVerb; - - public DesignerActionVerbItem(DesignerVerb verb) : base(null, null, null) - { - Debug.Assert(verb is not null, "All callers check whether the verb is null."); - _targetVerb = verb; - } - - public override string Category => "Verbs"; - - public override string DisplayName => _targetVerb.Text; - - public override void Invoke() => _targetVerb.Invoke(); -} diff --git a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/DemoConsole.csproj b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/DemoConsole.csproj deleted file mode 100644 index 32197d9479c..00000000000 --- a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/DemoConsole.csproj +++ /dev/null @@ -1,39 +0,0 @@ - - - - DesignSurface - TestConsole - painter.ico - WinExe - - false - false - $(NoWarn);SA1633;CS8002 - Copyright © Paolo Foti 2008 - - Paolo Foti - CPOL - https://www.codeproject.com/Articles/24385/Have-a-Great-DesignTime-Experience-with-a-Powerful - true - true - - - - - - - - - - - - - - - - - PreserveNewest - - - - diff --git a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.Designer.cs b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.Designer.cs deleted file mode 100644 index fa20d617056..00000000000 --- a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.Designer.cs +++ /dev/null @@ -1,322 +0,0 @@ -namespace TestConsole; - -partial class MainForm { -/// -/// Required designer variable. -/// -private System.ComponentModel.IContainer components = null; - -/// -/// Clean up any resources being used. -/// -/// true if managed resources should be disposed; otherwise, false. -protected override void Dispose ( bool disposing ) { - if ( disposing && ( components != null ) ) { - components.Dispose(); - } - base.Dispose ( disposing ); -} - -#region Windows Form Designer generated code - -/// -/// Required method for Designer support - do not modify -/// the contents of this method with the code editor. -/// -private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager( typeof( MainForm ) ); - this.splitContainer = new System.Windows.Forms.SplitContainer(); - this.tabControl1 = new System.Windows.Forms.TabControl(); - this.tabPage1 = new System.Windows.Forms.TabPage(); - this.tabPage2 = new System.Windows.Forms.TabPage(); - this.tabPage3 = new System.Windows.Forms.TabPage(); - this.tabPage4 = new System.Windows.Forms.TabPage(); - this.tabPage5 = new System.Windows.Forms.TabPage(); - this.propertyGrid = new System.Windows.Forms.PropertyGrid(); - this.menuStrip1 = new System.Windows.Forms.MenuStrip(); - this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripMenuItemUnDo = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripMenuItemReDo = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); - this.ToolStripMenuItemCut = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripMenuItemCopy = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripMenuItemPaste = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripMenuItemDelete = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); - this.toolStripMenuItemTools = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItemTabOrder = new System.Windows.Forms.ToolStripMenuItem(); - this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripMenuItemAbout = new System.Windows.Forms.ToolStripMenuItem(); - this.splitContainer.Panel1.SuspendLayout(); - this.splitContainer.Panel2.SuspendLayout(); - this.splitContainer.SuspendLayout(); - this.tabControl1.SuspendLayout(); - this.menuStrip1.SuspendLayout(); - this.SuspendLayout(); - // - // splitContainer - // - this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer.Location = new System.Drawing.Point( 0, 28 ); - this.splitContainer.Margin = new System.Windows.Forms.Padding( 4 ); - this.splitContainer.Name = "splitContainer"; - // - // splitContainer.Panel1 - // - this.splitContainer.Panel1.BackColor = System.Drawing.SystemColors.Window; - this.splitContainer.Panel1.Controls.Add( this.tabControl1 ); - // - // splitContainer.Panel2 - // - this.splitContainer.Panel2.Controls.Add( this.propertyGrid ); - this.splitContainer.Size = new System.Drawing.Size( 824, 502 ); - this.splitContainer.SplitterDistance = 593; - this.splitContainer.SplitterWidth = 5; - this.splitContainer.TabIndex = 0; - // - // tabControl1 - // - this.tabControl1.Controls.Add( this.tabPage1 ); - this.tabControl1.Controls.Add( this.tabPage2 ); - this.tabControl1.Controls.Add( this.tabPage3 ); - this.tabControl1.Controls.Add( this.tabPage4 ); - this.tabControl1.Controls.Add( this.tabPage5 ); - this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tabControl1.Location = new System.Drawing.Point( 0, 0 ); - this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size( 593, 502 ); - this.tabControl1.TabIndex = 0; - // - // tabPage1 - // - this.tabPage1.Location = new System.Drawing.Point( 4, 25 ); - this.tabPage1.Name = "tabPage1"; - this.tabPage1.Padding = new System.Windows.Forms.Padding( 3 ); - this.tabPage1.Size = new System.Drawing.Size( 585, 473 ); - this.tabPage1.TabIndex = 0; - this.tabPage1.Text = "tabPage1"; - this.tabPage1.UseVisualStyleBackColor = true; - // - // tabPage2 - // - this.tabPage2.Location = new System.Drawing.Point( 4, 25 ); - this.tabPage2.Name = "tabPage2"; - this.tabPage2.Padding = new System.Windows.Forms.Padding( 3 ); - this.tabPage2.Size = new System.Drawing.Size( 585, 473 ); - this.tabPage2.TabIndex = 1; - this.tabPage2.Text = "tabPage2"; - this.tabPage2.UseVisualStyleBackColor = true; - // - // tabPage3 - // - this.tabPage3.Location = new System.Drawing.Point( 4, 25 ); - this.tabPage3.Name = "tabPage3"; - this.tabPage3.Padding = new System.Windows.Forms.Padding( 3 ); - this.tabPage3.Size = new System.Drawing.Size( 585, 473 ); - this.tabPage3.TabIndex = 2; - this.tabPage3.Text = "tabPage3"; - this.tabPage3.UseVisualStyleBackColor = true; - // - // tabPage4 - // - this.tabPage4.Location = new System.Drawing.Point( 4, 25 ); - this.tabPage4.Name = "tabPage4"; - this.tabPage4.Padding = new System.Windows.Forms.Padding( 3 ); - this.tabPage4.Size = new System.Drawing.Size( 585, 473 ); - this.tabPage4.TabIndex = 3; - this.tabPage4.Text = "tabPage4"; - this.tabPage4.UseVisualStyleBackColor = true; - // - // tabPage5 - // - this.tabPage5.Location = new System.Drawing.Point(4, 25); - this.tabPage5.Name = "tabPage5"; - this.tabPage5.Padding = new System.Windows.Forms.Padding(3); - this.tabPage5.Size = new System.Drawing.Size(585, 473); - this.tabPage5.TabIndex = 3; - this.tabPage5.Text = "tabPage5"; - this.tabPage5.UseVisualStyleBackColor = true; - // - // propertyGrid - // - this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill; - this.propertyGrid.Location = new System.Drawing.Point( 0, 0 ); - this.propertyGrid.Margin = new System.Windows.Forms.Padding( 4 ); - this.propertyGrid.Name = "propertyGrid"; - this.propertyGrid.Size = new System.Drawing.Size( 226, 502 ); - this.propertyGrid.TabIndex = 0; - // - // menuStrip1 - // - this.menuStrip1.Items.AddRange( new System.Windows.Forms.ToolStripItem[] { - this.editToolStripMenuItem, - this.toolStripMenuItemTools, - this.helpToolStripMenuItem} ); - this.menuStrip1.Location = new System.Drawing.Point( 0, 0 ); - this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Padding = new System.Windows.Forms.Padding( 8, 2, 0, 2 ); - this.menuStrip1.Size = new System.Drawing.Size( 824, 28 ); - this.menuStrip1.TabIndex = 1; - this.menuStrip1.Text = "menuStrip1"; - // - // editToolStripMenuItem - // - this.editToolStripMenuItem.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { - this.ToolStripMenuItemUnDo, - this.ToolStripMenuItemReDo, - this.toolStripSeparator3, - this.ToolStripMenuItemCut, - this.ToolStripMenuItemCopy, - this.ToolStripMenuItemPaste, - this.ToolStripMenuItemDelete, - this.toolStripSeparator4} ); - this.editToolStripMenuItem.Name = "editToolStripMenuItem"; - this.editToolStripMenuItem.Size = new System.Drawing.Size( 47, 24 ); - this.editToolStripMenuItem.Text = "&Edit"; - // - // ToolStripMenuItemUnDo - // - this.ToolStripMenuItemUnDo.Name = "ToolStripMenuItemUnDo"; - this.ToolStripMenuItemUnDo.ShortcutKeys = ((System.Windows.Forms.Keys) ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); - this.ToolStripMenuItemUnDo.Size = new System.Drawing.Size( 165, 24 ); - this.ToolStripMenuItemUnDo.Text = "Undo"; - this.ToolStripMenuItemUnDo.Click += new System.EventHandler( this.undoToolStripMenuItem_Click ); - // - // ToolStripMenuItemReDo - // - this.ToolStripMenuItemReDo.Name = "ToolStripMenuItemReDo"; - this.ToolStripMenuItemReDo.ShortcutKeys = ((System.Windows.Forms.Keys) ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); - this.ToolStripMenuItemReDo.Size = new System.Drawing.Size( 165, 24 ); - this.ToolStripMenuItemReDo.Text = "Redo"; - this.ToolStripMenuItemReDo.Click += new System.EventHandler( this.redoToolStripMenuItem_Click ); - // - // toolStripSeparator3 - // - this.toolStripSeparator3.Name = "toolStripSeparator3"; - this.toolStripSeparator3.Size = new System.Drawing.Size( 162, 6 ); - // - // ToolStripMenuItemCut - // - this.ToolStripMenuItemCut.Image = ((System.Drawing.Image) (resources.GetObject( "ToolStripMenuItemCut.Image" ))); - this.ToolStripMenuItemCut.ImageTransparentColor = System.Drawing.Color.Magenta; - this.ToolStripMenuItemCut.Name = "ToolStripMenuItemCut"; - this.ToolStripMenuItemCut.ShortcutKeys = ((System.Windows.Forms.Keys) ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); - this.ToolStripMenuItemCut.Size = new System.Drawing.Size( 165, 24 ); - this.ToolStripMenuItemCut.Text = "Cut"; - this.ToolStripMenuItemCut.Click += new System.EventHandler( this.OnMenuClick ); - // - // ToolStripMenuItemCopy - // - this.ToolStripMenuItemCopy.Image = ((System.Drawing.Image) (resources.GetObject( "ToolStripMenuItemCopy.Image" ))); - this.ToolStripMenuItemCopy.ImageTransparentColor = System.Drawing.Color.Magenta; - this.ToolStripMenuItemCopy.Name = "ToolStripMenuItemCopy"; - this.ToolStripMenuItemCopy.ShortcutKeys = ((System.Windows.Forms.Keys) ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); - this.ToolStripMenuItemCopy.Size = new System.Drawing.Size( 165, 24 ); - this.ToolStripMenuItemCopy.Text = "Copy"; - this.ToolStripMenuItemCopy.Click += new System.EventHandler( this.OnMenuClick ); - // - // ToolStripMenuItemPaste - // - this.ToolStripMenuItemPaste.Image = ((System.Drawing.Image) (resources.GetObject( "ToolStripMenuItemPaste.Image" ))); - this.ToolStripMenuItemPaste.ImageTransparentColor = System.Drawing.Color.Magenta; - this.ToolStripMenuItemPaste.Name = "ToolStripMenuItemPaste"; - this.ToolStripMenuItemPaste.ShortcutKeys = ((System.Windows.Forms.Keys) ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); - this.ToolStripMenuItemPaste.Size = new System.Drawing.Size( 165, 24 ); - this.ToolStripMenuItemPaste.Text = "Paste"; - this.ToolStripMenuItemPaste.Click += new System.EventHandler( this.OnMenuClick ); - // - // ToolStripMenuItemDelete - // - this.ToolStripMenuItemDelete.Name = "ToolStripMenuItemDelete"; - this.ToolStripMenuItemDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete; - this.ToolStripMenuItemDelete.Size = new System.Drawing.Size( 165, 24 ); - this.ToolStripMenuItemDelete.Text = "Delete"; - this.ToolStripMenuItemDelete.Click += new System.EventHandler( this.OnMenuClick ); - // - // toolStripSeparator4 - // - this.toolStripSeparator4.Name = "toolStripSeparator4"; - this.toolStripSeparator4.Size = new System.Drawing.Size( 162, 6 ); - // - // toolStripMenuItemTools - // - this.toolStripMenuItemTools.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { - this.toolStripMenuItemTabOrder} ); - this.toolStripMenuItemTools.Name = "toolStripMenuItemTools"; - this.toolStripMenuItemTools.Size = new System.Drawing.Size( 57, 24 ); - this.toolStripMenuItemTools.Text = "&Tools"; - // - // toolStripMenuItemTabOrder - // - this.toolStripMenuItemTabOrder.Name = "toolStripMenuItemTabOrder"; - this.toolStripMenuItemTabOrder.Size = new System.Drawing.Size( 145, 24 ); - this.toolStripMenuItemTabOrder.Text = "Tab Order"; - this.toolStripMenuItemTabOrder.Click += new System.EventHandler( this.toolStripMenuItemTabOrder_Click ); - // - // helpToolStripMenuItem - // - this.helpToolStripMenuItem.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { - this.ToolStripMenuItemAbout} ); - this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - this.helpToolStripMenuItem.Size = new System.Drawing.Size( 53, 24 ); - this.helpToolStripMenuItem.Text = "&Help"; - // - // ToolStripMenuItemAbout - // - this.ToolStripMenuItemAbout.Name = "ToolStripMenuItemAbout"; - this.ToolStripMenuItemAbout.Size = new System.Drawing.Size( 128, 24 ); - this.ToolStripMenuItemAbout.Text = "About..."; - this.ToolStripMenuItemAbout.Click += new System.EventHandler( this.OnAbout ); - // - // MainForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF( 8F, 16F ); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size( 824, 530 ); - this.Controls.Add( this.splitContainer ); - this.Controls.Add( this.menuStrip1 ); - this.Icon = ((System.Drawing.Icon) (resources.GetObject( "$this.Icon" ))); - this.MainMenuStrip = this.menuStrip1; - this.Margin = new System.Windows.Forms.Padding( 4 ); - this.Name = "MainForm"; - this.Text = "Tiny Form Designer"; - this.Load += new System.EventHandler( this.MainForm_Load ); - this.splitContainer.Panel1.ResumeLayout( false ); - this.splitContainer.Panel2.ResumeLayout( false ); - this.splitContainer.ResumeLayout( false ); - this.tabControl1.ResumeLayout( false ); - this.menuStrip1.ResumeLayout( false ); - this.menuStrip1.PerformLayout(); - this.ResumeLayout( false ); - this.PerformLayout(); - -} - -#endregion - -private System.Windows.Forms.SplitContainer splitContainer; -private System.Windows.Forms.PropertyGrid propertyGrid; -private System.Windows.Forms.MenuStrip menuStrip1; -private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; -private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItemUnDo; -private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItemReDo; -private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; -private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItemCut; -private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItemCopy; -private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItemPaste; -private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; -private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItemDelete; -private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; -private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItemAbout; -private System.Windows.Forms.TabControl tabControl1; -private System.Windows.Forms.TabPage tabPage1; -private System.Windows.Forms.TabPage tabPage2; -private System.Windows.Forms.TabPage tabPage3; -private System.Windows.Forms.TabPage tabPage4; -private System.Windows.Forms.TabPage tabPage5; -private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemTools; -private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemTabOrder; - -} - diff --git a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs deleted file mode 100644 index eb31dc70e49..00000000000 --- a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs +++ /dev/null @@ -1,339 +0,0 @@ -using System.Drawing; -using System.Windows.Forms; -using System.ComponentModel.Design; - -using DesignSurfaceExt; -using Timer = System.Windows.Forms.Timer; - -namespace TestConsole; - -public partial class MainForm : Form -{ - ISelectionService _selectionService; - - private List _listOfDesignSurface = new(); - - public MainForm() - { - InitializeComponent(); - } - - private void InitFormDesigner() - { - CreateDesignSurface(1); - CreateDesignSurface(2); - CreateDesignSurface(3); - CreateDesignSurface(4); - CreateDesignSurface(5); - - tabPage1.Text = "Use SnapLines"; - tabPage2.Text = "Use Grid (Snap to the grid)"; - tabPage3.Text = "Use Grid"; - tabPage4.Text = "Align control by hand"; - tabPage5.Text = "TabControl and TableLayoutPanel"; - - //- enable the UndoEngines - for (int i = 0; i < tabControl1.TabCount; i++) - { - IDesignSurfaceExt isurf = _listOfDesignSurface[i]; - isurf.GetUndoEngineExt().Enabled = true; - } - - //- ISelectionService - //- try to get a ptr to ISelectionService interface - //- if we obtain it then hook the SelectionChanged event - for (int i = 0; i < tabControl1.TabCount; i++) - { - IDesignSurfaceExt isurf = _listOfDesignSurface[i]; - _selectionService = (ISelectionService)(isurf.GetIDesignerHost().GetService(typeof(ISelectionService))); - if (_selectionService is not null) - _selectionService.SelectionChanged += new System.EventHandler(OnSelectionChanged); - } - } - - //- When the selection changes this sets the PropertyGrid's selected component - private void OnSelectionChanged(object sender, System.EventArgs e) - { - if (_selectionService is null) - return; - - IDesignSurfaceExt isurf = _listOfDesignSurface[tabControl1.SelectedIndex]; - if (isurf is not null) - { - ISelectionService selectionService = isurf.GetIDesignerHost().GetService(typeof(ISelectionService)) as ISelectionService; - propertyGrid.SelectedObject = selectionService.PrimarySelection; - } - } - - private void CreateDesignSurface(int n) - { - //- step.0 - //- create a DesignSurface and put it inside a Form in DesignTime - DesignSurfaceExt.DesignSurfaceExt surface = new DesignSurfaceExt.DesignSurfaceExt(); - //- - //- - //- store for later use - _listOfDesignSurface.Add(surface); - //- - //- - //- step.1 - //- choose an alignment mode... - switch (n) - { - case 1: - surface.UseSnapLines(); - break; - case 2: - surface.UseGrid(new System.Drawing.Size(16, 16)); - break; - case 3: - surface.UseGridWithoutSnapping(new System.Drawing.Size(32, 32)); - break; - case 4: - surface.UseNoGuides(); - break; - case 5: - surface.UseNoGuides(); - break; - default: - Console.WriteLine("Invalid selection"); - break; - } - - //- - //- - //- step.2 - //- create the Root component, in these cases a Form - try - { - Form rootComponent = null; - switch (n) - { - case 1: - { - rootComponent = surface.CreateRootComponent(new Size(400, 400)); - rootComponent.BackColor = Color.Gray; - rootComponent.Text = "Root Component hosted by the DesignSurface N.1"; - //- step.3 - //- create some Controls at DesignTime - TextBox t1 = surface.CreateControl(new Size(200, 23), new Point(172, 12)); - Button b1 = surface.CreateControl