「開発室」の版間の差分

提供: MeryWiki
ナビゲーションに移動 検索に移動
編集の要約なし
5行目: 5行目:
Alpaca と Alpaka のどっちが正しいのか分からないけど、K の方が文字のバランスが良いし '''Mortal Kombat''' みたいでカッコイイ。
Alpaca と Alpaka のどっちが正しいのか分からないけど、K の方が文字のバランスが良いし '''Mortal Kombat''' みたいでカッコイイ。


=== 予定 ===
*64 ビット対応
*正規表現エンジン「鬼車」から「鬼雲」に変更
:→ 2.5 で対応済
*Tidy HTML5 採用
:→ 2.5 で対応済
=== やってみたいこと ===
*ツールバーの大きいアイコンが欲しい
:[http://www.glyfz.com/ Glyfz] の「Office 2016」が素敵。でも「Office 2010」の全部セットで $125 でも良いかもしれない
*オシャレな exe アイコンが欲しい
:デザインが統一された商用のアプリケーションアイコン一式が欲しい
*自動アップデートの実装
:技術的好奇心でやってみたいけど、サーバ増強が必要かもしれない
:自動でアップデートされてしまうとブログサイトの閲覧数が確実に減る (アイコンとか買いたいのでアフィ踏んで欲しい)
:通信するアプリはデジタル署名がないとノートン先生に消される率が高そう
:<span style="color: crimson;">そもそもセキュリティ的な問題が大きい。アップデートチェックに留めておくべき</span>
=== 開発環境 ===
*Embarcadero Delphi XE2
**Delphi 10 Seattle だとオーバースペック
**exe のファイルサイズが 400KB 程膨らむけど Delphi 10 Seattle よりはだいぶマシ
**ちなみにその 400KB は XE2 から搭載されたスキン機能のせいらしい
::(どうせならスキン機能使ってみるか?と思ったらダサいのしかなかった)
:[[ファイル:Mery3_01.png|border]]
*Microsoft Visual C++ 2008
**Visual C++ 2015 だとオーバースペック
**鬼雲、Tidy、Hunspell の 32 ビット版、64 ビット版がそれぞれビルドできれば何でも良い
=== 現状 ===
*本体の 64 ビット対応
:→ Active Script の 64 ビット対応がヤバかった
*Tidy HTML5 採用
:→ 2.5 で対応済
*[https://github.com/k-takata/Onigmo 鬼雲] 64 ビット版のビルド
:→ 良く分からなかったけどなんかできたっぽい
:→ ヘッダファイルの 64 ビット対応もほぼ完了
*[https://github.com/hunspell/hunspell Hunspell] 64 ビット版のビルド
:→ そもそも 64 ビット版なんてないし、64 ビットでビルドすればいいだけなのか謎
*[https://github.com/htacg/tidy-html5 Tidy HTML5] 64 ビット版のビルド
:→ なんかビルドできたっぽい
=== 注意 ===
*プラグインメソッドの Editor_SetCaretPos などの引数 TPoint が 32 ビットなので TNativePoint に変更する
:→ 完了
=== 問題 ===
*64 ビット対応しても恩恵少なくね?
:TNotePad の設計上、大きいファイルの扱いは苦手
:開いているファイルすべての合計が 2GB 以上いけるようになるので、まあ恩恵といえばそれぐらい
*フラットデザインにするかどうか?
:私はまだ Windows 7 なのでフラットデザインが似合わない
*Delphi XE2 ではビルド番号の自動更新が無くなってる
:ビルド番号があると「がんばってる感」があるんだけど、まぁ無くても良いか
*Delphi XE2 だと不具合でリソースが英語 (1033) になる
:それほど問題はなさそうだけどなんだかなぁ…
=== アイコン ===
*[https://github.com/paomedia/small-n-flat small-n-flat]
:パブリックドメインだし SVG なので使いやすい。種類も豊富なので他のアプリとデザインを統一できる
:試しにこのアイコンに変更してみたらサイズが 100KB も縮んだw
[[ファイル:Mery_Icon.png]]
*[http://graphicloads.com/ GraphicLoads]
:完全無料。PNG (256x256) と AI 形式がある。他にも有料 (割と安い) で各種アイコンあり
[[ファイル:Mery_Icon2.png]]
[[ファイル:Mery_Icon3.png]]
== Delphi 10 Seattle の不具合 ==
Delphi 10 Seattle の VCL で発生する高 DPI 環境向けの開発における不具合を愚痴ってみました。
Windows 10、ディスプレイ 1 (メイン: 125%)、ディスプレイ 2 (サブ: 100%) の Per-Monitor DPI で確認
=== Per-Monitor DPI にてフォーム表示直後にスケーリングされない ===
*フォームにボタンでも適当に貼りつけて起動するだけで発生
:BorderStyle が bsSizeable の場合が駄目っぽい
:起動直後に WM_DPICHANGED が飛んでこないためスケーリングされないようだ
::ステータスバーを貼りつけるとなぜか直る
::WS_POPUP を含めるとなぜか直る (Position で poDefault が効かないなどの副作用あり)
*<span style="color:crimson;">なお、Delphi 10 Seattle Update 1 ではもっと派手にぶっ壊れている模様</span>
=== Per-Monitor DPI にて Constraints を指定していると正常に動作しない ===
[http://qc.embarcadero.com/wc/qcmain.aspx?d=77955 http://qc.embarcadero.com/wc/qcmain.aspx?d=77955]
*Vcl.Forms.pas の問題
:ScaleConstraints(M, D) で制約のサイズを変更している箇所がフォームのサイズを変更した後になってるため
:スケールが小さくなる場合は先に制約のサイズを小さくしておかないと制約にひっかかってフォームのサイズを縮小できない
:スケールが大きくなる場合は後から制約のサイズを大きくしないと制約にひっかかってフォームのサイズを拡大できない
:それを踏まえて修正してみるとこんな感じかもしれない
<source lang="delphi">
procedure TCustomForm.ChangeScale(M, D: Integer);
var
  PriorHeight: Integer;
begin
  // modified begin
  if M < D then
    ScaleConstraints(M, D);
  // modified end
  ScaleScrollBars(M, D);
  ScaleControls(M, D);
  if IsClientSizeStored then
  begin
    PriorHeight := ClientHeight;
    ClientWidth := MulDiv(ClientWidth, M, D);
    ClientHeight := MulDiv(PriorHeight, M, D);
  end;
  Font.Height := MulDiv(Font.Height, M, D);
  // modified begin
  (*
  ScaleConstraints(M, D);
  *)
  if M > D then
    ScaleConstraints(M, D);
  // modified end
end;
</source>
=== Constraints を指定しているとスケーリング後のフォームサイズがおかしい ===
上記の現象を回避したうえでこの問題が発生する。
そもそも Constraints は ClientWidth、ClientHeight ではなく Width、Height が基準なので MaxHeight、MinHeight にはタイトルバーの高さも含まれている。Vcl.Controls.pas の ScaleConstraints メソッドでは単純に数値のみでスケーリングを行っているため Per-Monitor DPI 状況下でタイトルバーのサイズが一定ということが考慮されておらず、結果としてクライアント領域が計算上より狭くなってしまう。
この問題は ChangeScale の後でタイトルバーの高さをスケーリングした場合の差分を足してやることで回避は可能だが結果的に高さが WM_DPICHANGED で送られてくる LPARAM の中の高さと異なってしまうため、ディスプレイをまたぐ位置によってはサイズが変更されなかったり無限ループが発生する恐れがあると思われる。
=== FormCreate 時のフォームの PixelsPerInch がおかしい ===
*親フォームの場合
:BorderStyle が bsSizeable だと PixelsPerInch が Screen.PixelsPerInch のまま
:ステータスバーを貼りつけると直る
*子フォームの場合
:WS_POPUP を含めずステータスバーを貼りつけている場合、起動時の PixelsPerInch が入っている
:WS_POPUP を含めてステータスバーを貼りつけている場合、Screen.PixelsPerInch が入っている
:WS_POPUP を含めてステータスバーを貼りつけていない場合、Screen.PixelsPerInch が入っている
*いずれの場合も FormShow 以降に処理を書けば正しい PixelsPerInch を取得できる
=== WM_DPICHANGED の実装における問題 ===
*Vcl.Forms.pas の問題
:WM_DPICHANGED で飛んでくる LPARAM (DPI 変更後の推奨ウィンドウサイズ) を使用せずに ChangeScale(Message.YDpi, FPixelsPerInch); の部分で自前でサイズを計算しているが、このやり方だとディスプレイをまたぐ位置によってはサイズが変更されなかったり、無限ループに陥ることも考えられる
<source lang="delphi">
procedure TCustomForm.WMDpiChanged(var Message: TWMDpi);
var
  I: Integer;
  OldPPI: Integer;
begin
  if not (csDesigning in ComponentState) then
  begin
    if (Message.YDpi = 0) or (FPixelsPerInch = 0) then
    begin
      if (Application.MainForm <> nil) and (Application.MainForm.PixelsPerInch <> 0) then
        FPixelsPerInch := Application.MainForm.PixelsPerInch
      else
        Exit;
    end;
    if Message.YDpi <> FPixelsPerInch then
    begin
      if Assigned(FOnBeforeMonitorDpiChanged) then
        FOnBeforeMonitorDpiChanged(Self, FPixelsPerInch, Message.YDpi);
      ChangeScale(Message.YDpi, FPixelsPerInch);
      for I := 0 to MDIChildCount - 1 do
        MDIChildren[I].ChangeScale(Message.YDpi, FPixelsPerInch);
      OldPPI := FPixelsPerInch;
      FPixelsPerInch := Message.YDpi;
      if Assigned(FOnAfterMonitorDpiChanged) then
        FOnAfterMonitorDpiChanged(Self, OldPPI, FPixelsPerInch);
    end;
    Message.Result := 0;
  end;
end;
</source>
*対策としては Message.ScalledRect^ の値を使用して MS のマニュアル通り SetWindowPos でウィンドウサイズを変更する
:[https://msdn.microsoft.com/ja-jp/library/windows/desktop/dn312083(v=vs.85).aspx https://msdn.microsoft.com/ja-jp/library/windows/desktop/dn312083(v=vs.85).aspx]
*さらなる問題。MS のマニュアル通りにするとウィンドウの高さが若干おかしい
:これの理由は LPARAM に含まれているウィンドウの高さの値がタイトルバーも含めた値のため
::Windows 10 では Per-Monitor DPI でディスプレイをまたいでもタイトルバーの高さは変更されない (むしろ変更できないっぽい)
::ディスプレイをまたいで本来変更されるはずのタイトルバーの高さが変更されないので、その差分だけクライアント領域が狭くなる
::でも自前で高さを変更しちゃうと先に述べたとおり無限ループなどの原因になる
::<span style="color:crimson;">→ つまり回避不能</span>
*でも Windows 10 の電卓みたいな標準アプリはタイトルバーの高さも変わるぞ?
:調べたみたらタイトルバーの高さが変わるのは、実はあのタイトルバーは本物のタイトルバーではなく、クライアント領域に自前で描画されている絵らしいが…
::しかしメニューのサイズとかも変わっているので、もしかすると MS が裏技を用意しているのかも?
::EnableNonClientDpiScaling という API が存在するらしいがまだ公式には発表されていない
:::Windows 10 Anniversary Update の Insider Preview (ビルド 14342) にて EnableNonClientDpiScaling の動作を確認
:::WM_NCCREATE で呼び出して引数にウィンドウハンドルを渡してやれば DPI の変更に合わせてタイトルバーやメニューのサイズが変更されるが、スクロールバーやポップアップメニューのサイズまでは変更されない模様
:::(2016/06/11 時点での Windows 10 現行品では EnableNonClientDpiScaling は使用できず)
<source lang="delphi">
function EnableNonClientDpiScaling(hWnd: HWND): BOOL; stdcall;
function EnableNonClientDpiScaling; external user32 name 'EnableNonClientDpiScaling' delayed;
</source>
=== FormCreate でフォームのフォントを変更してもスケーリングされない ===
*Vcl.Forms.pas を見ると TCustomForm.ReadState の部分でフォントのサイズなどのスケーリングを行っているが、ReadState は FormCreate より前に呼び出されているので FormCreate でフォントを設定しても時すでに遅し
:かといって TCustomForm.ReadState より前にフォントを設定したとしても ReadState でリソースからフォントを上書きされてしまうので無意味
:フォントを変更したい場合は FormShow 以降に PixelsPerInch を使用して自前でフォントの Height をスケーリングしてやる必要がある


==ご意見・ご要望==
==ご意見・ご要望==

2016年9月25日 (日) 11:41時点における版

Mery 3 (コードネーム: Alpaka) ベータ版置き場の予定

Mery のエディタエンジン TNotePad の作者さんの開発記録によると TNotePad (真魚) の 64 ビット版は開発・公開を中止されたようです。Delphi XE2 では無理という雰囲気の内容でしたので、Mery の 64 ビット対応についても私の技術力でどこまで対応できるかは分かりませんが、最悪、やっぱ開発やめますというケースも想定してこの「開発室」でこっそりベータ版を公開していこうと思います。

Alpaca と Alpaka のどっちが正しいのか分からないけど、K の方が文字のバランスが良いし Mortal Kombat みたいでカッコイイ。


ご意見・ご要望

内容 状態 備考
ツールバーの大きいアイコンが欲しい 検討 Glyfz の「Office 2016」が素敵。でも「Office 2010」の全部セットで $125 でも良いかもしれない。いずれにせよ費用がかかる
オシャレな exe アイコンが欲しい 検討 デザインが統一された商用のアプリケーションアイコン一式が欲しい
長い行で検索したときに右端に余裕を持たせてスクロール 検討 TNotePad の仕様なのであまり触りたくない
UTF-16 の BOM 有無対応 検討 過去のバージョンと設定ファイルの互換性が保てなくなる
タブを閉じた後にアクティブにするタブの設定 (左・右・直近など) 検討 オプション画面がいっぱいなので困ってる
ファイルから検索のコマンドライン引数の増設 検討 仕様を考えるのがダルい
自動マーカー、手動マーカー 検討 面白そうだけどかなり大変
自動バックアップ 検討 個人的には必ずオフにする機能なのでダルい
開いているファイルから検索・置換 検討 試作品はできたけど検証がダルい
編集行の強調表示 検討 TNotePad に手を入れないといけないので大変
自動アップデートの実装 保留 サーバ増強、コードサイニングの取得など費用がかかる。そもそもセキュリティ的な問題が大きい。アップデートチェックに留めておくべき
EXE アイコンがダサい 保留 気に入ってるんだもん
単語分断折り返し 保留 折り返しは内部でキッチリ決まってるので手の着けようがなさそう
矩形選択で文字入力したときにイイ感じに入力されると良い 保留 作ってみたけど問題多すぎ
トリプルクリックからの論理行選択 保留 物理行選択派な人もいそう
マウスキャプチャ後のスクロールマージンの挙動を秀○さんっぽくしたい 完了
AddFontResource で追加したフォントが DirectWrite で使用できない 完了 2.5.0 で対応済
Tidy HTML5 完了 2.5.0 で対応済
アウトラインのドラッグドロップで並べ替え 完了 2.5.0 で対応済
ウィンドウの縦分割 完了 2.5.0 で対応済
特殊文字入力のインターフェイス考察 完了 特殊文字を入力するマクロを同梱した
書き換え禁止モードをわかりやすくする 完了 タブに鍵マークを表示するようにした
先頭大文字で Don'T になっちゃう 完了 アポストロフィは無視するようにした
最大化→最小化→復元時のファイルの更新チェックを走らせる手段の調査 完了
バイナリなどを開いたときの確認ダイアログで「キャンセル」したい 完了
文字間隔の設定 完了
グレーアイコンが濃すぎる 完了
新規作成時のエンコードの指定方法について検討 完了
ドラッグ中にメッセージボックスを表示させるとフリーズすることがある 完了
起動時引数行番号と一緒に桁番号も指定 完了
単語補完の自動起動 完了 実装したけど誰も使ってなさそうだったので廃止
0x200Fの挙動 完了
画面中央付近でキャレットを固定したい 完了 ScrollMargin を最大値に設定
起動時引数エンコードの指定 完了
起動時引数編集モードの指定 完了
SJIS、UTF8 とかごとの文字コード表示 却下 UTF8 標準化
CSV / TSV 編集機能の研究 却下 Excel で良いんじゃね?

参考資料

スポンサーリンク