目录

Wwise SDK 2018.1.11
如何创建版本控制插件 DLL

创建 Wwise 版本控制插件 DLL 需要以下步骤:

Note: 一个 DLL 中可以包含多个插件。更多信息请参阅 建立导出函数

开始新工程

在开始新的工程时,必须新建工程,并创建将在工程中使用的导出函数。

您还应熟悉将在工程中使用的版本控制接口。

创建工程

要使用 Visual Studio 创建工程,请执行以下步骤:

  1. 创建 MFC DLL C++ 工程。在 MFC DLL Wizard 对话框中,DLL 类型必须设置为使用 shared MFC DLL( 共享的MFC DLL)的 Regular DLL(常规 DLL)。
  2. 在新工程中,打开 Project Properties 对话框并执行以下步骤:
  • 在 General Property 页面,将 Character Set 属性设置为 Use Unicode Character Set。
  • 在 C/C++/General Property 页面中,将 SDK includes 目录的路径添加到 Additional Include Directories 属性中。

工程将被创建并配置为使用 Wwise Source Control SDK。下一步要创建 Wwise 管理插件 DLL 所用的函数。

Tip: 严格来说无需创建 MFC DLL 工程。但创建此工程将有助于操纵特定字符串和对白。如果您选择不使用 MFC DLL,请确保在 stdafx.h 文件中包含 oleauto.h 文件头,以便使用 SysAllocString function 函数。

建立导出函数

每个插件 DLL 必须导出三个函数:

  • AkSourceControlGetPluginIDList():获取所有插件 ID 的列表,以便 Wwise 能够访问 DLL 中包含的插件列表。
  • AkSourceControlGetPluginInfo():Wwise 通过此函数来访问与特定插件相关的 AK::Wwise::ISourceControl::PluginInfo 类。
  • AkSourceControlCreatePlugin():创建一个 AK::Wwise::ISourceControl 对象。

这些导出函数的原型可以在下列类型定义中找到:

对于包含两个插件的插件 DLL,其导出函数如下列所示:

#include "SamplePlugin.h"
namespace
{
// FirstSamplePlugin ID = {BD47DF98-1700-4542-A33F-E44705C25AF0}
static const GUID s_guidFirstSamplePluginID =
{ 0xbd47df98, 0x1700, 0x4542, { 0xa3, 0x3f, 0xe4, 0x47, 0x5, 0xc2, 0x5a, 0xf0 } };
// SecondSamplePlugin ID = {57168691-2354-4166-82BF-DD07A36C16C6}
static const GUID s_guidSecondSamplePluginID =
{ 0x57168691, 0x2354, 0x4166, { 0x82, 0xbf, 0xdd, 0x7, 0xa3, 0x6c, 0x16, 0xc6 } };
}
void __stdcall AkSourceControlGetPluginIDList ( AK::Wwise::ISourceControl::PluginIDList& out_rPluginIDList )
{
out_rPluginIDList.AddTail( s_guidFirstSamplePluginID );
out_rPluginIDList.AddTail( s_guidSecondSamplePluginID );
}
void __stdcall AkSourceControlGetPluginInfo ( const GUID& in_rguidPluginID,
{
if ( in_rguidPluginID == s_guidFirstSamplePluginID )
{
FirstSamplePlugin::GetPluginInfo( out_rPluginInfo );
}
else if ( in_rguidPluginID == s_guidSecondSamplePluginID )
{
SecondSamplePlugin::GetPluginInfo( out_rPluginInfo );
}
}
AK::Wwise::ISourceControl* __stdcall AkSourceControlCreatePlugin ( const GUID& in_rguidPluginID )
{
AK::Wwise::ISourceControl* pSourceControl = NULL;
if ( in_rguidPluginID == s_guidFirstSamplePluginID )
{
pSourceControl = new FirstSamplePlugin();
}
else if ( in_rguidPluginID == s_guidSecondSamplePluginID )
{
pSourceControl = new SecondSamplePlugin();
}
return pSourceControl;
}
Warning: 必须更改插件 GUID 值,以避免 ID 与其他插件发生冲突。

使用 Visual Studio 创建工程时,您需要在工程的 .def 文件中添加函数名称来导出这些函数。如果模块定义文件不存在,则须创建一个。

请按照下列步骤创建模块定义文件:

  1. 单击工具栏上的 Add New Item 按钮。
  2. 在模板列表中选择 Module-Definition File (.def) 模板。

典型的模块定义文件如下所示:

LIBRARY "SamplePlugin"
EXPORTS
AkSourceControlGetPluginIDList
AkSourceControlGetPluginInfo
AkSourceControlCreatePlugin

版本控制接口介绍

每个 Wwise 版本控制插件必须包含特定接口才能被正确集成。这些接口汇总如下,稍后将对它们进行详细介绍。

AK::Wwise::ISourceControl

插件必须应用此接口才能执行版本控制操作。

有关此接口的更多信息,请参阅 创建版本控制插件接口

AK::Wwise::ISourceControlUtilities

此接口由 Wwise 应用,并在创建时提供给插件。它将为插件提供一些实用的小函数模块。

有关此接口的更多信息,请参阅 使用版本控制实用函数接口

AK::Wwise::ISourceControlOperationProgress

此接口由 Wwise 应用,并通过 ISourceControlUtilities 类提供给插件。它提供了管理简单进度对话框的函数。

有关此接口的更多信息,请参阅 实现版本控制操作进度接口

AK::Wwise::ISourceControlDialogBase

插件必须应用此接口才能创建拥有 Wwise 界面外观的对话框。

有关此接口的更多信息,请参阅 定义版本控制插件对话框

创建版本控制插件接口

通过实现 AK::Wwise::ISourceControl 的各方法,可以定义响应 Wwise 中各种情形的插件行为。这些方法将允许插件对以下情形做出反应:

  • 初始化或终止插件时
  • 销毁插件时
  • 音频设计师单击 Project Settings 对话框中的“Config…”按钮时
  • Wwise 刷新 Project Explorer 中的图标时
  • 在 File Manager 内刷新 Work Units 或 Sources 选项卡中的文件列表时
  • 显示包含版本控制操作的上下文菜单时
  • 音频设计师在 File Manager 或 Project Explorer 中,从上下文菜单中选择操作时
  • 更新文件时
  • 音频设计师导入音频文件、创建新的工作单元或者保存工程时。

其中部分情况将在后文中进行介绍,也可以直接查阅 AK::Wwise::ISourceControl 参考文献,来了解所需实现的接口和功能的完整说明。

Tip: 此接口中的许多方法使用 AK::Wwise::ISourceControl::OperationResult 枚举作为返回类型。注意,只有发生全局性的操作失败时,即您不希望 Wwise 使用插件返回的数据时,才应返回 OperationResult_Failed。所述失败包括以下情况:
  • 连接失败。
  • 发生内部插件错误。

代码示例

必须创建 AK::Wwise::ISourceControl 派生类来实现此接口的所有方法。该类将用来管理与插件 UI 和版本控制操作相关的各个方面。这些方法的适用情形已在注释中注明。

#include <AK/Wwise/ISourceControl.h>
class SamplePlugin
{
public:
SamplePlugin();
virtual ~SamplePlugin();
// ISourceControl 实现
virtual void Init(AK::Wwise::ISourceControlUtilities* in_pUtilities ); // 初始化和插件实例
virtual void Term(); // 终止插件实例
virtual void Destroy(); // 销毁插件实例
virtual bool ShowConfigDlg(); // 插件配置
virtual void GetOperationList( OperationMenuType in_menuType, const StringList& in_rFilenameList,
OperationList& out_rOperationList ); // 上下文菜单
virtual DWORD GetOperationEffect(
DWORD in_dwOperationID ); // Wwise 需要清楚操作的影响
virtual LPCWSTR GetOperationName(
DWORD in_dwOperationID ); // 获取操作名称
virtual AK::Wwise::ISourceControlUtilities::OperationResult GetFileStatus(
const StringList& in_rFilenameList,
FilenameToStatusMap& out_rFileStatusMap ); // File Manager 对话框
virtual AK::Wwise::ISourceControlUtilities::OperationResult GetFileStatusIcons(
const StringList& in_rFilenameList,
FilenameToIconMap& out_rFileIconsMap ); // Project Explorer 图标刷新
virtual AK::Wwise::ISourceControlUtilities::OperationResult GetMissingFilesInDirectories(
const StringList& in_rDirectoryList, StringList& out_rFilenameList ); // File Manager 对话框
virtual void DoOperation( DWORD in_dwOperationID, const StringList& in_rFilenameList ); // 执行
// 版本控制操作
virtual AK::Wwise::ISourceControlUtilities::OperationResult PreCreateOrModify(
const StringList& in_rFilenameList,
bool& out_rContinue ); // 在 Wwise 中创建或修改文件
virtual AK::Wwise::ISourceControlUtilities::OperationResult PostCreateOrModify(
const StringList& in_rFilenameList,
bool& out_rContinue ); // 在 Wwise 中创建或修改文件
// 获取插件信息类的静态方法,可以参阅 Source Control Plug-in Information Class(版本控制插件信息类)
// 了解有关此方法的更多信息。
static void GetPluginInfo( PluginInfo& out_rPluginInfo );
private:
// 成员
AK::Wwise::ISourceControlUtilities* m_pSourceControlUtilities;
};
Caution: Wwise 与版本控制插件之间交换的字符串参数和结果必须采用 unicode 字符集。

构建版本控制插件信息类

当 Wwise 需要有关插件的信息时,将调用从 DLL 导出的 AkSourceControlGetPluginInfo 函数。(更多信息请参阅 建立导出函数 。)AK::Wwise::ISourceControl::PluginInfo 类包括以下数据:

  • 为用户显示的插件名称
  • 插件的版本
  • 用于告知 Wwise 在 Project Explorer 中是否显示工作单元版本控制图标的布尔值
  • 用于告知 Wwise 是否可以配置插件的布尔值
  • 用于告知 Wwise 是否可以使用 Update All 操作的布尔型值
  • 为用户显示的 Update All 操作的名称

Tip: 要想用简单方式获取插件信息,可以将 AkSourceControlGetPluginInfo (建立导出函数) 调用变为在 AK::Wwise::ISourceControl 接口实现中创建的静态方法。

该静态方法的简单实现如下:

void SamplePlugin::GetPluginInfo( PluginInfo& out_rPluginInfo )
{
// 插件名称和版本
out_rPluginInfo.m_bstrName = ::SysAllocString( L"Sample Source Control Plug-in" );
out_rPluginInfo.m_uiVersion = 1;
// 函数可用性
out_rPluginInfo.m_bShowConfigDlgAvailable = false;
out_rPluginInfo.m_dwUpdateCommandID = AK::Wwise::SourceControlConstant::s_dwInvalidOperationID;// Replace with your ID
out_rPluginInfo.m_dwCommitCommandID = AK::Wwise::SourceControlConstant::s_dwInvalidOperationID;// Replace with your ID
out_rPluginInfo.m_bStatusIconAvailable = false;
}
Warning: 须使用 SysAllocString 函数分配插件名称和 Update All 操作名称,因为 Wwise 将负责删除相应内存。

初始化和终止插件

在创建插件时,Wwise 将调用 AK::Wwise::ISourceControl::Init( ISourceControlUtilities* in_pUtilities ) 方法。此函数的指针参数指向 AK::Wwise::ISourceControlUtilities 接口的 Wwise 实现版本。需要将此指针复制为插件类的成员,从而可以创建对话框,显示进度对话框和消息框,或者加载和保存插件配置。更多相关信息,请参阅 使用版本控制实用函数接口

AK::Wwise::ISourceControl::Init() 的典型实现如下:

void SamplePlugin::Init( ISourceControlUtilities* in_pUtilities )
{
m_pSourceControlUtilities = in_pUtilities;
// 从注册表中加载插件配置
}

在销毁插件之前,Wwise 将调用 AK::Wwise::ISourceControl::Term() 方法。

AK::Wwise::ISourceControl::Term() 的典型实现如下:

{
// 将插件配置保存到注册表
m_pSourceControlUtilities = NULL;
}

关于加载/保存插件配置到注册表的更多信息,请参阅 版本控制插件例程

关于何时调用这些函数的更多信息,请参阅 销毁插件

销毁插件

当 Wwise 需要创建版本控制插件时,将调用 DLL(建立导出函数 )中的 AkSourceControlCreatePlugin() 函数来创建新插件。 此函数将向版本控制插件返回一个接口。当不再需要插件时,Wwise 将对该特定插件调用 AK::Wwise::ISourceControl::Destroy() 方法。该方法将释放对象消耗的内存或其他资源,然后删除对象本身。

使用 New 运算符来创建对象时,AK::Wwise::ISourceControl::Destroy() 的典型实现如下:

void SamplePlugin::Destroy()
{
delete this;
}

下列情况下将创建一个插件:

  • 音频设计师从 Project Settings 对话框中的版本控制插件列表中选择插件,并确认更改时
  • 音频设计师加载使用了该版本控制插件的工程时。

下列情况下将销毁插件:

  • 音频设计师在 Project Settings 对话框中选择另一版本控制插件,并确认更改时;
  • 关闭工程时。

使用版本控制实用函数接口

该接口将在插件初始化时提供(请参阅 初始化和终止插件 )。 其函数将帮助插件创建对话框、显示消息框和进度对话框以及加载和保存配置,且全部遵照 Wwise UI 外观和风格。

此接口提供以下方法:

显示进度对话框

在执行版本控制操作时,显示进度对话框和进度反馈消息将非常有用。可以通过调用 AK::Wwise::ISourceControlUtilities::GetProgressDialog() 方法来实现。该方法将返回 AK::Wwise::ISourceControlOperationProgress 接口。有关此接口的更多信息,请参阅 实现版本控制操作进度接口

显示消息对话框

要显示符合 Wwise UI 外观和风格的消息框,一个简单的方式是调用 AK::Wwise::ISourceControlUtilities::MessageBox() 方法。请按照标准的 MessageBox Windows 函数调用方式使用它。要让插件符合 Wwise UI 外观和风格,就应使用此方法,而非标准的 MessageBox 调用。

显示对话框

要创建符合 Wwise UI 外观和风格的对话框,必须调用 AK::Wwise::ISourceControlUtilities::CreateModalCustomDialog( ISourceControlDialogBase* in_pDialog ) 方法。该方法的工作方式与 CDialog::DoModal() 方法相同,不同的是前者接受 AK::Wwise::ISourceControlDialogBase 接口作为输入。有关这一点的更多信息,请参阅 定义版本控制插件对话框

显示进度对话框

AK::Wwise::ISourceControlUtilities 提供了一种在注册表中保存或加载插件配置的简单方法。通过调用 AK::Wwise::ISourceControlUtilities::GetRegistryPath() 方法,您可以获得在各工程和各插件的不同注册表文件夹路径。要加载或保存配置,应为当前插件版本创建一个子文件夹,并在其中创建所有插件键值。您可以在 AK::Wwise::ISourceControl::Init() 方法中加载配置,在 AK::Wwise::ISourceControl::Term() 方法中保存配置。

Warning: 必须使用 HKEY_CURRENT_USER 注册表键来访问此路径。工程注册表文件夹将使用此键来创建,版本控制插件配置必须与用户无关。

实现版本控制操作进度接口

AK::Wwise::ISourceControlOperationProgress 接口的实现可以通过在插件初始化时提供的 AK::Wwise::ISourceControlUtilities 接口来访问。 前一个接口提供以下方法:

创建进度对话框

要创建和显示进度对话框,请使用 AK::Wwise::ISourceControlOperationProgress::ShowProgress() 非阻塞方法。要向日志消息列表中添加消息,请使用 AK::Wwise::ISourceControlOperationProgress::AddLogMessage() 方法。

Warning:

Warning: 进度对话框不考虑转义符(例如“\n”或“\t”)。文本必须逐行添加,制表符必须替换为空格。

启用 OK 按钮

要启用 OK 按钮,可以调用 AK::Wwise::ISourceControlOperationProgress::OperationCompleted() 方法。此方法将在用户点击 OK 按钮之后才会返回结果。此时,对话框将关闭并销毁。

启用 Cancel 按钮

要知道用户是否按了 Cancel 按钮,只需调用 AK::Wwise::ISourceControlOperationProgress::IsCanceled() 方法即可。您还可以通过调用 AK::Wwise::ISourceControlOperationProgress::Cancel() 方法来取消操作。

Note: 即使您在程序中调用了 AK::Wwise::ISourceControlOperationProgress::Cancel() 方法来取消对话框,仍必须调用 AK::Wwise::ISourceControlOperationProgress::OperationCompleted() 来关闭和销毁对话框。

实现版本控制操作

要将您的版本控制插件集成到 音频设计师的工作流程中,必须按照如下方式实现下列功能。

启用插件配置

在 Project Settings 对话框中,音频设计师可以通过单击 Config… 按钮来配置插件。此按钮只有在 AK::Wwise::ISourceControl::PluginInfo::m_bShowConfigDlgAvailable 设为 True 时才会启用。单击此按钮时,Wwise 将调用 AK::Wwise::ISourceControl::ShowConfigDlg() 方法。此函数的返回一个布尔值。其含义如下:

  • True 表示已经接受配置更改,Project Explorer 图标将刷新。
  • False 表示已经拒绝配置更改,Project Explorer 图标不会刷新。

此方法的典型实现如下:

bool SamplePlugin::ShowConfigDlg()
{
DlgConfiguration configurationDialog();
// 如果用户点击“OK”,则返回 True
return m_pSourceControlUtilities->CreateModalCustomDialog( &configurationDialog ) == IDOK;
}

在此代码示例中,DlgConfiguration 类是 AK::Wwise::ISourceControlDialogBase 接口的一个实现。更多信息请参阅 定义版本控制插件对话框

启用 File Manager 对话框

当刷新 File Manager 时,将调用两个方法:

当生成文件列表时,Wwise 将搜索磁盘上的文件。然而在某些版本控制系统内,删除文件时会将其从磁盘中移除。尽管如此,仍须对这些文件进行标识,以确保在服务器中进行删除操作。为了获得处于此状态的文件列表,Wwise 将调用 AK::Wwise::ISourceControl::GetMissingFilesInDirectories() 方法。第一个参数是 Wwise 从中搜索这些缺失文件的目录列表,第二个参数是要改写为缺失文件的名称的字符串列表。

Warning: 插件不得包含位于给定目录子目录下的文件。

在 Wwise 获得完整文件列表后,Status 和 Owner(s) 列必须刷新。 为此,Wwise 将调用 AK::Wwise::ISourceControl::GetFileStatus() 方法。对于每个文件,插件需要显示其相应 Status 和 Owner。Wwise 将获取该函数第一个参数中所列的文件的状态。第二个参数是生成的映射,包含在 Status 和 Owner(s) 列中将要显示的文本。

Warning: 对于 AK::Wwise::ISourceControl::FilenameToStatusMapItem 的字符串成员,其内存必须使用 SysAllocString 函数分配,因为 Wwise 将负责删除相应内存。两个字符串不得共享同一内存空间,因为 Wwise 将单独销毁这两个字符串。

在上下文菜单中显示插件

当 Wwise 显示包含版本控制操作的上下文菜单时,需要获取在当前上下文中所有可用操作的列表。为此,Wwise 将调用 AK::Wwise::ISourceControl::GetOperationList( OperationMenuType in_menuType, const StringList& in_rFilenameList, OperationList& out_rOperationList ) 方法。第一个参数是显示操作列表的上下文。根据上下文限制,某些插件可能仅允许用户使用特定操作。第二个参数是用户所选择的文件名称列表。通过该列表可以根据文件的状态来启用或禁用某些操作。第三个参数是当前上下文中可用的操作列表。 此操作列表必须由插件生成。此列表中所含操作的相关信息将用于生成上下文菜单,并与操作 ID 一起回调给插件。对 ID 都没有限制。

Wwise 调用 LPCWSTR GetOperationName( DWORD in_dwOperationID ) 虚方法来获取操作名称,并在菜单和对话框中显示。

Warning: Wwise 不会删除操作名称字符串占用的内存。因此我们建议您随插件一起创建和销毁静态字符串。

在上下文菜单中显示版本控制操作

当 音频设计师从上下文菜单中选择操作时,Wwise 首先将调用 AK::Wwise::ISourceControl::GetOperationEffect( DWORD in_dwOperationID ) 方法。 其参数是相应操作的 ID。此方法的实现将返回 AK::Wwise::ISourceControl::OperationEffect 枚举中一个或多个值所构成的掩码。Wwise 根据返回值获悉,是否必须要求用户先保存工程,然后再继续执行版本控制操作。Update、Rename、Revert 和 Delete 等操作会更改本地文件的内容。Commit 和 Check-in 等操作会修改服务器中文件的内容。

Warning: 音频设计师可能会期望返回相关信息,来明确操作对文件的影响。 版本控制操作期间,当硬盘中的文件发生变化时,Wwise 可以检测到变化并将要求用户重新加载工程。 如果用户有未执行的更改(即工程未清理)并被要求重新加载,他们的更改将丢失。针对对未经清理的文件,如果用户选择 Revert 更改而不重新加载工程,再保存时则可能丢失新的更改。AK::Wwise::ISourceControl::GetOperationEffect 使用返回信息,强制用户进行保存来避免这些情况的发生。

在成功调用第一个方法后,Wwise 将调用 AK::Wwise::ISourceControl::DoOperation( DWORD in_dwOperationID, const StringList& in_rFilenameList ) 方法。第一个参数是相应操作的 ID。第二个参数是所选文件的列表。 此方法的实现使用 AK::Wwise::ISourceControlOperationProgress 接口来显示进度对话框。 更多信息请参阅 实现版本控制操作进度接口

允许 Wwise 刷新 Project Explorer 图标

在下列情况下,Wwise 需要刷新图标:

  • 加载了版本控制插件
  • 用户接受了插件配置
  • 用户单击“Refresh”或“Refresh All”Project Explorer 上下文菜单项,手动刷新了图标
  • 关闭了 File Manager 对话框。

在使用与 AK::Wwise::ISourceControl::GetFileStatus() 方法类似的模式时,AK::Wwise::ISourceControl::GetFileStatusIcons( const StringList& in_rFilenameList, FilenameToIconMap& out_rFileIconsMap ) 必须返回映射,其中包含列表文件图标和工具提示文本。第一个参数是 Wwise 需要映射图标的文件名称列表。第二个参数是生成的映射,其中包含以下组件:

  • 显示在工作单元原始图标之上的覆盖图标
  • 当鼠标移到该图标上方时显示的工具提示。
Warning: 对于 AK::Wwise::ISourceControl::FilenameToIconMapItem 的字符串成员,其内存必须使用 SysAllocString 函数分配,因为 Wwise 将负责删除相应内存。两个字符串不得共享同一内存空间,因为 Wwise 将单独销毁这两个字符串。

映射中包含的图标不限大小,但格式必须调整至 15x15 像素。 只有当 AK::Wwise::ISourceControl::PluginInfo::m_bStatusIconAvailable 设为 True 时,才会调用与图标相关的函数。

Tip: 随此 SDK 将安装一组您可以使用的图标。

允许在 Wwise 中创建和修改文件

当 音频设计师执行以下操作时,将进行文件创建和修改操作:

  • 创建新的工作单元
  • 导入音频源
  • 保存工程
  • 在外部编辑器中编辑音频源。

当发生上述情况时,Wwise 将调用 AK::Wwise::ISourceControl::PreCreateOrModify( const StringList& in_rFilenameList, CreateOrModifyOperation in_eOperation, bool& out_rContinue )AK::Wwise::ISourceControl::PostCreateOrModify( const StringList& in_rFilenameList, CreateOrModifyOperation in_eOperation, bool& out_rContinue ) 方法。第一个参数是要创建或修改的文件名称列表。第二个参数是定义了所要执行操作的标志。由于您可以对所列文件执行任一操作,因此您必须使用位运算符 AND 对第二个参数和预定义标志进行比较。例如,要想知道是否创建了某些文件,请执行以下操作:

if ( in_eOperation & CreateOrModifyOperation_Create )
{
// 执行操作
}

AK::Wwise::ISourceControl::PreCreateOrModify()AK::Wwise::ISourceControl::PostCreateOrModify() 函数的第三个参数需由插件设置,用于告诉 Wwise 要继续执行还是停止当前操作。此参数主要在调用 AK::Wwise::ISourceControl::PreCreateOrModify() 方法时使用。

Tip: 我们建议在执行版本控制系统专用操作时使用这两个方法。例如,您可以使用 AK::Wwise::ISourceControl::PreCreateOrModify() 方法执行 Perforce 的 checkout 操作,或者使用 AK::Wwise::ISourceControl::PostCreateOrModify() 方法添加未存在于服务器中的文件。在创建或修改文件前将会调用第一个方法,操作完成后将会调用第二个方法。此功能可以用来在插件中实现安全层。

定义版本控制插件对话框

如果 DLL 包含对话框,您可能希望它们符合 Wwise UI 的外观和风格。为此需要采取以下步骤:

创建对话框资源

您可以创建标准的 Windows 控件和 Wwise 专有控件。

常规控件

您可以直接在 Microsoft 开发环境 Dialog Editor 中使用 Toolbox 的 Dialog Editor 版块的相应工具添加各种常规控件,如静态控件、编辑控件、复选框、按钮、单选按钮和组合控件。Wwise 将自动对这些控件进行细分,实现与应用程序中其他控件相似的外观。

Note: 下拉/组合框控件将不会自动细分。如果对话框中需要下拉菜单控件,则应使用 Combo 自定义控件。请参阅“Wwise 控件”了解更多信息。

Wwise 控件

若要将 Wwise 对话框控件(如标题和组合框)集成到对话框中,请使用标题经过特殊编码的静态文本控件占位符。此文本需符合以下格式:

Class=[Classname];

其中类名称可以是下列之一:

  • 标题:只读文本显示
    您的资源中,静态控件高度应正好为 13 个单位,宽度应足够容纳可能包含的最长文本。要更改标题文本,需要使用以下标准 Windows 函数:
    • SetWindowText
    • GetWindowText
  • 组合:下拉列表
    您的资源中,静态控件高度应正好为 13 个单位,宽度应足够容纳可能包含的最长文本。要生成组合框或者设置/获取其当前选择,必须使用以下标准 Windows 消息宏:
    • ComboBox_InsertString
    • ComboBox_GetCurSel
    • ComboBox_SetCurSel
Tip: 为了便于查看对话框控件的布局,请在 Microsoft Development Environment Dialog Editor 中将静态占位符的 Border 属性设为 True。

启用对话框

必须先实现 AK::Wwise::ISourceControlDialogBase 接口,Wwise 才能显示对话框。 此接口提供以下方法:

Wwise 需要知道这些资源能在哪些上下文中找到。在创建对话框前,Wwise 将先调用 AK::Wwise::ISourceControlDialogBase::GetResourceHandle() 方法。此方法的典型实现如下:

HINSTANCE DlgSimple::GetResourceHandle() const
{
AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
return ::AfxGetResourceHandle();
}

Wwise 创建对话框时,还需要资源中的对话框 ID 。为了获取对话框 ID,Wwise 将调用 AK::Wwise::ISourceControlDialogBase::GetDialog() 方法。此方法的典型实现如下:

void DlgSimple::GetDialog( UINT & out_uiDialogID ) const
{
out_uiDialogID = IDD_SIMPLEDIALOGID;
}

为了获悉是否应在对话框标题栏上显示“?”图标,Wwise 将调用 AK::Wwise::ISourceControlDialogBase::HasHelp()。 如果存在与对话框相关的帮助内容,插件必须返回 True。此时将显示“?”图标。

bool DlgSimple::HasHelp() const
{
return true;
}

当 音频设计师单击对话框的“?”按钮时,Wwise 将调用 AK::Wwise::ISourceControlDialogBase::Help() 方法。如果插件处理了帮助请求,则必须返回 True,如果未执行任何操作,则应返回 false。此方法的实现示例如下:

bool DlgSimple::Help( HWND in_hWnd ) const
{
AFX_MANAGE_STATE( ::AfxGetStaticModuleState() ) ;
// 注:请勿调用 AfxGetApp()->HtmlHelp(),因为它将从错误的
// 父窗口中启动帮助窗口,导致悬浮窗口
// 行为表现异常。
::HtmlHelp( NULL, AfxGetApp()->m_pszHelpFilePath, HH_HELP_CONTEXT, ONLINEHELP::Simple_Dialog );
return true;
}
Caution: Help() 方法不应调用 AfxGetApp()->HtmlHelp()。它将从错误的父窗口中启动帮助窗口,导致悬浮窗口行为异常。 应使用带 Null 窗口语柄的 HtmlHelp() ,如上文示例中所示。

对话框不能使用 MFC 方法管理 Windows 消息。相反,当对话框收到 Windows 消息时,会调用 AK::Wwise::ISourceControlDialogBase::WindowProc()。此方法的实现示例如下:

bool DlgConfiguration::WindowProc( HWND in_hWnd, UINT in_message, WPARAM in_wParam, LPARAM in_lParam,
LRESULT & out_lResult )
{
if ( in_message == WM_INITDIALOG )
{
// 初始化对话框
}
// 例如:捕获窗口命令动作(仅针对主要对话框)来启用/禁用控件
else if ( in_message == WM_COMMAND )
{
// 通知代码
switch ( HIWORD( in_wParam ) )
{
case BN_CLICKED:
// 检查那个按钮被点击
switch ( LOWORD( in_wParam ) )
{
case IDOK:
// 用户按下“Ok”按钮
break;
}
} // 结束切换开关 hi 语句(通知代码)
} // 结束命令窗口事件
// 返回 False,让父窗口处理消息。Return True
// 对于不希望父窗口处理的消息,返回 True。
return false;
}

此方法的返回值含义如下:

  • False 表示消息将传给对象的父类。一般会返回此值
  • True 表示消息将不会传给对象的父类。当您希望父类对消息做出反应时,则返回此值。例如,当接收到 IDOK 按钮消息时,父类通常会关闭对话框。在某些情况下,如果部分信息尚未正确填写,您可能希望对话框保持打开。

要手动关闭对话框,需要使用 Windows PostMessage() 函数。调用此函数的典型代码如下所示:

PostMessage( in_hWnd, WM_CLOSE, 0, 0 );

显示对话框

要显示对话框,必须创建相应的 AK::Wwise::ISourceControlDialogBase 实现。通过使用 AK::Wwise::ISourceControlUtilities::CreateModalCustomDialog() 方法,对话框的显示将与模式对话框类似。如何创建和显示对话框的示例如下:

bool SamplePlugin::ShowConfigDlg()
{
DlgConfiguration configurationDialog( m_pSourceControlUtilities );
// 如果用户点击“OK”,则返回 true
return m_pSourceControlUtilities->CreateModalCustomDialog( &configurationDialog ) == IDOK;
}