HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2019
0505
まっきー.ttfを読み込むHSPソースについて11未解決


まっきー

リンク

2019/5/5(Sun) 05:33:03|NO.87246

ttf形式のファイルを読み込むプログラムを書いてるのですが、
以下のプログラムを実行した後、指定したttfファイルが
「System によってファイルは開かれているので操作を完了できません。」とでて
削除できません(ファイル名の変更とコピー、移動はできます)。
どこを修正したら改善されるか教えてくださいお願いします。

#uselib "gdi32.dll" #func global AddFontMemResourceEx "AddFontMemResourceEx" sptr,sptr,sptr,sptr #define global AddFontResource AddFontResourceA #func global AddFontResourceA "AddFontResourceA" sptr #func global GetFontResourceInfoW "GetFontResourceInfoW" wptr,wptr,wptr,wptr #func global RemoveFontMemResourceEx "RemoveFontMemResourceEx" sptr #module Fonts #defcfunc GetFontName str fonttype fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" AddFontResource fontfile bufsize = 0 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),2 dim buf,(bufsize + 3) / 4 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),2 fontname = cnvwtos(buf(7)) return fontname #defcfunc LoadTtfFont str file notesel buf noteload dir_cur + "\\fonts\\" + file + ".ttf" AddFontMemResourceEx varptr(buf),strsize,0,varptr(pcFonts) return stat #deffunc DeleteFont int a RemoveFontMemResourceEx a return #global name = GetFontName("font") ID = LoadTtfFont("font") font name mes "てすと" DeleteFont ID



この記事に返信する


MillkeyStars

リンク

2019/5/5(Sun) 12:13:52|NO.87248

AddFontResource に対応している RemoveFontResource がスクリプトに存在しません。
AddFontResource で追加したフォントは、アプリケーション終了時に、RemoveFontResource でフォントをシステムより削除してください。



まっきー

リンク

2019/5/6(Mon) 08:23:53|NO.87258

ありがとうござます!
以下のように修正させていただきました。

#uselib "gdi32.dll" #func global AddFontMemResourceEx "AddFontMemResourceEx" sptr,sptr,sptr,sptr #define global AddFontResource AddFontResourceA #func global AddFontResourceA "AddFontResourceA" sptr #func global GetFontResourceInfoW "GetFontResourceInfoW" wptr,wptr,wptr,wptr #define global RemoveFontResource RemoveFontResourceA #func global RemoveFontResourceA "RemoveFontResourceA" sptr #func global RemoveFontMemResourceEx "RemoveFontMemResourceEx" sptr #module Fonts #defcfunc GetFontName str fonttype fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" AddFontResource fontfile fontID = stat bufsize = 0 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),2 dim buf,(bufsize + 3) / 4 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),2 fontname = cnvwtos(buf(7)) RemoveFontResource fontID return fontname #defcfunc LoadTtfFont str file notesel buf noteload dir_cur + "\\fonts\\" + file + ".ttf" AddFontMemResourceEx varptr(buf),strsize,0,varptr(pcFonts) return stat #deffunc DeleteFont int a RemoveFontMemResourceEx a return #global
でも、やはり改善しません(一度フォントを削除してから再度ダウンロードしなおしています)。
どこが原因になっているのでしょうか?



まっきー

リンク

2019/5/6(Mon) 08:30:39|NO.87259

今まではDelコマンドで削除できたのですが、今は「アクセスが拒否されました」とでて
削除もできません。
削除し方も知ってる方教えてくださいお願いします。



MillkeyStars

リンク

2019/5/6(Mon) 13:31:24|NO.87262

いろいろおかしい部分が多々ありますが。
GetFontName の自作命令を行った際に、RemoveFontResource を利用してると思いますが、GetFontName 以降にフォントを利用しようとしてますよね。
この場合、GetFontName 命令内での RemoveFontResource の利用は適切ではないです。
なので、DeleteFont 命令に移動しましょう。

また、RemoveFontResource の引数は、ファイル名が必要です。ID ではありませんのでご注意を。
(AddFontResource から取得できる値は、そのプロセスでいくつ登録できた数なので正確には ID ではありません)

あと、AddFontMemResourceEx は、どういう目的で利用しようとしているのでしょうか?
この命令は、フォントファイルの内容をそのままメモリに展開しそのメモリを用いてフォントを登録する関数です。


下記、問題の対策スクリプト(利用意図が不明な自作命令・関数及び宣言は削除しています)

#uselib "gdi32.dll" #cfunc global AddFontResource "AddFontResourceA" sptr //ctype に変更 #func global GetFontResourceInfoW "GetFontResourceInfoW" wptr,wptr,wptr,wptr #func global RemoveFontResource "RemoveFontResourceA" sptr #define HWND_BROADCAST 0xFFFF #define WM_FONTCHANGE 0x001D #module Fonts #defcfunc GetFontName str fonttype fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" fontID = AddFontResource(fontfile) bufsize = 0 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),2 //構造体サイズ取得 dim buf,(bufsize + 3) / 4 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),2 //構造体データ取得 fontname = cnvwtos(buf(7)) sendmsg HWND_BROATCAST,WM_FONTCHANGE,0,0 //フォント変更通知(全域) // RemoveFontResource fontID //間違っているのでコメントアウト return fontname #deffunc DeleteFont int a,str fonttype fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" RemoveFontResource fontfile //間違ってたのをこっちに移動 sendmsg HWND_BROATCAST,WM_FONTCHANGE,0,0 //フォント変更通知(全域) return #global name = GetFontName("font") font name //ここでフォントを利用してるので、上記命令内部でフォントを削除しちゃダメ mes "てすと" DeleteFont ID,"font" //ここで利用したフォントの削除



まっきー

リンク

2019/5/12(Sun) 22:26:46|NO.87318

ありがとうございます!
複数のフォントを利用しているのですが、

> また、RemoveFontResource の引数は、ファイル名が必要です。
> ID ではありませんのでご注意を。
> (AddFontResource から取得できる値は、そのプロセスでいくつ登録できた数なので
> 正確には ID ではありません)

というのを見るとDeleteFontを登録した複数のフォントの回数だけする必要がないようにも思えます
複数回Deleteフォント命令を実行する必要はないのですか、それともあるのですか?


#uselib "gdi32.dll" #cfunc global AddFontResource "AddFontResourceA" sptr //ctype に変更 #func global GetFontResourceInfoW "GetFontResourceInfoW" wptr,wptr,wptr,wptr #func global RemoveFontResource "RemoveFontResourceA" sptr #define HWND_BROADCAST 0xFFFF #define WM_FONTCHANGE 0x001D #module Fonts #defcfunc GetFontName str fonttype fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" fontID = AddFontResource(fontfile) bufsize = 0 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),2 //構造体サイズ取得 dim buf,(bufsize + 3) / 4 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),2 //構造体データ取得 fontname = cnvwtos(buf(7)) sendmsg HWND_BROATCAST,WM_FONTCHANGE,0,0 //フォント変更通知(全域) // RemoveFontResource fontID //間違っているのでコメントアウト return fontname #deffunc DeleteFont str fonttype //int a が必要でしたら教えてください fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" RemoveFontResource fontfile //間違ってたのをこっちに移動 sendmsg HWND_BROATCAST,WM_FONTCHANGE,0,0 //フォント変更通知(全域) return #global name_one = GetFontName("font_1") name_two = GetFontName("font_2") font name_one //ここでフォントを利用してるので、上記命令内部でフォントを削除しちゃダメ mes "てすと1" font name_two mes "てすと2" DeleteFont ID,"font_1" //ここで利用したフォントの削除 DeleteFont ID,"font_2"

追記:No.87259の件、無事削除できたのでお知らせしときます。
あと引用の仕方わからなくてごめんなさい、、、



MillkeyStars

リンク

2019/5/12(Sun) 23:03:51|NO.87320

Windows へのフォント登録は、一時的と永続的の2種類となります。

一時的の場合は、Windows が終了するまでです。(シャットダウン及び再起動をするまで)
永続的の場合は、Windows が終了してもそのフォントは登録されたままです。

一時的と永続的の切り替えは、登録しようとしているプロセスが管理者権限で起動されているかで動作が違います。
管理者権限で AddFontResource を実行するとそのフォントファイルは Windows\Fonts にコピーされ永続的にフォントが登録されます。


今回の問題となったのは、一時的の方でアプリケーションで登録したフォントが PC を再起動するまでロックされてしまったという事です。
(原因 : ちゃんと手順通りに削除しなかった及び削除前にエラーでアプリケーションが終了されてしまったなど)

一時的な場合、登録したアプリケーション(同プロセスID)からでないと削除できないという制約があります。
これを守っていない場合、登録したフォントは削除されません。

>>また、RemoveFontResource の引数は、ファイル名が必要です。ID ではありませんのでご注意を。
>>(AddFontResource から取得できる値は、そのプロセスでいくつ登録できた数なので正確には ID ではありません)

>>というのを見るとDeleteFontを登録した複数のフォントの回数だけする必要がないようにも思えます複数回Deleteフォント命令を実行する必要はないのですか、それともあるのですか?
AddFontResource と RemoveFontResource は常に対で存在する事を忘れないでください。
他のアプリケーションが同じフォントを利用する場合などは、RemoveFontResource は不必要ですが、この場合 PC が再起動されるまでフォントファイルはロックされます。

#deffunc DeleteFont str fonttype //int a が必要でしたら教えてください fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" RemoveFontResource fontfile //間違ってたのをこっちに移動 sendmsg HWND_BROATCAST,WM_FONTCHANGE,0,0 //フォント変更通知(全域) return
ですが、RemoveFontMemResourceEx のハンドルである為、int a をわざと残しました。
RemoveFontMemResourceEx にしか int a を利用していないので、RemoveFontMemResourceEx を使用しない場合削除しても構いません。



まっきー

リンク

2019/5/12(Sun) 23:28:02|NO.87321

> (原因 : ちゃんと手順通りに削除しなかった及び
> 削除前にエラーでアプリケーションが終了されてしまったなど)

圧倒的前者ですね(プログラムしっかりしてなくてすいません)

> ですが、RemoveFontMemResourceEx のハンドルである為、int a をわざと残しました。
> RemoveFontMemResourceEx にしか int a を利用していないので、
> RemoveFontMemResourceEx を使用しない場合削除しても構いません。

要するにMillkeyStars様がつっくったソースコードを使う場合なら
int a の部分は削除してもいいということですか?

(引用の仕方ってShift + .の後に空白を入れるだけで大丈夫なんですね、)



MillkeyStars

リンク

2019/5/12(Sun) 23:57:16|NO.87323

>>要するにMillkeyStars様がつっくったソースコードを使う場合なら int a の部分は削除してもいいということですか?
まっきーさんが不必要と思うのなら削除しても良いと思います。

関数は、引数を削除する方が後々面倒なので質問の答えとしては、追加で引数が必要な場合は業と以前の引数を残して新しい引数を追加して回答するようにしています。
なのでお好きなように!



まっきー

リンク

2019/5/18(Sat) 20:11:12|NO.87393

いただいたソースコードですが
IDの中身ってどこかで指定していますか?
0になっているようにみえるのですが
ttfファイルだと必ず0になるのでしょうか?



MillkeyStars

リンク

2019/5/20(Mon) 11:55:14|NO.87414

>>いただいたソースコードですが
>>IDの中身ってどこかで指定していますか?
>>0になっているようにみえるのですが
>>ttfファイルだと必ず0になるのでしょうか?
この ID は、RemoveFontMemResourceEx 用の引数です。
まっきーさんが最初に提示したスクリプトで AddFontMemResourceEx を利用していますよね?
AddFontMemResourceEx は関数実行後に結果として ID を返値します。RemoveFontMemResourceEx はその返値された ID を必要としている為、業と引数を残しています。
RemoveFontMemResourceEx その物を使わない場合、ID は不必要であるので、引数自体を削除してかまいません。

【まっきーさんの最初に提示したスクリプト】

#deffunc DeleteFont int a RemoveFontMemResourceEx a return

【MillkeyStars が提示したスクリプト】

#deffunc DeleteFont str fonttype //int a が必要でしたら教えてください fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" RemoveFontResource fontfile //間違ってたのをこっちに移動 sendmsg HWND_BROATCAST,WM_FONTCHANGE,0,0 //フォント変更通知(全域) return
この二つを合体させると、引数はどーなりますか?

#deffunc DeleteFont int a,str fonttype RemoveFontMemResourceEx a //使うか使わないか不明な関数と引数 a fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" RemoveFontResource fontfile //間違ってたのをこっちに移動 sendmsg HWND_BROATCAST,WM_FONTCHANGE,0,0 //フォント変更通知(全域) return
となります。ただし、RemoveFontMemResourceEx の利用法が不明である為、解決のスクリプトではこの命令を削除して説明しています。
解決スクリプト提示時では、この RemoveFontMemResourceEx を使うのか使わないのか不明であるので、引数はそのまま残しつつ新しい引数を追加しただけです。

上記の事からID を使うか使わないかは、まっきーさんにお任せします。
現状では、ID が 0 であるという理解をしているので問題なく削除できると思います。



まっきー

リンク

2019/6/8(Sat) 20:54:36|NO.87566

ということは以下のソースでよろしいのでしょうか?
(フォントは最初に全部読み込んでおきたいと思っています。)


#uselib "gdi32.dll" #cfunc global AddFontResource "AddFontResourceA" sptr #func global GetFontResourceInfoW "GetFontResourceInfoW" wptr,wptr,wptr,wptr #func global RemoveFontResource "RemoveFontResourceA" sptr #define HWND_BROADCAST 0xFFFF #define WM_FONTCHANGE 0x001D #module Fonts #defcfunc GetFontName str fonttype fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" bufsize = 0 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),2 dim buf,(bufsize + 3) / 4 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),2 fontname = cnvwtos(buf(7)) return fontname #deffunc DeleteFont str fonttype fontfile = dir_cur + "\\fonts\\" + fonttype + ".ttf" RemoveFontResource fontfile return #global name_one = GetFontName("font_1") name_two = GetFontName("font_2") font name_one mes "てすと1" font name_two mes "てすと2" DeleteFont "font_1" DeleteFont "font_2"



ONION software Copyright 1997-2023(c) All rights reserved.