feat: add c++ wfassoc wrapper
This commit is contained in:
281
wfassoc-cdylib/codegen/wfassoc++.h
Normal file
281
wfassoc-cdylib/codegen/wfassoc++.h
Normal file
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
* @file wfassoc++.h
|
||||
* @brief Windows File Association C++ API header
|
||||
*
|
||||
* This header provides C++ API for managing Windows file associations,
|
||||
* based on its C-compatible API.
|
||||
* The API is designed to work with at least C++17.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef WFASSOCPP_H_
|
||||
#define WFASSOCPP_H_
|
||||
|
||||
#include "wfassoc.h"
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace wfassocpp {
|
||||
|
||||
using wfassoc::CStyleString;
|
||||
using wfassoc::Token;
|
||||
using wfassoc::HICON;
|
||||
using wfassoc::INVALID_HICON;
|
||||
using wfassoc::INVALID_INDEX;
|
||||
using wfassoc::Scope;
|
||||
using wfassoc::View;
|
||||
|
||||
/// @private
|
||||
inline void _Check(bool result) {
|
||||
if (!result) {
|
||||
throw std::runtime_error(wfassoc::WFGetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
/// @private
|
||||
inline Token _INVALID_TOKEN() {
|
||||
static Token v = wfassoc::WFInvalidToken();
|
||||
return v;
|
||||
}
|
||||
|
||||
class Schema {
|
||||
public:
|
||||
Schema() { _Check(wfassoc::WFSchemaCreate(&_token)); }
|
||||
~Schema() {
|
||||
if (_token != _INVALID_TOKEN()) {
|
||||
wfassoc::WFSchemaDestroy(_token);
|
||||
}
|
||||
}
|
||||
Schema(const Schema&) = delete;
|
||||
Schema& operator=(const Schema&) = delete;
|
||||
Schema(Schema&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
|
||||
Schema& operator=(Schema&& other) noexcept {
|
||||
if (this != &other) {
|
||||
if (_token != _INVALID_TOKEN()) {
|
||||
wfassoc::WFSchemaDestroy(_token);
|
||||
}
|
||||
_token = other._token;
|
||||
other._token = _INVALID_TOKEN();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SetIdentifier(const char* value) { _Check(wfassoc::WFSchemaSetIdentifier(_token, value)); }
|
||||
void SetPath(const char* value) { _Check(wfassoc::WFSchemaSetPath(_token, value)); }
|
||||
void SetClsid(const char* value) { _Check(wfassoc::WFSchemaSetClsid(_token, value)); }
|
||||
void SetName(const char* value) { _Check(wfassoc::WFSchemaSetName(_token, value)); }
|
||||
void SetIcon(const char* value) { _Check(wfassoc::WFSchemaSetIcon(_token, value)); }
|
||||
void SetBehavior(const char* value) { _Check(wfassoc::WFSchemaSetBehavior(_token, value)); }
|
||||
void AddStr(const char* name, const char* value) { _Check(wfassoc::WFSchemaAddStr(_token, name, value)); }
|
||||
void AddIcon(const char* name, const char* value) { _Check(wfassoc::WFSchemaAddIcon(_token, name, value)); }
|
||||
void AddBehavior(const char* name, const char* value) { _Check(wfassoc::WFSchemaAddBehavior(_token, name, value)); }
|
||||
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));
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Program;
|
||||
/// @private
|
||||
Token Release() noexcept {
|
||||
Token t = _token;
|
||||
_token = _INVALID_TOKEN();
|
||||
return t;
|
||||
}
|
||||
Token _token;
|
||||
};
|
||||
|
||||
class IconRc {
|
||||
public:
|
||||
explicit IconRc(Token token) : _token(token) {}
|
||||
~IconRc() {
|
||||
if (_token != _INVALID_TOKEN()) {
|
||||
wfassoc::WFIconRcDestroy(_token);
|
||||
}
|
||||
}
|
||||
IconRc(const IconRc&) = delete;
|
||||
IconRc& operator=(const IconRc&) = delete;
|
||||
IconRc(IconRc&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
|
||||
IconRc& operator=(IconRc&& other) noexcept {
|
||||
if (this != &other) {
|
||||
if (_token != _INVALID_TOKEN()) {
|
||||
wfassoc::WFIconRcDestroy(_token);
|
||||
}
|
||||
_token = other._token;
|
||||
other._token = _INVALID_TOKEN();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
HICON GetIcon() {
|
||||
HICON icon = nullptr;
|
||||
_Check(wfassoc::WFIconRcGetIcon(_token, &icon));
|
||||
return icon;
|
||||
}
|
||||
|
||||
private:
|
||||
Token _token;
|
||||
};
|
||||
|
||||
class ExtStatus {
|
||||
public:
|
||||
explicit ExtStatus(Token token) : _token(token) {}
|
||||
~ExtStatus() {
|
||||
if (_token != _INVALID_TOKEN()) {
|
||||
wfassoc::WFExtStatusDestroy(_token);
|
||||
}
|
||||
}
|
||||
ExtStatus(const ExtStatus&) = delete;
|
||||
ExtStatus& operator=(const ExtStatus&) = delete;
|
||||
ExtStatus(ExtStatus&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
|
||||
ExtStatus& operator=(ExtStatus&& other) noexcept {
|
||||
if (this != &other) {
|
||||
if (_token != _INVALID_TOKEN()) {
|
||||
wfassoc::WFExtStatusDestroy(_token);
|
||||
}
|
||||
_token = other._token;
|
||||
other._token = _INVALID_TOKEN();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string GetName() {
|
||||
const char* name = nullptr;
|
||||
_Check(wfassoc::WFExtStatusGetName(_token, &name));
|
||||
return name ? std::string(name) : std::string();
|
||||
}
|
||||
|
||||
HICON GetIcon() {
|
||||
HICON icon = nullptr;
|
||||
_Check(wfassoc::WFExtStatusGetIcon(_token, &icon));
|
||||
return icon;
|
||||
}
|
||||
|
||||
private:
|
||||
Token _token;
|
||||
};
|
||||
|
||||
class Ext {
|
||||
public:
|
||||
explicit Ext(Token token) : _token(token) {}
|
||||
~Ext() {
|
||||
if (_token != _INVALID_TOKEN()) {
|
||||
wfassoc::WFExtDestroy(_token);
|
||||
}
|
||||
}
|
||||
Ext(const Ext&) = delete;
|
||||
Ext& operator=(const Ext&) = delete;
|
||||
Ext(Ext&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
|
||||
Ext& operator=(Ext&& other) noexcept {
|
||||
if (this != &other) {
|
||||
if (_token != _INVALID_TOKEN()) {
|
||||
wfassoc::WFExtDestroy(_token);
|
||||
}
|
||||
_token = other._token;
|
||||
other._token = _INVALID_TOKEN();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string GetInner() {
|
||||
const char* inner = nullptr;
|
||||
_Check(wfassoc::WFExtGetInner(_token, &inner));
|
||||
return std::string(inner);
|
||||
}
|
||||
|
||||
std::string GetDottedInner() {
|
||||
const char* inner = nullptr;
|
||||
_Check(wfassoc::WFExtGetDottedInner(_token, &inner));
|
||||
return std::string(inner);
|
||||
}
|
||||
|
||||
private:
|
||||
Token _token;
|
||||
};
|
||||
|
||||
class Program {
|
||||
public:
|
||||
explicit Program(std::unique_ptr<Schema>&& schema) {
|
||||
_Check(wfassoc::WFProgramCreate(schema->Release(), &_token));
|
||||
}
|
||||
~Program() {
|
||||
if (_token != _INVALID_TOKEN()) {
|
||||
wfassoc::WFProgramDestroy(_token);
|
||||
}
|
||||
}
|
||||
Program(const Program&) = delete;
|
||||
Program& operator=(const Program&) = delete;
|
||||
Program(Program&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
|
||||
Program& operator=(Program&& other) noexcept {
|
||||
if (this != &other) {
|
||||
if (_token != _INVALID_TOKEN()) {
|
||||
wfassoc::WFProgramDestroy(_token);
|
||||
}
|
||||
_token = other._token;
|
||||
other._token = _INVALID_TOKEN();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string ResolveName() {
|
||||
const char* name = nullptr;
|
||||
_Check(wfassoc::WFProgramResolveName(_token, &name));
|
||||
return name ? std::string(name) : std::string();
|
||||
}
|
||||
|
||||
std::unique_ptr<IconRc> ResolveIcon() {
|
||||
Token token = _INVALID_TOKEN();
|
||||
_Check(wfassoc::WFProgramResolveIcon(_token, &token));
|
||||
if (token == _INVALID_TOKEN()) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<IconRc>(token);
|
||||
}
|
||||
|
||||
size_t ExtsLen() {
|
||||
size_t len = 0;
|
||||
_Check(wfassoc::WFProgramExtsLen(_token, &len));
|
||||
return len;
|
||||
}
|
||||
|
||||
std::unique_ptr<Ext> GetExt(size_t index) {
|
||||
Token token = _INVALID_TOKEN();
|
||||
_Check(wfassoc::WFProgramGetExt(_token, index, &token));
|
||||
return std::make_unique<Ext>(token);
|
||||
}
|
||||
|
||||
size_t FindExt(const char* body) {
|
||||
size_t index = INVALID_INDEX;
|
||||
_Check(wfassoc::WFProgramFindExt(_token, body, &index));
|
||||
return index;
|
||||
}
|
||||
|
||||
void Register(Scope scope) { _Check(wfassoc::WFProgramRegister(_token, scope)); }
|
||||
void Unregister(Scope scope) { _Check(wfassoc::WFProgramUnregister(_token, scope)); }
|
||||
|
||||
bool IsRegistered(Scope scope) {
|
||||
bool result = false;
|
||||
_Check(wfassoc::WFProgramIsRegistered(_token, scope, &result));
|
||||
return result;
|
||||
}
|
||||
|
||||
void LinkExt(Scope scope, size_t index) { _Check(wfassoc::WFProgramLinkExt(_token, scope, index)); }
|
||||
void UnlinkExt(Scope scope, size_t index) { _Check(wfassoc::WFProgramUnlinkExt(_token, scope, index)); }
|
||||
|
||||
std::unique_ptr<ExtStatus> QueryExt(View view, size_t index) {
|
||||
Token token = _INVALID_TOKEN();
|
||||
_Check(wfassoc::WFProgramQueryExt(_token, view, index, &token));
|
||||
if (token == _INVALID_TOKEN()) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<ExtStatus>(token);
|
||||
}
|
||||
|
||||
private:
|
||||
Token _token;
|
||||
};
|
||||
|
||||
} // namespace wfassocpp
|
||||
|
||||
#endif // WFASSOCPP_H_
|
||||
Reference in New Issue
Block a user