doc: add the doc for c++ binding according to c binding

This commit is contained in:
2026-06-26 14:59:14 +08:00
parent db69452213
commit e3a1195c04
2 changed files with 412 additions and 3 deletions

View File

@@ -17,40 +17,108 @@
#include <string> #include <string>
#include <utility> #include <utility>
/**
* @brief Windows File Association C++ API namespace
*
* Provides C++ RAII wrappers around the C-compatible wfassoc API.
*/
namespace wfassocpp { namespace wfassocpp {
/** @brief Type representing a null-terminated UTF-8 C-style string */
using CString = wfassoc::WFCString; using CString = wfassoc::WFCString;
/**
* @brief Type representing a handle/token for managed objects
*
* This library uses an object pool to manage any objects created during calling.
* This type is exposed as an opaque handle for visiting your created object.
*/
using Token = wfassoc::WFToken; using Token = wfassoc::WFToken;
/**
* @brief Type representing an icon handle (opaque pointer)
*
* This type is equivalent to the Win32 HICON type.
*/
using HICON = wfassoc::WFHICON; using HICON = wfassoc::WFHICON;
/** @brief Invalid icon handle value */
using INVALID_HICON = wfassoc::WF_INVALID_HICON; using INVALID_HICON = wfassoc::WF_INVALID_HICON;
/** @brief Invalid index value used for error conditions */
using INVALID_INDEX = wfassoc::WF_INVALID_INDEX; using INVALID_INDEX = wfassoc::WF_INVALID_INDEX;
/**
* @brief Registration scope for file associations
*
* Determines whether a program is registered for the current user or system-wide.
*/
using Scope = wfassoc::WFScope; using Scope = wfassoc::WFScope;
/**
* @brief View mode for querying file association status
*
* Determines how the association status is viewed/queried.
*/
using View = wfassoc::WFView; using View = wfassoc::WFView;
/// @private /**
* @private
* @brief Check the result of a C API call and throw on failure
*
* @param[in] result Boolean result from a C API call
* @throws std::runtime_error if result is false, with the error message from WFGetLastError()
*/
inline void _Check(bool result) { inline void _Check(bool result) {
if (!result) { if (!result) {
throw std::runtime_error(wfassoc::WFGetLastError()); throw std::runtime_error(wfassoc::WFGetLastError());
} }
} }
/// @private /**
* @private
* @brief Get the invalid token value
*
* In theory, invalid token value should be a constant value.
* However, due to the library used in Rust side, this value can only be fetched at runtime.
* This function caches the value on first call for subsequent use.
*
* @return An invalid token value
*/
inline Token _INVALID_TOKEN() { inline Token _INVALID_TOKEN() {
static Token v = wfassoc::WFInvalidToken(); static Token v = wfassoc::WFInvalidToken();
return v; return v;
} }
/**
* @brief Schema object for defining a program's file association configuration
*
* A Schema is a sketchpad of a complete program.
* Create a Schema object first, then convert it to a Program object for following operations.
*
* This class is move-only (non-copyable).
*/
class Schema { class Schema {
public: public:
/**
* @brief Construct a new Schema object
* @throws std::runtime_error if schema creation fails
*/
Schema() { _Check(wfassoc::WFSchemaCreate(&_token)); } Schema() { _Check(wfassoc::WFSchemaCreate(&_token)); }
/**
* @brief Destroy the Schema object
*
* Releases resources associated with the Schema object.
*/
~Schema() { ~Schema() {
if (_token != _INVALID_TOKEN()) { if (_token != _INVALID_TOKEN()) {
wfassoc::WFSchemaDestroy(_token); wfassoc::WFSchemaDestroy(_token);
} }
} }
/** @brief Non-copyable */
Schema(const Schema&) = delete; Schema(const Schema&) = delete;
/** @brief Non-copyable */
Schema& operator=(const Schema&) = delete; Schema& operator=(const Schema&) = delete;
/** @brief Move constructor */
Schema(Schema&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); } Schema(Schema&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
/** @brief Move assignment operator */
Schema& operator=(Schema&& other) noexcept { Schema& operator=(Schema&& other) noexcept {
if (this != &other) { if (this != &other) {
if (_token != _INVALID_TOKEN()) { if (_token != _INVALID_TOKEN()) {
@@ -62,41 +130,159 @@ public:
return *this; return *this;
} }
/**
* @brief Set the program identifier for this Schema
*
* @param[in] value Null-terminated UTF-8 string containing the identifier.
* This identifier should not be empty, must start with alphabet character,
* and follow with alphabet characters, digits, underline, or hyphens.
* @throws std::runtime_error if the operation fails
*/
void SetIdentifier(const char* value) { _Check(wfassoc::WFSchemaSetIdentifier(_token, value)); } void SetIdentifier(const char* value) { _Check(wfassoc::WFSchemaSetIdentifier(_token, value)); }
/**
* @brief Set the program path for this Schema
*
* @param[in] value Null-terminated UTF-8 string containing the program path.
* This path should be the fully qualified path to the application.
* @throws std::runtime_error if the operation fails
*/
void SetPath(const char* value) { _Check(wfassoc::WFSchemaSetPath(_token, value)); } void SetPath(const char* value) { _Check(wfassoc::WFSchemaSetPath(_token, value)); }
/**
* @brief Set the program CLSID for this Schema
*
* @param[in] value Null-terminated UTF-8 string containing the CLSID.
* This CLSID string should be in the format of @c {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}.
* Please note that curly braces are required.
* @throws std::runtime_error if the operation fails
*/
void SetClsid(const char* value) { _Check(wfassoc::WFSchemaSetClsid(_token, value)); } void SetClsid(const char* value) { _Check(wfassoc::WFSchemaSetClsid(_token, value)); }
/**
* @brief Set the program name for this Schema (optional)
*
* @param[in] value Null-terminated UTF-8 string containing the name, or nullptr to clear
* @throws std::runtime_error if the operation fails
*/
void SetName(const char* value) { _Check(wfassoc::WFSchemaSetName(_token, value)); } void SetName(const char* value) { _Check(wfassoc::WFSchemaSetName(_token, value)); }
/**
* @brief Set the program icon for this Schema (optional)
*
* @param[in] value Null-terminated UTF-8 string containing the icon path, or nullptr to clear
* @throws std::runtime_error if the operation fails
*/
void SetIcon(const char* value) { _Check(wfassoc::WFSchemaSetIcon(_token, value)); } void SetIcon(const char* value) { _Check(wfassoc::WFSchemaSetIcon(_token, value)); }
/**
* @brief Set the program behavior for this Schema (optional)
*
* @param[in] value Null-terminated UTF-8 string containing the behavior command, or nullptr to clear
* @throws std::runtime_error if the operation fails
*/
void SetBehavior(const char* value) { _Check(wfassoc::WFSchemaSetBehavior(_token, value)); } void SetBehavior(const char* value) { _Check(wfassoc::WFSchemaSetBehavior(_token, value)); }
/**
* @brief Add a string resource entry to this Schema
*
* @param[in] name Null-terminated UTF-8 string containing the name of this entry
* @param[in] value Null-terminated UTF-8 string containing the value of this entry.
* It can be a plain string or a reference string to resource.
* @throws std::runtime_error if the operation fails
*/
void AddStr(const char* name, const char* value) { _Check(wfassoc::WFSchemaAddStr(_token, name, value)); } void AddStr(const char* name, const char* value) { _Check(wfassoc::WFSchemaAddStr(_token, name, value)); }
/**
* @brief Add an icon registry entry to this Schema
*
* @param[in] name Null-terminated UTF-8 string containing the name of this entry
* @param[in] value Null-terminated UTF-8 string containing the value of this entry.
* It can be a path to icon or a reference string to resource.
* @throws std::runtime_error if the operation fails
*/
void AddIcon(const char* name, const char* value) { _Check(wfassoc::WFSchemaAddIcon(_token, name, value)); } void AddIcon(const char* name, const char* value) { _Check(wfassoc::WFSchemaAddIcon(_token, name, value)); }
/**
* @brief Add a behavior registry entry to this Schema
*
* @param[in] name Null-terminated UTF-8 string containing the name of this entry
* @param[in] value Null-terminated UTF-8 string containing the value of this entry.
* It should be a valid command line string which uses @c %1, @c %2, etc. to represent parameters.
* @throws std::runtime_error if the operation fails
*/
void AddBehavior(const char* name, const char* value) { _Check(wfassoc::WFSchemaAddBehavior(_token, name, value)); } void AddBehavior(const char* name, const char* value) { _Check(wfassoc::WFSchemaAddBehavior(_token, name, value)); }
/**
* @brief Add a file extension to this Schema
*
* @param[in] ext Null-terminated UTF-8 string containing the file extension name (without leading dot)
* @param[in] ext_name Null-terminated UTF-8 string containing the name pointing to associated name for this extension.
* This name should be registered by calling AddStr().
* @param[in] ext_icon Null-terminated UTF-8 string containing the name pointing to associated icon for this extension.
* This name should be registered by calling AddIcon().
* @param[in] ext_behavior Null-terminated UTF-8 string containing the name pointing to associated behavior for this extension.
* This name should be registered by calling AddBehavior().
* @throws std::runtime_error if the operation fails
*/
void AddExt(const char* ext, const char* ext_name, const char* ext_icon, const char* ext_behavior) { void AddExt(const char* ext, const char* ext_name, const char* ext_icon, const char* ext_behavior) {
_Check(wfassoc::WFSchemaAddExt(_token, ext, ext_name, ext_icon, ext_behavior)); _Check(wfassoc::WFSchemaAddExt(_token, ext, ext_name, ext_icon, ext_behavior));
} }
private: private:
friend class Program; friend class Program;
/// @private
/**
* @private
* @brief Release ownership of the token
*
* @return The released token
*/
Token Release() noexcept { Token Release() noexcept {
Token t = _token; Token t = _token;
_token = _INVALID_TOKEN(); _token = _INVALID_TOKEN();
return t; return t;
} }
Token _token; Token _token;
}; };
/**
* @brief Icon resource object for managing icon handles
*
* This class wraps an icon resource token and provides access to the icon handle.
* The icon handle will be freed when this object is destroyed.
*
* This class is move-only (non-copyable).
*/
class IconRc { class IconRc {
public: public:
/**
* @brief Construct an IconRc from an existing token
*
* @param[in] token The icon resource token to wrap
*/
explicit IconRc(Token token) : _token(token) {} explicit IconRc(Token token) : _token(token) {}
/**
* @brief Destroy the IconRc object
*
* Releases resources associated with the icon resource.
*/
~IconRc() { ~IconRc() {
if (_token != _INVALID_TOKEN()) { if (_token != _INVALID_TOKEN()) {
wfassoc::WFIconRcDestroy(_token); wfassoc::WFIconRcDestroy(_token);
} }
} }
/** @brief Non-copyable */
IconRc(const IconRc&) = delete; IconRc(const IconRc&) = delete;
/** @brief Non-copyable */
IconRc& operator=(const IconRc&) = delete; IconRc& operator=(const IconRc&) = delete;
/** @brief Move constructor */
IconRc(IconRc&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); } IconRc(IconRc&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
/** @brief Move assignment operator */
IconRc& operator=(IconRc&& other) noexcept { IconRc& operator=(IconRc&& other) noexcept {
if (this != &other) { if (this != &other) {
if (_token != _INVALID_TOKEN()) { if (_token != _INVALID_TOKEN()) {
@@ -108,6 +294,13 @@ public:
return *this; return *this;
} }
/**
* @brief Get the icon handle from this icon resource
*
* @return The icon handle. This handle will be freed when this object is destroyed.
* Please make a copy immediately if you need to use it longer.
* @throws std::runtime_error if the operation fails
*/
HICON GetIcon() { HICON GetIcon() {
HICON icon = nullptr; HICON icon = nullptr;
_Check(wfassoc::WFIconRcGetIcon(_token, &icon)); _Check(wfassoc::WFIconRcGetIcon(_token, &icon));
@@ -118,17 +311,42 @@ private:
Token _token; Token _token;
}; };
/**
* @brief Extension status object for querying file extension registration status
*
* This class wraps an extension status token and provides access to extension details.
* The extension status object will be freed when this object is destroyed.
*
* This class is move-only (non-copyable).
*/
class ExtStatus { class ExtStatus {
public: public:
/**
* @brief Construct an ExtStatus from an existing token
*
* @param[in] token The extension status token to wrap
*/
explicit ExtStatus(Token token) : _token(token) {} explicit ExtStatus(Token token) : _token(token) {}
/**
* @brief Destroy the ExtStatus object
*
* Releases resources associated with the extension status.
*/
~ExtStatus() { ~ExtStatus() {
if (_token != _INVALID_TOKEN()) { if (_token != _INVALID_TOKEN()) {
wfassoc::WFExtStatusDestroy(_token); wfassoc::WFExtStatusDestroy(_token);
} }
} }
/** @brief Non-copyable */
ExtStatus(const ExtStatus&) = delete; ExtStatus(const ExtStatus&) = delete;
/** @brief Non-copyable */
ExtStatus& operator=(const ExtStatus&) = delete; ExtStatus& operator=(const ExtStatus&) = delete;
/** @brief Move constructor */
ExtStatus(ExtStatus&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); } ExtStatus(ExtStatus&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
/** @brief Move assignment operator */
ExtStatus& operator=(ExtStatus&& other) noexcept { ExtStatus& operator=(ExtStatus&& other) noexcept {
if (this != &other) { if (this != &other) {
if (_token != _INVALID_TOKEN()) { if (_token != _INVALID_TOKEN()) {
@@ -140,12 +358,30 @@ public:
return *this; return *this;
} }
/**
* @brief Get the display name from this extension status
*
* The display name will be user specified first, then fallback to its ProgId verbatim.
* The library will try to use localized name first, then use raw ProgId name if localized name is not available.
*
* @return The display name string. There is no possibility that this value is empty.
* @throws std::runtime_error if the operation fails
*/
std::string GetName() { std::string GetName() {
const char* name = nullptr; const char* name = nullptr;
_Check(wfassoc::WFExtStatusGetName(_token, &name)); _Check(wfassoc::WFExtStatusGetName(_token, &name));
return std::string(name); return std::string(name);
} }
/**
* @brief Get the icon from this extension status
*
* The icon will be user specified first, then fallback to the system default file icon.
*
* @return The icon handle. This handle will be freed when this object is destroyed.
* Please make a copy immediately if you need to use it longer.
* @throws std::runtime_error if the operation fails
*/
HICON GetIcon() { HICON GetIcon() {
HICON icon = nullptr; HICON icon = nullptr;
_Check(wfassoc::WFExtStatusGetIcon(_token, &icon)); _Check(wfassoc::WFExtStatusGetIcon(_token, &icon));
@@ -156,17 +392,42 @@ private:
Token _token; Token _token;
}; };
/**
* @brief Self extension status object for accessing program-provided extension details
*
* This class wraps a self extension status token and provides access to extension details
* as defined by the program itself.
*
* This class is move-only (non-copyable).
*/
class SelfExtStatus { class SelfExtStatus {
public: public:
/**
* @brief Construct a SelfExtStatus from an existing token
*
* @param[in] token The self extension status token to wrap
*/
explicit SelfExtStatus(Token token) : _token(token) {} explicit SelfExtStatus(Token token) : _token(token) {}
/**
* @brief Destroy the SelfExtStatus object
*
* Releases resources associated with the self extension status.
*/
~SelfExtStatus() { ~SelfExtStatus() {
if (_token != _INVALID_TOKEN()) { if (_token != _INVALID_TOKEN()) {
wfassoc::WFSelfExtStatusDestroy(_token); wfassoc::WFSelfExtStatusDestroy(_token);
} }
} }
/** @brief Non-copyable */
SelfExtStatus(const SelfExtStatus&) = delete; SelfExtStatus(const SelfExtStatus&) = delete;
/** @brief Non-copyable */
SelfExtStatus& operator=(const SelfExtStatus&) = delete; SelfExtStatus& operator=(const SelfExtStatus&) = delete;
/** @brief Move constructor */
SelfExtStatus(SelfExtStatus&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); } SelfExtStatus(SelfExtStatus&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
/** @brief Move assignment operator */
SelfExtStatus& operator=(SelfExtStatus&& other) noexcept { SelfExtStatus& operator=(SelfExtStatus&& other) noexcept {
if (this != &other) { if (this != &other) {
if (_token != _INVALID_TOKEN()) { if (_token != _INVALID_TOKEN()) {
@@ -178,24 +439,53 @@ public:
return *this; return *this;
} }
/**
* @brief Get the display name from this self extension status
*
* The display name will be user specified first, then fallback to its ProgId verbatim.
*
* @return The display name string. There is no possibility that this value is empty.
* @throws std::runtime_error if the operation fails
*/
std::string GetName() { std::string GetName() {
const char* name = nullptr; const char* name = nullptr;
_Check(wfassoc::WFSelfExtStatusGetName(_token, &name)); _Check(wfassoc::WFSelfExtStatusGetName(_token, &name));
return std::string(name); return std::string(name);
} }
/**
* @brief Get the icon from this self extension status
*
* The icon will be user specified first, then fallback to the system default file icon.
*
* @return The icon handle. This handle will be freed when this object is destroyed.
* Please make a copy immediately if you need to use it longer.
* @throws std::runtime_error if the operation fails
*/
HICON GetIcon() { HICON GetIcon() {
HICON icon = nullptr; HICON icon = nullptr;
_Check(wfassoc::WFSelfExtStatusGetIcon(_token, &icon)); _Check(wfassoc::WFSelfExtStatusGetIcon(_token, &icon));
return icon; return icon;
} }
/**
* @brief Get the extension string (without leading dot) from this self extension status
*
* @return The file extension name (without leading dot). There is no possibility that this value is empty.
* @throws std::runtime_error if the operation fails
*/
std::string GetExt() { std::string GetExt() {
const char* inner = nullptr; const char* inner = nullptr;
_Check(wfassoc::WFSelfExtStatusGetExt(_token, &inner)); _Check(wfassoc::WFSelfExtStatusGetExt(_token, &inner));
return std::string(inner); return std::string(inner);
} }
/**
* @brief Get the dotted extension string (with leading dot) from this self extension status
*
* @return The file extension string (with leading dot). There is no possibility that this value is empty.
* @throws std::runtime_error if the operation fails
*/
std::string GetDottedExt() { std::string GetDottedExt() {
const char* inner = nullptr; const char* inner = nullptr;
_Check(wfassoc::WFSelfExtStatusGetDottedExt(_token, &inner)); _Check(wfassoc::WFSelfExtStatusGetDottedExt(_token, &inner));
@@ -206,19 +496,48 @@ private:
Token _token; Token _token;
}; };
/**
* @brief Program object for managing file association registration
*
* A Program is created from a Schema and provides methods for registering,
* unregistering, and querying file associations.
*
* This class is move-only (non-copyable).
*/
class Program { class Program {
public: public:
/**
* @brief Construct a Program from a Schema
*
* This constructor consumes the Schema object.
* The Schema object cannot be used after this call.
*
* @param[in] schema The Schema to create the Program from (will be consumed)
* @throws std::runtime_error if program creation fails
*/
explicit Program(Schema&& schema) { explicit Program(Schema&& schema) {
_Check(wfassoc::WFProgramCreate(schema.Release(), &_token)); _Check(wfassoc::WFProgramCreate(schema.Release(), &_token));
} }
/**
* @brief Destroy the Program object
*
* Releases resources associated with the Program.
*/
~Program() { ~Program() {
if (_token != _INVALID_TOKEN()) { if (_token != _INVALID_TOKEN()) {
wfassoc::WFProgramDestroy(_token); wfassoc::WFProgramDestroy(_token);
} }
} }
/** @brief Non-copyable */
Program(const Program&) = delete; Program(const Program&) = delete;
/** @brief Non-copyable */
Program& operator=(const Program&) = delete; Program& operator=(const Program&) = delete;
/** @brief Move constructor */
Program(Program&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); } Program(Program&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
/** @brief Move assignment operator */
Program& operator=(Program&& other) noexcept { Program& operator=(Program&& other) noexcept {
if (this != &other) { if (this != &other) {
if (_token != _INVALID_TOKEN()) { if (_token != _INVALID_TOKEN()) {
@@ -230,48 +549,132 @@ public:
return *this; return *this;
} }
/**
* @brief Resolve the provided program name of this Program
*
* The name will be user specified first,
* then fallback to program manifest file specified name,
* and finally fallback to the file name of executable.
*
* @return The resolved program name. There is no possibility that this value is empty.
* @throws std::runtime_error if the operation fails
*/
std::string ResolveName() { std::string ResolveName() {
const char* name = nullptr; const char* name = nullptr;
_Check(wfassoc::WFProgramResolveName(_token, &name)); _Check(wfassoc::WFProgramResolveName(_token, &name));
return std::string(name); return std::string(name);
} }
/**
* @brief Resolve the Program icon resource
*
* The icon will be user specified first,
* then fallback to the first icon of program,
* and finally fallback to the system default executable icon.
*
* @return An IconRc object containing the resolved icon
* @throws std::runtime_error if the operation fails
*/
IconRc ResolveIcon() { IconRc ResolveIcon() {
Token token = _INVALID_TOKEN(); Token token = _INVALID_TOKEN();
_Check(wfassoc::WFProgramResolveIcon(_token, &token)); _Check(wfassoc::WFProgramResolveIcon(_token, &token));
return IconRc(token); return IconRc(token);
} }
/**
* @brief Get the number of file extensions in the Program
*
* @return The number of extensions
* @throws std::runtime_error if the operation fails
*/
size_t ExtsLen() { size_t ExtsLen() {
size_t len = 0; size_t len = 0;
_Check(wfassoc::WFProgramExtsLen(_token, &len)); _Check(wfassoc::WFProgramExtsLen(_token, &len));
return len; return len;
} }
/**
* @brief Find a file extension by its body (extension string)
*
* @param[in] body Null-terminated UTF-8 string containing the file extension name (without leading dot) to find
* @return The index of the extension, or INVALID_INDEX if not found
* @throws std::runtime_error if the operation fails
*/
size_t FindExt(const char* body) { size_t FindExt(const char* body) {
size_t index = INVALID_INDEX; size_t index = INVALID_INDEX;
_Check(wfassoc::WFProgramFindExt(_token, body, &index)); _Check(wfassoc::WFProgramFindExt(_token, body, &index));
return index; return index;
} }
/**
* @brief Resolve this program provided extension's details by index
*
* @param[in] index Index of the extension to resolve
* @return A SelfExtStatus object containing the extension details
* @throws std::runtime_error if the operation fails
*/
SelfExtStatus ResolveExt(size_t index) { SelfExtStatus ResolveExt(size_t index) {
Token token = _INVALID_TOKEN(); Token token = _INVALID_TOKEN();
_Check(wfassoc::WFProgramResolveExt(_token, index, &token)); _Check(wfassoc::WFProgramResolveExt(_token, index, &token));
return SelfExtStatus(token); return SelfExtStatus(token);
} }
/**
* @brief Register the Program in the specified scope
*
* @param[in] scope Registration scope
* @throws std::runtime_error if the operation fails
*/
void Register(Scope scope) { _Check(wfassoc::WFProgramRegister(_token, scope)); } void Register(Scope scope) { _Check(wfassoc::WFProgramRegister(_token, scope)); }
/**
* @brief Unregister the Program from the specified scope
*
* @param[in] scope Registration scope
* @throws std::runtime_error if the operation fails
*/
void Unregister(Scope scope) { _Check(wfassoc::WFProgramUnregister(_token, scope)); } void Unregister(Scope scope) { _Check(wfassoc::WFProgramUnregister(_token, scope)); }
/**
* @brief Check if the Program is registered in the specified scope
*
* @param[in] scope Registration scope for checking
* @return true if the Program is registered in the specified scope, false otherwise
* @throws std::runtime_error if the operation fails
*/
bool IsRegistered(Scope scope) { bool IsRegistered(Scope scope) {
bool result = false; bool result = false;
_Check(wfassoc::WFProgramIsRegistered(_token, scope, &result)); _Check(wfassoc::WFProgramIsRegistered(_token, scope, &result));
return result; return result;
} }
/**
* @brief Link a file extension in the specified scope
*
* @param[in] scope Registration scope
* @param[in] index Index of the extension to link
* @throws std::runtime_error if the operation fails
*/
void LinkExt(Scope scope, size_t index) { _Check(wfassoc::WFProgramLinkExt(_token, scope, index)); } void LinkExt(Scope scope, size_t index) { _Check(wfassoc::WFProgramLinkExt(_token, scope, index)); }
/**
* @brief Unlink a file extension in the specified scope
*
* @param[in] scope Registration scope
* @param[in] index Index of the extension to unlink
* @throws std::runtime_error if the operation fails
*/
void UnlinkExt(Scope scope, size_t index) { _Check(wfassoc::WFProgramUnlinkExt(_token, scope, index)); } void UnlinkExt(Scope scope, size_t index) { _Check(wfassoc::WFProgramUnlinkExt(_token, scope, index)); }
/**
* @brief Query the status of a file extension
*
* @param[in] view View viewpoint
* @param[in] index Index of the extension to query
* @return An optional ExtStatus object. Returns std::nullopt if the extension is not found
* (usually means that this extension is not registered in the specified scope).
* @throws std::runtime_error if the operation fails
*/
std::optional<ExtStatus> QueryExt(View view, size_t index) { std::optional<ExtStatus> QueryExt(View view, size_t index) {
Token token = _INVALID_TOKEN(); Token token = _INVALID_TOKEN();
_Check(wfassoc::WFProgramQueryExt(_token, view, index, &token)); _Check(wfassoc::WFProgramQueryExt(_token, view, index, &token));

View File

@@ -22,6 +22,12 @@
#ifdef __cplusplus #ifdef __cplusplus
/**
* @brief Windows File Association C/C++ API namespace
*
* This namespace only provide the raw binding to C-compatible wfassoc API in C++.
* For the C++ RAII wrappers of this, please see @ref wfassocpp namespace.
*/
namespace wfassoc { namespace wfassoc {
#endif // __cplusplus #endif // __cplusplus