[Top Page][Edit][Discussion][Edit History][All Pages][Recent Changes][->Japanese]

文字列の矩形サイズ

概要

HSP標準のみで描画サイズを取得しようとすると一旦描画しないとginfoで取得できません。 そこでAPIを使って描画せずに文字列の描画される矩形サイズを取得しようというモジュールです。 複数行に対応しています。<kz3

モジュールスクリプト strrect.as

/*
################################################################################
#                                                                              #
#        strrect.as                                                            #
#        文字列の描画される矩形サイズをAPIを用いて取得するモジュール        #
#                                                      更新:2005/09/07        #
#                                                                              #
################################################################################
*/

#ifndef __KZ3_MOD_STRRECT__
#define global __KZ3_MOD_STRRECT__

    #module "kz3modstrrect"
        #ifndef __GDI32__
        #uselib "gdi32.dll"
        #func GetTextExtentPoint32A "GetTextExtentPoint32A" sptr,sptr,sptr,sptr

        #func GetTextMetricsA "GetTextMetricsA" sptr,sptr
        #endif

        #deffunc getstrrect array _rect , int _hdc , str _string
        ; < getstrrect >
        ;       文字列の描画矩形を取得する
        ; USAGE : getstrrectA p1,p2,p3
        ;       p1 : 取得される矩形サイズを格納する配列変数
        ;       p2 : デバイスコンテキストのハンドル
        ;       p3 : 矩形サイズを取得する文字列が格納された変数
        dim rc,8
        dim tm,56
        szTxt = _string

        GetTextMetricsA _hdc,varptr@(tm)
        if stat = 0 : goto *@f

        h = 0
        notesel szTxt
        repeat notemax
            noteget@ szLine,cnt
            nChar = strlen@(szLine)

            GetTextExtentPoint32A _hdc , szLine , nChar , varptr@(rc)
            if stat = 0 : break

            if w < rc(0) : w = rc(0)

            h += tm(0)
        loop

        if stat = 0 : goto *@f
        _rect = w , h
*@
        return
    #global
#endif

サンプルスクリプト strrect_sample.hsp

    #include "strrect.as"

    dim rc , 2
    s = "Hello,world!\nHello,HSP3\n\nGood bye,HSP2(^^;"
    getstrrect rc,hdc,s
    if stat ! 0{
        bgscr 0 , rc(0) , rc(1) , 1
        cls 4
        color 255 , 255 , 255
        mes s
    }
    stop

感想

モジュールの標準化について

wikiを利用している多くのHSP先輩方と肩を並べてモジュール書込み。HSP3ガイドラインを読んでみてglobalの付け方、@の付け方など変な個所もあると思います。

  • HSP標準命令に@をつけるか否か
  • システム変数に@をつけるか否か

スクリプトのコーディング上の解説

#ifndef __KZ3_MOD_STRRECT__
#define global __KZ3_MOD_STRRECT__

HSP3ガイドラインでglobalはなるべく付けないようにしたほうがいい、 とあるのですが、モジュールの識別子で他のファイルから識別子を参照できるようにと考えて モジュール識別子はglobalをつけました。

#ifndef __GDI32__
#ifndef __KERNEL32__

API定義ファイルのインクルードチェックでインクルードされていればそちらを使い、 インクルードされていなかった場合は使うものだけロードしています。 ただ現状gdi32.asは置換障害があってインクルードチェックだけでは無理だと思いますが・・・。

#deffunc getstrrectA array rect,str string
#deffunc getstrrectW array rect,str string

Unicode文字列用にAPIに習って書いてみたのですが、 使うAPIが違うだけでロジックは同じです。 #defineなどを使って統一的に扱えるようにしようとも考えてみましたが、 実際のところ、どういった場面でUnicode関数が使われるのか勉強不足です。 例えば文字列データをテキストファイルから読み込んで処理するといった場合に 影響してくるのかな。

修正2005/09/07

  • コーディングがHSP2とHSP3混在していたのをHSP3に統一。
  • よくわからないUnicode対応を削除。
  • システム変数には@をつけず、命令名に@をつけるようにした。(repeatは命令と見なしていない)
  • 文字数(バイト数)取得にAPIを用いず、HSP標準strlenを使用。
  • 呼び出し側でデバイスコンテキストを指定できないのは描画情報取得命令としては欠点だったので呼び出し側で指定するように引数追加。
  • その他、if文などで可読性UPを図って短縮形を採用。