Win32 API 日本語リファレンス
ホームSystem.Com › CoTreatAsClass

CoTreatAsClass

関数
あるCLSIDを別のCLSIDとして扱うエミュレーションを設定する。
DLLOLE32.dll呼出規約winapi対応OSWindows 2000 以降

シグネチャ

// OLE32.dll
#include <windows.h>

HRESULT CoTreatAsClass(
    const GUID* clsidOld,
    const GUID* clsidNew
);

パラメーター

名前方向説明
clsidOldGUID*inエミュレートされる対象オブジェクトの CLSID。
clsidNewGUID*in元のオブジェクトをエミュレートするオブジェクトの CLSID。これにより、clsidOld に対する既存のエミュレーションが置き換えられます。このパラメーターには CLSID_NULL を指定でき、その場合は clsidOld に対する既存のエミュレーションが解除されます。

戻り値の型: HRESULT

公式ドキュメント

あるクラスのオブジェクトを別のクラスのオブジェクトとして扱うエミュレーションを設定または解除します。

戻り値

この関数は、標準の戻り値 E_INVALIDARG のほか、次の値を返すことがあります。

Return code Description
S_OK
エミュレーションが正常に設定または解除されました。
REGDB_E_CLASSNOTREG
clsidOld パラメーターが登録データベースに正しく登録されていません。
REGDB_E_READREGDB
登録データベースの読み取り中にエラーが発生しました。
REGDB_E_WRITEREGDB
登録データベースへの書き込み中にエラーが発生しました。

解説(Remarks)

この関数は、指定されたオブジェクトのレジストリに TreatAs エントリを設定し、そのオブジェクトを別のアプリケーションによってエミュレートできるようにします。エミュレーションを使用すると、アプリケーションは異なる形式のオブジェクトを開いて編集しつつ、そのオブジェクトの元の形式を保持できます。このエントリが設定されると、CoGetClassObject のような関数がオブジェクトの元の CLSID (clsidOld) を指定するたびに、それは透過的に新しい CLSID (clsidNew) へ転送され、TreatAs の CLSID に関連付けられたアプリケーションが起動されます。オブジェクトを保存する際にはネイティブ形式で保存でき、その結果、元の形式でサポートされない編集内容が失われる場合があります。

アプリケーションがエミュレーションをサポートしている場合、次の状況で CoTreatAsClass を呼び出します。

最初のケースの例として、あるアプリケーションで作成されたスプレッドシートを、その元のアプリケーションのスプレッドシート形式を読み書きできる別のアプリケーションで編集したい、という場合が挙げられます。エミュレーションをサポートするアプリケーションでは、変換ダイアログ ボックスの Treat As オプションを実装するために CoTreatAsClass を呼び出すことができます。

セットアップ プログラムにおける CoTreatAsClass の使用例としては、アプリケーションの更新版が考えられます。アプリケーションが更新されると、以前のバージョンで作成されたオブジェクトを、以前の形式情報を保持したまま、新しいバージョンのオブジェクトとしてアクティブ化して扱うことができます。これにより、保存時に変換するか、あるいは以前の形式で (古いバージョンで利用できない形式情報を失う可能性はあるものの) 保存するかを、ユーザーが選択できるようになります。

エミュレーションを設定した結果の 1 つとして、既定ハンドラーにおける IOleObject::EnumVerbs メソッドの実装などで verb を列挙する際に、clsidOld ではなく clsidNew の verb が列挙される点が挙げられます。

アプリケーションをインストールする際に既存のエミュレーション情報が確実に削除されるよう、セットアップ プログラムでは、インストールするクラスに対する既存のエミュレーションを解除するために、clsidNew パラメーターに CLSID_NULL を設定して CoTreatAsClass を呼び出す必要があります。

レジストリの AutoTreatAs キーに CLSID が割り当てられていない場合、clsidNewclsidOld に同じ値を設定すると TreatAs エントリが削除され、エミュレーションは行われなくなります。AutoTreatAs キーに CLSID が割り当てられている場合は、その CLSID が TreatAs キーに割り当てられます。

CoTreatAsClass は、clsidNew に対する適切なレジストリ エントリが現在存在するかどうかを検証しません。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// OLE32.dll
#include <windows.h>

HRESULT CoTreatAsClass(
    const GUID* clsidOld,
    const GUID* clsidNew
);
[DllImport("OLE32.dll", ExactSpelling = true)]
static extern int CoTreatAsClass(
    ref Guid clsidOld,   // GUID*
    ref Guid clsidNew   // GUID*
);
<DllImport("OLE32.dll", ExactSpelling:=True)>
Public Shared Function CoTreatAsClass(
    ByRef clsidOld As Guid,   ' GUID*
    ByRef clsidNew As Guid   ' GUID*
) As Integer
End Function
' clsidOld : GUID*
' clsidNew : GUID*
Declare PtrSafe Function CoTreatAsClass Lib "ole32" ( _
    ByVal clsidOld As LongPtr, _
    ByVal clsidNew As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

CoTreatAsClass = ctypes.windll.ole32.CoTreatAsClass
CoTreatAsClass.restype = ctypes.c_int
CoTreatAsClass.argtypes = [
    ctypes.c_void_p,  # clsidOld : GUID*
    ctypes.c_void_p,  # clsidNew : GUID*
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('OLE32.dll')
CoTreatAsClass = Fiddle::Function.new(
  lib['CoTreatAsClass'],
  [
    Fiddle::TYPE_VOIDP,  # clsidOld : GUID*
    Fiddle::TYPE_VOIDP,  # clsidNew : GUID*
  ],
  Fiddle::TYPE_INT)
#[link(name = "ole32")]
extern "system" {
    fn CoTreatAsClass(
        clsidOld: *const GUID,  // GUID*
        clsidNew: *const GUID  // GUID*
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("OLE32.dll")]
public static extern int CoTreatAsClass(ref Guid clsidOld, ref Guid clsidNew);
"@
$api = Add-Type -MemberDefinition $sig -Name 'OLE32_CoTreatAsClass' -Namespace Win32 -PassThru
# $api::CoTreatAsClass(clsidOld, clsidNew)
#uselib "OLE32.dll"
#func global CoTreatAsClass "CoTreatAsClass" sptr, sptr
; CoTreatAsClass varptr(clsidOld), varptr(clsidNew)   ; 戻り値は stat
; clsidOld : GUID* -> "sptr"
; clsidNew : GUID* -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "OLE32.dll"
#cfunc global CoTreatAsClass "CoTreatAsClass" var, var
; res = CoTreatAsClass(clsidOld, clsidNew)
; clsidOld : GUID* -> "var"
; clsidNew : GUID* -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; HRESULT CoTreatAsClass(GUID* clsidOld, GUID* clsidNew)
#uselib "OLE32.dll"
#cfunc global CoTreatAsClass "CoTreatAsClass" var, var
; res = CoTreatAsClass(clsidOld, clsidNew)
; clsidOld : GUID* -> "var"
; clsidNew : GUID* -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ole32 = windows.NewLazySystemDLL("OLE32.dll")
	procCoTreatAsClass = ole32.NewProc("CoTreatAsClass")
)

// clsidOld (GUID*), clsidNew (GUID*)
r1, _, err := procCoTreatAsClass.Call(
	uintptr(clsidOld),
	uintptr(clsidNew),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // HRESULT
function CoTreatAsClass(
  clsidOld: PGUID;   // GUID*
  clsidNew: PGUID   // GUID*
): Integer; stdcall;
  external 'OLE32.dll' name 'CoTreatAsClass';
result := DllCall("OLE32\CoTreatAsClass"
    , "Ptr", clsidOld   ; GUID*
    , "Ptr", clsidNew   ; GUID*
    , "Int")   ; return: HRESULT
●CoTreatAsClass(clsidOld, clsidNew) = DLL("OLE32.dll", "int CoTreatAsClass(void*, void*)")
# 呼び出し: CoTreatAsClass(clsidOld, clsidNew)
# clsidOld : GUID* -> "void*"
# clsidNew : GUID* -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "ole32" fn CoTreatAsClass(
    clsidOld: [*c]GUID, // GUID*
    clsidNew: [*c]GUID // GUID*
) callconv(std.os.windows.WINAPI) i32;
proc CoTreatAsClass(
    clsidOld: ptr GUID,  # GUID*
    clsidNew: ptr GUID  # GUID*
): int32 {.importc: "CoTreatAsClass", stdcall, dynlib: "OLE32.dll".}
pragma(lib, "ole32");
extern(Windows)
int CoTreatAsClass(
    GUID* clsidOld,   // GUID*
    GUID* clsidNew   // GUID*
);
ccall((:CoTreatAsClass, "OLE32.dll"), stdcall, Int32,
      (Ptr{GUID}, Ptr{GUID}),
      clsidOld, clsidNew)
# clsidOld : GUID* -> Ptr{GUID}
# clsidNew : GUID* -> Ptr{GUID}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t CoTreatAsClass(
    void* clsidOld,
    void* clsidNew);
]]
local ole32 = ffi.load("ole32")
-- ole32.CoTreatAsClass(clsidOld, clsidNew)
-- clsidOld : GUID*
-- clsidNew : GUID*
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('OLE32.dll');
const CoTreatAsClass = lib.func('__stdcall', 'CoTreatAsClass', 'int32_t', ['void *', 'void *']);
// CoTreatAsClass(clsidOld, clsidNew)
// clsidOld : GUID* -> 'void *'
// clsidNew : GUID* -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("OLE32.dll", {
  CoTreatAsClass: { parameters: ["pointer", "pointer"], result: "i32" },
});
// lib.symbols.CoTreatAsClass(clsidOld, clsidNew)
// clsidOld : GUID* -> "pointer"
// clsidNew : GUID* -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t CoTreatAsClass(
    void* clsidOld,
    void* clsidNew);
C, "OLE32.dll");
// $ffi->CoTreatAsClass(clsidOld, clsidNew);
// clsidOld : GUID*
// clsidNew : GUID*
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Ole32 extends StdCallLibrary {
    Ole32 INSTANCE = Native.load("ole32", Ole32.class);
    int CoTreatAsClass(
        Pointer clsidOld,   // GUID*
        Pointer clsidNew   // GUID*
    );
}
@[Link("ole32")]
lib LibOLE32
  fun CoTreatAsClass = CoTreatAsClass(
    clsidOld : GUID*,   # GUID*
    clsidNew : GUID*   # GUID*
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef CoTreatAsClassNative = Int32 Function(Pointer<Void>, Pointer<Void>);
typedef CoTreatAsClassDart = int Function(Pointer<Void>, Pointer<Void>);
final CoTreatAsClass = DynamicLibrary.open('OLE32.dll')
    .lookupFunction<CoTreatAsClassNative, CoTreatAsClassDart>('CoTreatAsClass');
// clsidOld : GUID* -> Pointer<Void>
// clsidNew : GUID* -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function CoTreatAsClass(
  clsidOld: PGUID;   // GUID*
  clsidNew: PGUID   // GUID*
): Integer; stdcall;
  external 'OLE32.dll' name 'CoTreatAsClass';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "CoTreatAsClass"
  c_CoTreatAsClass :: Ptr () -> Ptr () -> IO Int32
-- clsidOld : GUID* -> Ptr ()
-- clsidNew : GUID* -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let cotreatasclass =
  foreign "CoTreatAsClass"
    ((ptr void) @-> (ptr void) @-> returning int32_t)
(* clsidOld : GUID* -> (ptr void) *)
(* clsidNew : GUID* -> (ptr void) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library ole32 (t "OLE32.dll"))
(cffi:use-foreign-library ole32)

(cffi:defcfun ("CoTreatAsClass" co-treat-as-class :convention :stdcall) :int32
  (clsid-old :pointer)   ; GUID*
  (clsid-new :pointer))   ; GUID*
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $CoTreatAsClass = Win32::API::More->new('OLE32',
    'int CoTreatAsClass(LPVOID clsidOld, LPVOID clsidNew)');
# my $ret = $CoTreatAsClass->Call($clsidOld, $clsidNew);
# clsidOld : GUID* -> LPVOID
# clsidNew : GUID* -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目