Tag Archives

6 Articles

HSPで高DPI対応ソフトを作ろう

こんにちは!

久しぶりにHSPの記事を書きたいと思います!
今回は、HSPの高DPI対応です。


はじめに

高DPIとはなんぞや、という説明をします。

昔のディスプレイは、1ドットのサイズが細かくないため、
1ピクセル=1ドットのような設計がほとんどでした。
そして、1ピクセルの大きさも、どのディスプレイもだいたい同じようなサイズ(96dpi)でした。
従って、ソフトを作る際に、1ドット=1ピクセルの前提で、GUIの設計をしていました。

ただ5、6年前ぐらいから、スマホが高繊細化してきており、
ディスプレイもRatinaディスプレイや4kディスプレイなど、高繊細なものが登場してきました。

例をあげると、次のようなものがあります。
Apple MacBook Pro 解像度 2560×1600、227dpi
Microsoft Surface Pro 解像度 2736×1824 、267 dpi
iiyama 4Kディスプレイ B2875UHSU-B1A 解像度 3840×2160、157 dpi

このように、96dpiより大きなものを高DPI(High DPI)と呼びます。

高DPIに対応していないソフトの問題点

このような高密度なディスプレイで、
これまで作成したソフトを実行するとどうなるでしょう。

高DPIで動作することを考えていないソフトの場合は、
OSがソフトのGUIを自動的にスケーリングして表示することとなります。

しかし、このスケーリングが問題でして、
ASCII.jp Windows 10+高解像度ディスプレイでのアプリのボケはRS2で解消される」のように
文字や画像がボケてしまうのです。

高DPI化に対応する方法と問題点

まず前提として、アプリ自身が「高DPIに対応してますよ!」と宣言しないといけません。
この宣言方法は、2種類あり、マニフェストで宣言するか、
アプリ内で「SetProcessDPIAware」を呼び出す方法があります。
これらの宣言方法については、「SetProcessDPIAware function」に記載されています。

一見、上記の方法だけで対応できるなら簡単じゃないかと思えるかもしれません。
実際の問題点は、高DPI対応宣言後の処理となります。
具体的には、座標、サイズ、位置などについて、
高DPIを考慮した数値で設定する必要が出てきます。

これから作るソフトならまだよいですが、今まで作ったソフトで高DPI化させようとした場合、
ソースコード上の全ての位置やサイズ情報を書き直す必要があるのです。

現実的な解決策

実は、今までのソースコード書き直しせず、簡単に解決することが可能です。
それは、標準関数の置き換えです。

以下に、いくつかの標準関数を置き換えたモジュールをおきます。
高DPI対応用のモジュールを作成する
(このモジュールは、実際に私が作ったツールで利用しています。)

このように、標準関数を置き換えたモジュールを
ソースコードの最初でincludeすることで、
全コードが高DPI対応用の命令で実行させるということです。

おわりに

これで、高DPI対応に関する記事は終わりです。
ありがとうございました。

ちなみに、高DPI対応を試験する際の注意点として
ディスプレイの設定から、「拡大縮小とレイアウト」で「100%」から変更させるという方法があるのですが、
一旦、サインアウト・サインインをやり直す必要があります。

サインアウト・サインインをしないと、
GetDeviceCaps の HIGHDPI_LOGPIXELSX / HIGHDPI_LOGPIXELSY
で取得できる数値が96のままになってしまいます。
気が付かずに、すこしはまってしまいました……。

マップオンデマンドの地図更新でパスワードが入力できない

by なたで 10 Comments

車を購入時にカーナビとしてNSZT-W61Gを付けたのですが、
カーナビ購入してから3年間はマップ情報のバージョンアップが無料ということで、
バージョンアップをしようとしました。

バージョンアップ方法の流れ
1. 購入時についていた「マップオンデマンドセットアップディスク」のDVDでセットアップツールをインストール
2. GAZOO」を無料でユーザー登録(「TOYOTA Web Passport」と同一?)
追記「MOD専用G-BOOK ID」では数値のパスワード作れるらしく、本問題自体を解決できるようです!
下記の話はログイン、出来なかったときに書いたものなので無視していいと思います。
3. マップオンデマンドのサイトからログイン
4. 購入時についていた取説の一番後ろのページにある「G-BOOK用車載端末ID」を入力
5. マップをダウンロード
6. あとは、取説通りに進める

といった感じなのですが、重大な問題が発生します。
それは、「マップオンデマンドセットアップディスク」でインストールした
専用アプリケーションに問題がある点です。(恐らく新しいセットアップディスクだと問題は起きません)

マップオンデマンドのツールでは、
G-BOOKか、GAZOO のどちらかのユーザー情報をGUIで入力する必要があるのですが、
このパスワード入力欄が、数値しか受け付けてくれません。

マップオンデマンド」のサイトにはたしかに、

2013年06月11日
【販売店装着オプションでSDナビをご利用のお客様へ】TOYOTA Web PassportのID、パスワード(PW)をご利用の場合、パスワードを「数字のみ」で設定登録してください。SD地図更新アプリを利用する際、PW入力時にエラーメッセージが表示される場合があります(ログイン画面のPW欄が英数対応していないため)。PWを「英数」で設定登録された方は、「数字のみ」に変更し、SD地図更新アプリをご利用下さい。バージョンアップにて英数対応予定です(別途、ご案内します)。

とあるのですが、解決方法の「パスワードを「数字のみ」で設定登録」に関しては、
そもそもパスワードが数字と英字両方を含めないと登録できない制約があるため、不可能なのです。

password

そのため、バージョンアップを待つ必要があると思いますが、
どこでバージョンアップツールをダウンロードできるのか、ちょっとわかりませんでした。
恐らくG-BOOK様に連絡すれば、ダウンロードできるかもしれません。
トヨタ様のディーラーに聞いても、下記のサポートディスクへ聞かないとわからないとのことでした。

マップオンデマンド・サポートデスク
0561-57-6814. 受付時間 9:00∼18:00

更新期日があと1日しかなく聞く時間がなかったため、
結局聞いてはいないのですが、バージョンアップする方法が分かりました。
このツールのメニューバーのヘルプの「最新バージョンを確認」でバージョンアップしてください。
すると、恐らくツールがバージョンアップできるはずです。
新しいバージョンでは英数字が入力可能のため、バージョンアップ後は問題が発生しなくなります。

ただし、私自身後で気が付いたものなので、上の方法ではうまくいかないかもしれません。
「最新バージョンを確認」自体がログインしないとできないものかもしれないからです。


一応、私がとった方法を紹介します。解決方法の1つとしてみてください。
方法とは、パスワードの入力欄の設定の「数値しか受け付けない」を解除させます。

専門的な話になりますが、Windowsの表示は多くが共通の部品によってできています。
この共通の部品は使い方が公開されており、みんなが知ることができます。
今回は、文字の入力用の共通部品であるエディットボックスを使用しており、
このエディットボックスに「数値しか受け付けない」という設定がされているわけです。
共通部品なので、ほかのソフトからもその設定を設定したり、逆に解除することができます。
今回は、その設定を解除することを行います。

1. パスワード入力欄のウィンドウハンドルを調査
2. GetWindowLong でウィンドウハンドルから、スタイル(GWL_STYLE)を取得
3. ウィンドウ情報から ES_NUMBER (0x2000) をビットマスクで削除
4. SetWindowLong でスタイル(GWL_STYLE)を再設定

これで、パスワード入力欄に英数字を入力できるようになります。
ログインをすると、新しいツールの確認が始まり、
新しいマップオンデマンドツールのバージョンアップされます。

上の手順をHSPというプログラミングツールで実行ファイルにしたものを用意しました。
なたでラボ物置から、「数値入力制限解除ツール」を選び、右側の雲のマークからダウンロードして利用できます。

上記の実行ファイルを実行したときに何か発生しても責任をとることはできません。
自己責任でお願いします。


追記
Yahoo知恵袋 「トヨタ純正カーナビで、データ更新をしようと思い、マップオンデマンドソフトを添…
fukushun1994様による解決方法の回答がありました。
MOD専用G-BOOK ID」というものをとるといいとのことです。


関連するブログ
MapOnDemandでちょいイラ‐(NSZT-W61G編)カッパっぱ、るっパッパ
ナビの地図データ更新&Gracenoteメディアデータベース更新*YOU*のページ

立て続けに…

by なたで 0 Comments
ここ立て続けに、「オンラインゲーム」と「システムのチェック」を公開したのですが
修正したいのが後から後から出てくる。

 修正したいの一覧

オンラインゲーム

 ・サーバーの状態で時間別の接続人数が、過去最大の接続人数になってる。
 1日以上サーバー付けっぱなしはなかったので気づかなかった

 ・サーバーを監視するプログラム
 サーバーは友人のを借りているので、
問題があった場合すぐさま再起動出来ない。
 また、サーバーはGUIでのみ操作するように作っちゃったので
なんか、その辺をどうにかしたい

 「システムのチェック

・多分64ビット版Vistaで終了できない
国産の言語HSPのバグ。対処方法はある。

そもそも窓の手がVistaで動かないらしいので
これ自体が動かない可能性も。 Vistaでテストする必要あるみたい

 ・タスクバーに表示される。

ダイアログっぽいウィンドウを目指してるので
ここに表示されたら雰囲気が……。)
でも、これ消したら、Win+Dとかどうなるんだろう。

ああ。いろいろ大変なことに。
 仕事も大変な時期なので、
ここら辺が完成したら、
しばらくゲーム作りとか休止したい。
 といっても、なんだかんだで更新続けそうですが。


7月2日追記
サーバー監視ソフト1つを残して全て解決しました。

Windowsの画面の16ビット色表現の方法

今日はWindowsXPでの16ビット色を、手探りで調べてみた。
とても疲れたけど、きっと誰かの役に立つはず。(^o^)
というか16ビットの環境での、レイヤード透過色指定に使いたかった。

はそれぞれ32色(5ビット)

  0,  8, 16, 24, 33, 41, 49, 57
 66, 74, 82, 90, 99,107,115,123
132,140,148,156,165,176,181,189
198,206,214,222,231,239,247,255

64色(6ビット)

  0,  4,  8, 12, 16, 20, 24, 28
 32, 36, 40, 44, 48, 52, 56, 60
 65, 69, 73, 77, 81, 85, 89, 93
 97,101,105,109,113,117,121,125
130,134,138,142,146,150,154,158
162,166,170,174,178,182,186,190
195,199,203,207,211,215,219,223
227,231,235,239,243,247,251,255

つまり緑の色の表現が、ほかの色に比べて多いことが分かった。
これ簡単に変換できる計算式ないかなー。

とりあえず、いつものHSPを使って、
単純に一番近い色を拾ってテーブル作る関数を作ってみた。

#deffunc setchromakeyinit local base_r_b,local base__g_,local buff
	sdim chromakey_rb,256
	sdim chromakey_g,256
	dim base_r_b,32
	base_r_b( 0) =   0,  8, 16, 24, 33, 41, 49, 57
	base_r_b( 8) =  66, 74, 82, 90, 99,107,115,123
	base_r_b(16) = 132,140,148,156,165,176,181,189
	base_r_b(24) = 198,206,214,222,231,239,247,255
	dim base__g_,64
	base__g_( 0) =   0,  4,  8, 12, 16, 20, 24, 28
	base__g_( 8) =  32, 36, 40, 44, 48, 52, 56, 60
	base__g_(16) =  65, 69, 73, 77, 81, 85, 89, 93
	base__g_(24) =  97,101,105,109,113,117,121,125
	base__g_(32) = 130,134,138,142,146,150,154,158
	base__g_(40) = 162,166,170,174,178,182,186,190
	base__g_(48) = 195,199,203,207,211,215,219,223
	base__g_(56) = 227,231,235,239,243,247,251,255
	dim buff,4
	repeat 256
		buff(0) = cnt
		buff(1) = 9
		repeat length(base_r_b)
			buff(2) = abs(base_r_b(cnt) - buff(0))
			if(buff(2)<=buff(1)){
				buff(1) = buff(2)
				buff(3) = cnt
			}
		loop
		poke chromakey_rb,cnt,base_r_b(buff(3))
		buff(1) = 5
		repeat length(base__g_)
			buff(2) = abs(base__g_(cnt) - buff(0))
			if(buff(2)<=buff(1)){
				buff(1) = buff(2)
				buff(3) = cnt
			}
		loop
		poke chromakey_g,cnt,base__g_(buff(3))
	loop
	return

HSPでアルファチャンネル付きレイヤードウィンドウを実装した

以前、アルファ値付きのウィンドウを作りたくて、
リージョンではなくレイヤードウィンドウについて色々調べてたのですが、なかなかうまくいかず。
結局HSPは32bitのウィンドウではなくて24bitのウィンドウのために、
アルファ値付きは不可能なんだと勝手に決めつけ断念していました・・・

それで、もう1度、昨日から再度調査しなおしていたのですが、
UpdateLayeredWindowを使えばいいことが判明!
駄目もとで、一度HSPで作ってみようと頑張ったら完成しました!

32bitのDIBの作り方は、すぽいと君のBITMAPのコピー処理の時に勉強してたので、そこらへんを流用。
何とか動いたんだけど、なんとなくで動いている部分もありプログラム的にはちょっと心配。
ゲームとかと違って、Windowsプログラムはソース自体は短いのに理解するまでが大変だ。

ちなみに、ただ単に透過色指定のSetLayeredWindowAttributesを利用したレイヤードウィンドウや、リージョンウィンドウと比べると
やっぱり、半透明の値をしっかりもっているので、UpdateLayeredWindowで作ったウィンドウはめっちゃきれい!!

アルファチャンネル付きレイヤードウィンドウとの比較画像

下の方は、ディザリング処理と言うか、灰色の中間色が透過されないためギザギザしている・・・

モジュール化して公開してみたのでよかったら使ってください!
なたでラボHSPのモジュールの「レイヤードウィンドウ総合モジュール」です。
Windows2000はGetLayeredWindowAttributesがないので動きません。

%d人のブロガーが「いいね」をつけました。