Windows 8.1 应用再出发 - 几种新增控件(2)

本文介绍了Windows8.1中新增的五种控件:Flyout、MenuFlyout、SettingsFlyout、Hub和Hyperlink。这些控件分别用于提供提示、展示菜单、设置配置、组织内容和创建超链接等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文: Windows 8.1 应用再出发 - 几种新增控件(2)

本篇我们接着来介绍Windows 8.1 的新增控件,分别是:Flyout、MenuFlyout、SettingsFlyout、Hub 和 Hyperlink。

1. Flyout

 Flyout被称为浮出控件,能起到提示或者简单交互作用。我们可以利用它来要求用户确认操作、收集用户输入信息或显示提示信息等。只有当用户点击时才显示Flyout,当点击外部任意点时,Flyout消失。

Flyout通常会附加到Button上,所以Button拥有Flyout属性来简化附加和使用的过程。

            <Button Content="Delete it">
                <Button.Flyout>
                    <Flyout>
                        <StackPanel>
                            <TextBlock>This item will be deleted. Do you want to continue ?</TextBlock>
                            <Button Click="DeleteConfirmation_Click">Yes, delete it.</Button>
                        </StackPanel>
                    </Flyout>
                </Button.Flyout>
            </Button>

如上图所示,我们为Button附加了Flyout控件,当Button点击时,Flyout出现。当点击外部任意点时,Flyout消失。当然其他控件也能使用Flyout控件,这就需要使用FlyoutBase.AttachedFlyout附加属性。这时我们必须响应控件的交互操作,并在代码中控制打开Flyout。

            <TextBlock Text="Tap me to show flyout." Tapped="TextBlock_Tapped" FontSize="20">
                <FlyoutBase.AttachedFlyout>
                    <Flyout>
                        <TextBlock FontSize="18" Text="You can do something..."/>
                    </Flyout>
                </FlyoutBase.AttachedFlyout>
            </TextBlock>

下面是TextBlock的Tapped事件处理

        private void TextBlock_Tapped(object sender, TappedRoutedEventArgs e)
        {
            TextBlock tb = sender as TextBlock;
            if (tb != null)
            {
                FlyoutBase.ShowAttachedFlyout(tb);
            }
        }

 

2. MenuFlyout

 MenuFlyout被称为菜单浮出控件,能够浮出显示菜单。大家看名字就能猜出,MenuFlyout 和 Flyout的用法很相似,可参照我们刚刚介绍的Flyout例子。而不同就在于MenuFlyout可以通过MenuFlyoutItem、ToggleMenuFlyoutItem 和 MenuFlyoutSeparator轻松定义菜单内容。

  • MenuFlyoutItem —— 执行即时操作
  • ToggleMenuFlyoutItem —— 打开或关闭选项
  • MenuFlyoutSeparator —— 菜单项之间的分隔符

我们下面以Button为例来演示MenuFlyout的用法

            <Button Content="Text Format">
                <Button.Flyout>
                    <MenuFlyout>
                        <MenuFlyoutItem Text="Reset" Click="Reset_Click"/>
                        <MenuFlyoutSeparator/>
                        <ToggleMenuFlyoutItem Text="TextWrap" IsChecked="True"/>
                        <ToggleMenuFlyoutItem Text="TextTrim" IsChecked="False"/>
                    </MenuFlyout>
                </Button.Flyout>
            </Button>

 

3. SettingsFlyout

 SettingsFlyout被称为设置浮出控件,利用它我们可以更轻松的创建应用设置的浮出控件。用户可以通过“设置”超级按钮来访问设置浮出控件,或触发我们定义的事件来访问。下面我们来演示如何通过触发事件的方式来访问SettingsFlyout。

首先,新建一个SettingsFlyout控件,步骤是:添加新建项 -> 在对话框中,选择““设置”浮出控件” -> 设置名称为 AutoplaySettingsFlyout。

<SettingsFlyout
    x:Class="HelloWorld.AutoplaySettingsFlyout"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloWorld"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    IconSource="Assets/SmallLogo.png"
    Title="Autoplay"
    d:DesignWidth="346" Width="346">

    <!-- 此 StackPanel 充当内容部分的垂直布局的根面板-->
    <StackPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
        <!-- 下列 StackPanel 定义个别内容部分-->
        <!-- 第 1 部分内容-->
        <StackPanel Style="{StaticResource SettingsFlyoutSectionStyle}">
            <!-- 第 1 部分标题-->
            <TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="Automatic plays" />
            <!-- 第 1 部分正文-->
            <TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,25" TextWrapping="Wrap">
                <TextBlock.Text>
                    Turn automatic playing on or off.
                </TextBlock.Text>
            </TextBlock>
            <ToggleSwitch Header="play automatically" />
        </StackPanel>
        <!-- 根据需要在下面定义更多内容部分-->
    </StackPanel>
</SettingsFlyout>

如上面代码和效果图所示,SettingsFlyout控件可以调整宽度和背景色,但高度一般是应用的高度。头部中包括了标题,回退按钮和应用图标。内容部分采用的是StackPanel流式布局。下面我们看看怎么把它添加到“设置”的窗体中。

        public MainPage()
        {
            this.InitializeComponent();
            Windows.UI.ApplicationSettings.SettingsPane.GetForCurrentView().CommandsRequested += MainPage_CommandsRequested;
        }

        void MainPage_CommandsRequested(Windows.UI.ApplicationSettings.SettingsPane sender, Windows.UI.ApplicationSettings.SettingsPaneCommandsRequestedEventArgs args)
        {
            Windows.UI.ApplicationSettings.SettingsCommand updateSetting =
                new Windows.UI.ApplicationSettings.SettingsCommand("AppUpdateSettings", "Auto Play", (handler) =>
                {
                    AutoplaySettingsFlyout autoplayFlyout = new AutoplaySettingsFlyout();
                    autoplayFlyout.Show();

                });

            args.Request.ApplicationCommands.Add(updateSetting);
        }

这样我们就把SettingsFlyout控件添加到“设置”中了,名字是'Auto Play',下面我们看看怎么通过按钮点击的方式来访问它。

        <Button Content="App update settings" Click="AutoplaySettingsButton_Click"/>
        private void AutoplaySettingsButton_Click(object sender, RoutedEventArgs e)
        {
            AutoplaySettingsFlyout autoplayFlyout = new AutoplaySettingsFlyout();
            autoplayFlyout.Show();
        }

通过按钮点击事件,我们调用了SettingsFlyout控件的Show方法,这样控件就可以访问了。当控件中的回退按钮点击后,浮出控件关闭并重新打开设置窗体。

如果我们调用的是ShowIndependent方法,回退按钮点击后,浮出控件关闭并回到应用中。同时我们也可以通过调用控件的Hide方法来关闭浮出控件,效果和回退按钮点击类似。

需要注意的是,一次只能显示一个浮出控件,调用Show/ShowIndependent 方法显示会关闭当前其他浮出控件。

 

4. Hub

中心控件,帮助我们更好的实现“中心”设计模式,中心页是用户进入应用的入口点,比如说应用商城。用户进入应用商城后,看到的类别分类就是中心的实现,它可以在横向或纵向的滚动视图中显示丰富而有序的内容。 

Hub的Header属性可以设置中心的标题,可以设置Header或HeaderTemplate来实现。

Hub可以分区显示,通过将不同的内容放入不同的HubSection来实现。HubSection也可以设置标题,做法与Hub一致。如果HubSection的IsHeaderInteractive属性为true,那么标题默认包含 '>' 字型,以及悬停和按下状态。我们来看看代码实现

        <Hub Header="Movies">
            <HubSection MinWidth="600" Header="Latest">
                <DataTemplate>
                    <Grid>
                        <TextBlock Text="The most recent movies will be here." 
                           Style="{ThemeResource BodyTextBlockStyle}" />
                    </Grid>
                </DataTemplate>
            </HubSection>

            <HubSection Header="Comedy" IsHeaderInteractive="True"  
                Background="#222222" MinWidth="250">
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="Comedy movies goes here."
                           Style="{ThemeResource BodyTextBlockStyle}" />
                        <TextBlock Text="Click the header to go to the Comedy page."
                           Style="{ThemeResource BodyTextBlockStyle}" />
                    </StackPanel>
                </DataTemplate>
            </HubSection>

            <HubSection Header="Action" IsHeaderInteractive="True" 
                Background="#444444" MinWidth="250">
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="Action movies goes here."
                           Style="{ThemeResource BodyTextBlockStyle}" />
                        <TextBlock Text="Click the header to go to the Action movies." 
                           Style="{ThemeResource BodyTextBlockStyle}" />
                    </StackPanel>
                </DataTemplate>
            </HubSection>
        </Hub>

 

5. Hyperlink

超链接,我们可以把它添加到文本上,它和文本具有相同的处理方式,换行、截断等。当文本被标记为超链接后,文本会显示为特定的颜色,点击文本会转到指定的URI,这个URI由NavigateUri属性来指定。

            <RichTextBlock Width="400" FontSize="20">
                <Paragraph>Hyperlinks let you give readers a visual hint that certain text links to other content.
                    <Hyperlink NavigateUri="http://dev.windows.com">Read more on the Windows Dev Center</Hyperlink>
                    ... Text in a Hyperlink element is treated like the rest of the text and participates in line breaking.
                </Paragraph>
            </RichTextBlock>

如上图所示,紫色文字部分为超链接,点击后会跳转到我们指定的NavigateUri。

 

这样我们就把Windows 8.1 的新增控件介绍完了,希望对大家有所帮助,谢谢。

#ifndef _RENDER_DEVICE_H_ #define _RENDER_DEVICE_H_ #ifdef _WIN32 #include "SystemDetector.h" //Win7 SP1必须安装补丁:KB2670838 才支持 D2D+D3D混合渲染 /*本模块渲染模式: *Win7 : 使用D2D + WIC + D3D10 + SwapChain混合渲染,交换链呈现内容 *Win8 : 使用D2D + D3D11 + SwapChain混合渲染,交换链呈现内容, 能兼容DComposition视觉树 *Win8.1 : 使用D2D + D3D11 + DirectComposition混合渲染,DComposition视觉树呈现内容 : 目前最强模式 *Win10 : 同8.1模式 * Win8兼容DComposition视觉树意义: 虽然最终呈现是SwapChanin的工作, 但DComposition提供了管理视觉树的功能 * 你可以将 DirectComposition(DComposition)的视觉树管理 粗略地类比为 Windows 7 中按 Win + Tab 显示的窗口切换器(任务视图),但它的功能和应用场景更加广泛和灵活。 * 进入了视觉树,说明你能很轻松就把动画效果做出来 */ /*Win7 性能瓶颈警告 * Win7 只支持D2D1.0版本,导致了无法与D3D共享显存,导致D2D+D3D混合渲染性能下降,但依然是win7最高性能,Win7如果想做D2D+D3D+SwapChain混合,必须经过CPU拷贝,但也比GDI+快 * Win7 如果放弃D2D+D3D混合渲染,则只能使用纯D2D绘制+虽然绘图过程可以使用D2D的功能,但最终渲染还是给CPU工作的。Win7下纯D2D绘图需要BindDC * 可以参考微软官网理论: https://learn.microsoft.com/zh-cn/windows/win32/direct2d/comparing-direct2d-and-gdi * win7 想做D2D+D3D+SwapChain混合,必须经过CPU拷贝,但也比GDI+快得多 * win7的绘图方案如下: * 方案 是否支持 GPU 加速 图像质量 开发难度 性能 适用场景 性能排名 GDI ❌ 低 低 低 老系统维护、简单控件 4 GDI+ ❌ 中等 低 中等 快速开发、非高性能需求 3 D2D + BindDC ✅(受限) 高 高 中等 少量高质量图形、混合 D3D 2 D2D + WIC + D3D10 + SwapChain ✅ 高 高 高 高性能 UI、混合 2D/3D 1 特别注意: D2D + WIC + D3D10 + SwapChain模式, D2D的上下文对象是不公开的,并且只有唯一一个,所以不能多线程竞争:BeginDraw() / EndDraw(); 绘图操作要自己进行同步 特别建议: 避免在 Win7 上使用多线程绘制 D2D 渲染目标,即使每个控件有独立的 CreateWicBitmapRenderTarget 哪怕你硬是成功获取了IDXGIFactory2对象,当你创建交换链时,会报错: XGI ERROR: IDXGIFactory::CreateSwapChainForComposition: Composition SwapChains are not supported on Windows 7.[ MISCELLANEOUS ERROR #137: ] 所以只能老实使用D2D + WIC + D3D10 + SwapChain模式 */ //注意性能: 高版本只是增加了特性功能API, 基础核心功能永远都在基础版本ID3D11Device中.性能差异:系统更新, 硬件支持,SDK 和运行时版本, API 调用方式, 多线程支持 #include <d3d11.h> //注意: 所有高版本并没有集成在 d3d11.h 中 /* 各版本的d3d11.h文件对应的系统版本:越高版本越多新特性,但我们的绘图需求不需要那么高版本,低版本能兼容更多系统 * d3d11.h = win7; * d3d11_1.h = win8; * d3d11_2.h = win8.1; * d3d11_3.h = win10(1507) * d3d11_4.h = win10(1709) * 微软已停止更新 D3D11:自 Windows 11 发布后,微软将图形开发重点转向 D3D12,不再为 D3D11 提供新特性。最高文件d3d11_4.h * 接口版本与对应的 DirectX 版本及 SDK 接口名称 对应的 DirectX 版本 引入的 Windows SDK 版本 引入的操作系统版本 ID3D11Device DirectX 11.0 Windows SDK v7.0 Windows 7 SP1 ID3D11Device1 DirectX 11.1 Windows SDK v8.0 (Win8 SDK) Windows 8 ID3D11Device2 DirectX 11.2 Windows SDK v8.1 (Win8.1 SDK) Windows 8.1 ID3D11Device3 DirectX 11.3 Windows SDK v10.0.10240.0 Windows 10 TH1 (1507) ID3D11Device4 DirectX 11.4 Windows SDK v10.0.10586.0 Windows 10 TH2 (1511) ID3D11Device5 DirectX 11.4 Windows SDK v10.0.14393.0 Windows 10 RS1 (1607) */ //注意性能: 高版本只是增加了特性功能API, 基础核心功能永远都在基础版本ID2D1Factory中.性能差异:系统更新, 硬件支持,SDK 和运行时版本, API 调用方式, 多线程支持 #include <d2d1.h> //注意: 所有高版本声明都集成在 d2d1.h 中 /* 各版本的d2d1.h文件对应的系统版本:越高版本越多新特性,但我们的绘图需求不需要那么多特性,低版本能兼容更多系统 * d2d1.h = win7 / vista; * d2d1_1.h = win8; * d2d1_2.h = win8.1; * d2d1_3.h = win10(1507) * * 虽然更新了新版本,但微软不再递增文件号了,所以最高文件为d2d1_3.h * d2d1_4.h = win10(1607) * d2d1_5.h = win10(1703) * d2d1_6.h = win10(19041) * ID2D1Factory 系列版本与对应系统/SDK 接口名称 对应版本号 引入操作系统 对应 SDK 版本 主要功能增强 ID2D1Factory v1.1 Windows 7 SP1 Windows SDK v7.1+ 基础 2D 图形渲染支持 实际使用win7是支持1.1版本 ID2D1Factory1 v1.1 Windows 8 Windows SDK v8.0+ 设备上下文、多线程支持 ID2D1Factory2 v1.2 Windows 8.1 Windows SDK v8.1+ 支持图像效果(Image Effects) ID2D1Factory3 v1.3 Windows 10 Windows 10 SDK v10.0.10240+ 性能优化、GPU 加速改进 ID2D1Factory4 v1.4 Windows 10 1607 Windows 10 SDK v10.0.14393+ 更多 GPU 渲染特性 ID2D1Factory5 v1.5 Windows 10 1803 Windows 10 SDK v10.0.17134+ 新增 D2D 与 D3D 的交互能力 ID2D1Factory6 v1.6 Windows 10 1903 Windows 10 SDK v10.0.18362+ 改进资源管理、图形性能优化 ID2D1Factory7 v1.7 Windows 10 20H2 Windows 10 SDK v10.0.19041+ 支持更复杂的 GPU 渲染流程 ID2D1Factory8 v1.8 Windows 11/Windows 10 21H2+ Windows 10 SDK v10.0.22621+ 与 D3D12 更好的集成、新增高级图像处理功能 注意:每个新版本的接口都继承自前一版本,因此高版本接口通常可以替代低版本使用,但需确保目标平台支持该版本。 接口版本与对应的 Direct2D 版本、SDK 及操作系统 接口名称 对应的 Direct2D 版本 引入的 Windows SDK 版本 引入的操作系统版本 ID2D1Device Direct2D 1.0 Windows SDK v7.1 (Win7 SDK) Windows 7 ID2D1Device Direct2D 1.1 Windows SDK v8.0 (Win8 SDK) Windows 8 ID2D1Device1 Direct2D 1.2 Windows SDK v8.1 (Win8.1 SDK) Windows 8.1 ID2D1Device2 Direct2D 1.3 Windows SDK v10.0.10240.0 Windows 10 TH1 (1507) ID2D1Device3 Direct2D 1.4 Windows SDK v10.0.14393.0 Windows 10 RS1 (1607) ID2D1DeviceContext 版本对应表 接口名称 引入的 SDK 版本 对应操作系统版本 主要新增功能 / 改进 ID2D1DeviceContext Windows SDK v7.0A Windows 8 RTM (6.2) 基础设备上下文接口,支持 Direct2D 设备模型 ID2D1DeviceContext1 Windows SDK v8.0A Windows 8.1 (6.3) 添加对位图格式扩展、纹理采样器状态等的支持 ID2D1DeviceContext2 Windows SDK v10.0.10240.0 Windows 10 TH1 (1507) 支持混合模式渲染、GPU 状态控制、多线程绘制优化 ID2D1DeviceContext3 Windows SDK v10.0.10586.0 Windows 10 TH2 (1511) 增加对 D3D11.3 的支持,例如支持更多着色器资源视图 ID2D1DeviceContext4 Windows SDK v10.0.14393.0 Windows 10 RS1 (1607) 支持更高效的图像处理、硬件加速的模糊效果 ID2D1DeviceContext5 Windows SDK v10.0.15063.0 Windows 10 RS2 (1703) 支持 GPU 后期合成(GPU compositing),提升性能与帧率 ID2D1DeviceContext6 Windows SDK v10.0.17134.0 Windows 10 RS4 (1803) 支持更复杂的 GPU 渲染管线,例如支持 DX12 相关功能(通过兼容层) ID2D1DeviceContext7 Windows SDK v10.0.19041.0 Windows 10 20H2 (2020) 支持 Direct2D 在现代 UI 框架(如 WinUI 3)中的集成,改进跨平台一致性 */ //注意性能: 高版本只是增加了特性功能API, 基础核心功能永远都在基础版本IDXGIDevice中.性能差异:系统更新, 硬件支持,SDK 和运行时版本, API 调用方式, 多线程支持 #include <dxgi.h>//注意: 所有高版本都集成在dxgi.h中 /* DXGI版本 头文件 支持的操作系统 DXGI 1.0 dxgi.h Windows Vista (带更新), Windows 7 DXGI 1.1 dxgi1_2.h Windows Vista SP2 (带更新), Windows 7, 和版本2集成在同一个文件中 DXGI 1.2 dxgi1_2.h Windows 7 (带KB2670838), Windows 8, 和版本1集成在同一个文件中 DXGI 1.3 dxgi1_3.h Windows 8.1, Windows Server 2012 R2 DXGI 1.4 dxgi1_4.h Windows 10 (初始版本) DXGI 1.5 dxgi1_5.h Windows 10 版本1607 (周年更新) 及以上 DXGI 1.6 dxgi1_6.h Windows 10 版本1803 及以上 * 接口版本与对应的 DXGI 版本、SDK 及操作系统 接口名称 对应的 DXGI 版本 引入的 Windows SDK 版本 引入的操作系统版本 IDXGIDevice DXGI 1.0 Windows SDK v7.0 Windows 7 SP1 IDXGIDevice1 DXGI 1.2 Windows SDK v8.0 (Win8 SDK) Windows 8 IDXGIDevice2 DXGI 1.3 Windows SDK v8.1 (Win8.1 SDK) Windows 8.1 IDXGIDevice3 DXGI 1.4 Windows SDK v10.0.10240.0 Windows 10 TH1 (1507) IDXGIDevice4 DXGI 1.5 Windows SDK v10.0.14393.0 Windows 10 RS1 (1607) */ #include <dcomp.h>//dcomp.h 首次出现在 Windows 8 SDK 中 /* 接口名称 引入版本 主要功能 IDCompositionDevice Windows 8 基础合成对象创建 IDCompositionDevice2 Windows 8.1 动画系统增强 IDCompositionDevice3 Windows 10 1511 图像处理和动画扩展 IDCompositionDevice4 Windows 10 1709 高级图像特效支持 IDCompositionDevice5 Windows 10 1809 新增图像处理特效和优化 */ #include <mutex>//设备是共享的,所以需要互斥锁 namespace D2DRENDER { class CRenderDevice { public: CRenderDevice(); ~CRenderDevice(); private: /***************************************开始准备D3D******************************************************************/ void CreateD3DDevice();//创建D3D设备 void GetDXGIDevice();//查询 DXGI 设备需要CreateDevice3D()支持 /***************************************开始准备D2D******************************************************************/ void CreateD2DFactory(); void CreateD2DDevice(); /***************************************开始准备DirectComposition****************************************************/ void CreateDcompDevice(); private: ID3D11Device* m_pD3DDevice; // Direct3D设备,使用交换链过程: 创建D3D设备->取出DXGI设备->桥接:使用DXGI创建D2D设备 IDXGIFactory* m_pDXGIFactory; // DXGI工厂,用于创建交换链 IDXGIDevice* m_pDXGIDevice; // DXGI设备: D3D桥接D2D的桥梁 ID2D1Factory1* m_pD2DFactory1; // Direct2D工厂 ID2D1Device* m_pD2DDevice; // Direct2D设备 // DirectComposition = win8 开始才引入 IDCompositionDevice* m_pDcompDevice; //DirectComposition设备 std::mutex m_mutex; // 用于保护内部资源访问 }; } #endif // _WIN32 #endif // !_RENDER_DEVICE_H_ #include "DcompFactory.h" #include "SystemDetector.h" using namespace D2DRENDER; // 匹配 dcomp.h 中的 DCompositionCreateDevice 函数原型 typedef HRESULT(WINAPI* fDCompositionCreateDevice)( IUnknown* dxgiDevice, REFIID riid, void** ppv ); // 匹配 dcomp.h 中的 DCompositionCreateDevice2 函数原型 typedef HRESULT(WINAPI* fDCompositionCreateDevice2)( IUnknown* renderingDevice, REFIID riid, void** ppv ); // COM最优解, 接口聚全(Interface Aggregation) -> 即最新版本的接口聚合到旧版本接口中 class CDcompFactoryImpl : public IDcompFactory1 { public: CDcompFactoryImpl(); // 构造函数 ~CDcompFactoryImpl(); // 析构函数 STDMETHOD_(HRESULT, QueryInterface)(REFIID riid, void** ppvObject); // COM接口查询 STDMETHOD_(ULONG, AddRef)(); // COM接口引用计数 STDMETHOD_(ULONG, Release)(); // COM接口释放计数 STDMETHOD_(INT32, GetDcompVersion)()CONST; STDMETHOD(DCompositionCreateDevice)(IUnknown* dxgiDevice, REFIID riid, void** ppv); // 创建DComposition设备 STDMETHOD(DCompositionCreateDevice2)(IUnknown* dxgiDevice, REFIID riid, void** ppv); // 创建DComposition设备 private: DWORD m_dwRefCount; // 引用计数 HMODULE m_hModule; // 模块句柄 INT32 m_iVersion; // 支持的版本 fDCompositionCreateDevice m_pfDCompositionCreateDevice; fDCompositionCreateDevice2 m_pfDCompositionCreateDevice2; }; CDcompFactoryImpl::CDcompFactoryImpl(): m_dwRefCount(0), m_hModule(nullptr), m_iVersion(-1), m_pfDCompositionCreateDevice(nullptr), m_pfDCompositionCreateDevice2(nullptr) { m_hModule = LoadLibrary("dcomp.dll"); if (m_hModule) { m_pfDCompositionCreateDevice = (fDCompositionCreateDevice)GetProcAddress(m_hModule, "DCompositionCreateDevice"); m_pfDCompositionCreateDevice2 = (fDCompositionCreateDevice2)GetProcAddress(m_hModule, "DCompositionCreateDevice2"); m_iVersion = m_pfDCompositionCreateDevice2 ? 2 : m_pfDCompositionCreateDevice ? 1 : 0; } else { m_iVersion = 0;//win8以下不支持 } } CDcompFactoryImpl::~CDcompFactoryImpl() { if(m_hModule)FreeLibrary(m_hModule); } STDMETHODIMP CDcompFactoryImpl::QueryInterface(REFIID riid, void** ppvObject) { if (riid == __uuidof(IDcompFactory)) { *ppvObject = this; AddRef(); return S_OK; } else if (riid == __uuidof(IDcompFactory1)) { *ppvObject = this; AddRef(); return S_OK; } else { *ppvObject = nullptr; return E_NOINTERFACE; } } STDMETHODIMP_(ULONG) CDcompFactoryImpl::AddRef() { return InterlockedIncrement(&m_dwRefCount); } STDMETHODIMP_(ULONG) CDcompFactoryImpl::Release() { ULONG ulCount = InterlockedDecrement(&m_dwRefCount); if (ulCount == 0) { delete this; } return ulCount; } STDMETHODIMP_(INT32) CDcompFactoryImpl::GetDcompVersion()CONST { return m_iVersion; } STDMETHODIMP CDcompFactoryImpl::DCompositionCreateDevice(IUnknown* dxgiDevice, REFIID riid, void** ppv) { HRESULT hr = m_pfDCompositionCreateDevice(dxgiDevice, riid, ppv); return hr; } STDMETHODIMP CDcompFactoryImpl::DCompositionCreateDevice2(IUnknown* dxgiDevice, REFIID riid, void** ppv) { HRESULT hr = m_pfDCompositionCreateDevice2(dxgiDevice, riid, ppv); return hr; } STDAPI D2DRENDER::CreateDcompFactory(REFIID riid, void** ppv) { IDcompFactory* pFactory = new CDcompFactoryImpl(); if (pFactory->GetDcompVersion() == 0)//如果版本太低 { pFactory->Release();//释放对象 *ppv = nullptr; return E_NOINTERFACE;//不支持 } pFactory->AddRef(); *ppv = pFactory; return S_OK; }
08-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值