ExtEscape
関数シグネチャ
// GDI32.dll
#include <windows.h>
INT ExtEscape(
HDC hdc,
INT iEscape,
INT cjInput,
LPCSTR lpInData, // optional
INT cjOutput,
LPSTR lpOutData // optional
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| hdc | HDC | in | デバイスコンテキストへのハンドル。 |
| iEscape | INT | in | 実行するエスケープ関数。次のいずれか、またはアプリケーション定義のエスケープ関数を指定できます。 |
| cjInput | INT | in | lpszInData パラメーターが指すデータのバイト数。 |
| lpInData | LPCSTR | inoptional | 指定したエスケープに必要な入力構造体へのポインター。「解説」も参照してください。 |
| cjOutput | INT | in | lpszOutData パラメーターが指すデータのバイト数。 |
| lpOutData | LPSTR | outoptional | このエスケープからの出力を受け取る構造体へのポインター。ExtEscape をクエリ関数として呼び出す場合、このパラメーターを NULL にすることはできません。この構造体で返すデータがない場合は、cbOutput に 0 を設定します。「解説」も参照してください。 |
戻り値の型: INT
公式ドキュメント
ExtEscape 関数を使用すると、アプリケーションは GDI 経由では利用できないデバイスの機能にアクセスできます。
戻り値
戻り値は関数の結果を示します。関数が成功した場合は 0 より大きい値になります。ただし、実装の有無のみを確認する QUERYESCSUPPORT プリンターエスケープは例外です。エスケープが実装されていない場合、戻り値は 0 になります。0 未満の戻り値はエラーを示します。
解説(Remarks)
システム定義のエスケープ値をデバイスに渡すには、Escape 関数を使用してください。ただし、そのエスケープが nEscape に定義されたエスケープのいずれかである場合を除きます。ExtEscape は、システム定義のエスケープでは正しく動作しないことがあります。特に、lpszInData がポインターであるメンバーを含む構造体へのポインターであるようなエスケープは失敗します。
なお、この記事で説明する動作は期待される動作ですが、このモデルに従うかどうかはドライバー次第です。
lpszInData と lpszOutData が参照する変数は、同一であったり重なり合ったりしてはなりません。入力と出力のバッファーサイズ変数が重なっている場合、呼び出しから戻った後に正しい値が格納されていないことがあります。最良の結果を得るには、lpszInData と lpszOutData は別々の変数を参照するようにしてください。
CHECKJPEGFORMAT プリンターエスケープ関数は、プリンターが JPEG 画像の印刷をサポートしているかどうかを判定します。
CHECKJPEGFORMAT プリンターエスケープ関数を使用する前に、QUERYESCSUPPORT プリンターエスケープ関数を呼び出して、ドライバーが CHECKJPEGFORMAT をサポートしているかどうかを確認してください。CHECKJPEGFORMAT の使用方法を示すサンプルコードについては、プリンターの JPEG または PNG サポートのテストを参照してください。
CHECKPNGFORMAT プリンターエスケープ関数は、プリンターが PNG 画像の印刷をサポートしているかどうかを判定します。
CHECKJPEGFORMAT プリンターエスケープ関数を使用する前に、QUERYESCSUPPORT プリンターエスケープ関数を呼び出して、ドライバーが CHECKJPEGFORMAT をサポートしているかどうかを確認してください。サンプルコードについては、プリンターの JPEG または PNG サポートのテストを参照してください。
DRAWPATTERNRECT プリンターエスケープは、Hewlett-Packard LaserJet または LaserJet 互換プリンターにおける Page Control Language (PCL) のパターンおよびルール機能を使用して、白、グレースケール、または塗りつぶしの黒の四角形を作成します。グレースケールとは、黒と白のピクセルを特定の割合で混ぜたグレーのパターンです。
アプリケーションは、DRAWPATTERNRECT エスケープを使用する前に、QUERYESCSUPPORT エスケープを使用して、プリンターがパターンとルールを描画できるかどうかを確認する必要があります。
- DRAWPATTERNRECT で描画されたルールは、デバイスコンテキストのクリッピング領域の影響を受けません。
- アプリケーションは、DRAWPATTERNRECT で作成したパターンやルールを、不透明なオブジェクトを上に重ねて消去しようとしてはなりません。
プリンターが白のルールをサポートしている場合は、それを使用して DRAWPATTERNRECT で作成したパターンを消去できます。プリンターが白のルールをサポートしていない場合、これらのパターンを消去する方法はありません。
アプリケーションが DRAWPATTERNRECT エスケープを使用できず、デバイスがプリンターである場合は、通常は代わりに PatBlt 関数を使用してください。PatBlt を使用して黒の四角形を印刷する場合は、BLACKNESS ラスターオペレーターを使用する必要がある点に注意してください。ただし、デバイスがプロッターの場合は、Rectangle 関数を使用してください。
GET_PS_FEATURESETTING プリンターエスケープ関数は、PostScript ドライバーの指定された機能設定に関する情報を取得します。
このエスケープ関数は、PostScript ドライバーが PostScript 中心モードまたは GDI 中心モードの場合にのみサポートされます。PostScript ドライバーのモードを設定するには、POSTSCRIPT_IDENTIFY エスケープ関数を呼び出します。
この操作を実行するには、次のパラメーターを指定して ExtEscape 関数を呼び出します。
GET_PS_FEATURESETTING プリンターエスケープ関数は、CreateDC 関数を呼び出した後、DeleteDC 関数を呼び出す前であれば、いつ呼び出しても有効です。
GETTECHNOLOGY プリンターエスケープ関数は、プリンタードライバーの種類を識別します。
XPSDrv 以外のプリンターの場合、このエスケープはドライバーが PostScript ドライバーであるかどうかを報告します。
XPSDrv プリンターの場合、このエスケープはドライバーが Microsoft XPS Document Converter (MXDC) であるかどうかを報告します。該当する場合、このエスケープはゼロ終端文字列 "http://schemas.microsoft.com/xps/2005/06" を返します
PASSTHROUGH プリンターエスケープ関数は、プリンタードライバーへ直接データを送信します。この操作を実行するには、次のパラメーターを指定して ExtEscape 関数を呼び出します。
PASSTHROUGH プリンターエスケープ関数は、GDI 中心モードまたは互換モードの PostScript ドライバーでサポートされますが、PostScript 中心モードではサポートされません。PostScript 中心モードのドライバーでは、POSTSCRIPT_PASSTHROUGH エスケープ関数を使用できます。PostScript ドライバーのモードを設定するには、POSTSCRIPT_IDENTIFY エスケープ関数を呼び出します。
EPSPRINTING または PostScript 中心のアプリケーションから送信された PASSTHROUGH データに対しては、PostScript ドライバーは一切変更を加えません。それ以外のアプリケーションから送信された PASSTHROUGH データについては、PostScript ドライバーが BCP (Binary Communication Protocol) または TBCP (Tagged Binary Communication Protocol) の出力プロトコルを使用している場合、ドライバーは「Adobe Serial and Parallel Communications Protocols Specification」に記載されているとおり、特殊文字に対して適切な BCP または TBCP のクォート処理を行います。したがって、アプリケーションは ASCII または純粋なバイナリのいずれかの PASSTHROUGH データを送信する必要があります。
POSTSCRIPT_DATA プリンターエスケープ関数は、プリンタードライバーへ直接データを送信します。この操作を実行するには、次のパラメーターを指定して ExtEscape 関数を呼び出します。
POSTSCRIPT_DATA 関数は PASSTHROUGH エスケープ関数と同一ですが、互換モードの PostScript ドライバーでのみサポートされる点が異なります。PostScript 中心モードまたは GDI 中心モードの PostScript ドライバーではサポートされません。
PostScript 中心モードのドライバーでは POSTSCRIPT_PASSTHROUGH エスケープ関数を、GDI 中心モードのドライバーでは PASSTHROUGH エスケープ関数を使用できます。PostScript ドライバーのモードを設定するには、POSTSCRIPT_IDENTIFY エスケープ関数を呼び出します。
POSTSCRIPT_IDENTIFY プリンターエスケープ関数は、PostScript ドライバーを GDI 中心モードまたは PostScript 中心モードに設定します。
ドライバーを GDI 中心モードまたは PostScript 中心モードにするには、まず QUERYESCSUPPORT プリンターエスケープ関数を呼び出して、ドライバーが POSTSCRIPT_IDENTIFY プリンターエスケープ関数をサポートしているかどうかを確認します。サポートしている場合、そのドライバーは PSCRIPT 5.0 であると見なせます。その後、他のプリンターエスケープ関数を呼び出す前に、POSTSCRIPT_IDENTIFY を呼び出して PSIDENT_GDICENTRIC または PSIDENT_PSCENTRIC のいずれかを指定する必要があります。QUERYESCSUPPORT と POSTSCRIPT_IDENTIFY の各プリンターエスケープ関数は、他のプリンターエスケープ関数を呼び出す前に呼び出す必要があります。
POSTSCRIPT_PASSTHROUGH をサポートする PostScript ドライバーでは、PASSTHROUGH と POSTSCRIPT_PASSTHROUGH のプリンターエスケープ関数は同一です。
PostScript 中心モードでは、用紙にマークを付けるすべての PostScript 出力を、POSTSCRIPT_PASSTHROUGH エスケープ関数を使用してアプリケーションが行う責任を負います。GDI 関数は使用できません。ドキュメント全体の構造とプリンターの制御設定はドライバーが担当します。アプリケーションは、POSTSCRIPT_INJECTION プリンターエスケープ関数を使用して、ジョブストリームの特定の位置に生データのブロック (DSC コメントを含む) を挿入できます。
POSTSCRIPT_INJECTION プリンターエスケープ関数は、PostScript ジョブストリームの指定された位置に生データのブロックを挿入します。
PostScript ドライバーは、GDI 中心モードまたは PostScript 中心モードではこのエスケープ関数をサポートしますが、互換モードではサポートしません。
PostScript ドライバーのモードを設定するには、POSTSCRIPT_IDENTIFY エスケープ関数を呼び出します。
この操作を実行するには、次のパラメーターを指定して ExtEscape 関数を呼び出します。
ドライバーは挿入データを内部的にキャッシュし、出力の適切な位置でそれを出力します。キャッシュされた情報は、不要になった時点で破棄されます。遅くとも EndDoc の呼び出し後には破棄されます。
GDI 中心モードでは、アプリケーションは POSTSCRIPT_INJECTION プリンターエスケープ関数を使用して、有効な DSC ブロックデータのみを挿入できます。有効な DSC ブロックは、次の条件をすべて満たす必要があります。
- 整数個の「行」の並びで構成されていること。
- 各「行」は "%%" で始まる必要があります。
- 最後の行を除く各「行」は、<CR>、<LF>、または <CR><LF> で終わる必要があります。最後の行が <CR>、<LF>、または <CR><LF> で終わっていない場合、ドライバーは挿入データの最後のバイトの後に <CR><LF> を追加します。
- 各「行」は、"%%" を含め、<CR>/<LF> の行終端を除いて 255 バイト以下でなければなりません。
PostScript ドライバーは、PostScript 中心モードまたは互換モードではこのエスケープ関数をサポートしますが、GDI 中心モードではサポートしません。
PostScript ドライバーのモードを設定するには、POSTSCRIPT_IDENTIFY エスケープ関数を呼び出します。
QUERYESCSUPPORT プリンターエスケープ関数は、プリンターエスケープ関数が実装されているかどうかを確認します。
SPCLPASSTHROUGH2 プリンターエスケープ関数は、EPSPRINTING を使用して PostScript デバイスに印刷するアプリケーションが、ドキュメントレベルの save コンテキストでプライベートな PostScript プロシージャやその他のリソースを含められるようにします。
このエスケープは、Adobe Acrobat との下位互換性のためにのみサポートされています。他のアプリケーションでは、この廃止されたエスケープを使用しないでください。
アプリケーションは、ドライバーが PostScript ストリームの正しい位置に挿入できるようデータをキャッシュするために、StartDoc を呼び出す前にこのエスケープを呼び出す必要があります。このエスケープがサポートされている場合、ドライバーは StartDoc より前の DOWNLOADFACE エスケープの呼び出しも許可します。ドライバーは、挿入するデータと、StartDoc より前の DOWNLOADFACE エスケープ呼び出しに必要なデータを内部的にキャッシュし、%%EndProlog の直前にそれらをすべて出力します。SPCLPASSTHROUGH2 と DOWNLOADFACE の呼び出しの順序は、データが渡された順序どおりに保持されます。つまり、後の呼び出しのデータは、先の呼び出しのデータより後に出力されます。ドライバーは、StartDoc より前の DOWNLOADFACE エスケープ呼び出しによってダウンロードされたフォントを、そのジョブの範囲内では削除できないものとして扱います。
このエスケープはオペレーティングシステムによって EMF ファイルに記録されません。そのため、アプリケーションはこのエスケープを使用するジョブについて EMF の記録が無効になっていることを確認する必要があります。
例
例については、JPEG または PNG 画像のサイズ設定を参照してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// GDI32.dll
#include <windows.h>
INT ExtEscape(
HDC hdc,
INT iEscape,
INT cjInput,
LPCSTR lpInData, // optional
INT cjOutput,
LPSTR lpOutData // optional
);[DllImport("GDI32.dll", ExactSpelling = true)]
static extern int ExtEscape(
IntPtr hdc, // HDC
int iEscape, // INT
int cjInput, // INT
[MarshalAs(UnmanagedType.LPStr)] string lpInData, // LPCSTR optional
int cjOutput, // INT
[MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder lpOutData // LPSTR optional, out
);<DllImport("GDI32.dll", ExactSpelling:=True)>
Public Shared Function ExtEscape(
hdc As IntPtr, ' HDC
iEscape As Integer, ' INT
cjInput As Integer, ' INT
<MarshalAs(UnmanagedType.LPStr)> lpInData As String, ' LPCSTR optional
cjOutput As Integer, ' INT
<MarshalAs(UnmanagedType.LPStr)> lpOutData As System.Text.StringBuilder ' LPSTR optional, out
) As Integer
End Function' hdc : HDC
' iEscape : INT
' cjInput : INT
' lpInData : LPCSTR optional
' cjOutput : INT
' lpOutData : LPSTR optional, out
Declare PtrSafe Function ExtEscape Lib "gdi32" ( _
ByVal hdc As LongPtr, _
ByVal iEscape As Long, _
ByVal cjInput As Long, _
ByVal lpInData As String, _
ByVal cjOutput As Long, _
ByVal lpOutData As String) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
ExtEscape = ctypes.windll.gdi32.ExtEscape
ExtEscape.restype = ctypes.c_int
ExtEscape.argtypes = [
wintypes.HANDLE, # hdc : HDC
ctypes.c_int, # iEscape : INT
ctypes.c_int, # cjInput : INT
wintypes.LPCSTR, # lpInData : LPCSTR optional
ctypes.c_int, # cjOutput : INT
wintypes.LPSTR, # lpOutData : LPSTR optional, out
]require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('GDI32.dll')
ExtEscape = Fiddle::Function.new(
lib['ExtEscape'],
[
Fiddle::TYPE_VOIDP, # hdc : HDC
Fiddle::TYPE_INT, # iEscape : INT
Fiddle::TYPE_INT, # cjInput : INT
Fiddle::TYPE_VOIDP, # lpInData : LPCSTR optional
Fiddle::TYPE_INT, # cjOutput : INT
Fiddle::TYPE_VOIDP, # lpOutData : LPSTR optional, out
],
Fiddle::TYPE_INT)#[link(name = "gdi32")]
extern "system" {
fn ExtEscape(
hdc: *mut core::ffi::c_void, // HDC
iEscape: i32, // INT
cjInput: i32, // INT
lpInData: *const u8, // LPCSTR optional
cjOutput: i32, // INT
lpOutData: *mut u8 // LPSTR optional, out
) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[DllImport("GDI32.dll")]
public static extern int ExtEscape(IntPtr hdc, int iEscape, int cjInput, [MarshalAs(UnmanagedType.LPStr)] string lpInData, int cjOutput, [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder lpOutData);
"@
$api = Add-Type -MemberDefinition $sig -Name 'GDI32_ExtEscape' -Namespace Win32 -PassThru
# $api::ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, lpOutData)#uselib "GDI32.dll"
#func global ExtEscape "ExtEscape" sptr, sptr, sptr, sptr, sptr, sptr
; ExtEscape hdc, iEscape, cjInput, lpInData, cjOutput, varptr(lpOutData) ; 戻り値は stat
; hdc : HDC -> "sptr"
; iEscape : INT -> "sptr"
; cjInput : INT -> "sptr"
; lpInData : LPCSTR optional -> "sptr"
; cjOutput : INT -> "sptr"
; lpOutData : LPSTR optional, out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "GDI32.dll" #cfunc global ExtEscape "ExtEscape" sptr, int, int, str, int, var ; res = ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, lpOutData) ; hdc : HDC -> "sptr" ; iEscape : INT -> "int" ; cjInput : INT -> "int" ; lpInData : LPCSTR optional -> "str" ; cjOutput : INT -> "int" ; lpOutData : LPSTR optional, out -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "GDI32.dll" #cfunc global ExtEscape "ExtEscape" sptr, int, int, str, int, sptr ; res = ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, varptr(lpOutData)) ; hdc : HDC -> "sptr" ; iEscape : INT -> "int" ; cjInput : INT -> "int" ; lpInData : LPCSTR optional -> "str" ; cjOutput : INT -> "int" ; lpOutData : LPSTR optional, out -> "sptr" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; INT ExtEscape(HDC hdc, INT iEscape, INT cjInput, LPCSTR lpInData, INT cjOutput, LPSTR lpOutData) #uselib "GDI32.dll" #cfunc global ExtEscape "ExtEscape" intptr, int, int, str, int, var ; res = ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, lpOutData) ; hdc : HDC -> "intptr" ; iEscape : INT -> "int" ; cjInput : INT -> "int" ; lpInData : LPCSTR optional -> "str" ; cjOutput : INT -> "int" ; lpOutData : LPSTR optional, out -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; INT ExtEscape(HDC hdc, INT iEscape, INT cjInput, LPCSTR lpInData, INT cjOutput, LPSTR lpOutData) #uselib "GDI32.dll" #cfunc global ExtEscape "ExtEscape" intptr, int, int, str, int, intptr ; res = ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, varptr(lpOutData)) ; hdc : HDC -> "intptr" ; iEscape : INT -> "int" ; cjInput : INT -> "int" ; lpInData : LPCSTR optional -> "str" ; cjOutput : INT -> "int" ; lpOutData : LPSTR optional, out -> "intptr" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
gdi32 = windows.NewLazySystemDLL("GDI32.dll")
procExtEscape = gdi32.NewProc("ExtEscape")
)
// hdc (HDC), iEscape (INT), cjInput (INT), lpInData (LPCSTR optional), cjOutput (INT), lpOutData (LPSTR optional, out)
r1, _, err := procExtEscape.Call(
uintptr(hdc),
uintptr(iEscape),
uintptr(cjInput),
uintptr(unsafe.Pointer(windows.BytePtrFromString(lpInData))),
uintptr(cjOutput),
uintptr(lpOutData),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // INTfunction ExtEscape(
hdc: THandle; // HDC
iEscape: Integer; // INT
cjInput: Integer; // INT
lpInData: PAnsiChar; // LPCSTR optional
cjOutput: Integer; // INT
lpOutData: PAnsiChar // LPSTR optional, out
): Integer; stdcall;
external 'GDI32.dll' name 'ExtEscape';result := DllCall("GDI32\ExtEscape"
, "Ptr", hdc ; HDC
, "Int", iEscape ; INT
, "Int", cjInput ; INT
, "AStr", lpInData ; LPCSTR optional
, "Int", cjOutput ; INT
, "Ptr", lpOutData ; LPSTR optional, out
, "Int") ; return: INT●ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, lpOutData) = DLL("GDI32.dll", "int ExtEscape(void*, int, int, char*, int, char*)")
# 呼び出し: ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, lpOutData)
# hdc : HDC -> "void*"
# iEscape : INT -> "int"
# cjInput : INT -> "int"
# lpInData : LPCSTR optional -> "char*"
# cjOutput : INT -> "int"
# lpOutData : LPSTR optional, out -> "char*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "gdi32" fn ExtEscape(
hdc: ?*anyopaque, // HDC
iEscape: i32, // INT
cjInput: i32, // INT
lpInData: [*c]const u8, // LPCSTR optional
cjOutput: i32, // INT
lpOutData: [*c]u8 // LPSTR optional, out
) callconv(std.os.windows.WINAPI) i32;proc ExtEscape(
hdc: pointer, # HDC
iEscape: int32, # INT
cjInput: int32, # INT
lpInData: cstring, # LPCSTR optional
cjOutput: int32, # INT
lpOutData: ptr char # LPSTR optional, out
): int32 {.importc: "ExtEscape", stdcall, dynlib: "GDI32.dll".}pragma(lib, "gdi32");
extern(Windows)
int ExtEscape(
void* hdc, // HDC
int iEscape, // INT
int cjInput, // INT
const(char)* lpInData, // LPCSTR optional
int cjOutput, // INT
char* lpOutData // LPSTR optional, out
);ccall((:ExtEscape, "GDI32.dll"), stdcall, Int32,
(Ptr{Cvoid}, Int32, Int32, Cstring, Int32, Ptr{UInt8}),
hdc, iEscape, cjInput, lpInData, cjOutput, lpOutData)
# hdc : HDC -> Ptr{Cvoid}
# iEscape : INT -> Int32
# cjInput : INT -> Int32
# lpInData : LPCSTR optional -> Cstring
# cjOutput : INT -> Int32
# lpOutData : LPSTR optional, out -> Ptr{UInt8}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
int32_t ExtEscape(
void* hdc,
int32_t iEscape,
int32_t cjInput,
const char* lpInData,
int32_t cjOutput,
char* lpOutData);
]]
local gdi32 = ffi.load("gdi32")
-- gdi32.ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, lpOutData)
-- hdc : HDC
-- iEscape : INT
-- cjInput : INT
-- lpInData : LPCSTR optional
-- cjOutput : INT
-- lpOutData : LPSTR optional, out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('GDI32.dll');
const ExtEscape = lib.func('__stdcall', 'ExtEscape', 'int32_t', ['void *', 'int32_t', 'int32_t', 'str', 'int32_t', 'char *']);
// ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, lpOutData)
// hdc : HDC -> 'void *'
// iEscape : INT -> 'int32_t'
// cjInput : INT -> 'int32_t'
// lpInData : LPCSTR optional -> 'str'
// cjOutput : INT -> 'int32_t'
// lpOutData : LPSTR optional, out -> 'char *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("GDI32.dll", {
ExtEscape: { parameters: ["pointer", "i32", "i32", "buffer", "i32", "buffer"], result: "i32" },
});
// lib.symbols.ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, lpOutData)
// hdc : HDC -> "pointer"
// iEscape : INT -> "i32"
// cjInput : INT -> "i32"
// lpInData : LPCSTR optional -> "buffer"
// cjOutput : INT -> "i32"
// lpOutData : LPSTR optional, out -> "buffer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t ExtEscape(
void* hdc,
int32_t iEscape,
int32_t cjInput,
const char* lpInData,
int32_t cjOutput,
char* lpOutData);
C, "GDI32.dll");
// $ffi->ExtEscape(hdc, iEscape, cjInput, lpInData, cjOutput, lpOutData);
// hdc : HDC
// iEscape : INT
// cjInput : INT
// lpInData : LPCSTR optional
// cjOutput : INT
// lpOutData : LPSTR optional, out
// 構造体/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 Gdi32 extends StdCallLibrary {
Gdi32 INSTANCE = Native.load("gdi32", Gdi32.class);
int ExtEscape(
Pointer hdc, // HDC
int iEscape, // INT
int cjInput, // INT
String lpInData, // LPCSTR optional
int cjOutput, // INT
byte[] lpOutData // LPSTR optional, out
);
}@[Link("gdi32")]
lib LibGDI32
fun ExtEscape = ExtEscape(
hdc : Void*, # HDC
iEscape : Int32, # INT
cjInput : Int32, # INT
lpInData : UInt8*, # LPCSTR optional
cjOutput : Int32, # INT
lpOutData : UInt8* # LPSTR optional, out
) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef ExtEscapeNative = Int32 Function(Pointer<Void>, Int32, Int32, Pointer<Utf8>, Int32, Pointer<Utf8>);
typedef ExtEscapeDart = int Function(Pointer<Void>, int, int, Pointer<Utf8>, int, Pointer<Utf8>);
final ExtEscape = DynamicLibrary.open('GDI32.dll')
.lookupFunction<ExtEscapeNative, ExtEscapeDart>('ExtEscape');
// hdc : HDC -> Pointer<Void>
// iEscape : INT -> Int32
// cjInput : INT -> Int32
// lpInData : LPCSTR optional -> Pointer<Utf8>
// cjOutput : INT -> Int32
// lpOutData : LPSTR optional, out -> Pointer<Utf8>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function ExtEscape(
hdc: THandle; // HDC
iEscape: Integer; // INT
cjInput: Integer; // INT
lpInData: PAnsiChar; // LPCSTR optional
cjOutput: Integer; // INT
lpOutData: PAnsiChar // LPSTR optional, out
): Integer; stdcall;
external 'GDI32.dll' name 'ExtEscape';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "ExtEscape"
c_ExtEscape :: Ptr () -> Int32 -> Int32 -> CString -> Int32 -> CString -> IO Int32
-- hdc : HDC -> Ptr ()
-- iEscape : INT -> Int32
-- cjInput : INT -> Int32
-- lpInData : LPCSTR optional -> CString
-- cjOutput : INT -> Int32
-- lpOutData : LPSTR optional, out -> CString
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let extescape =
foreign "ExtEscape"
((ptr void) @-> int32_t @-> int32_t @-> string @-> int32_t @-> string @-> returning int32_t)
(* hdc : HDC -> (ptr void) *)
(* iEscape : INT -> int32_t *)
(* cjInput : INT -> int32_t *)
(* lpInData : LPCSTR optional -> string *)
(* cjOutput : INT -> int32_t *)
(* lpOutData : LPSTR optional, out -> string *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)(cffi:define-foreign-library gdi32 (t "GDI32.dll"))
(cffi:use-foreign-library gdi32)
(cffi:defcfun ("ExtEscape" ext-escape :convention :stdcall) :int32
(hdc :pointer) ; HDC
(i-escape :int32) ; INT
(cj-input :int32) ; INT
(lp-in-data :string) ; LPCSTR optional
(cj-output :int32) ; INT
(lp-out-data :pointer)) ; LPSTR optional, out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $ExtEscape = Win32::API::More->new('GDI32',
'int ExtEscape(HANDLE hdc, int iEscape, int cjInput, LPCSTR lpInData, int cjOutput, LPSTR lpOutData)');
# my $ret = $ExtEscape->Call($hdc, $iEscape, $cjInput, $lpInData, $cjOutput, $lpOutData);
# hdc : HDC -> HANDLE
# iEscape : INT -> int
# cjInput : INT -> int
# lpInData : LPCSTR optional -> LPCSTR
# cjOutput : INT -> int
# lpOutData : LPSTR optional, out -> LPSTR
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。関連項目
- f Escape — デバイス固有の機能にアクセスするためのエスケープ命令を送る。
- f GetDeviceCaps — デバイスの能力や属性情報を取得する。