Skip to content

Commit

Permalink
Second set of samples including Acrylic and Advanced Color. (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajbennet authored Jun 12, 2019
1 parent 57443df commit 1eeb30a
Show file tree
Hide file tree
Showing 107 changed files with 6,744 additions and 1,649 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ For related documentation, see [Modernize your desktop app using the Visual laye

Minimum requirements for using the Visual layer in desktop apps are listed here. Individual samples might have different requirements, which are listed in the readme for the sample.

- Visual Studio 2017 - [Get a free copy of Visual Studio 2017 with support for building Universal Windows apps](http://go.microsoft.com/fwlink/?LinkID=280676)
- Visual Studio 2017 or later - [Get a free copy of Visual Studio](http://go.microsoft.com/fwlink/?LinkID=280676)
- .NET Framework 4.7.2 or later
- Windows 10 version 1803 or later
- Windows 10 SDK 17134 or later
Expand All @@ -32,6 +32,7 @@ Minimum requirements for using the Visual layer in desktop apps are listed here.
| [**Hello Composition sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/cpp/HelloComposition)</br>Demonstrates how to set up a project to use Composition APIs in a C++ Win32 app.</br>See the [Using the Visual layer with Win32](https://docs.microsoft.com/windows/uwp/composition/using-the-visual-layer-with-win32) tutorial for more info. | ![Hello Composition sample](images/hello-comp-win32.png) |
| [**Hello Vectors sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/cpp/HelloVectors)</br>Demonstrates how to use vectors in the Visual layer. | ![Vector graphics UI](images/hello-vectors-win32.png) |
| [**Virtual Surfaces sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/cpp/VirtualSurfaces)</br>Demonstrates how to use virtual surfaces in the Visual layer. | ![Virtual surfaces UI](images/virtual-surfaces-win32.png) |
| [**Advanced Color sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/cpp/AdvancedColorImages)</br>Demonstrates how to load advanced color (HDR, High Color Gamut, High precision) images into a Virtual Surface and use an Interaction Tracker that helps create a smooth scrollable surface that responds well to touch, mouse, and precision touchpad. | ![Advanced color image UI](images/advanced-color-win32.png) |
| [**Screen Capture sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/cpp/ScreenCaptureforHWND)</br>Demonstrates how to use screen capture APIs. | ![Screen capture UI](images/screen-capture-win32.png) |

### Windows Forms
Expand All @@ -40,6 +41,7 @@ Minimum requirements for using the Visual layer in desktop apps are listed here.
| - | - |
| [**Hello Composition sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/WinForms/HelloComposition)</br>Demonstrates how to set up a project to use Composition APIs in a Windows Forms app.</br>See the [Using the Visual layer with Windows Forms](https://docs.microsoft.com/windows/uwp/composition/using-the-visual-layer-with-windows-forms) tutorial for more info. | ![Hello Composition sample](images/hello-comp-wf.png) |
| [**Visual Layer Integration sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/WinForms/VisualLayerIntegration)</br>Demonstrates how to use a bar graph created with Composition APIs in a Windows Forms app. | ![Bar graph UI](images/bar-graph-winforms.png) |
| [**Win2D Effects (Acrylic) sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/WinForms/AcrylicEffect)</br>Demonstrates how to use Win2D effects to show an acrylic overlay on top of a picture. | ![Acrylic effect](images/acrylic-effect-winforms.png) |

### WPF

Expand All @@ -48,12 +50,13 @@ Minimum requirements for using the Visual layer in desktop apps are listed here.
| [**Hello Composition sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/WPF/HelloComposition)</br>Demonstrates how to set up a project to use Composition APIs in a WPF app.</br>See the [Using the Visual layer with WPF](https://docs.microsoft.com/windows/uwp/composition/using-the-visual-layer-with-wpf) tutorial for more info. | ![Hello Composition sample](images/hello-comp-wpf.png) |
| [**Visual Layer Integration sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/WPF/VisualLayerIntegration)</br>Demonstrates how to use a bar graph created with Composition APIs in a WPF app. | ![Bar graph UI](images/bar-graph-wpf.png) |
| [**Screen Capture sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/WPF/ScreenCapture)</br>Demonstrates how to use screen capture APIs. | ![Screen capture UI](images/capture-wpf.png) |
| [**Win2D Effects (Acrylic) sample**](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/WPF/AcrylicEffect)</br>Demonstrates how to use Win2D effects to show an acrylic overlay on top of a picture. | ![Acrylic effect](images/acrlyic-effect-wpf.png) |

## Limitations

While many Visual Layer features work the same when hosted in a desktop application as they do in a UWP app, some features do have limitations. Here are some of the limitations to be aware of:

- Effect chains rely on [Win2D](http://microsoft.github.io/Win2D/html/Introduction.htm) for the effect descriptions. The [Win2D NuGet package](https://www.nuget.org/packages/Win2D.uwp) is not supported in desktop applications, so you would need to recompile it from the [source code](https://github.com/Microsoft/Win2D).
- Effect chains rely on [Win2D](http://microsoft.github.io/Win2D/html/Introduction.htm) for the effect descriptions. The [Win2D NuGet package](https://www.nuget.org/packages/Win2D.uwp) is not supported in desktop applications, so you need to manually add the DLL to your projects output folder. See the **Win2D Effects (Acrylic) sample** for [WPF](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/WPF/AcrylicEffect) or [Windows Forms](https://github.com/Microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/WinForms/AcrylicEffect) for more information.
- To do hit testing, you need to do bounds calculations by walking the visual tree yourself. This is the same as the Visual Layer in UWP, except in this case there's no XAML element you can easily bind to for hit testing.
- The Visual Layer does not have a primitive for rendering text.
- When two different UI technologies are used together, such as WPF and the Visual Layer, they are each responsible for drawing their own pixels on the screen, and they can't share pixels. As a result, Visual Layer content is always rendered on top of other UI content. (This is known as the _airspace_ issue.) You might need to do extra coding and testing to ensure your Visual layer content resizes with the host UI and doesn't occlude other content.
Expand Down
31 changes: 31 additions & 0 deletions cpp/AdvancedColorImages/AdvancedColorImages.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.168
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdvancedColorImages", "AdvancedColorImages\AdvancedColorImages.vcxproj", "{740EF6CC-CDDA-4413-8D66-FF32C113F077}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{740EF6CC-CDDA-4413-8D66-FF32C113F077}.Debug|x64.ActiveCfg = Debug|x64
{740EF6CC-CDDA-4413-8D66-FF32C113F077}.Debug|x64.Build.0 = Debug|x64
{740EF6CC-CDDA-4413-8D66-FF32C113F077}.Debug|x86.ActiveCfg = Debug|Win32
{740EF6CC-CDDA-4413-8D66-FF32C113F077}.Debug|x86.Build.0 = Debug|Win32
{740EF6CC-CDDA-4413-8D66-FF32C113F077}.Release|x64.ActiveCfg = Release|x64
{740EF6CC-CDDA-4413-8D66-FF32C113F077}.Release|x64.Build.0 = Release|x64
{740EF6CC-CDDA-4413-8D66-FF32C113F077}.Release|x86.ActiveCfg = Release|Win32
{740EF6CC-CDDA-4413-8D66-FF32C113F077}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7B0452A9-175E-4DE1-ACAE-560B0327AF7A}
EndGlobalSection
EndGlobal
289 changes: 289 additions & 0 deletions cpp/AdvancedColorImages/AdvancedColorImages/AdvancedColorImages.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// 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.
//
//*********************************************************

// main.cpp : Defines the entry point for the application.

#include "stdafx.h"
#include "AdvancedColorImages.h"
#include "WinComp.h"

using namespace winrt;
using namespace Windows::UI;
using namespace Windows::UI::Composition;
using namespace Windows::UI::Composition::Desktop;
using namespace Windows::UI::Input;


#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst; // current instance
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
HWND m_childHWnd;
WinComp* m_winComp;

// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{


UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

winrt::init_apartment(winrt::apartment_type::single_threaded);

// Initialize global strings
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_ADVANCEDCOLORIMAGES, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}

HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_ADVANCEDCOLORIMAGES));

MSG msg;

// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}


//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ADVANCEDCOLORIMAGES));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_ADVANCEDCOLORIMAGES);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

return RegisterClassExW(&wcex);
}

//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable

HWND hWndParent = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

//SetWindowPos(hWndParent, HWND_TOPMOST, 0, 0, 300, 300, SWP_SHOWWINDOW);
if (!hWndParent)
{
return FALSE;
}

//Create the child HWND with the same size as the parent HWND, so it fills up the entire space.

RECT rect;
::GetWindowRect(hWndParent, &rect);

m_childHWnd = CreateWindowW(szWindowClass, szTitle, WS_CHILD,
0, 0, rect.right - rect.left, rect.bottom - rect.top,
hWndParent, nullptr, hInstance, nullptr);

if (!m_childHWnd)
{
return FALSE;
}
m_winComp = new WinComp();
// Ensure that the DispatcherQueue is initialized. This is required by the Compositor.
auto controller = m_winComp->EnsureDispatcherQueue();

ShowWindow(hWndParent, nCmdShow);
UpdateWindow(hWndParent);
ShowWindow(m_childHWnd, nCmdShow);
UpdateWindow(m_childHWnd);
m_winComp->Initialize(m_childHWnd);
m_winComp->PrepareVisuals();
m_winComp->ConfigureInteraction();
m_winComp->LoadImageFromFileName(L"hdr-image.jxr");
m_winComp->UpdateViewPort(true);
return TRUE;
}

bool LocateImageFile(HWND hWnd, LPWSTR pszFileName, DWORD cchFileName)
{
pszFileName[0] = L'\0';

OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(ofn));

ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter = L"All Image Files\0" L"*.bmp;*.dib;*.wdp;*.mdp;*.hdp;*.gif;*.png;*.jpg;*.jpeg;*.tif;*.ico;*.jxr\0"
L"JPEG File Interchange Format\0" L"*.jpg;*.jpeg\0"
L"JPEG XR Extented Range Format\0" L"*.jxr\0"
L"Windows Bitmap\0" L"*.bmp;*.dib\0"
L"High Definition Photo\0" L"*.wdp;*.mdp;*.hdp\0"
L"Graphics Interchange Format\0" L"*.gif\0"
L"Portable Network Graphics\0" L"*.png\0"
L"Tiff File\0" L"*.tif\0"
L"Icon\0" L"*.ico\0"
L"All Files\0" L"*.*\0"
L"\0";
ofn.lpstrFile = pszFileName;
ofn.nMaxFile = cchFileName;
ofn.lpstrTitle = L"Open Image";
ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;

// Display the Open dialog box.
return (GetOpenFileName(&ofn) == TRUE);
}

//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{

case IDM_FILE:
WCHAR szFileName[MAX_PATH];

if (LocateImageFile(hWnd, szFileName, ARRAYSIZE(szFileName)))
{
m_winComp->LoadImageFromFileName(szFileName);
}
else
{
MessageBox(hWnd, L"Failed to load image, select a new one.", L"Application Error", MB_ICONEXCLAMATION | MB_OK);
}

break;

case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_POINTERDOWN:
{
//Redirect input events to the InteractionTracker for input events.
PointerPoint pp = PointerPoint::GetCurrentPoint(GET_POINTERID_WPARAM(wParam));
m_winComp->TryRedirectForManipulation(pp);
break;
}


case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;

case WM_SIZE:
{
//Update the child HWND to the new size of the parent HWnd.
RECT windowRect;
::GetWindowRect(hWnd, &windowRect);
::SetWindowPos(m_childHWnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOZORDER);
if (m_winComp != nullptr)
m_winComp->UpdateViewPort(true);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

#include "resource.h"

Binary file not shown.
Binary file not shown.
Loading

0 comments on commit 1eeb30a

Please sign in to comment.