GCP_RESULTSW
構造体サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。
フィールド
| フィールド | 型 | サイズ | x64 | x86 | 説明 | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| lStructSize | DWORD | 4 | +0 | +0 | 構造体のサイズ (バイト単位)。 | ||||||||||||||||||||||||||||||||
| lpOutString | LPWSTR | 8/4 | +8 | +4 | 出力文字列を受け取るバッファーへのポインター。出力文字列が不要な場合は NULL を指定します。出力文字列は、指定したデバイス上で表示される順序に並べられた元の文字列です。通常、出力文字列は元の文字列と同一ですが、文字列の並べ替えが必要で GCP_REORDER フラグが設定されている場合や、元の文字列が最大範囲を超えていて GCP_MAXEXTENT フラグが設定されている場合は異なることがあります。 | ||||||||||||||||||||||||||||||||
| lpOrder | DWORD* | 8/4 | +16 | +8 | 順序インデックスを受け取る配列へのポインター。順序インデックスが不要な場合は NULL を指定します。ただし、その意味は GCP_RESULTS の他の要素によって異なります。グリフインデックスが返される場合、インデックスは lpGlyphs 配列に対するものです。グリフインデックスが返されず lpOrder が要求された場合、インデックスは lpOutString に対するものです。たとえば後者の場合、lpOrder[i] の値は、出力文字列 lpOutString における lpString[i] の位置を表します。 これは通常、GetFontLanguageInfo が GCP_REORDER フラグを返す場合、つまり元の文字列の並べ替えが必要な場合に使用します。たとえば、テキストが右から左に流れるヘブライ語では、lpOrder 配列によって元の文字列の各要素の正確な位置が示されます。 | ||||||||||||||||||||||||||||||||
| lpDx | INT* | 8/4 | +24 | +12 | 隣接する文字セル間の距離を受け取る配列へのポインター。これらの距離が不要な場合は NULL を指定します。グリフによる描画を行う場合、距離は文字ではなくグリフに対するものになるため、得られた配列を ExtTextOut 関数で使用できます。 この配列内の距離は表示順に並んでいます。元の文字列の ith 番目の文字に対する距離を求めるには、次のように lpOrder 配列を使用します。 | ||||||||||||||||||||||||||||||||
| lpCaretPos | INT* | 8/4 | +32 | +16 | キャレット位置の値を受け取る配列へのポインター。キャレット位置が不要な場合は NULL を指定します。各値は、対応する文字の直前のキャレット位置を指定します。言語によっては、各文字のキャレット位置が文字のすぐ左になるとは限りません。たとえば、テキストが右から左に流れるヘブライ語では、キャレット位置は文字の右側になります。グリフの並べ替えが行われる場合、lpCaretPos は出力文字列ではなく元の文字列に対応します。そのため、隣接する値が同じになることがあります。 この配列内の値は入力順に並んでいます。元の文字列の ith 番目の文字に対するキャレット位置の値を求めるには、次のように配列を使用します。 | ||||||||||||||||||||||||||||||||
| lpClass | LPSTR | 8/4 | +40 | +20 | 文字の分類を格納する、または受け取る配列へのポインター。これらの値は文字列内の文字をどのようにレイアウトするかを示し、GetStringTypeEx 関数が返す CT_CTYPE2 の値に似ています (ただし同一ではありません)。配列の各要素には、0 または次のいずれかの値を設定できます。
さらに、GCP_CLASSIN フラグを指定して lpClass 配列に値を渡す場合は、次の値も使用できます。
GCP_REORDER フラグを使用する言語では、GCP_CLASSIN フラグとともに次の値も使用できます。lpClass 配列内のどこでも使用できる上記の値とは異なり、以下の値はすべて配列の先頭位置でのみ使用します。いずれも他の分類と組み合わせられます。 GCPCLASS_PREBOUNDLTR と GCPCLASS_PREBOUNDRTL は相互に排他的であり、GCPCLASSPOSTBOUNDLTR と GCPCLASSPOSTBOUNDRTL も同様である点に注意してください。
文字のレイアウトを特定の方法で強制するには、対応する配列要素に分類をあらかじめ設定します。関数はそのように設定済みの分類を変更せず、0 に設定されている配列要素についてのみ分類を計算します。設定済みの分類は、GCP_CLASSIN フラグが設定され、かつ lpClass 配列が指定されている場合にのみ使用されます。 現在のフォントに対して GetFontLanguageInfo が GCP_REORDER を返さない場合、意味を持つのは GCPCLASS_LATIN の値だけです。 | ||||||||||||||||||||||||||||||||
| lpGlyphs | LPWSTR | 8/4 | +48 | +24 | 文字列の描画に使用されるグリフを識別する値を受け取る配列へのポインター。グリフによる描画が不要な場合は NULL を指定します。文字列に合字グリフが含まれる場合、配列内のグリフ数は元の文字列の文字数より少なくなることがあります。また、並べ替えが必要な場合、グリフの順序は連続しないことがあります。 この配列は、何らかの形の合字、カーニング、順序の入れ替えを伴う文字列に対して複数の操作を行う場合に役立ちます。以降の操作でこの配列の値を使用すれば、毎回グリフインデックスを生成するために必要な時間を節約できます。 この配列には常にグリフインデックスが格納されるため、この配列を ExtTextOut 関数で使用する場合は、常に ETO_GLYPH_INDEX の値を使用しなければなりません。 GCP_LIGATE を使用する場合は、合字として結合される文字数を制限できます (たとえばアラビア語では 3 文字の合字が一般的です)。これは、lpGcpResults->lpGlyphs[0] に必要な最大値を設定することで行います。最大値が不要な場合は、このフィールドに 0 を設定してください。 アラビア語のように GetFontLanguageInfo が GCP_GLYPHSHAPE フラグを返す言語では、文字のグリフは、その文字が単語の先頭、中間、末尾のいずれにあるかによって異なります。通常、入力文字列の最初の文字は単語の最初の文字としても扱われ、入力文字列の最後の文字は単語の最後の文字として扱われます。しかし、スクロールされたテキストの一部を表示する場合など、表示する文字列が完全な文字列の一部であるときは、これが当てはまらないことがあります。このような場合には、最初または最後の文字を語頭形・語末形として整形しないように強制することが望まれます。そのためには、やはり lpGlyphs 配列の先頭位置を使用し、前述の合字の値と GCPGLYPH_LINKBEFORE や GCPGLYPH_LINKAFTER の値とのビット単位のOR を行います。たとえば GCPGLYPH_LINKBEFORE | 2 という値は、必要な合字の最大が 2 文字であり、文字列の最初の文字を単語の中間にあるものとして扱うことを意味します。 | ||||||||||||||||||||||||||||||||
| nGlyphs | DWORD | 4 | +56 | +28 | 入力時には、このメンバーに、配列ポインターの各メンバーが指す配列のサイズを設定しなければなりません。出力時には、出力配列に格納されたグリフの数が設定されます。グリフの置換が不要な場合 (つまり、各入力文字がちょうど 1 つのグリフに対応する場合)、このメンバーは入力時と同じ値になります。 | ||||||||||||||||||||||||||||||||
| nMaxFit | INT | 4 | +60 | +32 | GetCharacterPlacement 関数の nMaxExtent パラメーターで指定された範囲に収まる文字数。GCP_MAXEXTENT または GCP_JUSTIFY の値が設定されている場合、この値は元の文字列の文字数より少なくなることがあります。このメンバーは、GCP_MAXEXTENT や GCP_JUSTIFY の値が指定されているかどうかにかかわらず設定されます。出力されるグリフ数を示す nGlyphs とは異なり、nMaxFit は入力文字列の文字数を指します。ラテン系のシングルバイト文字セット (SBCS) 言語では、両者は同じ値になります。 |
公式ドキュメント
GCP_RESULTS 構造体は、文字列内の文字に関する情報を格納します。この構造体は GetCharacterPlacement 関数の結果を受け取ります。一部の言語では、配列の最初の要素に言語依存の追加情報が格納されることがあります。
解説(Remarks)
lpGlyphs と lpOutString のどちらが必要か、あるいはどちらも不要かは、GetFontLanguageInfo の呼び出し結果によって決まります。
英語のように、GCP_DBCS、GCP_REORDER、GCP_GLYPHSHAPE、GCP_LIGATE、GCP_DIACRITIC、GCP_KASHIDA のいずれのフラグも返されない言語のフォントの場合、正しく動作させるためにどちらの配列も必要ありません (必須ではありませんが、使用することはできます。lpOutString 配列を使用した場合、その内容は GetCharacterPlacement に渡した lpInputString とまったく同じになります)。ただし、GCP_MAXEXTENT を使用した場合、lpOutString には元の文字列の正確なコピーではなく、切り詰められた文字列が格納される点に注意してください。
ヘブライ語のように、並べ替えは行われるものの、通常は追加のグリフ形状を持たない言語のフォントの場合は、lpOutString を使用してください。これにより、画面上で読める順序の文字列が得られます。ただし、lpGlyphs 配列は通常必要ありません (フォントが TrueType/Open フォントの場合、ヘブライ語でも追加のグリフを持つことがあります)。
タイ語やアラビア語のように、GetFontLanguageInfo が GCP_GLYPHSHAPE フラグを返す言語の場合、lpOutString には GetCharacterPlacement に渡された文字列が表示可能な順序で格納されますが、値は整形前の文字のままです。正しく表示するには、lpGlyphs 配列を使用しなければなりません。
wingdi.h ヘッダーは GCP_RESULTS を、UNICODE プリプロセッサー定数の定義に応じてこの関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして定義しています。エンコーディング中立のエイリアスと、エンコーディング中立でないコードを混在させると不一致が生じ、コンパイルエラーや実行時エラーの原因となることがあります。詳細については、関数プロトタイプの規則 を参照してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での定義
#include <windows.h>
// GCP_RESULTSW (x64 64 / x86 36 バイト)
typedef struct GCP_RESULTSW {
DWORD lStructSize;
LPWSTR lpOutString;
DWORD* lpOrder;
INT* lpDx;
INT* lpCaretPos;
LPSTR lpClass;
LPWSTR lpGlyphs;
DWORD nGlyphs;
INT nMaxFit;
} GCP_RESULTSW;using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct GCP_RESULTSW
{
public uint lStructSize;
public IntPtr lpOutString;
public IntPtr lpOrder;
public IntPtr lpDx;
public IntPtr lpCaretPos;
public IntPtr lpClass;
public IntPtr lpGlyphs;
public uint nGlyphs;
public int nMaxFit;
}Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure GCP_RESULTSW
Public lStructSize As UInteger
Public lpOutString As IntPtr
Public lpOrder As IntPtr
Public lpDx As IntPtr
Public lpCaretPos As IntPtr
Public lpClass As IntPtr
Public lpGlyphs As IntPtr
Public nGlyphs As UInteger
Public nMaxFit As Integer
End Structureimport ctypes
from ctypes import wintypes
class GCP_RESULTSW(ctypes.Structure):
_fields_ = [
("lStructSize", wintypes.DWORD),
("lpOutString", ctypes.c_void_p),
("lpOrder", ctypes.c_void_p),
("lpDx", ctypes.c_void_p),
("lpCaretPos", ctypes.c_void_p),
("lpClass", ctypes.c_void_p),
("lpGlyphs", ctypes.c_void_p),
("nGlyphs", wintypes.DWORD),
("nMaxFit", ctypes.c_int),
]#[repr(C)]
pub struct GCP_RESULTSW {
pub lStructSize: u32,
pub lpOutString: *mut core::ffi::c_void,
pub lpOrder: *mut core::ffi::c_void,
pub lpDx: *mut core::ffi::c_void,
pub lpCaretPos: *mut core::ffi::c_void,
pub lpClass: *mut core::ffi::c_void,
pub lpGlyphs: *mut core::ffi::c_void,
pub nGlyphs: u32,
pub nMaxFit: i32,
}import "golang.org/x/sys/windows"
type GCP_RESULTSW struct {
lStructSize uint32
lpOutString uintptr
lpOrder uintptr
lpDx uintptr
lpCaretPos uintptr
lpClass uintptr
lpGlyphs uintptr
nGlyphs uint32
nMaxFit int32
}type
GCP_RESULTSW = record
lStructSize: DWORD;
lpOutString: Pointer;
lpOrder: Pointer;
lpDx: Pointer;
lpCaretPos: Pointer;
lpClass: Pointer;
lpGlyphs: Pointer;
nGlyphs: DWORD;
nMaxFit: Integer;
end;const GCP_RESULTSW = extern struct {
lStructSize: u32,
lpOutString: ?*anyopaque,
lpOrder: ?*anyopaque,
lpDx: ?*anyopaque,
lpCaretPos: ?*anyopaque,
lpClass: ?*anyopaque,
lpGlyphs: ?*anyopaque,
nGlyphs: u32,
nMaxFit: i32,
};type
GCP_RESULTSW {.bycopy.} = object
lStructSize: uint32
lpOutString: pointer
lpOrder: pointer
lpDx: pointer
lpCaretPos: pointer
lpClass: pointer
lpGlyphs: pointer
nGlyphs: uint32
nMaxFit: int32struct GCP_RESULTSW
{
uint lStructSize;
void* lpOutString;
void* lpOrder;
void* lpDx;
void* lpCaretPos;
void* lpClass;
void* lpGlyphs;
uint nGlyphs;
int nMaxFit;
}HSP用 定義
HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; GCP_RESULTSW サイズ: 36 バイト(x86)
dim st, 9 ; 4byte整数×9(構造体サイズ 36 / 4 切り上げ)
; lStructSize : DWORD (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; lpOutString : LPWSTR (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; lpOrder : DWORD* (+8, 4byte) st.2 = 値 / 値 = st.2 (lpoke/lpeek も可)
; lpDx : INT* (+12, 4byte) st.3 = 値 / 値 = st.3 (lpoke/lpeek も可)
; lpCaretPos : INT* (+16, 4byte) st.4 = 値 / 値 = st.4 (lpoke/lpeek も可)
; lpClass : LPSTR (+20, 4byte) st.5 = 値 / 値 = st.5 (lpoke/lpeek も可)
; lpGlyphs : LPWSTR (+24, 4byte) st.6 = 値 / 値 = st.6 (lpoke/lpeek も可)
; nGlyphs : DWORD (+28, 4byte) st.7 = 値 / 値 = st.7 (lpoke/lpeek も可)
; nMaxFit : INT (+32, 4byte) st.8 = 値 / 値 = st.8 (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; GCP_RESULTSW サイズ: 64 バイト(x64)
dim st, 16 ; 4byte整数×16(構造体サイズ 64 / 4 切り上げ)
; lStructSize : DWORD (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; lpOutString : LPWSTR (+8, 8byte) qpoke st,8,値 / qpeek(st,8) ※IronHSPのみ。3.7/3.8は lpoke st,8,下位 : lpoke st,12,上位
; lpOrder : DWORD* (+16, 8byte) qpoke st,16,値 / qpeek(st,16) ※IronHSPのみ。3.7/3.8は lpoke st,16,下位 : lpoke st,20,上位
; lpDx : INT* (+24, 8byte) qpoke st,24,値 / qpeek(st,24) ※IronHSPのみ。3.7/3.8は lpoke st,24,下位 : lpoke st,28,上位
; lpCaretPos : INT* (+32, 8byte) qpoke st,32,値 / qpeek(st,32) ※IronHSPのみ。3.7/3.8は lpoke st,32,下位 : lpoke st,36,上位
; lpClass : LPSTR (+40, 8byte) qpoke st,40,値 / qpeek(st,40) ※IronHSPのみ。3.7/3.8は lpoke st,40,下位 : lpoke st,44,上位
; lpGlyphs : LPWSTR (+48, 8byte) qpoke st,48,値 / qpeek(st,48) ※IronHSPのみ。3.7/3.8は lpoke st,48,下位 : lpoke st,52,上位
; nGlyphs : DWORD (+56, 4byte) st.14 = 値 / 値 = st.14 (lpoke/lpeek も可)
; nMaxFit : INT (+60, 4byte) st.15 = 値 / 値 = st.15 (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
#defstruct global GCP_RESULTSW
#field int lStructSize
#field intptr lpOutString
#field intptr lpOrder
#field intptr lpDx
#field intptr lpCaretPos
#field intptr lpClass
#field intptr lpGlyphs
#field int nGlyphs
#field int nMaxFit
#endstruct
stdim st, GCP_RESULTSW ; NSTRUCT 変数を確保
st->lStructSize = 100
mes "lStructSize=" + st->lStructSize