自作スタイルのウィンドウ
自作スタイルのウィンドウ
ウィンドウをオリジナルにしたいのですが、全て自作するとwindowsのAero機能などが適用されず困っています。
例えば、Google Chrome や、Photoshop が分かりやすい例ですが、見た目は明らかに普通のウィンドウではなく、すべてオリジナルになっています。しかし、タイトルバーを移動するとAero機能などの普通のウィンドウの操作ができます。
これをC言語で作りたいのですが、非クライアント領域への描画以外に何か方法はありますか?
また、質問とは離れてしまいますが、タイトルバーにOfficeボタンみたいなオブジェクト?を付けるのはどのように行っているのでしょうか?
よろしくお願いします。
例えば、Google Chrome や、Photoshop が分かりやすい例ですが、見た目は明らかに普通のウィンドウではなく、すべてオリジナルになっています。しかし、タイトルバーを移動するとAero機能などの普通のウィンドウの操作ができます。
これをC言語で作りたいのですが、非クライアント領域への描画以外に何か方法はありますか?
また、質問とは離れてしまいますが、タイトルバーにOfficeボタンみたいなオブジェクト?を付けるのはどのように行っているのでしょうか?
よろしくお願いします。
Dango San
Re: 自作スタイルのウィンドウ
Aero機能ってなんでしょう。
AeroスナップやAeroシェイクのことならそう書かないと。
聞きたいのはAeroテーマを適用する方法ではないですよね?
WM_NCHITTESTメッセージを処理すればウィンドウのどこでも好きな場所をタイトルバーにできます。
タイトルバーにしたところはどこでもクリックアンドドラッグで移動できるしAeroスナップやAeroシェイクも効きます。
ウィンドウをどのように描画しているかは無関係。
Officeボタンのようなものもボタンは自前で描画してやはりWM_NCHITTESTメッセージを処理してマウスメッセージを横流しすれば良いかと。
AeroスナップやAeroシェイクのことならそう書かないと。
聞きたいのはAeroテーマを適用する方法ではないですよね?
WM_NCHITTESTメッセージを処理すればウィンドウのどこでも好きな場所をタイトルバーにできます。
タイトルバーにしたところはどこでもクリックアンドドラッグで移動できるしAeroスナップやAeroシェイクも効きます。
ウィンドウをどのように描画しているかは無関係。
Officeボタンのようなものもボタンは自前で描画してやはりWM_NCHITTESTメッセージを処理してマウスメッセージを横流しすれば良いかと。
Re: 自作スタイルのウィンドウ
なるほど。WM_NCHITTESTに対して、マウス座標がある範囲内だったらHTCAPTIONを返してあげればいい感じでしょうか?Mana さんが書きました:WM_NCHITTESTメッセージを処理すればウィンドウのどこでも好きな場所をタイトルバーにできます。
タイトルバーにしたところはどこでもクリックアンドドラッグで移動できるしAeroスナップやAeroシェイクも効きます。
また同様にサイズ変更のフレーム部分もWM_NCHITTESTで何らかの値を返せばいいということでしょうか?
Dango San
Re: 自作スタイルのウィンドウ
タイトルバーはできました。ありがとうございます。
ですが、サイズ変更(Aeroスナップ)については、どうやらウィンドウスタイルでフレームを指定しないと、WM_NCHITTESTで適当な値を返してもダメなようです。
しかしchromeなどのソフトはAeroスナップが効きますし、何らかの方法があるはずです。何か良い方法はあるのでしょうか?
ですが、サイズ変更(Aeroスナップ)については、どうやらウィンドウスタイルでフレームを指定しないと、WM_NCHITTESTで適当な値を返してもダメなようです。
しかしchromeなどのソフトはAeroスナップが効きますし、何らかの方法があるはずです。何か良い方法はあるのでしょうか?
Dango San
Re: 自作スタイルのウィンドウ
Aeroスナップが機能するウィンドウには、WS_MINIMIZEBOX,WS_MAXIMIZEBOX,WS_THICKFRAMEのスタイルが最低限必要みたいです。
正しい情報を知りたければウィンドウスパイツールなどで実際にウィンドウスタイルを確認すると良いでしょう。
正しい情報を知りたければウィンドウスパイツールなどで実際にウィンドウスタイルを確認すると良いでしょう。
Re: 自作スタイルのウィンドウ
Google Chrome のスタイルを調べてみました。Mana さんが書きました:正しい情報を知りたければウィンドウスパイツールなどで実際にウィンドウスタイルを確認すると良いでしょう。
・WS_OVERLAPPEDWINDOW
・WS_VISIBLE
・WS_CLIPSIBLINGS
・WS_CLIPCHILDREN
・WS_BORDER
・WS_DLGFRAME
・WS_EX_WINDOWEDGE
OVERLAPPEDWINDOWが指定されている時点で境界線もタイトルバーも作られているようですね…。
Dango San
Re: 自作スタイルのウィンドウ
WS_DLGFRAMEが謎ですけどWS_OVERLAPPEDWINDOWということは標準フレームをベースにしているようですね。
Google Chromeを使ってないのでネットで見かけたスナップショットから感想ですが、フレーム部分は標準のまま使っていて内側からはみ出しているものもないように見えます。
具体的にどこがどんなふうに特別だと思われたのでしょうか?
調べているうちにAeroテーマが有効だとWM_NCPAINTでフレームを描き変えられないと分かりました。
OfficeボタンをC言語で実装する方法は公開されていないようです。
確かなことは分かりませんが.NET用のWPFツールキットというのを使うとできるらしいという情報を見かけました。
Google Chromeを使ってないのでネットで見かけたスナップショットから感想ですが、フレーム部分は標準のまま使っていて内側からはみ出しているものもないように見えます。
具体的にどこがどんなふうに特別だと思われたのでしょうか?
調べているうちにAeroテーマが有効だとWM_NCPAINTでフレームを描き変えられないと分かりました。
OfficeボタンをC言語で実装する方法は公開されていないようです。
確かなことは分かりませんが.NET用のWPFツールキットというのを使うとできるらしいという情報を見かけました。
Re: 自作スタイルのウィンドウ
私もスナップショットを見て気付いたのですが、そういえばChromeにはテーマを変更する機能があります。私は今標準ではないテーマを適用しているので「特別」だと思っていました。Mana さんが書きました:Google Chromeを使ってないのでネットで見かけたスナップショットから感想ですが、フレーム部分は標準のまま使っていて内側からはみ出しているものもないように見えます。
具体的にどこがどんなふうに特別だと思われたのでしょうか?
もしChromeで見るのでしたら、「Google Chrome テーマ」で検索していただければよいかと思います。フレーム部分(というか背景)が自分好みになります。
NCPAINTでフレームを描画できないようにと考えたんですが、そううまくいかず…
.NETのWPFツールキット…ググったらとても使いやすそうですね。
これはC言語と併用できるような代物でしょうか…?
Dango San
Re: 自作スタイルのウィンドウ
Google Chromeはメインウィンドウの透明度をいじったり奥や手前に別のウィンドウを重ねたりすればできそうな気がしなくもないですが。
こちらでは検証もできないので詳しいことは分からないですね。すみません。
WPFのウィンドウはいわば.NETのフォームなのでメインはC#やVBでしょうか。
イベントハンドラから呼び出して使うライブラリをC言語あるいはC++/CLIとかでも作れるというふうですね。
こちらも実際に使ってないので詳しいことは分かりません。
将来的にも.NETベースに移行したほうがいろいろと便利で楽なのかもしれません。
こちらでは検証もできないので詳しいことは分からないですね。すみません。
WPFのウィンドウはいわば.NETのフォームなのでメインはC#やVBでしょうか。
イベントハンドラから呼び出して使うライブラリをC言語あるいはC++/CLIとかでも作れるというふうですね。
こちらも実際に使ってないので詳しいことは分かりません。
将来的にも.NETベースに移行したほうがいろいろと便利で楽なのかもしれません。
Re: 自作スタイルのウィンドウ
…と、諦め切れずに色々と試行錯誤した結果、何とかできましたので報告いたします。
まず、フレームを見えなくする方法としてクライアント領域を広げることで解決いたしました。 良い方法かどうかは分かりませんが、これが一番いいと思います。
次に、ウィンドウがアクティブになるときにフレームが再描画?されるようでチラつきます。これをなくすために、WM_NCACTIVATEメッセージで0を返すことで解決しました。 フレームが非表示(というかクライアント領域)になっていますので、サイズ変更ができません。
そこで自分でマウスの当たり判定を行い、WM_NCHITTESTでHTTOPなどの値を返すことで実装しました。 これでフレームが見えない状態でAero機能が使えるようになりました。
まず、フレームを見えなくする方法としてクライアント領域を広げることで解決いたしました。 良い方法かどうかは分かりませんが、これが一番いいと思います。
次に、ウィンドウがアクティブになるときにフレームが再描画?されるようでチラつきます。これをなくすために、WM_NCACTIVATEメッセージで0を返すことで解決しました。 フレームが非表示(というかクライアント領域)になっていますので、サイズ変更ができません。
そこで自分でマウスの当たり判定を行い、WM_NCHITTESTでHTTOPなどの値を返すことで実装しました。 これでフレームが見えない状態でAero機能が使えるようになりました。
Dango San