sakura-editor / sakura

SAKURA Editor (Japanese text editor for MS Windows)
https://sakura-editor.github.io/
Other
1.23k stars 162 forks source link

エディト領域のウィンドウの透過表示 #691

Open beru opened 5 years ago

beru commented 5 years ago

665 から分離します。

ちょっと長いですが関連する comments を引用します。

https://github.com/sakura-editor/sakura/issues/659#issuecomment-443463489

別のissueとして登録した方が良いと思いますが 背景画像に対して透過効果を出来るようにして欲しいです。

自分もそれは思った事があります。あとターミナルエミュレータとかでよくありますが背景を透過させて後ろのウィンドウの内容が透けて見えたりとか、実用性は微妙な気がしますが出来ても良いと思います。

https://github.com/sakura-editor/sakura/issues/665#issuecomment-445391768

背景画像の透過ですが簡単に実現出来そうなことが分かりました。

BLENDFUNCTION::SourceConstantAlpha の値で画像の透過度を調節出来るようです。 0 の時に透明で 255 で不透明。

もし #683 が merge されたら、別のPRで設定画面の変更も含めて対応しようと思います。

なお、エディト領域のウィンドウ自体が透過して後ろのウィンドウの内容が透けて見えるようにするには、WS_EX_LAYERED を指定してから UpdateLayeredWindow を使えば出来るようです。しかし WM_PAINT に頼れなくなるようなのでそうすると結構大きな改造が必要そうでしんどい気がします。。

https://github.com/sakura-editor/sakura/issues/665#issuecomment-445433580

参考情報を追記しときます。

サクラエディタのウインドウ構造はこうなっています。 ・CEditWnd ・・・ タイトルバーを表示する、ルートのフレームウインドウ  ┗CSplitterWnd ・・・ ウインドウ分割を実現するウインドウ   ┗CEditView ・・・ ビュー、エディタ部分のウインドウ、表示してなくても5つのインスタンス

透過実装を行う場合、少なくともこの3つのウインドウクラスに対して変更が必要です。 レイヤーという言い方だと3層構造になので各層を透過させないといかんです。

現状の WM_PAINT は更新領域の情報を部分的にしか使っていないので、 そのあたりを改修する必要があると思われます。

  • 更新矩形 ・・・ 更新対象のRECT(矩形)、既存コードで既に部分的に考慮されている
  • 更新領域 ・・・ 更新対象のREGION(矩形とは限らない)
beru commented 5 years ago

Layered Window について

情報源として解説ページへのリンクを列挙します。 https://msdn.microsoft.com/en-us/library/ms997507.aspx?f=255&MSPPError=-2147217396 https://docs.microsoft.com/en-us/windows/desktop/winmsg/window-features#layered-windows

DirectComposition について

https://qiita.com/Pctg-x8/items/98a67d7c3bd747afad70 https://docs.microsoft.com/en-us/windows/desktop/directcomp/directcomposition-portal

サクラエディタのコードについて

CEditView のインスタンスが5つというのは、上下左右分割の分が4つ、MiniMapの分が1つ。 分割の2つ目以降のビューは CEditWnd::CreateEditViewBySplit で new されるので、表示してなくても5つのインスタンスが有るわけでは無いと思います。

さて、CEditWnd, CSplitterWnd, CEditView という階層構造という事を説明して頂きましたが、ウィンドウの透過実装をするとなるとウィンドウ自体は1つにまとめてしまうのが良いかと思います。元から自前描画でエディタ表示が実現されているので理論的には全然不可能ではない筈。。ただ実際にやろうとすると結構な大改造になりそうな気が…。

beru commented 5 years ago

エディトのウィンドウを1つにまとめる改造を行うとなると必然的にスクロールバーの描画も自前でやる事になります。Visual Studio や Visual Studio Code は検索でヒットした箇所がスクロールバー上でもハイライトされるのでそういう表示を行おうと思ったら結局スクロールバーを自前描画しないといけません。

準備として先にスクロールバーの自前描画を実装するべきかも?

berryzplus commented 5 years ago

LayeredWindow について良く知らんと思ったら、これwin8以降の機能なんですね。

ウィンドウを任意のカタチ(矩形でないカタチ)に見せる技術は昔からあって、 たしか「猫でも分かる(ry」にも解説があった気がします。 ざっと見た感じ layerd の技術は「そっち系」のにおいがしました。

ウインドウを1つにまとめる提案についてですが、慎重に行きたいと思っています。

ぼくがそれをやるとしたら、まずツールバーの廃止することから考えると思うんですが、 それ(ツールバー等の全廃)は何か違うような気がするんです。

ツールバーやステータスバーのようなレガシーコントロールを活用するには、 フレームの上に「ビュー」が乗ってる構成が理想だと思います。 フレームの領域を少しずつ切り出して「バー」に割り当て、 余った部分にビューを配置すればよい、という考え方はシンプルです。 しかし、モノリスなウインドウでそれをやろうとすると少しめんどくさい気がします。

ビューをモノリス化する試み自体は賛成です。 たぶん、なくなるのはハンドルだけで、ウインドウの実質は残るんじゃないかと思っています。

現在よりもさらに細かい区分けの描画単位を作って、 各々担当領域の描画に専念する機構にできればもっと効率化できるのになぁ、とは前から思っていました。

beru commented 5 years ago

LayeredWindow について良く知らんと思ったら、これwin8以降の機能なんですね。

Windows 2000 からの機能です。内部でやってる事はOSが新しくになるにしたがって色々変わってそうです。色々と説明を書いたんですがブラウザのタブを閉じて消えてしまいました。。

ウィンドウを任意のカタチ(矩形でないカタチ)に見せる技術は昔からあって、 たしか「猫でも分かる(ry」にも解説があった気がします。 ざっと見た感じ layerd の技術は「そっち系」のにおいがしました。

それはGDIのウィンドウリージョンの機能ですね。なおこの方法だとウィンドウの縁がギザギザになります。

ウインドウを1つにまとめる提案についてですが、慎重に行きたいと思っています。

ぼくがそれをやるとしたら、まずツールバーの廃止することから考えると思うんですが、 それ(ツールバー等の全廃)は何か違うような気がするんです。

ツールバーやステータスバーのようなレガシーコントロールを活用するには、 フレームの上に「ビュー」が乗ってる構成が理想だと思います。 フレームの領域を少しずつ切り出して「バー」に割り当て、 余った部分にビューを配置すればよい、という考え方はシンプルです。 しかし、モノリスなウインドウでそれをやろうとすると少しめんどくさい気がします。

ビューをモノリス化する試み自体は賛成です。 たぶん、なくなるのはハンドルだけで、ウインドウの実質は残るんじゃないかと思っています。

現在よりもさらに細かい区分けの描画単位を作って、 各々担当領域の描画に専念する機構にできればもっと効率化できるのになぁ、とは前から思っていました。

エディタ本体は機能を満たすために自作されていますが、その他のパーツに関してはレガシーなコモンコントロールに結構頼っている部分もあるので、それらを少しずつ自前のものに置き換えが必要ですね。

berryzplus さんが懸念している通り、自前でとにかく同等っぽい描画とかイベント処理が記述出来るからと言って分割統治をさぼってしまうとカオスなコードになってメンテの苦しみが増大しそうです。

beru commented 5 years ago

なお最近 WPF, Windows Forms, WinUI がオープンソース化されましたが WPF と Windows Forms は .NET 用、Windows UI は Universal Windows Platform (UWP) 向けで Windows 10 向けという事で、現状ではサクラエディタはどちらにも移行し難いかと思います。

ダイアログリソースの量も多いし、このまま枯れた gdi32, user32 と心中路線かもしれないですね。 平成もそろそろ終わりそうな今の時代にコモンコントロール的な車輪の再発明をしないといけないのもなんだかプログラムの再利用には壁があるなぁと感じますが…。

berryzplus commented 5 years ago

Gdiと心中させる気はないです。もっとも、win32が滅びる未来をぼくは想定していませんが。

大雑把な話ですが、この先「ビジネスロジック」とwin32を切り離す作業をしたいと考えています。この試みは従来のサクラエディタでも行われていて、cviewcommanderクラスなどにその片鱗を見ることができます。現状は何のためにあるかよく分からないクラスですが、当初はwin32依存を減らす目的だったと考えると、高度な設計検討の結果作られたものとも取れます。

遠い未来の話は置いといて、ビューの統合には基本賛成なことは改めて書いときます。