作者:webabcd
介紹
重新想象 Windows 8 Store Apps 之 其它
C# 中調用 Windows Runtime Component(C++)
讓 Windows Runtime Component(C++) 作為代理以調用 DLL(C++)
通過 C++ 和 D3D 獲取屏幕分辨率
示例
一、演示如何在 C# 中調用 Windows Runtime Component(C++),以及 Windows Runtime Component(C++) 如何作為代理調用 DLL(C++)
1、WindowsDll 項目
WindowsDll.h
#pragma once
// 用於演示 C# 調用 Windows Dynamic Link Library(C++) 中的函數(需要通過 Windows Runtime Component 做為代理)
extern "C" _declspec(dllexport) int Add(int x, int y);
WindowsDll.cpp
#include "pch.h"
#include "WindowsDll.h"
// 注意:要想 C# 能調用此 dll,則必須要有以下這兩行(wp8 則不需要)
#include "winapifamily.h""
#define WINAPI_FAMILY WINAPI_PARTITION_APP
int Add(int x, int y)
{
return x + y;
}
2、WindowsRuntimeComponent 項目
MyRuntimeComponent.h
#pragma once
#include <windows.h>
namespace WindowsRuntimeComponent
{
public ref class MyRuntimeComponent sealed
{
public:
// 用於演示 C# 調用 Windows Runtime Component(C++) 中的函數
int Add(int x, int y);
// 用於演示通過此 Windows Runtime Component 做為代理,然後調用 Windows Dynamic Link Library(C++) 中的函數
typedef int(*myAdd)(int x, int y);
int Add2(int i, int j);
};
}
MyRuntimeComponent.cpp
#include "pch.h"
#include "MyRuntimeComponent.h"
using namespace WindowsRuntimeComponent;
int MyRuntimeComponent::Add(int x, int y)
{
return x + y;
}
// 作為代理,調用 WindowsDLL.dll 中的函數
int MyRuntimeComponent::Add2(int i, int j)
{
HINSTANCE hDll = LoadPackagedLibrary(L"CPP/WindowsDLL.dll", 0);
myAdd add = (myAdd)GetProcAddress(hDll, "Add");
int result = add(i, j);
FreeLibrary(hDll);
return result;
}
3、調用者
CPP/Demo.xaml
<Page
x:Class="XamlDemo.CPP.Demo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.CPP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Transparent">
<StackPanel Margin="120 0 0 0">
<TextBlock Name="lblMsg" FontSize="14.667" TextWrapping="Wrap" />
</StackPanel>
</Grid>
</Page>
CPP/Demo.xaml.cs
/*
* 演示如何在 C# 中調用 Windows Runtime Component(C++),以及 Windows Runtime Component(C++) 如何作為代理調用 DLL(C++)
*
*
* 注:
* 1、Windows Runtime Component(C++) 項目參見:WindowsRuntimeComponent 項目
* 2、DLL(C++) 項目參見:WindowsDll 項目
* 3、將 PhoneDLL.dll 復制到本項目的根目錄下,以便 WPRuntimeComponent 項目調用
*/
using System;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace XamlDemo.CPP
{
public sealed partial class Demo : Page
{
public Demo()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// 引用 Windows Runtime Component 項目
WindowsRuntimeComponent.MyRuntimeComponent component = new WindowsRuntimeComponent.MyRuntimeComponent();
// 調用 Windows Runtime Component(C++) 中的函數
lblMsg.Text = "調用 Windows Runtime Component 中的函數:" + component.Add(10, 10).ToString();
lblMsg.Text += Environment.NewLine;
// 調用 DLL(C++) 中的函數,方式:Windows Runtime Component(C++) 作為一個代理調用 DLL(C++),然後 C# 調用 Windows Runtime Component(C++)
lblMsg.Text += "調用 Windows Runtime Component 中的函數(其僅作為一個代理,實際調用的是 WindowsDLL 中的函數):" + component.Add2(10, 10).ToString();
base.OnNavigatedTo(e);
}
}
}
二、演示如何在 C# 中調用 Windows Runtime Component(C++ & D3D),從而獲取屏幕的分辨率
1、WindowsRuntimeComponent 項目
Helper.h
/*
* 注意:
* 由於需要 D3D,所以需要在 項目屬性 -> 配置屬性 -> 鏈接器 -> 輸入 -> 附加依賴項 中增加“d3d11.lib”
*
* 參考:
* http://blogs.microsoft.co.il/blogs/tomershamam/archive/2012/07/24/get-screen-resolution-in-windows-8-metro-style-application.aspx
*/
#pragma once
#include <wrl/client.h>
#include <d3d11_1.h>
#include <d2d1_1.h>
#include <d2d1effects.h>
#include <dwrite_1.h>
#include <wincodec.h>
namespace DX
{
inline void ThrowIfFailed(HRESULT hr)
{
if (FAILED(hr))
{
// 拋出 DirectX API 的錯誤
throw Platform::Exception::CreateException(hr);
}
}
}
namespace WindowsRuntimeComponent
{
public ref class Helper sealed
{
public:
Helper();
// 一個屬性,用於得到屏幕分辨率
property Windows::Foundation::Point ScreenResolution
{
Windows::Foundation::Point get();
}
private:
D3D_FEATURE_LEVEL m_featureLevel;
Microsoft::WRL::ComPtr<ID3D11Device1> m_d3dDevice;
};
}
Helper.cpp
查看本欄目
/*
* 注意:
* 由於需要 D3D,所以需要在 項目屬性 -> 配置屬性 -> 鏈接器 -> 輸入 -> 附加依賴項 中增加“d3d11.lib”
*
* 參考:
* http://blogs.microsoft.co.il/blogs/tomershamam/archive/2012/07/24/get-screen-resolution-in-windows-8-metro-style-application.aspx
*/
#include "pch.h"
#include "Helper.h"
#include <agile.h>
#include <windows.ui.xaml.media.dxinterop.h>
using namespace Microsoft::WRL;
using namespace Windows::Foundation;
using namespace WindowsRuntimeComponent;
using namespace Platform;
Helper::Helper()
{
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#if defined(_DEBUG)
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
ComPtr<ID3D11Device> device;
ComPtr<ID3D11DeviceContext> context;
DX::ThrowIfFailed(
D3D11CreateDevice(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
0,
creationFlags,
featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION,
&device,
&m_featureLevel,
&context
)
);
DX::ThrowIfFailed(device.As(&m_d3dDevice));
}
// 獲取屏幕分辨率
Point Helper::ScreenResolution::get()
{
ComPtr<IDXGIDevice> dxgiDevice;
DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice));
ComPtr<IDXGIAdapter> dxgiAdapter;
DX::ThrowIfFailed(dxgiDevice->GetAdapter(&dxgiAdapter));
IDXGIOutput * pOutput;
if (dxgiAdapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND)
{
DXGI_OUTPUT_DESC desc;
pOutput->GetDesc(&desc);
return Point(desc.DesktopCoordinates.right, desc.DesktopCoordinates.bottom);
}
return Point(0, 0);
}
2、調用者
CPP/GetResolution.xaml
<Page
x:Class="XamlDemo.CPP.GetResolution"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.CPP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Transparent">
<StackPanel Margin="120 0 0 0">
<TextBlock Name="lblMsg" FontSize="14.667" TextWrapping="Wrap" />
</StackPanel>
</Grid>
</Page>
CPP/GetResolution.xaml.cs
/*
* 演示如何在 C# 中調用 Windows Runtime Component(C++ & D3D),從而獲取屏幕的分辨率
*
*
* 注:
* 用於獲取屏幕分辨率的 Windows Runtime Component(C++ & D3D) 項目參見:WindowsRuntimeComponent 項目
*/
using Windows.Foundation;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace XamlDemo.CPP
{
public sealed partial class GetResolution : Page
{
public GetResolution()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// 引用 C++ 項目,實例化 Helper 類
WindowsRuntimeComponent.Helper helper = new WindowsRuntimeComponent.Helper();
// 調用 Helper 中的屬性,得到屏幕分辨率
Point screenResolution = helper.ScreenResolution;
// 顯示分辨率
lblMsg.Text = string.Format("分辨率:{0}×{1}", screenResolution.X.ToString(), screenResolution.Y.ToString());
base.OnNavigatedTo(e);
}
}
}
OK
源碼下載:http://files.cnblogs.com/webabcd/Windows8.rar