├── .gitattributes
├── .gitignore
├── CREDITS.md
├── Common.props
├── LICENSE
├── README.md
├── UniteWindow.sln
└── UniteWindow
├── ConfigDialog.cpp
├── ConfigDialog.h
├── UniteWindow.cpp
├── UniteWindow.def
├── UniteWindow.h
├── UniteWindow.rc
├── UniteWindow.vcxproj
├── UniteWindow.vcxproj.filters
├── UniteWindow_Config_Load.cpp
├── UniteWindow_Config_Save.cpp
├── UniteWindow_Window.cpp
├── UniteWindow_Window_AviUtlWindow.cpp
├── UniteWindow_Window_ExeditWindow.cpp
├── UniteWindow_Window_SettingDialog.cpp
├── pch.cpp
├── pch.h
└── resource.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Oo]ut/
33 | [Ll]og/
34 | [Ll]ogs/
35 | _bin/
36 | _obj/
37 |
38 | # Visual Studio 2015/2017 cache/options directory
39 | .vs/
40 | # Uncomment if you have tasks that create the project's static files in wwwroot
41 | #wwwroot/
42 |
43 | # Visual Studio 2017 auto generated files
44 | Generated\ Files/
45 |
46 | # MSTest test Results
47 | [Tt]est[Rr]esult*/
48 | [Bb]uild[Ll]og.*
49 |
50 | # NUnit
51 | *.VisualState.xml
52 | TestResult.xml
53 | nunit-*.xml
54 |
55 | # Build Results of an ATL Project
56 | [Dd]ebugPS/
57 | [Rr]eleasePS/
58 | dlldata.c
59 |
60 | # Benchmark Results
61 | BenchmarkDotNet.Artifacts/
62 |
63 | # .NET Core
64 | project.lock.json
65 | project.fragment.lock.json
66 | artifacts/
67 |
68 | # ASP.NET Scaffolding
69 | ScaffoldingReadMe.txt
70 |
71 | # StyleCop
72 | StyleCopReport.xml
73 |
74 | # Files built by Visual Studio
75 | *_i.c
76 | *_p.c
77 | *_h.h
78 | *.ilk
79 | *.meta
80 | *.obj
81 | *.iobj
82 | *.pch
83 | *.pdb
84 | *.ipdb
85 | *.pgc
86 | *.pgd
87 | *.rsp
88 | *.sbr
89 | *.tlb
90 | *.tli
91 | *.tlh
92 | *.tmp
93 | *.tmp_proj
94 | *_wpftmp.csproj
95 | *.log
96 | *.vspscc
97 | *.vssscc
98 | .builds
99 | *.pidb
100 | *.svclog
101 | *.scc
102 |
103 | # Chutzpah Test files
104 | _Chutzpah*
105 |
106 | # Visual C++ cache files
107 | ipch/
108 | *.aps
109 | *.ncb
110 | *.opendb
111 | *.opensdf
112 | *.sdf
113 | *.cachefile
114 | *.VC.db
115 | *.VC.VC.opendb
116 |
117 | # Visual Studio profiler
118 | *.psess
119 | *.vsp
120 | *.vspx
121 | *.sap
122 |
123 | # Visual Studio Trace Files
124 | *.e2e
125 |
126 | # TFS 2012 Local Workspace
127 | $tf/
128 |
129 | # Guidance Automation Toolkit
130 | *.gpState
131 |
132 | # ReSharper is a .NET coding add-in
133 | _ReSharper*/
134 | *.[Rr]e[Ss]harper
135 | *.DotSettings.user
136 |
137 | # TeamCity is a build add-in
138 | _TeamCity*
139 |
140 | # DotCover is a Code Coverage Tool
141 | *.dotCover
142 |
143 | # AxoCover is a Code Coverage Tool
144 | .axoCover/*
145 | !.axoCover/settings.json
146 |
147 | # Coverlet is a free, cross platform Code Coverage Tool
148 | coverage*.json
149 | coverage*.xml
150 | coverage*.info
151 |
152 | # Visual Studio code coverage results
153 | *.coverage
154 | *.coveragexml
155 |
156 | # NCrunch
157 | _NCrunch_*
158 | .*crunch*.local.xml
159 | nCrunchTemp_*
160 |
161 | # MightyMoose
162 | *.mm.*
163 | AutoTest.Net/
164 |
165 | # Web workbench (sass)
166 | .sass-cache/
167 |
168 | # Installshield output folder
169 | [Ee]xpress/
170 |
171 | # DocProject is a documentation generator add-in
172 | DocProject/buildhelp/
173 | DocProject/Help/*.HxT
174 | DocProject/Help/*.HxC
175 | DocProject/Help/*.hhc
176 | DocProject/Help/*.hhk
177 | DocProject/Help/*.hhp
178 | DocProject/Help/Html2
179 | DocProject/Help/html
180 |
181 | # Click-Once directory
182 | publish/
183 |
184 | # Publish Web Output
185 | *.[Pp]ublish.xml
186 | *.azurePubxml
187 | # Note: Comment the next line if you want to checkin your web deploy settings,
188 | # but database connection strings (with potential passwords) will be unencrypted
189 | *.pubxml
190 | *.publishproj
191 |
192 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
193 | # checkin your Azure Web App publish settings, but sensitive information contained
194 | # in these scripts will be unencrypted
195 | PublishScripts/
196 |
197 | # NuGet Packages
198 | *.nupkg
199 | # NuGet Symbol Packages
200 | *.snupkg
201 | # The packages folder can be ignored because of Package Restore
202 | **/[Pp]ackages/*
203 | # except build/, which is used as an MSBuild target.
204 | !**/[Pp]ackages/build/
205 | # Uncomment if necessary however generally it will be regenerated when needed
206 | #!**/[Pp]ackages/repositories.config
207 | # NuGet v3's project.json files produces more ignorable files
208 | *.nuget.props
209 | *.nuget.targets
210 |
211 | # Microsoft Azure Build Output
212 | csx/
213 | *.build.csdef
214 |
215 | # Microsoft Azure Emulator
216 | ecf/
217 | rcf/
218 |
219 | # Windows Store app package directories and files
220 | AppPackages/
221 | BundleArtifacts/
222 | Package.StoreAssociation.xml
223 | _pkginfo.txt
224 | *.appx
225 | *.appxbundle
226 | *.appxupload
227 |
228 | # Visual Studio cache files
229 | # files ending in .cache can be ignored
230 | *.[Cc]ache
231 | # but keep track of directories ending in .cache
232 | !?*.[Cc]ache/
233 |
234 | # Others
235 | ClientBin/
236 | ~$*
237 | *~
238 | *.dbmdl
239 | *.dbproj.schemaview
240 | *.jfm
241 | *.pfx
242 | *.publishsettings
243 | orleans.codegen.cs
244 |
245 | # Including strong name files can present a security risk
246 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
247 | #*.snk
248 |
249 | # Since there are multiple workflows, uncomment next line to ignore bower_components
250 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
251 | #bower_components/
252 |
253 | # RIA/Silverlight projects
254 | Generated_Code/
255 |
256 | # Backup & report files from converting an old project file
257 | # to a newer Visual Studio version. Backup files are not needed,
258 | # because we have git ;-)
259 | _UpgradeReport_Files/
260 | Backup*/
261 | UpgradeLog*.XML
262 | UpgradeLog*.htm
263 | ServiceFabricBackup/
264 | *.rptproj.bak
265 |
266 | # SQL Server files
267 | *.mdf
268 | *.ldf
269 | *.ndf
270 |
271 | # Business Intelligence projects
272 | *.rdl.data
273 | *.bim.layout
274 | *.bim_*.settings
275 | *.rptproj.rsuser
276 | *- [Bb]ackup.rdl
277 | *- [Bb]ackup ([0-9]).rdl
278 | *- [Bb]ackup ([0-9][0-9]).rdl
279 |
280 | # Microsoft Fakes
281 | FakesAssemblies/
282 |
283 | # GhostDoc plugin setting file
284 | *.GhostDoc.xml
285 |
286 | # Node.js Tools for Visual Studio
287 | .ntvs_analysis.dat
288 | node_modules/
289 |
290 | # Visual Studio 6 build log
291 | *.plg
292 |
293 | # Visual Studio 6 workspace options file
294 | *.opt
295 |
296 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
297 | *.vbw
298 |
299 | # Visual Studio LightSwitch build output
300 | **/*.HTMLClient/GeneratedArtifacts
301 | **/*.DesktopClient/GeneratedArtifacts
302 | **/*.DesktopClient/ModelManifest.xml
303 | **/*.Server/GeneratedArtifacts
304 | **/*.Server/ModelManifest.xml
305 | _Pvt_Extensions
306 |
307 | # Paket dependency manager
308 | .paket/paket.exe
309 | paket-files/
310 |
311 | # FAKE - F# Make
312 | .fake/
313 |
314 | # CodeRush personal settings
315 | .cr/personal
316 |
317 | # Python Tools for Visual Studio (PTVS)
318 | __pycache__/
319 | *.pyc
320 |
321 | # Cake - Uncomment if you are using it
322 | # tools/**
323 | # !tools/packages.config
324 |
325 | # Tabs Studio
326 | *.tss
327 |
328 | # Telerik's JustMock configuration file
329 | *.jmconfig
330 |
331 | # BizTalk build output
332 | *.btp.cs
333 | *.btm.cs
334 | *.odx.cs
335 | *.xsd.cs
336 |
337 | # OpenCover UI analysis results
338 | OpenCover/
339 |
340 | # Azure Stream Analytics local run output
341 | ASALocalRun/
342 |
343 | # MSBuild Binary and Structured Log
344 | *.binlog
345 |
346 | # NVidia Nsight GPU debugger configuration file
347 | *.nvuser
348 |
349 | # MFractors (Xamarin productivity tool) working folder
350 | .mfractor/
351 |
352 | # Local History for Visual Studio
353 | .localhistory/
354 |
355 | # BeatPulse healthcheck temp database
356 | healthchecksdb
357 |
358 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
359 | MigrationBackup/
360 |
361 | # Ionide (cross platform F# VS Code tools) working folder
362 | .ionide/
363 |
364 | # Fody - auto-generated XML schema
365 | FodyWeavers.xsd
--------------------------------------------------------------------------------
/CREDITS.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hebiiro/AviUtl-Plugin-UniteWindow/db5ad9837eb88479afbea34fc84eb3bafd73d607/CREDITS.md
--------------------------------------------------------------------------------
/Common.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)_bin\
7 | $(SolutionDir)_obj\$(PlatformTarget)\$(Configuration)\$(ProjectName)\
8 |
9 |
10 |
11 | $(IntDir)
12 |
13 |
14 |
15 |
16 | $(IntDir)
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 hebiiro
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AviUtl プラグイン - UniteWindow
2 |
3 | AviUtl のウィンドウを結合してシングルウィンドウにまとめます。
4 | [最新バージョンをダウンロード](../../releases/latest/)
5 |
6 | 
7 |
8 | ## 導入方法
9 |
10 | 1. 以下のファイルを AviUtl の Plugins フォルダに配置します。
11 | * UniteWindow.aul
12 | * UniteWindow.xml
13 | * UniteWindow (フォルダ)
14 |
15 | ## 使用方法
16 |
17 | ボーダーをドラッグしてペインのサイズを調整します。Shift キーを押したままドラッグするとボーダーが十字になるように調整されます。
18 |
19 | ## 設定方法
20 |
21 | タイトルバーを右クリックしてシステムメニューを表示します。
22 |
23 | ### レイアウトのインポート
24 |
25 | レイアウトファイルを選択してインポートします。
26 |
27 | ### レイアウトのエクスポート
28 |
29 | レイアウトファイルを選択してエクスポートします。
30 |
31 | ### UniteWindowの設定
32 |
33 | UniteWindowの設定ダイアログを開きます。
34 |
35 | * ```レイアウトモード```
36 | * ```垂直分割``` 最初に垂直ボーダーで分割するモードです。水平ボーダーは個別に位置調整ができます。
37 | * ```水平分割``` 最初に水平ボーダーで分割するモードです。垂直ボーダーは個別に位置調整ができます。
38 |
39 | * ```ウィンドウの配置```
40 | * ```左上```
41 | * ```右上```
42 | * ```左下```
43 | * ```右下```
44 | * それぞれに ```AviUtlウィンドウ```、```拡張編集ウィンドウ```、```設定ダイアログ```、```ウィンドウなし``` を指定できます。同じウィンドウを重複して指定することはできません。
45 |
46 | * ```ボーダー位置 (垂直分割)``` 垂直分割モードのボーダーの位置を指定します。
47 | * ```中央``` 中央にある垂直ボーダーの X 座標を指定します。
48 | * ```左``` 左側にある水平ボーダーの Y 座標を指定します。
49 | * ```右``` 右側にある水平ボーダーの Y 座標を指定します。
50 |
51 | * ```ボーダー位置 (水平分割)``` 水平分割モードのボーダーの位置を指定します。
52 | * ```中央``` 中央にある水平ボーダーの Y 座標を指定します。
53 | * ```上``` 上側にある垂直ボーダーの X 座標を指定します。
54 | * ```下``` 下側にある垂直ボーダーの X 座標を指定します。
55 | * エディットボックスの下にあるコンボボックスで基点を指定します。例えばボーダーを右端で固定したい場合は基点を「右下」に設定します。
56 |
57 | * ```配色``` 背景色とボーダーの配色を指定します。
58 | * ```塗り潰し``` 背景色を指定します。
59 | * ```ボーダー``` ボーダーの色を指定します。
60 | * ```ホットボーダー``` ホットボーダーの色を指定します。
61 |
62 | * ```アクティブキャプションの配色``` アクティブキャプションの配色を指定します。
63 | * ```背景``` 背景色を指定します。
64 | * ```テキスト``` テキストの色を指定します。
65 |
66 | * ```非アクティブキャプションの配色``` 非アクティブキャプションの配色を指定します。
67 | * ```背景``` 背景色を指定します。
68 | * ```テキスト``` テキストの色を指定します。
69 |
70 | * ```配色ではなくテーマを使用する```
71 | チェックを入れるとテーマを使用してボーダーとキャプションを描画するようになります。この場合「UniteWindow」の配色は無視されます。その代わりに「黒窓」のテーマカスタマイズ機能が反映されます。
72 |
73 | ### 設定ファイル
74 |
75 | UniteWindow.xml をテキストエディタで開いて編集します。
76 |
77 | * ``````
78 | * ```borderWidth``` ボーダーの幅を指定します。
79 | * ```captionHeight``` キャプションの高さを指定します。
80 | * ```borderSnapRange``` ボーダーのスナップ範囲を指定します。
81 | * ```fillColor``` 背景の塗りつぶし色を指定します。
82 | * ```borderColor``` ボーダーの色を指定します。
83 | * ```hotBorderColor``` ホット状態のボーダーの色を指定します。
84 | * ```activeCaptionColor``` アクティブキャプションの背景色を指定します。
85 | * ```activeCaptionTextColor``` アクティブキャプションのテキストの色を指定します。
86 | * ```inactiveCaptionColor``` 非アクティブキャプションの背景色を指定します。
87 | * ```inactiveCaptionTextColor``` 非アクティブキャプションのテキストの色を指定します。
88 | * ```useTheme``` ```YES``` を指定するとボーダーとキャプションの描画にテーマを使用するようになります。
89 | * `````` シングルウィンドウの位置を指定します。ウィンドウ位置がおかしくなった場合はこのタグを削除してください。
90 | * `````` レイアウトを指定します。レイアウトがおかしくなった場合はこのタグを削除してください。
91 | * ```layoutMode``` ```vertSplit```、```horzSplit``` のいずれかを指定します。
92 | * ``````
93 | * ```pos``` ```topLeft```、```topRight```、```bottomLeft```、```bottomRight``` のいずれかを指定します。
94 | * ```id``` ```aviutlWindow```、```exeditWindow```、```settingDialog```、空文字のいずれかを指定します。
95 | * `````` ```layoutMode``` が ```vertSplit``` のときのボーダーの位置を指定します。
96 | * ```center``` 中央にある垂直ボーダーの X 座標を指定します。
97 | * ```left``` 左側にある水平ボーダーの Y 座標を指定します。
98 | * ```right``` 右側にある水平ボーダーの Y 座標を指定します。
99 | * ```centerOrigin``` 中央にある垂直ボーダーの基点を指定します。
100 | * ```leftOrigin``` 左側にある水平ボーダーの基点を指定します。
101 | * ```rightOrigin``` 右側にある水平ボーダーの基点を指定します。
102 | * `````` ```layoutMode``` が ```horzSplit``` のときのボーダーの位置を指定します。
103 | * ```center``` 中央にある水平ボーダーの Y 座標を指定します。
104 | * ```top``` 上側にある垂直ボーダーの X 座標を指定します。
105 | * ```bottom``` 下側にある垂直ボーダーの X 座標を指定します。
106 | * ```centerOrigin``` 中央にある水平ボーダーの基点を指定します。
107 | * ```topOrigin``` 上側にある垂直ボーダーの基点を指定します。
108 | * ```bottomOrigin``` 下側にある垂直ボーダーの基点を指定します。
109 |
110 | ## 更新履歴
111 |
112 | * 3.5.0 - 2022/06/22 キャプションとボーダーの描画方式を選択できるように変更
113 | * 3.4.0 - 2022/06/09 設定ダイアログのホイール操作の既定動作抑制
114 | * 3.3.1 - 2022/06/06 「rikky_module」が正常に動作しない問題を修正
115 | * 3.3.0 - 2022/06/03 コンフィグダイアログでの配色の変更に対応
116 | * 3.2.0 - 2022/06/03 設定ダイアログの高さをコンテナの高さまで広げるように変更
117 | * 3.1.0 - 2022/06/03 タイトルの描画方式を変更
118 | * 3.0.6 - 2022/06/02 スポイトが正しく動作しない問題を修正
119 | * 3.0.5 - 2022/05/22 ポップアップウィンドウを最小化できない問題を修正
120 | * 3.0.4 - 2022/05/19 「スクリプト並べ替え管理」「シークバー+」が動作しない問題を修正
121 | * 3.0.3 - 2022/05/13 メニューが再描画されない問題を修正
122 | * 3.0.2 - 2022/05/13 設定ダイアログでエンターキーが効かない問題を修正
123 | * 3.0.1 - 2022/05/11 タイトルの色が読み込まれない問題を修正
124 | * 3.0.0 - 2022/05/08 子ウィンドウにフォーカスが当たっていない問題を修正
125 | * 2.0.0 - 2022/05/08 各ウィンドウを子ウィンドウに変更
126 | * 1.1.6 - 2022/05/07 ボーダーに基点を追加
127 | * 1.1.5 - 2022/05/06 シングルウィンドウのクラス名を "AviUtl" に変更
128 | * 1.1.4 - 2022/05/06 ボーダーのスナップ機能を追加
129 | * 1.1.3 - 2022/05/06 スポイトが動作しない問題を修正
130 | * 1.1.2 - 2022/05/06 各ウィンドウが操作不能になる問題を修正
131 | * 1.1.1 - 2022/05/05 ウィンドウをクリックしても最前面にならなかった問題を修正
132 | * 1.1.0 - 2022/05/05 Shift キードラッグでボーダーを十字にできるように修正
133 | * 1.0.7 - 2022/05/04 パフォーマンスの低下を改善
134 | * 1.0.6 - 2022/05/04 「拡張編集RAMプレビュー」が動作しない問題に対応
135 | * 1.0.5 - 2022/05/04 「イージング設定時短プラグイン」が動作しない問題に対応
136 | * 1.0.4 - 2022/05/04 スピンボタンで数値を変更できないバグを修正
137 | * 1.0.3 - 2022/05/04 「PSDToolKit」の「送る」に対応
138 | * 1.0.2 - 2022/05/04 マウスホイールでスクロールに対応
139 | * 1.0.1 - 2022/05/04 「テキスト編集補助プラグイン」が動作しない問題に対応
140 | * 1.0.0 - 2022/05/03 初版
141 |
142 | ## 動作確認
143 |
144 | * (必須) AviUtl 1.10 & 拡張編集 0.92 http://spring-fragrance.mints.ne.jp/aviutl/
145 | * (共存確認) patch.aul r41 https://scrapbox.io/ePi5131/patch.aul
146 |
147 | ## クレジット
148 |
149 | * Microsoft Research Detours Package https://github.com/microsoft/Detours
150 | * aviutl_exedit_sdk https://github.com/ePi5131/aviutl_exedit_sdk
151 | * Common Library https://github.com/hebiiro/Common-Library
152 |
153 | ## 作成者情報
154 |
155 | * 作成者 - 蛇色 (へびいろ)
156 | * GitHub - https://github.com/hebiiro
157 | * Twitter - https://twitter.com/io_hebiiro
158 |
159 | ## 免責事項
160 |
161 | このプラグインおよび同梱物を使用したことによって生じたすべての障害・損害・不具合等に関しては、私と私の関係者および私の所属するいかなる団体・組織とも、一切の責任を負いません。各自の責任においてご使用ください。
162 |
--------------------------------------------------------------------------------
/UniteWindow.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31515.178
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UniteWindow", "UniteWindow\UniteWindow.vcxproj", "{772BC0B9-7CA2-4EF5-9439-91D4F823156E}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{77E9C1D4-FC85-44BA-981A-77402A637511}"
9 | ProjectSection(SolutionItems) = preProject
10 | CREDITS.md = CREDITS.md
11 | LICENSE = LICENSE
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|x64 = Debug|x64
18 | Debug|x86 = Debug|x86
19 | Release|x64 = Release|x64
20 | Release|x86 = Release|x86
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {772BC0B9-7CA2-4EF5-9439-91D4F823156E}.Debug|x64.ActiveCfg = Debug|x64
24 | {772BC0B9-7CA2-4EF5-9439-91D4F823156E}.Debug|x64.Build.0 = Debug|x64
25 | {772BC0B9-7CA2-4EF5-9439-91D4F823156E}.Debug|x86.ActiveCfg = Debug|Win32
26 | {772BC0B9-7CA2-4EF5-9439-91D4F823156E}.Debug|x86.Build.0 = Debug|Win32
27 | {772BC0B9-7CA2-4EF5-9439-91D4F823156E}.Release|x64.ActiveCfg = Release|x64
28 | {772BC0B9-7CA2-4EF5-9439-91D4F823156E}.Release|x64.Build.0 = Release|x64
29 | {772BC0B9-7CA2-4EF5-9439-91D4F823156E}.Release|x86.ActiveCfg = Release|Win32
30 | {772BC0B9-7CA2-4EF5-9439-91D4F823156E}.Release|x86.Build.0 = Release|Win32
31 | EndGlobalSection
32 | GlobalSection(SolutionProperties) = preSolution
33 | HideSolutionNode = FALSE
34 | EndGlobalSection
35 | GlobalSection(ExtensibilityGlobals) = postSolution
36 | SolutionGuid = {04F73712-35B3-45DC-891D-A4ADC727C31E}
37 | EndGlobalSection
38 | EndGlobal
39 |
--------------------------------------------------------------------------------
/UniteWindow/ConfigDialog.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "ConfigDialog.h"
3 |
4 | //---------------------------------------------------------------------
5 |
6 | int getComboBoxIndexFromWindow(Window* window)
7 | {
8 | if (window == &g_aviutlWindow) return 0;
9 | else if (window == &g_exeditWindow) return 1;
10 | else if (window == &g_settingDialog) return 2;
11 |
12 | return 3;
13 | }
14 |
15 | Window* getWindowFromComboBoxIndex(int i)
16 | {
17 | switch (i)
18 | {
19 | case 0: return &g_aviutlWindow;
20 | case 1: return &g_exeditWindow;
21 | case 2: return &g_settingDialog;
22 | }
23 |
24 | return 0;
25 | }
26 |
27 | int showConfigDialog(HWND hwnd)
28 | {
29 | ConfigDialog dialog(hwnd);
30 |
31 | HWND hwndLayoutMode = ::GetDlgItem(dialog, IDC_LAYOUT_MODE);
32 | ComboBox_AddString(hwndLayoutMode, _T("垂直分割"));
33 | ComboBox_AddString(hwndLayoutMode, _T("水平分割"));
34 | ComboBox_SetCurSel(hwndLayoutMode, g_layoutMode);
35 |
36 | HWND hwndWindow[WindowPos::maxSize] = {};
37 | hwndWindow[WindowPos::topLeft] = ::GetDlgItem(dialog, IDC_WINDOW_TOP_LEFT);
38 | hwndWindow[WindowPos::topRight] = ::GetDlgItem(dialog, IDC_WINDOW_TOP_RIGHT);
39 | hwndWindow[WindowPos::bottomLeft] = ::GetDlgItem(dialog, IDC_WINDOW_BOTTOM_LEFT);
40 | hwndWindow[WindowPos::bottomRight] = ::GetDlgItem(dialog, IDC_WINDOW_BOTTOM_RIGHT);
41 | for (int i = 0; i < WindowPos::maxSize; i++)
42 | {
43 | ComboBox_AddString(hwndWindow[i], _T("AviUtlウィンドウ"));
44 | ComboBox_AddString(hwndWindow[i], _T("拡張編集ウィンドウ"));
45 | ComboBox_AddString(hwndWindow[i], _T("設定ダイアログ"));
46 | ComboBox_AddString(hwndWindow[i], _T("ウィンドウなし"));
47 | ComboBox_SetCurSel(hwndWindow[i], getComboBoxIndexFromWindow(g_windowArray[i]));
48 | }
49 | ::SetDlgItemInt(dialog, IDC_BORDER_VERT_CENTER, g_borders.m_vertCenter, TRUE);
50 | ::SetDlgItemInt(dialog, IDC_BORDER_VERT_LEFT, g_borders.m_vertLeft, TRUE);
51 | ::SetDlgItemInt(dialog, IDC_BORDER_VERT_RIGHT, g_borders.m_vertRight, TRUE);
52 | ::SetDlgItemInt(dialog, IDC_BORDER_HORZ_CENTER, g_borders.m_horzCenter, TRUE);
53 | ::SetDlgItemInt(dialog, IDC_BORDER_HORZ_TOP, g_borders.m_horzTop, TRUE);
54 | ::SetDlgItemInt(dialog, IDC_BORDER_HORZ_BOTTOM, g_borders.m_horzBottom, TRUE);
55 | HWND hwndOrigin[6] = {};
56 | hwndOrigin[0] = ::GetDlgItem(dialog, IDC_BORDER_VERT_CENTER_ORIGIN);
57 | hwndOrigin[1] = ::GetDlgItem(dialog, IDC_BORDER_VERT_LEFT_ORIGIN);
58 | hwndOrigin[2] = ::GetDlgItem(dialog, IDC_BORDER_VERT_RIGHT_ORIGIN);
59 | hwndOrigin[3] = ::GetDlgItem(dialog, IDC_BORDER_HORZ_CENTER_ORIGIN);
60 | hwndOrigin[4] = ::GetDlgItem(dialog, IDC_BORDER_HORZ_TOP_ORIGIN);
61 | hwndOrigin[5] = ::GetDlgItem(dialog, IDC_BORDER_HORZ_BOTTOM_ORIGIN);
62 | for (int i = 0; i < 6; i++)
63 | {
64 | ComboBox_AddString(hwndOrigin[i], _T("左上基点"));
65 | ComboBox_AddString(hwndOrigin[i], _T("右下基点"));
66 | }
67 | ComboBox_SetCurSel(hwndOrigin[0], g_borders.m_vertCenterOrigin);
68 | ComboBox_SetCurSel(hwndOrigin[1], g_borders.m_vertLeftOrigin);
69 | ComboBox_SetCurSel(hwndOrigin[2], g_borders.m_vertRightOrigin);
70 | ComboBox_SetCurSel(hwndOrigin[3], g_borders.m_horzCenterOrigin);
71 | ComboBox_SetCurSel(hwndOrigin[4], g_borders.m_horzTopOrigin);
72 | ComboBox_SetCurSel(hwndOrigin[5], g_borders.m_horzBottomOrigin);
73 | ::SetDlgItemInt(dialog, IDC_FILL_COLOR, g_fillColor, FALSE);
74 | ::SetDlgItemInt(dialog, IDC_BORDER_COLOR, g_borderColor, FALSE);
75 | ::SetDlgItemInt(dialog, IDC_HOT_BORDER_COLOR, g_hotBorderColor, FALSE);
76 | ::SetDlgItemInt(dialog, IDC_ACTIVE_CAPTION_COLOR, g_activeCaptionColor, FALSE);
77 | ::SetDlgItemInt(dialog, IDC_ACTIVE_CAPTION_TEXT_COLOR, g_activeCaptionTextColor, FALSE);
78 | ::SetDlgItemInt(dialog, IDC_INACTIVE_CAPTION_COLOR, g_inactiveCaptionColor, FALSE);
79 | ::SetDlgItemInt(dialog, IDC_INACTIVE_CAPTION_TEXT_COLOR, g_inactiveCaptionTextColor, FALSE);
80 | HWND hwndUseTheme = ::GetDlgItem(dialog, IDC_USE_THEME);
81 | Button_SetCheck(hwndUseTheme, g_useTheme);
82 |
83 | ::EnableWindow(hwnd, FALSE);
84 | int retValue = dialog.doModal();
85 | ::EnableWindow(hwnd, TRUE);
86 | ::SetActiveWindow(hwnd);
87 |
88 | if (IDOK != retValue)
89 | return retValue;
90 |
91 | g_layoutMode = ComboBox_GetCurSel(hwndLayoutMode);
92 | for (int i = 0; i < WindowPos::maxSize; i++)
93 | g_windowArray[i] = getWindowFromComboBoxIndex(ComboBox_GetCurSel(hwndWindow[i]));
94 | g_borders.m_vertCenter = ::GetDlgItemInt(dialog, IDC_BORDER_VERT_CENTER, 0, TRUE);
95 | g_borders.m_vertLeft = ::GetDlgItemInt(dialog, IDC_BORDER_VERT_LEFT, 0, TRUE);
96 | g_borders.m_vertRight = ::GetDlgItemInt(dialog, IDC_BORDER_VERT_RIGHT, 0, TRUE);
97 | g_borders.m_horzCenter = ::GetDlgItemInt(dialog, IDC_BORDER_HORZ_CENTER, 0, TRUE);
98 | g_borders.m_horzTop = ::GetDlgItemInt(dialog, IDC_BORDER_HORZ_TOP, 0, TRUE);
99 | g_borders.m_horzBottom = ::GetDlgItemInt(dialog, IDC_BORDER_HORZ_BOTTOM, 0, TRUE);
100 | g_borders.m_vertCenterOrigin = ComboBox_GetCurSel(hwndOrigin[0]);
101 | g_borders.m_vertLeftOrigin = ComboBox_GetCurSel(hwndOrigin[1]);
102 | g_borders.m_vertRightOrigin = ComboBox_GetCurSel(hwndOrigin[2]);
103 | g_borders.m_horzCenterOrigin = ComboBox_GetCurSel(hwndOrigin[3]);
104 | g_borders.m_horzTopOrigin = ComboBox_GetCurSel(hwndOrigin[4]);
105 | g_borders.m_horzBottomOrigin = ComboBox_GetCurSel(hwndOrigin[5]);
106 | g_fillColor = ::GetDlgItemInt(dialog, IDC_FILL_COLOR, 0, FALSE);
107 | g_borderColor = ::GetDlgItemInt(dialog, IDC_BORDER_COLOR, 0, FALSE);
108 | g_hotBorderColor = ::GetDlgItemInt(dialog, IDC_HOT_BORDER_COLOR, 0, FALSE);
109 | g_activeCaptionColor = ::GetDlgItemInt(dialog, IDC_ACTIVE_CAPTION_COLOR, 0, FALSE);
110 | g_activeCaptionTextColor = ::GetDlgItemInt(dialog, IDC_ACTIVE_CAPTION_TEXT_COLOR, 0, FALSE);
111 | g_inactiveCaptionColor = ::GetDlgItemInt(dialog, IDC_INACTIVE_CAPTION_COLOR, 0, FALSE);
112 | g_inactiveCaptionTextColor = ::GetDlgItemInt(dialog, IDC_INACTIVE_CAPTION_TEXT_COLOR, 0, FALSE);
113 | g_useTheme = Button_GetCheck(hwndUseTheme);
114 |
115 | // レイアウトを再計算する。
116 | recalcLayout();
117 |
118 | // 再描画する。
119 | ::InvalidateRect(hwnd, 0, FALSE);
120 |
121 | return retValue;
122 | }
123 |
124 | //---------------------------------------------------------------------
125 |
126 | ConfigDialog::ConfigDialog(HWND hwnd)
127 | : Dialog(g_instance, MAKEINTRESOURCE(IDD_CONFIG), hwnd)
128 | {
129 | }
130 |
131 | void ConfigDialog::onOK()
132 | {
133 | Dialog::onOK();
134 | }
135 |
136 | void ConfigDialog::onCancel()
137 | {
138 | Dialog::onCancel();
139 | }
140 |
141 | INT_PTR ConfigDialog::onDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
142 | {
143 | switch (message)
144 | {
145 | case WM_COMMAND:
146 | {
147 | UINT id = LOWORD(wParam);
148 |
149 | switch (id)
150 | {
151 | case IDC_FILL_COLOR:
152 | case IDC_BORDER_COLOR:
153 | case IDC_HOT_BORDER_COLOR:
154 | case IDC_ACTIVE_CAPTION_COLOR:
155 | case IDC_ACTIVE_CAPTION_TEXT_COLOR:
156 | case IDC_INACTIVE_CAPTION_COLOR:
157 | case IDC_INACTIVE_CAPTION_TEXT_COLOR:
158 | {
159 | HWND control = (HWND)lParam;
160 |
161 | COLORREF color = ::GetDlgItemInt(hwnd, id, 0, FALSE);
162 |
163 | static COLORREF customColors[16] = {};
164 | CHOOSECOLOR cc { sizeof(cc) };
165 | cc.hwndOwner = hwnd;
166 | cc.lpCustColors = customColors;
167 | cc.rgbResult = color;
168 | cc.Flags = CC_RGBINIT | CC_FULLOPEN;
169 | if (!::ChooseColor(&cc)) return TRUE;
170 |
171 | color = cc.rgbResult;
172 |
173 | ::SetDlgItemInt(hwnd, id, color, FALSE);
174 | ::InvalidateRect(control, 0, FALSE);
175 |
176 | return TRUE;
177 | }
178 | }
179 |
180 | break;
181 | }
182 | case WM_DRAWITEM:
183 | {
184 | UINT id = wParam;
185 |
186 | switch (id)
187 | {
188 | case IDC_FILL_COLOR:
189 | case IDC_BORDER_COLOR:
190 | case IDC_HOT_BORDER_COLOR:
191 | case IDC_ACTIVE_CAPTION_COLOR:
192 | case IDC_ACTIVE_CAPTION_TEXT_COLOR:
193 | case IDC_INACTIVE_CAPTION_COLOR:
194 | case IDC_INACTIVE_CAPTION_TEXT_COLOR:
195 | {
196 | DRAWITEMSTRUCT* dis = (DRAWITEMSTRUCT*)lParam;
197 |
198 | COLORREF color = ::GetDlgItemInt(hwnd, id, 0, FALSE);
199 |
200 | HBRUSH brush = ::CreateSolidBrush(color);
201 | FillRect(dis->hDC, &dis->rcItem, brush);
202 | ::DeleteObject(brush);
203 |
204 | return TRUE;
205 | }
206 | }
207 |
208 | break;
209 | }
210 | }
211 |
212 | return Dialog::onDlgProc(hwnd, message, wParam, lParam);
213 | }
214 |
215 | //---------------------------------------------------------------------
216 |
--------------------------------------------------------------------------------
/UniteWindow/ConfigDialog.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Resource.h"
4 | #include "UniteWindow.h"
5 |
6 | //---------------------------------------------------------------------
7 |
8 | int showConfigDialog(HWND hwnd);
9 |
10 | //---------------------------------------------------------------------
11 |
12 | class ConfigDialog : public Dialog
13 | {
14 | public:
15 | ConfigDialog(HWND hwnd);
16 |
17 | virtual void onOK();
18 | virtual void onCancel();
19 | virtual INT_PTR onDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
20 | };
21 |
22 | //---------------------------------------------------------------------
23 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "UniteWindow.h"
3 | #include "ConfigDialog.h"
4 |
5 | //---------------------------------------------------------------------
6 |
7 | // デバッグ用コールバック関数。デバッグメッセージを出力する
8 | void ___outputLog(LPCTSTR text, LPCTSTR output)
9 | {
10 | ::OutputDebugString(output);
11 | }
12 |
13 | //---------------------------------------------------------------------
14 |
15 | AviUtlInternal g_auin;
16 | HINSTANCE g_instance = 0;
17 | HWND g_singleWindow = 0;
18 | HTHEME g_theme = 0;
19 | WNDPROC g_aviutlWindowProc = 0;
20 | WNDPROC g_exeditWindowProc = 0;
21 |
22 | AviUtlWindow g_aviutlWindow;
23 | ExEditWindow g_exeditWindow;
24 | SettingDialog g_settingDialog;
25 |
26 | Window* g_windowArray[WindowPos::maxSize] =
27 | {
28 | &g_aviutlWindow,
29 | &g_settingDialog,
30 | &g_exeditWindow,
31 | 0,
32 | };
33 |
34 | int g_layoutMode = LayoutMode::horzSplit;
35 | Borders g_borders = {};
36 | int g_hotBorder = HotBorder::none;
37 |
38 | int g_borderWidth = 8;
39 | int g_captionHeight = 24;
40 | int g_borderSnapRange = 8;
41 | COLORREF g_fillColor = RGB(0x99, 0x99, 0x99);
42 | COLORREF g_borderColor = RGB(0xcc, 0xcc, 0xcc);
43 | COLORREF g_hotBorderColor = RGB(0x00, 0x00, 0x00);
44 | COLORREF g_activeCaptionColor = ::GetSysColor(COLOR_HIGHLIGHT);
45 | COLORREF g_activeCaptionTextColor = RGB(0xff, 0xff, 0xff);
46 | COLORREF g_inactiveCaptionColor = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
47 | COLORREF g_inactiveCaptionTextColor = RGB(0x00, 0x00, 0x00);
48 | BOOL g_useTheme = FALSE;
49 |
50 | RECT g_captionRect[WindowPos::maxSize];
51 |
52 | int g_offset = 0; // ドラッグ処理に使う。
53 |
54 | //---------------------------------------------------------------------
55 |
56 | void initHook()
57 | {
58 | MY_TRACE(_T("initHook()\n"));
59 |
60 | HMODULE user32 = ::GetModuleHandle(_T("user32.dll"));
61 | true_CreateWindowExA = (Type_CreateWindowExA)::GetProcAddress(user32, "CreateWindowExA");
62 |
63 | DetourTransactionBegin();
64 | DetourUpdateThread(::GetCurrentThread());
65 |
66 | ATTACH_HOOK_PROC(CreateWindowExA);
67 | ATTACH_HOOK_PROC(GetMenu);
68 | ATTACH_HOOK_PROC(SetMenu);
69 | ATTACH_HOOK_PROC(DrawMenuBar);
70 | ATTACH_HOOK_PROC(FindWindowExA);
71 | ATTACH_HOOK_PROC(FindWindowW);
72 | ATTACH_HOOK_PROC(GetWindow);
73 | ATTACH_HOOK_PROC(EnumThreadWindows);
74 | ATTACH_HOOK_PROC(EnumWindows);
75 |
76 | if (DetourTransactionCommit() == NO_ERROR)
77 | {
78 | MY_TRACE(_T("API フックに成功しました\n"));
79 | }
80 | else
81 | {
82 | MY_TRACE(_T("API フックに失敗しました\n"));
83 | }
84 | }
85 |
86 | void termHook()
87 | {
88 | MY_TRACE(_T("termHook()\n"));
89 | }
90 |
91 | //---------------------------------------------------------------------
92 |
93 | HWND createSingleWindow()
94 | {
95 | MY_TRACE(_T("createSingleWindow()\n"));
96 |
97 | // 土台となるシングルウィンドウを作成する。
98 |
99 | WNDCLASS wc = {};
100 | wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
101 | wc.hCursor = ::LoadCursor(0, IDC_ARROW);
102 | wc.lpfnWndProc = singleWindowProc;
103 | wc.hInstance = g_instance;
104 | wc.lpszClassName = _T("AviUtl"); // クラス名を AviUtl に偽装する。「AoiSupport」用。
105 | ::RegisterClass(&wc);
106 |
107 | HWND hwnd = ::CreateWindowEx(
108 | 0,
109 | _T("AviUtl"),
110 | _T("UniteWindow"),
111 | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME |
112 | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
113 | CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
114 | 0, 0, g_instance, 0);
115 |
116 | // ここでレイアウトの初期値を算出しておく。
117 |
118 | RECT rc; ::GetClientRect(hwnd, &rc);
119 | int cx = (rc.left + rc.right) / 2;
120 | int cy = (rc.top + rc.bottom) / 2;
121 |
122 | g_layoutMode = LayoutMode::horzSplit;
123 |
124 | g_borders.m_vertCenter = cx;
125 | g_borders.m_vertLeft = cy;
126 | g_borders.m_vertRight = cy;
127 | g_borders.m_vertCenterOrigin = Origin::bottomRight;
128 | g_borders.m_vertLeftOrigin = Origin::bottomRight;
129 | g_borders.m_vertRightOrigin = Origin::bottomRight;
130 |
131 | g_borders.m_horzCenter = cy;
132 | g_borders.m_horzTop = cx;
133 | g_borders.m_horzBottom = cx;
134 | g_borders.m_horzCenterOrigin = Origin::bottomRight;
135 | g_borders.m_horzTopOrigin = Origin::bottomRight;
136 | g_borders.m_horzBottomOrigin = Origin::bottomRight;
137 |
138 | return hwnd;
139 | }
140 |
141 | void normalizeLayoutVertSplit()
142 | {
143 | MY_TRACE(_T("normalizeLayoutVertSplit()\n"));
144 |
145 | RECT rc; ::GetClientRect(g_singleWindow, &rc);
146 |
147 | g_borders.m_vertCenter = max(g_borders.m_vertCenter, rc.left);
148 | g_borders.m_vertCenter = min(g_borders.m_vertCenter, rc.right - g_borderWidth);
149 |
150 | g_borders.m_vertLeft = max(g_borders.m_vertLeft, rc.top);
151 | g_borders.m_vertLeft = min(g_borders.m_vertLeft, rc.bottom - g_borderWidth);
152 |
153 | g_borders.m_vertRight = max(g_borders.m_vertRight, rc.top);
154 | g_borders.m_vertRight = min(g_borders.m_vertRight, rc.bottom - g_borderWidth);
155 | }
156 |
157 | void normalizeLayoutHorzSplit()
158 | {
159 | MY_TRACE(_T("normalizeLayoutHorzSplit()\n"));
160 |
161 | RECT rc; ::GetClientRect(g_singleWindow, &rc);
162 |
163 | g_borders.m_horzCenter = max(g_borders.m_horzCenter, rc.top);
164 | g_borders.m_horzCenter = min(g_borders.m_horzCenter, rc.bottom - g_borderWidth);
165 |
166 | g_borders.m_horzTop = max(g_borders.m_horzTop, rc.left);
167 | g_borders.m_horzTop = min(g_borders.m_horzTop, rc.right - g_borderWidth);
168 |
169 | g_borders.m_horzBottom = max(g_borders.m_horzBottom, rc.left);
170 | g_borders.m_horzBottom = min(g_borders.m_horzBottom, rc.right - g_borderWidth);
171 | }
172 |
173 | void normalizeLayout()
174 | {
175 | MY_TRACE(_T("normalizeLayout()\n"));
176 |
177 | switch (g_layoutMode)
178 | {
179 | case LayoutMode::vertSplit:
180 | {
181 | normalizeLayoutVertSplit();
182 |
183 | break;
184 | }
185 | case LayoutMode::horzSplit:
186 | {
187 | normalizeLayoutHorzSplit();
188 |
189 | break;
190 | }
191 | }
192 | }
193 |
194 | int borderToX(LPCRECT rcClient, int border, int borderOrigin)
195 | {
196 | switch (borderOrigin)
197 | {
198 | case Origin::topLeft:
199 | {
200 | return border;
201 | }
202 | case Origin::bottomRight:
203 | {
204 | return rcClient->right - border - g_borderWidth;
205 | }
206 | }
207 |
208 | return 0;
209 | }
210 |
211 | int borderToY(LPCRECT rcClient, int border, int borderOrigin)
212 | {
213 | switch (borderOrigin)
214 | {
215 | case Origin::topLeft:
216 | {
217 | return border;
218 | }
219 | case Origin::bottomRight:
220 | {
221 | return rcClient->bottom - border - g_borderWidth;
222 | }
223 | }
224 |
225 | return 0;
226 | }
227 |
228 | int xToBorder(LPCRECT rcClient, int x, int borderOrigin)
229 | {
230 | switch (borderOrigin)
231 | {
232 | case Origin::topLeft:
233 | {
234 | return x;
235 | }
236 | case Origin::bottomRight:
237 | {
238 | return rcClient->right - x - g_borderWidth;
239 | }
240 | }
241 |
242 | return 0;
243 | }
244 |
245 | int yToBorder(LPCRECT rcClient, int y, int borderOrigin)
246 | {
247 | switch (borderOrigin)
248 | {
249 | case Origin::topLeft:
250 | {
251 | return y;
252 | }
253 | case Origin::bottomRight:
254 | {
255 | return rcClient->bottom - y - g_borderWidth;
256 | }
257 | }
258 |
259 | return 0;
260 | }
261 |
262 | inline RECT getCaptionRectFromContainerRect(const RECT& rcContainer) {
263 | return RECT
264 | {
265 | rcContainer.left,
266 | rcContainer.top - g_captionHeight,
267 | rcContainer.right,
268 | rcContainer.top,
269 | };
270 | }
271 |
272 | void recalcLayoutVertSplit()
273 | {
274 | MY_TRACE(_T("recalcLayoutVertSplit()\n"));
275 |
276 | RECT rcClient; ::GetClientRect(g_singleWindow, &rcClient);
277 | int borderVertCenter = borderToX(&rcClient, g_borders.m_vertCenter, g_borders.m_vertCenterOrigin);
278 | int borderVertLeft = borderToY(&rcClient, g_borders.m_vertLeft, g_borders.m_vertLeftOrigin);
279 | int borderVertRight = borderToY(&rcClient, g_borders.m_vertRight, g_borders.m_vertRightOrigin);
280 |
281 | if (g_windowArray[WindowPos::topLeft])
282 | {
283 | RECT rcContainer =
284 | {
285 | rcClient.left,
286 | rcClient.top + g_captionHeight,
287 | borderVertCenter,
288 | borderVertLeft,
289 | };
290 |
291 | g_windowArray[WindowPos::topLeft]->resize(&rcContainer);
292 | g_captionRect[WindowPos::topLeft] = getCaptionRectFromContainerRect(rcContainer);
293 | }
294 |
295 | if (g_windowArray[WindowPos::topRight])
296 | {
297 | RECT rcContainer =
298 | {
299 | borderVertCenter + g_borderWidth,
300 | rcClient.top + g_captionHeight,
301 | rcClient.right,
302 | borderVertRight,
303 | };
304 |
305 | g_windowArray[WindowPos::topRight]->resize(&rcContainer);
306 | g_captionRect[WindowPos::topRight] = getCaptionRectFromContainerRect(rcContainer);
307 | }
308 |
309 | if (g_windowArray[WindowPos::bottomLeft])
310 | {
311 | RECT rcContainer =
312 | {
313 | rcClient.left,
314 | borderVertLeft + g_borderWidth + g_captionHeight,
315 | borderVertCenter,
316 | rcClient.bottom,
317 | };
318 |
319 | g_windowArray[WindowPos::bottomLeft]->resize(&rcContainer);
320 | g_captionRect[WindowPos::bottomLeft] = getCaptionRectFromContainerRect(rcContainer);
321 | }
322 |
323 | if (g_windowArray[WindowPos::bottomRight])
324 | {
325 | RECT rcContainer =
326 | {
327 | borderVertCenter + g_borderWidth,
328 | borderVertRight + g_borderWidth + g_captionHeight,
329 | rcClient.right,
330 | rcClient.bottom,
331 | };
332 |
333 | g_windowArray[WindowPos::bottomRight]->resize(&rcContainer);
334 | g_captionRect[WindowPos::bottomRight] = getCaptionRectFromContainerRect(rcContainer);
335 | }
336 | }
337 |
338 | void recalcLayoutHorzSplit()
339 | {
340 | MY_TRACE(_T("recalcLayoutHorzSplit()\n"));
341 |
342 | RECT rcClient; ::GetClientRect(g_singleWindow, &rcClient);
343 | int borderHorzCenter = borderToY(&rcClient, g_borders.m_horzCenter, g_borders.m_horzCenterOrigin);
344 | int borderHorzTop = borderToX(&rcClient, g_borders.m_horzTop, g_borders.m_horzTopOrigin);
345 | int borderHorzBottom = borderToX(&rcClient, g_borders.m_horzBottom, g_borders.m_horzBottomOrigin);
346 |
347 | if (g_windowArray[WindowPos::topLeft])
348 | {
349 | RECT rcContainer =
350 | {
351 | rcClient.left,
352 | rcClient.top + g_captionHeight,
353 | borderHorzTop,
354 | borderHorzCenter,
355 | };
356 |
357 | g_windowArray[WindowPos::topLeft]->resize(&rcContainer);
358 | g_captionRect[WindowPos::topLeft] = getCaptionRectFromContainerRect(rcContainer);
359 | }
360 |
361 | if (g_windowArray[WindowPos::topRight])
362 | {
363 | RECT rcContainer =
364 | {
365 | borderHorzTop + g_borderWidth,
366 | rcClient.top + g_captionHeight,
367 | rcClient.right,
368 | borderHorzCenter,
369 | };
370 |
371 | g_windowArray[WindowPos::topRight]->resize(&rcContainer);
372 | g_captionRect[WindowPos::topRight] = getCaptionRectFromContainerRect(rcContainer);
373 | }
374 |
375 | if (g_windowArray[WindowPos::bottomLeft])
376 | {
377 | RECT rcContainer =
378 | {
379 | rcClient.left,
380 | borderHorzCenter + g_borderWidth + g_captionHeight,
381 | borderHorzBottom,
382 | rcClient.bottom,
383 | };
384 |
385 | g_windowArray[WindowPos::bottomLeft]->resize(&rcContainer);
386 | g_captionRect[WindowPos::bottomLeft] = getCaptionRectFromContainerRect(rcContainer);
387 | }
388 |
389 | if (g_windowArray[WindowPos::bottomRight])
390 | {
391 | RECT rcContainer =
392 | {
393 | borderHorzBottom + g_borderWidth,
394 | borderHorzCenter + g_borderWidth + g_captionHeight,
395 | rcClient.right,
396 | rcClient.bottom,
397 | };
398 |
399 | g_windowArray[WindowPos::bottomRight]->resize(&rcContainer);
400 | g_captionRect[WindowPos::bottomRight] = getCaptionRectFromContainerRect(rcContainer);
401 | }
402 | }
403 |
404 | void recalcLayout()
405 | {
406 | MY_TRACE(_T("recalcLayout()\n"));
407 |
408 | if (::IsIconic(g_singleWindow))
409 | return;
410 |
411 | switch (g_layoutMode)
412 | {
413 | case LayoutMode::vertSplit:
414 | {
415 | normalizeLayoutVertSplit();
416 | recalcLayoutVertSplit();
417 |
418 | break;
419 | }
420 | case LayoutMode::horzSplit:
421 | {
422 | normalizeLayoutHorzSplit();
423 | recalcLayoutHorzSplit();
424 |
425 | break;
426 | }
427 | }
428 | }
429 |
430 | int hitTestVertSplit(POINT point)
431 | {
432 | RECT rcClient; ::GetClientRect(g_singleWindow, &rcClient);
433 | int borderVertCenter = borderToX(&rcClient, g_borders.m_vertCenter, g_borders.m_vertCenterOrigin);
434 | int borderVertLeft = borderToY(&rcClient, g_borders.m_vertLeft, g_borders.m_vertLeftOrigin);
435 | int borderVertRight = borderToY(&rcClient, g_borders.m_vertRight, g_borders.m_vertRightOrigin);
436 |
437 | if (point.x < borderVertCenter)
438 | {
439 | if (point.y >= borderVertLeft && point.y < borderVertLeft + g_borderWidth)
440 | return HotBorder::vertLeft;
441 | }
442 | else if (point.x < borderVertCenter + g_borderWidth)
443 | {
444 | return HotBorder::vertCenter;
445 | }
446 | else
447 | {
448 | if (point.y >= borderVertRight && point.y < borderVertRight + g_borderWidth)
449 | return HotBorder::vertRight;
450 | }
451 |
452 | return HotBorder::none;
453 | }
454 |
455 | int hitTestHorzSplit(POINT point)
456 | {
457 | RECT rcClient; ::GetClientRect(g_singleWindow, &rcClient);
458 | int borderHorzCenter = borderToY(&rcClient, g_borders.m_horzCenter, g_borders.m_horzCenterOrigin);
459 | int borderHorzTop = borderToX(&rcClient, g_borders.m_horzTop, g_borders.m_horzTopOrigin);
460 | int borderHorzBottom = borderToX(&rcClient, g_borders.m_horzBottom, g_borders.m_horzBottomOrigin);
461 |
462 | if (point.y < borderHorzCenter)
463 | {
464 | if (point.x >= borderHorzTop && point.x < borderHorzTop + g_borderWidth)
465 | return HotBorder::horzTop;
466 | }
467 | else if (point.y < borderHorzCenter + g_borderWidth)
468 | {
469 | return HotBorder::horzCenter;
470 | }
471 | else
472 | {
473 | if (point.x >= borderHorzBottom && point.x < borderHorzBottom + g_borderWidth)
474 | return HotBorder::horzBottom;
475 | }
476 |
477 | return HotBorder::none;
478 | }
479 |
480 | int hitTest(POINT point)
481 | {
482 | switch (g_layoutMode)
483 | {
484 | case LayoutMode::vertSplit: return hitTestVertSplit(point);
485 | case LayoutMode::horzSplit: return hitTestHorzSplit(point);
486 | }
487 |
488 | return HotBorder::none;
489 | }
490 |
491 | int getOffset(POINT point)
492 | {
493 | RECT rcClient; ::GetClientRect(g_singleWindow, &rcClient);
494 |
495 | switch (g_hotBorder)
496 | {
497 | case HotBorder::horzCenter: return g_borders.m_horzCenter - yToBorder(&rcClient, point.y, g_borders.m_horzCenterOrigin);
498 | case HotBorder::horzTop: return g_borders.m_horzTop - xToBorder(&rcClient, point.x, g_borders.m_horzTopOrigin);
499 | case HotBorder::horzBottom: return g_borders.m_horzBottom - xToBorder(&rcClient, point.x, g_borders.m_horzBottomOrigin);
500 | case HotBorder::vertCenter: return g_borders.m_vertCenter - xToBorder(&rcClient, point.x, g_borders.m_vertCenterOrigin);
501 | case HotBorder::vertLeft: return g_borders.m_vertLeft - yToBorder(&rcClient, point.y, g_borders.m_vertLeftOrigin);
502 | case HotBorder::vertRight: return g_borders.m_vertRight - yToBorder(&rcClient, point.y, g_borders.m_vertRightOrigin);
503 | }
504 |
505 | return 0;
506 | }
507 |
508 | void dragBorder(POINT point)
509 | {
510 | RECT rcClient; ::GetClientRect(g_singleWindow, &rcClient);
511 |
512 | switch (g_hotBorder)
513 | {
514 | case HotBorder::horzCenter:
515 | {
516 | g_borders.m_horzCenter = yToBorder(&rcClient, point.y, g_borders.m_horzCenterOrigin) + g_offset;
517 | break;
518 | }
519 | case HotBorder::horzTop:
520 | {
521 | g_borders.m_horzTop = xToBorder(&rcClient, point.x, g_borders.m_horzTopOrigin) + g_offset;
522 | if (abs(g_borders.m_horzTop - g_borders.m_horzBottom) < g_borderSnapRange)
523 | g_borders.m_horzTop = g_borders.m_horzBottom;
524 | break;
525 | }
526 | case HotBorder::horzBottom:
527 | {
528 | g_borders.m_horzBottom = xToBorder(&rcClient, point.x, g_borders.m_horzBottomOrigin) + g_offset;
529 | if (abs(g_borders.m_horzBottom - g_borders.m_horzTop) < g_borderSnapRange)
530 | g_borders.m_horzBottom = g_borders.m_horzTop;
531 | break;
532 | }
533 | case HotBorder::vertCenter:
534 | {
535 | g_borders.m_vertCenter = xToBorder(&rcClient, point.x, g_borders.m_vertCenterOrigin) + g_offset;
536 | break;
537 | }
538 | case HotBorder::vertLeft:
539 | {
540 | g_borders.m_vertLeft = yToBorder(&rcClient, point.y, g_borders.m_vertLeftOrigin) + g_offset;
541 | if (abs(g_borders.m_vertLeft - g_borders.m_vertRight) < g_borderSnapRange)
542 | g_borders.m_vertLeft = g_borders.m_vertRight;
543 | break;
544 | }
545 | case HotBorder::vertRight:
546 | {
547 | g_borders.m_vertRight = yToBorder(&rcClient, point.y, g_borders.m_vertRightOrigin) + g_offset;
548 | if (abs(g_borders.m_vertRight - g_borders.m_vertLeft) < g_borderSnapRange)
549 | g_borders.m_vertRight = g_borders.m_vertLeft;
550 | break;
551 | }
552 | }
553 |
554 | if (::GetKeyState(VK_SHIFT) < 0)
555 | {
556 | switch (g_hotBorder)
557 | {
558 | case HotBorder::horzTop: g_borders.m_horzBottom = g_borders.m_horzTop; break;
559 | case HotBorder::horzBottom: g_borders.m_horzTop = g_borders.m_horzBottom; break;
560 | case HotBorder::vertLeft: g_borders.m_vertRight = g_borders.m_vertLeft; break;
561 | case HotBorder::vertRight: g_borders.m_vertLeft = g_borders.m_vertRight; break;
562 | }
563 | }
564 | }
565 |
566 | BOOL getBorderRect(LPRECT rc, int border)
567 | {
568 | RECT rcClient; ::GetClientRect(g_singleWindow, &rcClient);
569 | int borderVertCenter = borderToX(&rcClient, g_borders.m_vertCenter, g_borders.m_vertCenterOrigin);
570 | int borderVertLeft = borderToY(&rcClient, g_borders.m_vertLeft, g_borders.m_vertLeftOrigin);
571 | int borderVertRight = borderToY(&rcClient, g_borders.m_vertRight, g_borders.m_vertRightOrigin);
572 | int borderHorzCenter = borderToY(&rcClient, g_borders.m_horzCenter, g_borders.m_horzCenterOrigin);
573 | int borderHorzTop = borderToX(&rcClient, g_borders.m_horzTop, g_borders.m_horzTopOrigin);
574 | int borderHorzBottom = borderToX(&rcClient, g_borders.m_horzBottom, g_borders.m_horzBottomOrigin);
575 |
576 | switch (border)
577 | {
578 | case HotBorder::vertCenter:
579 | {
580 | rc->left = borderVertCenter;
581 | rc->top = rcClient.top;
582 | rc->right = borderVertCenter + g_borderWidth;
583 | rc->bottom = rcClient.bottom;
584 |
585 | return TRUE;
586 | }
587 | case HotBorder::vertLeft:
588 | {
589 | rc->left = rcClient.left;
590 | rc->top = borderVertLeft;
591 | rc->right = borderVertCenter;
592 | rc->bottom = borderVertLeft + g_borderWidth;
593 |
594 | return TRUE;
595 | }
596 | case HotBorder::vertRight:
597 | {
598 | rc->left = borderVertCenter + g_borderWidth;
599 | rc->top = borderVertRight;
600 | rc->right = rcClient.right;
601 | rc->bottom = borderVertRight + g_borderWidth;
602 |
603 | return TRUE;
604 | }
605 | case HotBorder::horzCenter:
606 | {
607 | rc->left = rcClient.left;
608 | rc->top = borderHorzCenter;
609 | rc->right = rcClient.right;
610 | rc->bottom = borderHorzCenter + g_borderWidth;
611 |
612 | return TRUE;
613 | }
614 | case HotBorder::horzTop:
615 | {
616 | rc->left = borderHorzTop;
617 | rc->top = rcClient.top;
618 | rc->right = borderHorzTop + g_borderWidth;
619 | rc->bottom = borderHorzCenter;
620 |
621 | return TRUE;
622 | }
623 | case HotBorder::horzBottom:
624 | {
625 | rc->left = borderHorzBottom;
626 | rc->top = borderHorzCenter + g_borderWidth;
627 | rc->right = borderHorzBottom + g_borderWidth;
628 | rc->bottom = rcClient.bottom;
629 |
630 | return TRUE;
631 | }
632 | }
633 |
634 | return FALSE;
635 | }
636 |
637 | void drawCaption(HDC dc, HWND hwnd, Window* window)
638 | {
639 | // コンテナウィンドウの矩形を取得する。
640 | RECT rc; ::GetWindowRect(window->m_hwndContainer, &rc);
641 |
642 | if ((rc.bottom - rc.top) <= 0)
643 | return; // ウィンドウの高さが小さすぎる場合は何もしない。
644 |
645 | // コンテナウィンドウの上隣にあるキャプション矩形を取得する。
646 | ::MapWindowPoints(0, hwnd, (POINT*)&rc, 2);
647 | rc.bottom = rc.top;
648 | rc.top = rc.top - g_captionHeight;
649 |
650 | // ウィンドウテキストを取得する。
651 | WCHAR text[MAX_PATH] = {};
652 | ::GetWindowTextW(window->m_hwnd, text, MAX_PATH);
653 |
654 | if (g_useTheme)
655 | {
656 | // ウィンドウの状態から stateId を取得する。
657 | int stateId = CS_ACTIVE;
658 | if (::GetFocus() != window->m_hwnd) stateId = CS_INACTIVE;
659 | if (!::IsWindowEnabled(window->m_hwnd)) stateId = CS_DISABLED;
660 |
661 | // テーマ API を使用してタイトルを描画する。
662 | ::DrawThemeBackground(g_theme, dc, WP_CAPTION, stateId, &rc, 0);
663 | ::DrawThemeText(g_theme, dc, WP_CAPTION, stateId,
664 | text, ::lstrlenW(text), DT_CENTER | DT_VCENTER | DT_SINGLELINE, 0, &rc);
665 | }
666 | else
667 | {
668 | COLORREF captionColor = g_activeCaptionColor;
669 | COLORREF captionTextColor = g_activeCaptionTextColor;
670 |
671 | if (::GetFocus() != window->m_hwnd)
672 | {
673 | captionColor = g_inactiveCaptionColor;
674 | captionTextColor = g_inactiveCaptionTextColor;
675 | }
676 |
677 | HBRUSH brush = ::CreateSolidBrush(captionColor);
678 | ::FillRect(dc, &rc, brush);
679 | ::DeleteObject(brush);
680 |
681 | int bkMode = ::SetBkMode(dc, TRANSPARENT);
682 | COLORREF textColor = ::SetTextColor(dc, captionTextColor);
683 | ::DrawTextW(dc, text, ::lstrlenW(text), &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
684 | ::SetTextColor(dc, textColor);
685 | ::SetBkMode(dc, bkMode);
686 | }
687 | }
688 |
689 | //---------------------------------------------------------------------
690 |
691 | BOOL importLayout(HWND hwnd)
692 | {
693 | // ファイル選択ダイアログを表示してファイル名を取得する。
694 |
695 | WCHAR fileName[MAX_PATH] = {};
696 |
697 | WCHAR folderName[MAX_PATH] = {};
698 | ::GetModuleFileNameW(g_instance, folderName, MAX_PATH);
699 | ::PathRemoveExtensionW(folderName);
700 |
701 | OPENFILENAMEW ofn = { sizeof(ofn) };
702 | ofn.hwndOwner = hwnd;
703 | ofn.Flags = OFN_FILEMUSTEXIST;
704 | ofn.lpstrTitle = L"レイアウトのインポート";
705 | ofn.lpstrInitialDir = folderName;
706 | ofn.lpstrFile = fileName;
707 | ofn.nMaxFile = MAX_PATH;
708 | ofn.lpstrFilter = L"レイアウトファイル (*.xml)\0*.xml\0" "すべてのファイル (*.*)\0*.*\0";
709 | ofn.lpstrDefExt = L"xml";
710 |
711 | if (!::GetOpenFileNameW(&ofn))
712 | return FALSE;
713 |
714 | // レイアウトファイルをインポートする。
715 | loadConfig(fileName, TRUE);
716 |
717 | // レイアウトを再計算する。
718 | recalcLayout();
719 |
720 | // 再描画する。
721 | ::InvalidateRect(hwnd, 0, FALSE);
722 |
723 | return TRUE;
724 | }
725 |
726 | BOOL exportLayout(HWND hwnd)
727 | {
728 | // ファイル選択ダイアログを表示してファイル名を取得する。
729 |
730 | WCHAR fileName[MAX_PATH] = {};
731 |
732 | WCHAR folderName[MAX_PATH] = {};
733 | ::GetModuleFileNameW(g_instance, folderName, MAX_PATH);
734 | ::PathRemoveExtensionW(folderName);
735 |
736 | OPENFILENAMEW ofn = { sizeof(ofn) };
737 | ofn.hwndOwner = hwnd;
738 | ofn.Flags = OFN_OVERWRITEPROMPT;
739 | ofn.lpstrTitle = L"レイアウトのエクスポート";
740 | ofn.lpstrInitialDir = folderName;
741 | ofn.lpstrFile = fileName;
742 | ofn.nMaxFile = MAX_PATH;
743 | ofn.lpstrFilter = L"レイアウトファイル (*.xml)\0*.xml\0" "すべてのファイル (*.*)\0*.*\0";
744 | ofn.lpstrDefExt = L"xml";
745 |
746 | if (!::GetSaveFileNameW(&ofn))
747 | return FALSE;
748 |
749 | // レイアウトファイルをエクスポートする。
750 | saveConfig(fileName, TRUE);
751 |
752 | return TRUE;
753 | }
754 |
755 | LRESULT CALLBACK singleWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
756 | {
757 | switch (message)
758 | {
759 | case WM_COMMAND:
760 | {
761 | MY_TRACE(_T("singleWindowProc(WM_COMMAND)\n"));
762 |
763 | return ::SendMessage(g_aviutlWindow.m_hwnd, message, wParam, lParam);
764 | }
765 | case WM_SYSCOMMAND:
766 | {
767 | MY_TRACE(_T("singleWindowProc(WM_SYSCOMMAND)\n"));
768 |
769 | switch (wParam)
770 | {
771 | case CommandID::ShowConfigDialog:
772 | {
773 | // UniteWindow の設定ダイアログを開く。
774 | showConfigDialog(hwnd);
775 |
776 | break;
777 | }
778 | case CommandID::ImportLayout:
779 | {
780 | // レイアウトファイルをインポートする。
781 | importLayout(hwnd);
782 |
783 | break;
784 | }
785 | case CommandID::ExportLayout:
786 | {
787 | // レイアウトファイルをエクスポートする。
788 | exportLayout(hwnd);
789 |
790 | break;
791 | }
792 | }
793 |
794 | break;
795 | }
796 | case WM_CREATE:
797 | {
798 | MY_TRACE(_T("singleWindowProc(WM_CREATE)\n"));
799 |
800 | g_theme = ::OpenThemeData(hwnd, VSCLASS_WINDOW);
801 | MY_TRACE_HEX(g_theme);
802 |
803 | HMENU menu = ::GetSystemMenu(hwnd, FALSE);
804 | ::InsertMenu(menu, 0, MF_BYPOSITION | MF_STRING, CommandID::ImportLayout, _T("レイアウトのインポート"));
805 | ::InsertMenu(menu, 1, MF_BYPOSITION | MF_STRING, CommandID::ExportLayout, _T("レイアウトのエクスポート"));
806 | ::InsertMenu(menu, 2, MF_BYPOSITION | MF_STRING, CommandID::ShowConfigDialog, _T("UniteWindowの設定"));
807 | ::InsertMenu(menu, 3, MF_BYPOSITION | MF_SEPARATOR, 0, 0);
808 |
809 | break;
810 | }
811 | case WM_DESTROY:
812 | {
813 | MY_TRACE(_T("singleWindowProc(WM_DESTROY)\n"));
814 |
815 | ::CloseThemeData(g_theme), g_theme = 0;
816 |
817 | break;
818 | }
819 | case WM_CLOSE:
820 | {
821 | MY_TRACE(_T("singleWindowProc(WM_CLOSE)\n"));
822 |
823 | return ::SendMessage(g_aviutlWindow.m_hwnd, message, wParam, lParam);
824 | }
825 | case WM_SETFOCUS:
826 | {
827 | MY_TRACE(_T("singleWindowProc(WM_SETFOCUS)\n"));
828 |
829 | ::SetFocus(g_aviutlWindow.m_hwnd);
830 |
831 | break;
832 | }
833 | case WM_PAINT:
834 | {
835 | PAINTSTRUCT ps;
836 | HDC dc = ::BeginPaint(hwnd, &ps);
837 | RECT rc = ps.rcPaint;
838 |
839 | BP_PAINTPARAMS pp = { sizeof(pp) };
840 | HDC mdc = 0;
841 | HPAINTBUFFER pb = ::BeginBufferedPaint(dc, &rc, BPBF_COMPATIBLEBITMAP, &pp, &mdc);
842 |
843 | if (pb)
844 | {
845 | HDC dc = mdc;
846 |
847 | {
848 | // 背景を塗りつぶす。
849 |
850 | HBRUSH brush = ::CreateSolidBrush(g_fillColor);
851 | FillRect(dc, &rc, brush);
852 | ::DeleteObject(brush);
853 | }
854 |
855 | if (g_useTheme)
856 | {
857 | // ボーダーを描画する。
858 |
859 | int partId = WP_BORDER;
860 | int stateId = CS_INACTIVE;
861 |
862 | int firstBorder = (g_layoutMode == LayoutMode::vertSplit) ? HotBorder::vertCenter : HotBorder::horzCenter;
863 | for (int i = 0; i < 3; i++)
864 | {
865 | int border = firstBorder + i;
866 | if (border == g_hotBorder) continue;
867 | RECT rcBorder;
868 | if (getBorderRect(&rcBorder, border))
869 | {
870 | // テーマ API を使用してボーダーを描画する。
871 | ::DrawThemeBackground(g_theme, dc, partId, stateId, &rcBorder, 0);
872 | }
873 | }
874 | }
875 | else
876 | {
877 | // ボーダーを描画する。
878 |
879 | HBRUSH brush = ::CreateSolidBrush(g_borderColor);
880 |
881 | int firstBorder = (g_layoutMode == LayoutMode::vertSplit) ? HotBorder::vertCenter : HotBorder::horzCenter;
882 | for (int i = 0; i < 3; i++)
883 | {
884 | int border = firstBorder + i;
885 | if (border == g_hotBorder) continue;
886 | RECT rcBorder;
887 | if (getBorderRect(&rcBorder, border))
888 | ::FillRect(dc, &rcBorder, brush);
889 | }
890 |
891 | ::DeleteObject(brush);
892 | }
893 |
894 | if (g_useTheme)
895 | {
896 | // ホットボーダーを描画する。
897 |
898 | int partId = WP_BORDER;
899 | int stateId = CS_ACTIVE;
900 |
901 | RECT rcHotBorder;
902 | if (getBorderRect(&rcHotBorder, g_hotBorder))
903 | {
904 | // テーマ API を使用してボーダーを描画する。
905 | ::DrawThemeBackground(g_theme, dc, partId, stateId, &rcHotBorder, 0);
906 | }
907 | }
908 | else
909 | {
910 | // ホットボーダーを描画する。
911 |
912 | RECT rcHotBorder;
913 | if (getBorderRect(&rcHotBorder, g_hotBorder))
914 | {
915 | HBRUSH brush = ::CreateSolidBrush(g_hotBorderColor);
916 | ::FillRect(dc, &rcHotBorder, brush);
917 | ::DeleteObject(brush);
918 | }
919 | }
920 |
921 | {
922 | // 各ウィンドウのキャプションを描画する。
923 |
924 | LOGFONTW lf = {};
925 | ::GetThemeSysFont(g_theme, TMT_CAPTIONFONT, &lf);
926 | HFONT font = ::CreateFontIndirectW(&lf);
927 | HFONT oldFont = (HFONT)::SelectObject(dc, font);
928 |
929 | drawCaption(dc, hwnd, &g_aviutlWindow);
930 | drawCaption(dc, hwnd, &g_exeditWindow);
931 | drawCaption(dc, hwnd, &g_settingDialog);
932 |
933 | ::SelectObject(dc, oldFont);
934 | ::DeleteObject(font);
935 | }
936 |
937 | ::EndBufferedPaint(pb, TRUE);
938 | }
939 |
940 | EndPaint(hwnd, &ps);
941 | return 0;
942 | }
943 | case WM_SIZE:
944 | {
945 | recalcLayout();
946 |
947 | break;
948 | }
949 | case WM_SETCURSOR:
950 | {
951 | if (hwnd == (HWND)wParam)
952 | {
953 | POINT point; ::GetCursorPos(&point);
954 | ::ScreenToClient(hwnd, &point);
955 |
956 | int hotBorder = hitTest(point);
957 |
958 | switch (hotBorder)
959 | {
960 | case HotBorder::vertCenter:
961 | case HotBorder::horzTop:
962 | case HotBorder::horzBottom:
963 | {
964 | ::SetCursor(::LoadCursor(0, IDC_SIZEWE));
965 |
966 | return TRUE;
967 | }
968 | case HotBorder::horzCenter:
969 | case HotBorder::vertLeft:
970 | case HotBorder::vertRight:
971 | {
972 | ::SetCursor(::LoadCursor(0, IDC_SIZENS));
973 |
974 | return TRUE;
975 | }
976 | }
977 | }
978 |
979 | break;
980 | }
981 | case WM_LBUTTONDOWN:
982 | {
983 | MY_TRACE(_T("singleWindowProc(WM_LBUTTONDOWN)\n"));
984 |
985 | // マウス座標を取得する。
986 | POINT point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
987 |
988 | // マウス座標にあるボーダーを取得する。
989 | g_hotBorder = hitTest(point);
990 |
991 | // ボーダーが有効かチェックする。
992 | if (g_hotBorder != HotBorder::none)
993 | {
994 | // オフセットを取得する。
995 | g_offset = getOffset(point);
996 |
997 | // マウスキャプチャを開始する。
998 | ::SetCapture(hwnd);
999 |
1000 | // 再描画する。
1001 | ::InvalidateRect(hwnd, 0, FALSE);
1002 | }
1003 |
1004 | // キャプションクリック時にウィンドウをアクティブにする
1005 | for (int i = 0; i < WindowPos::maxSize; i++)
1006 | {
1007 | if (g_windowArray[i] != NULL && ::PtInRect(&g_captionRect[i], point))
1008 | {
1009 | ::SetFocus(g_windowArray[i]->m_hwnd);
1010 | }
1011 | }
1012 |
1013 | break;
1014 | }
1015 | case WM_RBUTTONDOWN:
1016 | {
1017 | MY_TRACE(_T("singleWindowProc(WM_RBUTTONDOWN)\n"));
1018 |
1019 | // マウス座標を取得する。
1020 | POINT point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1021 |
1022 | // キャプションクリック時にウィンドウをアクティブにする
1023 | for (int i = 0; i < WindowPos::maxSize; i++)
1024 | {
1025 | if (g_windowArray[i] != NULL && ::PtInRect(&g_captionRect[i], point))
1026 | {
1027 | ::SetFocus(g_windowArray[i]->m_hwnd);
1028 | }
1029 | }
1030 |
1031 | break;
1032 | }
1033 | case WM_LBUTTONUP:
1034 | {
1035 | MY_TRACE(_T("singleWindowProc(WM_LBUTTONUP)\n"));
1036 |
1037 | // マウス座標を取得する。
1038 | POINT point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1039 |
1040 | // マウスをキャプチャ中かチェックする。
1041 | if (::GetCapture() == hwnd)
1042 | {
1043 | // マウスキャプチャを終了する。
1044 | ::ReleaseCapture();
1045 |
1046 | // ボーダーを動かす。
1047 | dragBorder(point);
1048 |
1049 | // レイアウトを再計算する。
1050 | recalcLayout();
1051 |
1052 | // 再描画する。
1053 | ::InvalidateRect(hwnd, 0, FALSE);
1054 | }
1055 |
1056 | break;
1057 | }
1058 | case WM_MOUSEMOVE:
1059 | {
1060 | // マウス座標を取得する。
1061 | POINT point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1062 |
1063 | // マウスをキャプチャ中かチェックする。
1064 | if (::GetCapture() == hwnd)
1065 | {
1066 | // ボーダーを動かす。
1067 | dragBorder(point);
1068 |
1069 | // レイアウトを再計算する。
1070 | recalcLayout();
1071 |
1072 | // 再描画する。
1073 | ::InvalidateRect(hwnd, 0, FALSE);
1074 | }
1075 | else
1076 | {
1077 | // マウス座標にあるボーダーを取得する。
1078 | int hotBorder = hitTest(point);
1079 |
1080 | // ホットボーダーと別のボーダーかチェックする。
1081 | if (g_hotBorder != hotBorder)
1082 | {
1083 | // ホットボーダーを更新する。
1084 | g_hotBorder = hotBorder;
1085 |
1086 | // 再描画する。
1087 | ::InvalidateRect(hwnd, 0, FALSE);
1088 | }
1089 |
1090 | // マウスリーブイベントをトラックする。
1091 | TRACKMOUSEEVENT tme = { sizeof(tme) };
1092 | tme.dwFlags = TME_LEAVE;
1093 | tme.hwndTrack = hwnd;
1094 | ::TrackMouseEvent(&tme);
1095 | }
1096 |
1097 | break;
1098 | }
1099 | case WM_MOUSELEAVE:
1100 | {
1101 | MY_TRACE(_T("singleWindowProc(WM_MOUSELEAVE)\n"));
1102 |
1103 | // 無効なボーダーを取得する。
1104 | int hotBorder = HotBorder::none;
1105 |
1106 | // ホットボーダーと別のボーダーかチェックする。
1107 | if (g_hotBorder != hotBorder)
1108 | {
1109 | // ホットボーダーを更新する。
1110 | g_hotBorder = hotBorder;
1111 |
1112 | // 再描画する。
1113 | ::InvalidateRect(hwnd, 0, FALSE);
1114 | }
1115 |
1116 | break;
1117 | }
1118 | case WindowMessage::WM_POST_INIT: // 最後の初期化処理。
1119 | {
1120 | // 最初のレイアウト計算。
1121 | recalcLayout();
1122 | ::SetForegroundWindow(hwnd);
1123 | ::SetActiveWindow(hwnd);
1124 |
1125 | break;
1126 | }
1127 | }
1128 |
1129 | return ::DefWindowProc(hwnd, message, wParam, lParam);
1130 | }
1131 |
1132 | //---------------------------------------------------------------------
1133 |
1134 | IMPLEMENT_HOOK_PROC_NULL(HWND, WINAPI, CreateWindowExA, (DWORD exStyle, LPCSTR className, LPCSTR windowName, DWORD style, int x, int y, int w, int h, HWND parent, HMENU menu, HINSTANCE instance, LPVOID param))
1135 | {
1136 | if (!((DWORD)className & 0xFFFF0000UL))
1137 | {
1138 | // className が ATOM の場合は何もしない。
1139 | return true_CreateWindowExA(exStyle, className, windowName, style, x, y, w, h, parent, menu, instance, param);
1140 | }
1141 |
1142 | // デバッグ用出力。
1143 | MY_TRACE(_T("CreateWindowExA(%hs, %hs)\n"), className, windowName);
1144 |
1145 | if (::lstrcmpiA(windowName, "AviUtl") == 0)
1146 | {
1147 | // AviUtl ウィンドウが作成される直前のタイミング。
1148 |
1149 | // 土台となるシングルウィンドウを作成する。
1150 | g_singleWindow = createSingleWindow();
1151 |
1152 | // 設定をファイルから読み込む。
1153 | loadConfig();
1154 |
1155 | // シングルウィンドウが非表示なら表示する。
1156 | if (!::IsWindowVisible(g_singleWindow))
1157 | ::ShowWindow(g_singleWindow, SW_SHOW);
1158 | }
1159 | else if (::lstrcmpiA(className, "AviUtl") == 0 && parent == g_aviutlWindow.m_hwnd)
1160 | {
1161 | // AviUtl のポップアップウィンドウの親をシングルウィンドウに変更する。
1162 | parent = g_singleWindow;
1163 | }
1164 |
1165 | HWND hwnd = true_CreateWindowExA(exStyle, className, windowName, style, x, y, w, h, parent, menu, instance, param);
1166 |
1167 | if (::lstrcmpiA(windowName, "AviUtl") == 0)
1168 | {
1169 | // AviUtl ウィンドウに関する初期化処理を行う。
1170 | g_aviutlWindow.init(hwnd);
1171 | }
1172 | else if (::lstrcmpiA(windowName, "拡張編集") == 0)
1173 | {
1174 | // 拡張編集が読み込まれたのでアドレスを取得する。
1175 | g_auin.initExEditAddress();
1176 |
1177 | // 設定ダイアログのフックを仕掛ける。
1178 | true_SettingDialogProc = g_auin.HookSettingDialogProc(hook_SettingDialogProc);
1179 | MY_TRACE_HEX(true_SettingDialogProc);
1180 | MY_TRACE_HEX(&hook_SettingDialogProc);
1181 |
1182 | DWORD exedit = g_auin.GetExEdit();
1183 |
1184 | // rikky_memory.auf + rikky_module.dll 用のフック。
1185 | true_ScriptParamDlgProc = writeAbsoluteAddress(exedit + 0x3454 + 1, hook_ScriptParamDlgProc);
1186 |
1187 | // 拡張編集ウィンドウに関する初期化処理を行う。
1188 | g_exeditWindow.init(hwnd);
1189 | }
1190 | else if (::lstrcmpiA(windowName, "ExtendedFilter") == 0)
1191 | {
1192 | // 設定ダイアログに関する初期化処理を行う。
1193 | g_settingDialog.init(hwnd);
1194 |
1195 | // すべてのウィンドウの初期化処理が終わったので
1196 | // ポストメッセージ先で最初のレイアウト計算を行う。
1197 | ::PostMessage(g_singleWindow, WindowMessage::WM_POST_INIT, 0, 0);
1198 | }
1199 | #if 0
1200 | else if (::lstrcmpiA(className, "AviUtl") == 0 && parent == g_aviutlWindow.m_hwnd)
1201 | {
1202 | // 「スクリプト並べ替え管理」「シークバー+」用。
1203 | // ::GetWindow(fp->hwnd, GW_OWNER) が AviUtl ウィンドウを返すようにする。
1204 | ::SetWindowLong(hwnd, GWL_HWNDPARENT, (LONG)g_aviutlWindow.m_hwnd);
1205 | }
1206 | #endif
1207 | return hwnd;
1208 | }
1209 |
1210 | /*
1211 | GetMenu、SetMenu、DrawMenuBar では
1212 | AviUtl ウィンドウのハンドルが渡されたとき、シングルウィンドウのハンドルに取り替えて偽装する。
1213 | これによって、AviUtl ウィンドウのメニュー処理がシングルウィンドウに対して行われるようになる。
1214 | */
1215 | IMPLEMENT_HOOK_PROC(HMENU, WINAPI, GetMenu, (HWND hwnd))
1216 | {
1217 | // MY_TRACE(_T("GetMenu(0x%08X)\n"), hwnd);
1218 |
1219 | if (hwnd == g_aviutlWindow.m_hwnd)
1220 | {
1221 | // MY_TRACE(_T("ウィンドウを偽装します\n"));
1222 |
1223 | hwnd = g_singleWindow;
1224 | }
1225 |
1226 | return true_GetMenu(hwnd);
1227 | }
1228 |
1229 | IMPLEMENT_HOOK_PROC(BOOL, WINAPI, SetMenu, (HWND hwnd, HMENU menu))
1230 | {
1231 | // MY_TRACE(_T("SetMenu(0x%08X, 0x%08X)\n"), hwnd, menu);
1232 |
1233 | if (hwnd == g_aviutlWindow.m_hwnd)
1234 | {
1235 | // MY_TRACE(_T("ウィンドウを偽装します\n"));
1236 |
1237 | hwnd = g_singleWindow;
1238 | }
1239 |
1240 | return true_SetMenu(hwnd, menu);
1241 | }
1242 |
1243 | IMPLEMENT_HOOK_PROC(BOOL, WINAPI, DrawMenuBar, (HWND hwnd))
1244 | {
1245 | // MY_TRACE(_T("DrawMenuBar(0x%08X)\n"), hwnd);
1246 |
1247 | if (hwnd == g_aviutlWindow.m_hwnd)
1248 | {
1249 | // MY_TRACE(_T("ウィンドウを偽装します\n"));
1250 |
1251 | hwnd = g_singleWindow;
1252 | }
1253 |
1254 | return true_DrawMenuBar(hwnd);
1255 | }
1256 |
1257 | IMPLEMENT_HOOK_PROC(HWND, WINAPI, FindWindowExA, (HWND parent, HWND childAfter, LPCSTR className, LPCSTR windowName))
1258 | {
1259 | MY_TRACE(_T("FindWindowExA(0x%08X, 0x%08X, %hs, %hs)\n"), parent, childAfter, className, windowName);
1260 |
1261 | // 「テキスト編集補助プラグイン」用。
1262 | if (!parent && className && ::lstrcmpiA(className, "ExtendedFilterClass") == 0)
1263 | return g_settingDialog.m_hwnd;
1264 |
1265 | return true_FindWindowExA(parent, childAfter, className, windowName);
1266 | }
1267 |
1268 | IMPLEMENT_HOOK_PROC(HWND, WINAPI, FindWindowW, (LPCWSTR className, LPCWSTR windowName))
1269 | {
1270 | MY_TRACE(_T("FindWindowW(%ws, %ws)\n"), className, windowName);
1271 |
1272 | // 「PSDToolKit」の「送る」用。
1273 | if (className && ::lstrcmpiW(className, L"ExtendedFilterClass") == 0)
1274 | return g_settingDialog.m_hwnd;
1275 |
1276 | return true_FindWindowW(className, windowName);
1277 | }
1278 |
1279 | IMPLEMENT_HOOK_PROC(HWND, WINAPI, GetWindow, (HWND hwnd, UINT cmd))
1280 | {
1281 | // MY_TRACE(_T("GetWindow(0x%08X, %d)\n"), hwnd, cmd);
1282 | // MY_TRACE_HWND(hwnd);
1283 |
1284 | if (cmd == GW_OWNER)
1285 | {
1286 | if (hwnd == g_exeditWindow.m_hwnd)
1287 | {
1288 | // 拡張編集ウィンドウのオーナーウィンドウは AviUtl ウィンドウ。
1289 | return g_aviutlWindow.m_hwnd;
1290 | }
1291 | else if (hwnd == g_settingDialog.m_hwnd)
1292 | {
1293 | // 設定ダイアログのオーナーウィンドウは拡張編集ウィンドウ。
1294 | return g_exeditWindow.m_hwnd;
1295 | }
1296 | #if 1
1297 | HWND retValue = true_GetWindow(hwnd, cmd);
1298 |
1299 | if (retValue == g_singleWindow)
1300 | {
1301 | // 「スクリプト並べ替え管理」「シークバー+」などの一般的なプラグイン用。
1302 | // シングルウィンドウがオーナーになっている場合は AviUtl ウィンドウを返すようにする。
1303 | return g_aviutlWindow.m_hwnd;
1304 | }
1305 |
1306 | return retValue;
1307 | #endif
1308 | }
1309 |
1310 | return true_GetWindow(hwnd, cmd);
1311 | }
1312 |
1313 | IMPLEMENT_HOOK_PROC(BOOL, WINAPI, EnumThreadWindows, (DWORD threadId, WNDENUMPROC enumProc, LPARAM lParam))
1314 | {
1315 | MY_TRACE(_T("EnumThreadWindows(%d, 0x%08X, 0x%08X)\n"), threadId, enumProc, lParam);
1316 |
1317 | // 「イージング設定時短プラグイン」用。
1318 | if (threadId == ::GetCurrentThreadId() && enumProc && lParam)
1319 | {
1320 | // enumProc() の中で ::GetWindow() が呼ばれる。
1321 | if (!enumProc(g_settingDialog.m_hwnd, lParam))
1322 | return FALSE;
1323 | }
1324 |
1325 | return true_EnumThreadWindows(threadId, enumProc, lParam);
1326 | }
1327 |
1328 | IMPLEMENT_HOOK_PROC(BOOL, WINAPI, EnumWindows, (WNDENUMPROC enumProc, LPARAM lParam))
1329 | {
1330 | MY_TRACE(_T("EnumWindows(0x%08X, 0x%08X)\n"), enumProc, lParam);
1331 |
1332 | // 「拡張編集RAMプレビュー」用。
1333 | if (enumProc && lParam)
1334 | {
1335 | if (!enumProc(g_aviutlWindow.m_hwnd, lParam))
1336 | return FALSE;
1337 | }
1338 |
1339 | return true_EnumWindows(enumProc, lParam);
1340 | }
1341 |
1342 | IMPLEMENT_HOOK_PROC_NULL(INT_PTR, CALLBACK, ScriptParamDlgProc, (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam))
1343 | {
1344 | switch (message)
1345 | {
1346 | case WM_INITDIALOG:
1347 | {
1348 | MY_TRACE(_T("ScriptParamDlgProc(WM_INITDIALOG)\n"));
1349 |
1350 | // rikky_memory.auf + rikky_module.dll 用。
1351 | ::PostMessage(g_settingDialog.m_hwnd, WM_NCACTIVATE, FALSE, (LPARAM)hwnd);
1352 |
1353 | break;
1354 | }
1355 | }
1356 |
1357 | return true_ScriptParamDlgProc(hwnd, message, wParam, lParam);
1358 | }
1359 |
1360 | COLORREF WINAPI Dropper_GetPixel(HDC _dc, int x, int y)
1361 | {
1362 | MY_TRACE(_T("Dropper_GetPixel(0x%08X, %d, %d)\n"), _dc, x, y);
1363 |
1364 | // すべてのモニタのすべての場所から色を抽出できるようにする。
1365 |
1366 | POINT point; ::GetCursorPos(&point);
1367 | ::LogicalToPhysicalPointForPerMonitorDPI(0, &point);
1368 | HDC dc = ::GetDC(0);
1369 | COLORREF color = ::GetPixel(dc, point.x, point.y);
1370 | ::ReleaseDC(0, dc);
1371 | return color;
1372 | }
1373 |
1374 | BOOL isAncestor(HWND hwnd, HWND child)
1375 | {
1376 | while (child)
1377 | {
1378 | if (child == hwnd)
1379 | return TRUE;
1380 |
1381 | child = ::GetParent(child);
1382 | }
1383 |
1384 | return FALSE;
1385 | }
1386 |
1387 | HWND WINAPI KeyboardHook_GetActiveWindow()
1388 | {
1389 | MY_TRACE(_T("KeyboardHook_GetActiveWindow()\n"));
1390 |
1391 | HWND focus = ::GetFocus();
1392 |
1393 | if (isAncestor(g_settingDialog.m_hwnd, focus))
1394 | {
1395 | MY_TRACE(_T("設定ダイアログを返します\n"));
1396 | return g_settingDialog.m_hwnd;
1397 | }
1398 |
1399 | if (isAncestor(g_exeditWindow.m_hwnd, focus))
1400 | {
1401 | MY_TRACE(_T("拡張編集ウィンドウを返します\n"));
1402 | return g_exeditWindow.m_hwnd;
1403 | }
1404 |
1405 | return ::GetActiveWindow();
1406 | }
1407 |
1408 | //---------------------------------------------------------------------
1409 |
1410 | EXTERN_C BOOL APIENTRY DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
1411 | {
1412 | switch (reason)
1413 | {
1414 | case DLL_PROCESS_ATTACH:
1415 | {
1416 | // ロケールを設定する。
1417 | // これをやらないと日本語テキストが文字化けするので最初に実行する。
1418 | _tsetlocale(LC_ALL, _T(""));
1419 |
1420 | MY_TRACE(_T("DLL_PROCESS_ATTACH\n"));
1421 |
1422 | // この DLL のハンドルをグローバル変数に保存しておく。
1423 | g_instance = instance;
1424 | MY_TRACE_HEX(g_instance);
1425 |
1426 | // この DLL の参照カウンタを増やしておく。
1427 | WCHAR moduleFileName[MAX_PATH] = {};
1428 | ::GetModuleFileNameW(g_instance, moduleFileName, MAX_PATH);
1429 | ::LoadLibraryW(moduleFileName);
1430 |
1431 | initHook();
1432 |
1433 | break;
1434 | }
1435 | case DLL_PROCESS_DETACH:
1436 | {
1437 | MY_TRACE(_T("DLL_PROCESS_DETACH\n"));
1438 |
1439 | termHook();
1440 |
1441 | break;
1442 | }
1443 | }
1444 |
1445 | return TRUE;
1446 | }
1447 |
1448 | //---------------------------------------------------------------------
1449 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow.def:
--------------------------------------------------------------------------------
1 | EXPORTS
2 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | //---------------------------------------------------------------------
4 |
5 | class Window
6 | {
7 | public:
8 | HWND m_hwnd = 0;
9 | HWND m_hwndContainer = 0;
10 | public:
11 | virtual void init(HWND hwnd) = 0;
12 | static HWND getWindow(HWND hwndContainer);
13 | static void setWindow(HWND hwndContainer, HWND hwnd);
14 | static HWND createContainerWindow(HWND child, WNDPROC wndProc, LPCTSTR className);
15 | void resize(LPCRECT rc);
16 | };
17 |
18 | class AviUtlWindow : public Window
19 | {
20 | public:
21 | virtual void init(HWND hwnd);
22 | static LRESULT CALLBACK containerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
23 | };
24 |
25 | class ExEditWindow : public Window
26 | {
27 | public:
28 | virtual void init(HWND hwnd);
29 | static LRESULT CALLBACK containerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
30 | };
31 |
32 | class SettingDialog : public Window
33 | {
34 | public:
35 |
36 | BOOL m_blockSizeHandler = FALSE;
37 | SIZE m_rawWindowSize = {};
38 |
39 | virtual void init(HWND hwnd);
40 | void updateScrollBar();
41 | void scroll(int bar, WPARAM wParam);
42 | void recalcLayout();
43 | void extend();
44 | static LRESULT CALLBACK containerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
45 | };
46 |
47 | struct WindowPos
48 | {
49 | static const int topLeft = 0;
50 | static const int topRight = 1;
51 | static const int bottomLeft = 2;
52 | static const int bottomRight = 3;
53 |
54 | static const int maxSize = 4;
55 | };
56 |
57 | struct
58 | {
59 | int value;
60 | LPCWSTR label;
61 |
62 | } const g_windowPosLabel[] =
63 | {
64 | { WindowPos::topLeft, L"topLeft" },
65 | { WindowPos::topRight, L"topRight" },
66 | { WindowPos::bottomLeft, L"bottomLeft" },
67 | { WindowPos::bottomRight, L"bottomRight" },
68 | };
69 |
70 | struct LayoutMode
71 | {
72 | static const int vertSplit = 0;
73 | static const int horzSplit = 1;
74 |
75 | static const int maxSize = 2;
76 | };
77 |
78 | struct
79 | {
80 | int value;
81 | LPCWSTR label;
82 |
83 | } const g_layoutModeLabel[] =
84 | {
85 | { LayoutMode::vertSplit, L"vertSplit" },
86 | { LayoutMode::horzSplit, L"horzSplit" },
87 | };
88 |
89 | struct Origin
90 | {
91 | static const int topLeft = 0;
92 | static const int bottomRight = 1;
93 | };
94 |
95 | struct
96 | {
97 | int value;
98 | LPCWSTR label;
99 |
100 | } const g_originLabel[] =
101 | {
102 | { Origin::topLeft, L"topLeft" },
103 | { Origin::bottomRight, L"bottomRight" },
104 | };
105 |
106 | struct Borders
107 | {
108 | int m_vertCenter;
109 | int m_vertLeft;
110 | int m_vertRight;
111 |
112 | int m_vertCenterOrigin;
113 | int m_vertLeftOrigin;
114 | int m_vertRightOrigin;
115 |
116 | int m_horzCenter;
117 | int m_horzTop;
118 | int m_horzBottom;
119 |
120 | int m_horzCenterOrigin;
121 | int m_horzTopOrigin;
122 | int m_horzBottomOrigin;
123 | };
124 |
125 | struct HotBorder
126 | {
127 | static const int none = 0;
128 |
129 | static const int vertCenter = 1;
130 | static const int vertLeft = 2;
131 | static const int vertRight = 3;
132 |
133 | static const int horzCenter = 4;
134 | static const int horzTop = 5;
135 | static const int horzBottom = 6;
136 | };
137 |
138 | struct CommandID
139 | {
140 | static const int ShowConfigDialog = 1000;
141 | static const int ImportLayout = 1001;
142 | static const int ExportLayout = 1002;
143 | };
144 |
145 | struct WindowMessage
146 | {
147 | static const UINT WM_POST_INIT = WM_APP + 1;
148 | };
149 |
150 | //---------------------------------------------------------------------
151 |
152 | extern AviUtlInternal g_auin;
153 | extern HINSTANCE g_instance;
154 | extern HWND g_singleWindow;
155 | extern HTHEME g_theme;
156 | extern WNDPROC g_aviutlWindowProc;
157 | extern WNDPROC g_exeditWindowProc;
158 |
159 | extern AviUtlWindow g_aviutlWindow;
160 | extern ExEditWindow g_exeditWindow;
161 | extern SettingDialog g_settingDialog;
162 |
163 | extern Window* g_windowArray[WindowPos::maxSize];
164 | extern int g_layoutMode;
165 | extern Borders g_borders;
166 | extern int g_hotBorder;
167 |
168 | extern int g_borderWidth;
169 | extern int g_captionHeight;
170 | extern int g_borderSnapRange;
171 | extern COLORREF g_fillColor;
172 | extern COLORREF g_borderColor;
173 | extern COLORREF g_hotBorderColor;
174 | extern COLORREF g_activeCaptionColor;
175 | extern COLORREF g_activeCaptionTextColor;
176 | extern COLORREF g_inactiveCaptionColor;
177 | extern COLORREF g_inactiveCaptionTextColor;
178 | extern BOOL g_useTheme;
179 |
180 | //---------------------------------------------------------------------
181 |
182 | struct
183 | {
184 | Window* value;
185 | LPCWSTR label;
186 |
187 | } const g_windowIdLabel[] =
188 | {
189 | { &g_aviutlWindow, L"aviutlWindow" },
190 | { &g_exeditWindow, L"exeditWindow" },
191 | { &g_settingDialog, L"settingDialog" },
192 | { 0, L"" },
193 | };
194 |
195 | //---------------------------------------------------------------------
196 |
197 | HWND createSingleWindow();
198 | void normalizeLayoutHorzSplit();
199 | void normalizeLayoutVertSplit();
200 | void recalcLayoutHorzSplit();
201 | void recalcLayoutVertSplit();
202 | void recalcLayout();
203 | LRESULT CALLBACK singleWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
204 | LRESULT CALLBACK aviutlWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
205 | LRESULT CALLBACK exeditWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
206 |
207 | HRESULT loadConfig();
208 | HRESULT loadConfig(LPCWSTR fileName, BOOL _import);
209 | HRESULT loadLayout(const MSXML2::IXMLDOMElementPtr& element);
210 |
211 | HRESULT saveConfig();
212 | HRESULT saveConfig(LPCWSTR fileName, BOOL _export);
213 | HRESULT saveLayout(const MSXML2::IXMLDOMElementPtr& element);
214 |
215 | //---------------------------------------------------------------------
216 |
217 | DECLARE_HOOK_PROC(LRESULT, WINAPI, SettingDialogProc, (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam));
218 | DECLARE_HOOK_PROC(HWND, WINAPI, CreateWindowExA, (DWORD exStyle, LPCSTR className, LPCSTR windowName, DWORD style, int x, int y, int w, int h, HWND parent, HMENU menu, HINSTANCE instance, LPVOID param));
219 | DECLARE_HOOK_PROC(HMENU, WINAPI, GetMenu, (HWND hwnd));
220 | DECLARE_HOOK_PROC(BOOL, WINAPI, SetMenu, (HWND hwnd, HMENU menu));
221 | DECLARE_HOOK_PROC(BOOL, WINAPI, DrawMenuBar, (HWND hwnd));
222 | DECLARE_HOOK_PROC(HWND, WINAPI, FindWindowExA, (HWND parent, HWND childAfter, LPCSTR className, LPCSTR windowName));
223 | DECLARE_HOOK_PROC(HWND, WINAPI, FindWindowW, (LPCWSTR className, LPCWSTR windowName));
224 | DECLARE_HOOK_PROC(HWND, WINAPI, GetWindow, (HWND hwnd, UINT cmd));
225 | DECLARE_HOOK_PROC(BOOL, WINAPI, EnumThreadWindows, (DWORD threadId, WNDENUMPROC enumProc, LPARAM lParam));
226 | DECLARE_HOOK_PROC(BOOL, WINAPI, EnumWindows, (WNDENUMPROC enumProc, LPARAM lParam));
227 | DECLARE_HOOK_PROC(INT_PTR, CALLBACK, ScriptParamDlgProc, (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam));
228 |
229 | COLORREF WINAPI Dropper_GetPixel(HDC dc, int x, int y);
230 | HWND WINAPI KeyboardHook_GetActiveWindow();
231 |
232 | //---------------------------------------------------------------------
233 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hebiiro/AviUtl-Plugin-UniteWindow/db5ad9837eb88479afbea34fc84eb3bafd73d607/UniteWindow/UniteWindow.rc
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 16.0
23 | Win32Proj
24 | {772bc0b9-7ca2-4ef5-9439-91d4f823156e}
25 | UniteWindow
26 | 10.0
27 |
28 |
29 |
30 | DynamicLibrary
31 | true
32 | v142
33 | MultiByte
34 |
35 |
36 | DynamicLibrary
37 | false
38 | v142
39 | true
40 | MultiByte
41 |
42 |
43 | DynamicLibrary
44 | true
45 | v142
46 | MultiByte
47 |
48 |
49 | DynamicLibrary
50 | false
51 | v142
52 | true
53 | MultiByte
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | true
79 |
80 |
81 | false
82 |
83 |
84 | true
85 |
86 |
87 | false
88 |
89 |
90 |
91 | Level3
92 | true
93 | WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
94 | true
95 | Use
96 | pch.h
97 | ../../;../../AviUtl/aviutl_exedit_sdk/
98 | stdcpplatest
99 |
100 |
101 | Windows
102 | true
103 | false
104 | $(TargetName).def
105 | ../../
106 |
107 |
108 | copy /B /Y "$(TargetDir)$(TargetFileName)" "C:\AviUtl110_test_psd\Plugins\$(TargetName).aul"
109 |
110 |
111 |
112 |
113 | Level3
114 | true
115 | true
116 | true
117 | WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
118 | true
119 | Use
120 | pch.h
121 | ../../;../../AviUtl/aviutl_exedit_sdk/
122 | stdcpplatest
123 |
124 |
125 | Windows
126 | true
127 | true
128 | true
129 | false
130 | $(TargetName).def
131 | ../../
132 |
133 |
134 | copy /B /Y "$(TargetDir)$(TargetFileName)" "C:\AviUtl110_test_psd\Plugins\$(TargetName).aul"
135 |
136 |
137 |
138 |
139 | Level3
140 | true
141 | _DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
142 | true
143 | Use
144 | pch.h
145 | ../../;../../AviUtl/aviutl_exedit_sdk/
146 | stdcpplatest
147 |
148 |
149 | Windows
150 | true
151 | false
152 | $(TargetName).def
153 | ../../
154 |
155 |
156 | copy /B /Y "$(TargetDir)$(TargetFileName)" "C:\AviUtl110_test_psd\Plugins\$(TargetName).aul"
157 |
158 |
159 |
160 |
161 | Level3
162 | true
163 | true
164 | true
165 | NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
166 | true
167 | Use
168 | pch.h
169 | ../../;../../AviUtl/aviutl_exedit_sdk/
170 | stdcpplatest
171 |
172 |
173 | Windows
174 | true
175 | true
176 | true
177 | false
178 | $(TargetName).def
179 | ../../
180 |
181 |
182 | copy /B /Y "$(TargetDir)$(TargetFileName)" "C:\AviUtl110_test_psd\Plugins\$(TargetName).aul"
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 | Create
202 | Create
203 | Create
204 | Create
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Common
8 |
9 |
10 | Common
11 |
12 |
13 | Common
14 |
15 |
16 | Common
17 |
18 |
19 | Common
20 |
21 |
22 |
23 | Common
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | {177f322b-85e3-40d8-98e7-bca29a16eb22}
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow_Config_Load.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "UniteWindow.h"
3 |
4 | //---------------------------------------------------------------------
5 |
6 | HRESULT loadConfig()
7 | {
8 | MY_TRACE(_T("loadConfig()\n"));
9 |
10 | WCHAR fileName[MAX_PATH] = {};
11 | ::GetModuleFileNameW(g_instance, fileName, MAX_PATH);
12 | ::PathRenameExtensionW(fileName, L".xml");
13 |
14 | return loadConfig(fileName, FALSE);
15 | }
16 |
17 | HRESULT loadConfig(LPCWSTR fileName, BOOL _import)
18 | {
19 | MY_TRACE(_T("loadConfig(%ws, %d)\n"), fileName, _import);
20 |
21 | try
22 | {
23 | // MSXML を使用する。
24 | MSXML2::IXMLDOMDocumentPtr document(__uuidof(MSXML2::DOMDocument));
25 |
26 | // 設定ファイルを開く。
27 | if (document->load(fileName) == VARIANT_FALSE)
28 | {
29 | MY_TRACE(_T("%s を開けませんでした\n"), fileName);
30 |
31 | return S_FALSE;
32 | }
33 |
34 | MSXML2::IXMLDOMElementPtr element = document->documentElement;
35 |
36 | if (!_import) // インポートのときはこれらの変数は取得しない。
37 | {
38 | getPrivateProfileInt(element, L"borderWidth", g_borderWidth);
39 | getPrivateProfileInt(element, L"captionHeight", g_captionHeight);
40 | getPrivateProfileInt(element, L"borderSnapRange", g_borderSnapRange);
41 | getPrivateProfileColor(element, L"fillColor", g_fillColor);
42 | getPrivateProfileColor(element, L"borderColor", g_borderColor);
43 | getPrivateProfileColor(element, L"hotBorderColor", g_hotBorderColor);
44 | getPrivateProfileColor(element, L"activeCaptionColor", g_activeCaptionColor);
45 | getPrivateProfileColor(element, L"activeCaptionTextColor", g_activeCaptionTextColor);
46 | getPrivateProfileColor(element, L"inactiveCaptionColor", g_inactiveCaptionColor);
47 | getPrivateProfileColor(element, L"inactiveCaptionTextColor", g_inactiveCaptionTextColor);
48 | getPrivateProfileBool(element, L"useTheme", g_useTheme);
49 | }
50 |
51 | // ウィンドウ位置を取得する。
52 | getPrivateProfileWindow(element, L"singleWindow", g_singleWindow);
53 |
54 | // を読み込む。
55 | loadLayout(element);
56 |
57 | MY_TRACE(_T("設定ファイルの読み込みに成功しました\n"));
58 |
59 | return S_OK;
60 | }
61 | catch (_com_error& e)
62 | {
63 | MY_TRACE(_T("設定ファイルの読み込みに失敗しました\n"));
64 | MY_TRACE(_T("%s\n"), e.ErrorMessage());
65 | return e.Error();
66 | }
67 | }
68 |
69 | // を読み込む。
70 | HRESULT loadLayout(const MSXML2::IXMLDOMElementPtr& element)
71 | {
72 | MY_TRACE(_T("loadLayout()\n"));
73 |
74 | // を読み込む。
75 | MSXML2::IXMLDOMNodeListPtr nodeList = element->selectNodes(L"layout");
76 | int c = nodeList->length;
77 | for (int i = 0; i < c; i++)
78 | {
79 | MSXML2::IXMLDOMElementPtr layoutElement = nodeList->item[i];
80 |
81 | // のアトリビュートを読み込む。
82 |
83 | // layoutMode を取得する。
84 | getPrivateProfileLabel(layoutElement, L"layoutMode", g_layoutMode, g_layoutModeLabel);
85 |
86 | {
87 | // を読み込む。
88 | MSXML2::IXMLDOMNodeListPtr nodeList = layoutElement->selectNodes(L"window");
89 | int c = nodeList->length;
90 | for (int i = 0; i < c; i++)
91 | {
92 | MSXML2::IXMLDOMElementPtr windowElement = nodeList->item[i];
93 |
94 | // pos を取得する。
95 | int pos = WindowPos::maxSize;
96 | getPrivateProfileLabel(windowElement, L"pos", pos, g_windowPosLabel);
97 | if (pos == WindowPos::maxSize) continue;
98 |
99 | // id を取得する。
100 | getPrivateProfileLabel(windowElement, L"id", g_windowArray[pos], g_windowIdLabel);
101 | }
102 | }
103 |
104 | {
105 | // を読み込む。
106 | MSXML2::IXMLDOMNodeListPtr nodeList = layoutElement->selectNodes(L"vertSplit");
107 | int c = nodeList->length;
108 | for (int i = 0; i < c; i++)
109 | {
110 | MSXML2::IXMLDOMElementPtr vertSplitElement = nodeList->item[i];
111 |
112 | // のアトリビュートを読み込む。
113 |
114 | getPrivateProfileInt(vertSplitElement, L"center", g_borders.m_vertCenter);
115 | getPrivateProfileInt(vertSplitElement, L"left", g_borders.m_vertLeft);
116 | getPrivateProfileInt(vertSplitElement, L"right", g_borders.m_vertRight);
117 |
118 | getPrivateProfileLabel(vertSplitElement, L"centerOrigin", g_borders.m_vertCenterOrigin, g_originLabel);
119 | getPrivateProfileLabel(vertSplitElement, L"leftOrigin", g_borders.m_vertLeftOrigin, g_originLabel);
120 | getPrivateProfileLabel(vertSplitElement, L"rightOrigin", g_borders.m_vertRightOrigin, g_originLabel);
121 | }
122 | }
123 |
124 | {
125 | // を読み込む。
126 | MSXML2::IXMLDOMNodeListPtr nodeList = layoutElement->selectNodes(L"horzSplit");
127 | int c = nodeList->length;
128 | for (int i = 0; i < c; i++)
129 | {
130 | MSXML2::IXMLDOMElementPtr horzSplitElement = nodeList->item[i];
131 |
132 | // のアトリビュートを読み込む。
133 |
134 | getPrivateProfileInt(horzSplitElement, L"center", g_borders.m_horzCenter);
135 | getPrivateProfileInt(horzSplitElement, L"top", g_borders.m_horzTop);
136 | getPrivateProfileInt(horzSplitElement, L"bottom", g_borders.m_horzBottom);
137 |
138 | getPrivateProfileLabel(horzSplitElement, L"centerOrigin", g_borders.m_horzCenterOrigin, g_originLabel);
139 | getPrivateProfileLabel(horzSplitElement, L"topOrigin", g_borders.m_horzTopOrigin, g_originLabel);
140 | getPrivateProfileLabel(horzSplitElement, L"bottomOrigin", g_borders.m_horzBottomOrigin, g_originLabel);
141 | }
142 | }
143 | }
144 |
145 | return S_OK;
146 | }
147 |
148 | //---------------------------------------------------------------------
149 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow_Config_Save.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "UniteWindow.h"
3 |
4 | //---------------------------------------------------------------------
5 |
6 | HRESULT saveConfig()
7 | {
8 | MY_TRACE(_T("saveConfig()\n"));
9 |
10 | WCHAR fileName[MAX_PATH] = {};
11 | ::GetModuleFileNameW(g_instance, fileName, MAX_PATH);
12 | ::PathRenameExtensionW(fileName, L".xml");
13 |
14 | return saveConfig(fileName, FALSE);
15 | }
16 |
17 | HRESULT saveConfig(LPCWSTR fileName, BOOL _export)
18 | {
19 | MY_TRACE(_T("saveConfig(%ws, %d)\n"), fileName, _export);
20 |
21 | try
22 | {
23 | // ドキュメントを作成する。
24 | MSXML2::IXMLDOMDocumentPtr document(__uuidof(MSXML2::DOMDocument));
25 |
26 | // ドキュメントエレメントを作成する。
27 | MSXML2::IXMLDOMElementPtr element = appendElement(document, document, L"config");
28 |
29 | if (!_export) // エクスポートのときはこれらの変数は保存しない。
30 | {
31 | setPrivateProfileInt(element, L"borderWidth", g_borderWidth);
32 | setPrivateProfileInt(element, L"captionHeight", g_captionHeight);
33 | setPrivateProfileInt(element, L"borderSnapRange", g_borderSnapRange);
34 | setPrivateProfileColor(element, L"fillColor", g_fillColor);
35 | setPrivateProfileColor(element, L"borderColor", g_borderColor);
36 | setPrivateProfileColor(element, L"hotBorderColor", g_hotBorderColor);
37 | setPrivateProfileColor(element, L"activeCaptionColor", g_activeCaptionColor);
38 | setPrivateProfileColor(element, L"activeCaptionTextColor", g_activeCaptionTextColor);
39 | setPrivateProfileColor(element, L"inactiveCaptionColor", g_inactiveCaptionColor);
40 | setPrivateProfileColor(element, L"inactiveCaptionTextColor", g_inactiveCaptionTextColor);
41 | setPrivateProfileBool(element, L"useTheme", g_useTheme);
42 | }
43 |
44 | // ウィンドウ位置を保存する。
45 | setPrivateProfileWindow(element, L"singleWindow", g_singleWindow);
46 |
47 | // を作成する。
48 | saveLayout(element);
49 |
50 | return saveXMLDocument(document, fileName, L"UTF-16");
51 | }
52 | catch (_com_error& e)
53 | {
54 | MY_TRACE(_T("%s\n"), e.ErrorMessage());
55 | return e.Error();
56 | }
57 | }
58 |
59 | // を作成する。
60 | HRESULT saveLayout(const MSXML2::IXMLDOMElementPtr& element)
61 | {
62 | MY_TRACE(_T("saveLayout()\n"));
63 |
64 | // を作成する。
65 | MSXML2::IXMLDOMElementPtr layoutElement = appendElement(element, L"layout");
66 |
67 | setPrivateProfileLabel(layoutElement, L"layoutMode", g_layoutMode, g_layoutModeLabel);
68 |
69 | for (int i = 0; i < WindowPos::maxSize; i++)
70 | {
71 | // を作成する。
72 | MSXML2::IXMLDOMElementPtr windowElement = appendElement(layoutElement, L"window");
73 | setPrivateProfileLabel(windowElement, L"pos", i, g_windowPosLabel);
74 | setPrivateProfileLabel(windowElement, L"id", g_windowArray[i], g_windowIdLabel);
75 | }
76 |
77 | // を作成する。
78 | MSXML2::IXMLDOMElementPtr vertSplitElement = appendElement(layoutElement, L"vertSplit");
79 | setPrivateProfileInt(vertSplitElement, L"center", g_borders.m_vertCenter);
80 | setPrivateProfileInt(vertSplitElement, L"left", g_borders.m_vertLeft);
81 | setPrivateProfileInt(vertSplitElement, L"right", g_borders.m_vertRight);
82 | setPrivateProfileLabel(vertSplitElement, L"centerOrigin", g_borders.m_vertCenterOrigin, g_originLabel);
83 | setPrivateProfileLabel(vertSplitElement, L"leftOrigin", g_borders.m_vertLeftOrigin, g_originLabel);
84 | setPrivateProfileLabel(vertSplitElement, L"rightOrigin", g_borders.m_vertRightOrigin, g_originLabel);
85 |
86 | // を作成する。
87 | MSXML2::IXMLDOMElementPtr horzSplitElement = appendElement(layoutElement, L"horzSplit");
88 | setPrivateProfileInt(horzSplitElement, L"center", g_borders.m_horzCenter);
89 | setPrivateProfileInt(horzSplitElement, L"top", g_borders.m_horzTop);
90 | setPrivateProfileInt(horzSplitElement, L"bottom", g_borders.m_horzBottom);
91 | setPrivateProfileLabel(horzSplitElement, L"centerOrigin", g_borders.m_horzCenterOrigin, g_originLabel);
92 | setPrivateProfileLabel(horzSplitElement, L"topOrigin", g_borders.m_horzTopOrigin, g_originLabel);
93 | setPrivateProfileLabel(horzSplitElement, L"bottomOrigin", g_borders.m_horzBottomOrigin, g_originLabel);
94 |
95 | return S_OK;
96 | }
97 |
98 | //---------------------------------------------------------------------
99 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow_Window.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "UniteWindow.h"
3 |
4 | //---------------------------------------------------------------------
5 |
6 | HWND Window::getWindow(HWND hwndContainer)
7 | {
8 | return (HWND)::GetProp(hwndContainer, _T("UniteWindow.Window"));
9 | }
10 |
11 | void Window::setWindow(HWND hwndContainer, HWND hwnd)
12 | {
13 | ::SetProp(hwndContainer, _T("UniteWindow.Window"), hwnd);
14 | }
15 |
16 | HWND Window::createContainerWindow(HWND hwnd, WNDPROC wndProc, LPCTSTR className)
17 | {
18 | MY_TRACE(_T("createContainerWindow(0x%08X, %s)\n"), hwnd, className);
19 |
20 | WNDCLASS wc = {};
21 | wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
22 | wc.hCursor = ::LoadCursor(0, IDC_ARROW);
23 | wc.lpfnWndProc = wndProc;
24 | wc.hInstance = g_instance;
25 | wc.lpszClassName = className;
26 | ::RegisterClass(&wc);
27 |
28 | HWND hwndContainer = ::CreateWindowEx(
29 | 0,
30 | className,
31 | className,
32 | WS_VISIBLE | WS_CHILD |
33 | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
34 | 0, 0, 0, 0,
35 | g_singleWindow, 0, g_instance, 0);
36 |
37 | setWindow(hwndContainer, hwnd);
38 |
39 | return hwndContainer;
40 | }
41 |
42 | void Window::resize(LPCRECT rc)
43 | {
44 | int x = rc->left;
45 | int y = rc->top;
46 | int w = rc->right - rc->left;
47 | int h = rc->bottom - rc->top;
48 |
49 | x = min(rc->left, rc->right);
50 | y = min(rc->top, rc->bottom);
51 | w = max(w, 0);
52 | h = max(h, 0);
53 |
54 | ::MoveWindow(m_hwndContainer, x, y, w, h, TRUE);
55 | }
56 |
57 | //---------------------------------------------------------------------
58 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow_Window_AviUtlWindow.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "UniteWindow.h"
3 |
4 | //---------------------------------------------------------------------
5 |
6 | void AviUtlWindow::init(HWND hwnd)
7 | {
8 | m_hwnd = hwnd;
9 | m_hwndContainer = createContainerWindow(
10 | hwnd, containerWndProc, _T("UniteWindow.AviUtlWindow"));
11 |
12 | ::SetParent(m_hwnd, m_hwndContainer);
13 |
14 | DWORD style = ::GetWindowLong(m_hwnd, GWL_STYLE);
15 | style &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
16 | style |= WS_CHILD;
17 | ::SetWindowLong(m_hwnd, GWL_STYLE, style);
18 | #if 0
19 | DWORD exStyle = ::GetWindowLong(m_hwnd, GWL_EXSTYLE);
20 | exStyle |= WS_EX_NOACTIVATE;
21 | ::SetWindowLong(m_hwnd, GWL_EXSTYLE, exStyle);
22 | #endif
23 | ::SetWindowPos(m_hwnd, 0, 0, 0, 0, 0,
24 | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
25 |
26 | g_aviutlWindowProc = (WNDPROC)::SetWindowLongPtr(
27 | m_hwnd, GWLP_WNDPROC, (LONG_PTR)aviutlWindowProc);
28 |
29 | HICON icon = (HICON)::GetClassLong(m_hwnd, GCL_HICON);
30 | ::SetClassLong(g_singleWindow, GCL_HICON, (LONG)icon);
31 | ::SetClassLong(g_singleWindow, GCL_HICONSM, (LONG)icon);
32 | }
33 |
34 | LRESULT CALLBACK AviUtlWindow::containerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
35 | {
36 | switch (message)
37 | {
38 | case WM_PAINT:
39 | {
40 | PAINTSTRUCT ps = {};
41 | HDC dc = ::BeginPaint(hwnd, &ps);
42 | HBRUSH brush = (HBRUSH)::SendMessage(hwnd, WM_CTLCOLORDLG, (WPARAM)dc, (LPARAM)hwnd);
43 | if (brush) ::FillRect(dc, &ps.rcPaint, brush);
44 | ::EndPaint(hwnd, &ps);
45 | return 0;
46 | }
47 | case WM_SIZE:
48 | {
49 | RECT rc; ::GetClientRect(hwnd, &rc);
50 |
51 | HWND child = getWindow(hwnd);
52 | RECT rcClient; ::GetClientRect(child, &rcClient);
53 | RECT rcWindow; ::GetWindowRect(child, &rcWindow);
54 | ::MapWindowPoints(child, 0, (POINT*)&rcClient, 2);
55 |
56 | rc.left += rcWindow.left - rcClient.left;
57 | rc.top += rcWindow.top - rcClient.top;
58 | rc.right += rcWindow.right - rcClient.right;
59 | rc.bottom += rcWindow.bottom - rcClient.bottom;
60 |
61 | int x = rc.left;
62 | int y = rc.top;
63 | int w = rc.right - rc.left;
64 | int h = rc.bottom - rc.top;
65 |
66 | ::MoveWindow(child, x, y, w, h, TRUE);
67 |
68 | break;
69 | }
70 | case WM_SETFOCUS:
71 | case WM_LBUTTONDOWN:
72 | case WM_RBUTTONDOWN:
73 | {
74 | ::SetFocus(g_aviutlWindow.m_hwnd);
75 |
76 | break;
77 | }
78 | }
79 |
80 | return ::DefWindowProc(hwnd, message, wParam, lParam);
81 | }
82 |
83 | LRESULT CALLBACK aviutlWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
84 | {
85 | switch (message)
86 | {
87 | case WM_DESTROY:
88 | {
89 | MY_TRACE(_T("aviutlWindowProc(WM_DESTROY)\n"));
90 |
91 | saveConfig();
92 |
93 | break;
94 | }
95 | case WM_SETTEXT:
96 | {
97 | // MY_TRACE(_T("aviutlWindowProc(WM_SETTEXT)\n"));
98 |
99 | ::InvalidateRect(g_singleWindow, 0, FALSE);
100 |
101 | AviUtl::EditHandle* editp = (AviUtl::EditHandle*)g_auin.GetEditp();
102 |
103 | char fileName[MAX_PATH] = {};
104 | if (editp->frame_n)
105 | {
106 | ::StringCbCopyA(fileName, sizeof(fileName), editp->project_filename);
107 | ::PathStripPathA(fileName);
108 |
109 | if (::lstrlenA(fileName) == 0)
110 | ::StringCbCopyA(fileName, sizeof(fileName), (LPCSTR)lParam);
111 | }
112 | else
113 | {
114 | ::StringCbCopyA(fileName, sizeof(fileName), "無題");
115 | }
116 | ::StringCbCatA(fileName, sizeof(fileName), " - AviUtl");
117 | ::SetWindowTextA(g_singleWindow, fileName);
118 |
119 | break;
120 | }
121 | case WM_SETFOCUS:
122 | case WM_KILLFOCUS:
123 | {
124 | ::InvalidateRect(g_singleWindow, 0, FALSE);
125 |
126 | break;
127 | }
128 | case WM_LBUTTONDOWN:
129 | case WM_RBUTTONDOWN:
130 | {
131 | ::SetFocus(hwnd);
132 |
133 | break;
134 | }
135 | }
136 |
137 | return ::CallWindowProc(g_aviutlWindowProc, hwnd, message, wParam, lParam);
138 | }
139 |
140 | //---------------------------------------------------------------------
141 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow_Window_ExeditWindow.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "UniteWindow.h"
3 |
4 | //---------------------------------------------------------------------
5 |
6 | void ExEditWindow::init(HWND hwnd)
7 | {
8 | m_hwnd = hwnd;
9 | m_hwndContainer = createContainerWindow(
10 | hwnd, containerWndProc, _T("UniteWindow.ExEditWindow"));
11 |
12 | ::SetParent(m_hwnd, m_hwndContainer);
13 |
14 | DWORD style = ::GetWindowLong(m_hwnd, GWL_STYLE);
15 | style &= ~(WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
16 | style |= WS_CHILD;
17 | ::SetWindowLong(m_hwnd, GWL_STYLE, style);
18 | #if 0
19 | DWORD exStyle = ::GetWindowLong(m_hwnd, GWL_EXSTYLE);
20 | exStyle |= WS_EX_NOACTIVATE;
21 | ::SetWindowLong(m_hwnd, GWL_EXSTYLE, exStyle);
22 | #endif
23 | ::SetWindowPos(m_hwnd, 0, 0, 0, 0, 0,
24 | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
25 |
26 | g_exeditWindowProc = (WNDPROC)::SetWindowLongPtr(
27 | m_hwnd, GWLP_WNDPROC, (LONG_PTR)exeditWindowProc);
28 |
29 | DWORD exedit = (DWORD)::GetModuleHandle(_T("exedit.auf"));
30 | hookAbsoluteCall(exedit + 0x22128, Dropper_GetPixel);
31 |
32 | {
33 | BYTE code[6];
34 | code[0] = (BYTE)0x90; // NOP
35 | code[1] = (BYTE)0xBD; // MOV EBP,DWORD
36 | *(DWORD*)&code[2] = (DWORD)KeyboardHook_GetActiveWindow;
37 |
38 | writeCode(exedit + 0x30D0E, code, sizeof(code));
39 | }
40 | }
41 |
42 | LRESULT CALLBACK ExEditWindow::containerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
43 | {
44 | switch (message)
45 | {
46 | case WM_PAINT:
47 | {
48 | PAINTSTRUCT ps = {};
49 | HDC dc = ::BeginPaint(hwnd, &ps);
50 | HBRUSH brush = (HBRUSH)::SendMessage(hwnd, WM_CTLCOLORDLG, (WPARAM)dc, (LPARAM)hwnd);
51 | if (brush) ::FillRect(dc, &ps.rcPaint, brush);
52 | ::EndPaint(hwnd, &ps);
53 | return 0;
54 | }
55 | case WM_SIZE:
56 | {
57 | RECT rc; ::GetClientRect(hwnd, &rc);
58 |
59 | HWND child = getWindow(hwnd);
60 | RECT rcClient; ::GetClientRect(child, &rcClient);
61 | RECT rcWindow; ::GetWindowRect(child, &rcWindow);
62 | ::MapWindowPoints(child, 0, (POINT*)&rcClient, 2);
63 |
64 | rc.left += rcWindow.left - rcClient.left;
65 | rc.top += rcWindow.top - rcClient.top;
66 | rc.right += rcWindow.right - rcClient.right;
67 | rc.bottom += rcWindow.bottom - rcClient.bottom;
68 |
69 | rc.bottom -= g_auin.GetLayerHeight() / 2;
70 | ::SendMessage(child, WM_SIZING, WMSZ_BOTTOM, (LPARAM)&rc);
71 |
72 | int x = rc.left;
73 | int y = rc.top;
74 | int w = rc.right - rc.left;
75 | int h = rc.bottom - rc.top;
76 |
77 | ::MoveWindow(child, x, y, w, h, TRUE);
78 |
79 | break;
80 | }
81 | case WM_SETFOCUS:
82 | case WM_LBUTTONDOWN:
83 | case WM_RBUTTONDOWN:
84 | {
85 | ::SetFocus(g_exeditWindow.m_hwnd);
86 |
87 | break;
88 | }
89 | }
90 |
91 | return ::DefWindowProc(hwnd, message, wParam, lParam);
92 | }
93 |
94 | LRESULT CALLBACK exeditWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
95 | {
96 | switch (message)
97 | {
98 | case WM_NCPAINT:
99 | {
100 | HDC dc = ::GetWindowDC(hwnd);
101 | RECT rc; ::GetWindowRect(hwnd, &rc);
102 | ::OffsetRect(&rc, -rc.left, -rc.top);
103 | HBRUSH brush = (HBRUSH)::SendMessage(hwnd, WM_CTLCOLORDLG, (WPARAM)dc, (LPARAM)hwnd);
104 | if (brush) ::FillRect(dc, &rc, brush);
105 | ::ReleaseDC(hwnd, dc);
106 | return 0;
107 | }
108 | case WM_SETFOCUS:
109 | case WM_KILLFOCUS:
110 | {
111 | ::InvalidateRect(g_singleWindow, 0, FALSE);
112 |
113 | break;
114 | }
115 | case WM_LBUTTONDOWN:
116 | case WM_RBUTTONDOWN:
117 | {
118 | ::SetFocus(hwnd);
119 |
120 | break;
121 | }
122 | }
123 |
124 | return ::CallWindowProc(g_exeditWindowProc, hwnd, message, wParam, lParam);
125 | }
126 |
127 | //---------------------------------------------------------------------
128 |
--------------------------------------------------------------------------------
/UniteWindow/UniteWindow_Window_SettingDialog.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "UniteWindow.h"
3 |
4 | //---------------------------------------------------------------------
5 |
6 | void SettingDialog::init(HWND hwnd)
7 | {
8 | m_hwnd = hwnd;
9 | m_hwndContainer = createContainerWindow(
10 | hwnd, containerWndProc, _T("UniteWindow.SettingDialog"));
11 |
12 | ::SetParent(m_hwnd, m_hwndContainer);
13 |
14 | DWORD style = ::GetWindowLong(m_hwnd, GWL_STYLE);
15 | style &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
16 | style |= WS_CHILD;
17 | ::SetWindowLong(m_hwnd, GWL_STYLE, style);
18 | #if 0
19 | DWORD exStyle = ::GetWindowLong(m_hwnd, GWL_EXSTYLE);
20 | exStyle |= WS_EX_NOACTIVATE;
21 | ::SetWindowLong(m_hwnd, GWL_EXSTYLE, exStyle);
22 | #endif
23 | ::SetWindowPos(m_hwnd, 0, 0, 0, 0, 0,
24 | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
25 | }
26 |
27 | void SettingDialog::updateScrollBar()
28 | {
29 | RECT rc; ::GetClientRect(m_hwnd, &rc);
30 | int w = rc.right - rc.left;
31 | int h = rc.bottom - rc.top;
32 |
33 | RECT rcContainer; ::GetClientRect(m_hwndContainer, &rcContainer);
34 | int cw = rcContainer.right - rcContainer.left;
35 | int ch = rcContainer.bottom - rcContainer.top;
36 |
37 | SCROLLINFO si = { sizeof(si) };
38 | si.fMask = SIF_PAGE | SIF_RANGE | SIF_DISABLENOSCROLL;
39 | si.nMin = 0;
40 | si.nMax = w - 1;
41 | si.nPage = cw;
42 | ::SetScrollInfo(m_hwndContainer, SB_HORZ, &si, TRUE);
43 | si.nMin = 0;
44 | si.nMax = h - 1;
45 | si.nPage = ch;
46 | ::SetScrollInfo(m_hwndContainer, SB_VERT, &si, TRUE);
47 | }
48 |
49 | void SettingDialog::scroll(int bar, WPARAM wParam)
50 | {
51 | SCROLLINFO si = { sizeof(si) };
52 | si.fMask = SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;
53 | ::GetScrollInfo(m_hwndContainer, bar, &si);
54 |
55 | switch (LOWORD(wParam))
56 | {
57 | case SB_LEFT: si.nPos = si.nMin; break;
58 | case SB_RIGHT: si.nPos = si.nMax; break;
59 | case SB_LINELEFT: si.nPos += -10; break;
60 | case SB_LINERIGHT: si.nPos += 10; break;
61 | case SB_PAGELEFT: si.nPos += -60; break;
62 | case SB_PAGERIGHT: si.nPos += 60; break;
63 | case SB_THUMBTRACK:
64 | case SB_THUMBPOSITION: si.nPos = HIWORD(wParam); break;
65 | }
66 |
67 | ::SetScrollInfo(m_hwndContainer, bar, &si, TRUE);
68 | }
69 |
70 | void SettingDialog::recalcLayout()
71 | {
72 | RECT rc; ::GetClientRect(m_hwndContainer, &rc);
73 |
74 | RECT rcClient; ::GetClientRect(m_hwnd, &rcClient);
75 | RECT rcWindow; ::GetWindowRect(m_hwnd, &rcWindow);
76 | ::MapWindowPoints(m_hwnd, 0, (POINT*)&rcClient, 2);
77 |
78 | rc.left += rcWindow.left - rcClient.left;
79 | rc.top += rcWindow.top - rcClient.top;
80 | rc.right += rcWindow.right - rcClient.right;
81 | rc.bottom += rcWindow.bottom - rcClient.bottom;
82 |
83 | int x = rc.left;
84 | int y = rc.top;
85 | int w = rc.right - rc.left;
86 | int h = rc.bottom - rc.top;
87 |
88 | x -= ::GetScrollPos(m_hwndContainer, SB_HORZ);
89 | y -= ::GetScrollPos(m_hwndContainer, SB_VERT);
90 |
91 | ::SetWindowPos(m_hwnd, 0, x, y, 0, 0,
92 | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
93 | }
94 |
95 | // 設定ダイアログのサイズをコンテナウィンドウのサイズまで広げる。
96 | void SettingDialog::extend()
97 | {
98 | RECT rc; ::GetWindowRect(m_hwnd, &rc);
99 | RECT rcContainer; ::GetWindowRect(m_hwndContainer, &rcContainer);
100 |
101 | int w = rc.right - rc.left;
102 | int h = m_rawWindowSize.cy;
103 | int cw = rcContainer.right - rcContainer.left;
104 | int ch = rcContainer.bottom - rcContainer.top;
105 |
106 | // 初期化が完全に終わっていないときは何もしない。
107 | if (w == 0 || h == 0 || cw == 0 || ch == 0) return;
108 |
109 | // WM_SIZE ハンドラをブロック状態にしてからサイズを変更する。
110 | m_blockSizeHandler = TRUE;
111 | ::SetWindowPos(m_hwnd, 0, 0, 0, w, max(h, ch),
112 | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
113 | m_blockSizeHandler = FALSE;
114 | }
115 |
116 | LRESULT CALLBACK SettingDialog::containerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
117 | {
118 | switch (message)
119 | {
120 | case WM_SETFOCUS:
121 | case WM_LBUTTONDOWN:
122 | case WM_RBUTTONDOWN:
123 | {
124 | ::SetFocus(g_settingDialog.m_hwnd);
125 |
126 | break;
127 | }
128 | }
129 |
130 | switch (message)
131 | {
132 | case WM_PAINT:
133 | {
134 | PAINTSTRUCT ps = {};
135 | HDC dc = ::BeginPaint(hwnd, &ps);
136 | HBRUSH brush = ::CreateSolidBrush(g_fillColor);
137 | FillRect(dc, &ps.rcPaint, brush);
138 | ::DeleteObject(brush);
139 | ::EndPaint(hwnd, &ps);
140 | return 0;
141 | }
142 | case WM_SIZE:
143 | {
144 | g_settingDialog.updateScrollBar();
145 | g_settingDialog.recalcLayout();
146 |
147 | g_settingDialog.extend();
148 |
149 | break;
150 | }
151 | case WM_VSCROLL:
152 | {
153 | g_settingDialog.scroll(SB_VERT, wParam);
154 | g_settingDialog.recalcLayout();
155 |
156 | break;
157 | }
158 | case WM_HSCROLL:
159 | {
160 | g_settingDialog.scroll(SB_HORZ, wParam);
161 | g_settingDialog.recalcLayout();
162 |
163 | break;
164 | }
165 | case WM_RBUTTONDOWN:
166 | case WM_RBUTTONUP:
167 | {
168 | // マウス座標を取得する。
169 | POINT point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
170 |
171 | // マウス座標を変換する。
172 | ::MapWindowPoints(hwnd, g_settingDialog.m_hwnd, &point, 1);
173 |
174 | // 設定ダイアログにメッセージを転送する。
175 | return ::SendMessage(g_settingDialog.m_hwnd, message, wParam, MAKELPARAM(point.x, point.y));
176 | }
177 | case WM_MOUSEWHEEL:
178 | {
179 | MY_TRACE(_T("SettingDialog::containerWndProc(WM_MOUSEWHEEL, %d)\n"), wParam);
180 |
181 | g_settingDialog.scroll(SB_VERT, ((int)wParam > 0) ? SB_PAGEUP : SB_PAGEDOWN);
182 | g_settingDialog.recalcLayout();
183 |
184 | break;
185 | }
186 | }
187 |
188 | return ::DefWindowProc(hwnd, message, wParam, lParam);
189 | }
190 |
191 | IMPLEMENT_HOOK_PROC_NULL(LRESULT, WINAPI, SettingDialogProc, (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam))
192 | {
193 | switch (message)
194 | {
195 | case WM_GETMINMAXINFO:
196 | {
197 | MY_TRACE(_T("SettingDialogProc(WM_GETMINMAXINFO)\n"));
198 |
199 | MINMAXINFO* mmi = (MINMAXINFO*)lParam;
200 | mmi->ptMaxTrackSize.y *= 3;
201 |
202 | break;
203 | }
204 | case WM_SIZE:
205 | {
206 | MY_TRACE(_T("SettingDialogProc(WM_SIZE)\n"));
207 |
208 | // WM_SIZE ハンドラがブロックされているときは何もしない。
209 | if (g_settingDialog.m_blockSizeHandler) break;
210 |
211 | // 元のウィンドウ矩形のサイズを取得しておく。
212 | RECT rc; ::GetWindowRect(g_settingDialog.m_hwnd, &rc);
213 | g_settingDialog.m_rawWindowSize.cx = rc.right - rc.left;
214 | g_settingDialog.m_rawWindowSize.cy = rc.bottom - rc.top;
215 |
216 | g_settingDialog.updateScrollBar();
217 | g_settingDialog.recalcLayout();
218 | ::InvalidateRect(g_settingDialog.m_hwndContainer, 0, FALSE);
219 |
220 | g_settingDialog.extend();
221 |
222 | break;
223 | }
224 | case WM_SETFOCUS:
225 | case WM_KILLFOCUS:
226 | {
227 | ::InvalidateRect(g_singleWindow, 0, FALSE);
228 |
229 | break;
230 | }
231 | case WM_LBUTTONDOWN:
232 | case WM_RBUTTONDOWN:
233 | {
234 | ::SetFocus(hwnd);
235 |
236 | break;
237 | }
238 | case WM_MOUSEWHEEL:
239 | {
240 | // 既定の処理をブロックし、コンテナウィンドウへバイパス
241 | ::SendMessage(g_settingDialog.m_hwndContainer, message, wParam, lParam);
242 | return 0;
243 | }
244 | }
245 |
246 | return true_SettingDialogProc(hwnd, message, wParam, lParam);
247 | }
248 |
249 | //---------------------------------------------------------------------
250 |
--------------------------------------------------------------------------------
/UniteWindow/pch.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 |
--------------------------------------------------------------------------------
/UniteWindow/pch.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define ISOLATION_AWARE_ENABLED 1
4 | #define WIN32_LEAN_AND_MEAN
5 | #include
6 | #include
7 | #include
8 | #pragma comment(lib, "shlwapi.lib")
9 | #include
10 | #pragma comment(lib, "comctl32.lib")
11 | #include
12 | #pragma comment(lib, "comdlg32.lib")
13 | #include
14 | #include
15 | #include
16 | #pragma comment(lib, "uxtheme.lib")
17 | #include
18 | #pragma comment(lib, "winmm.lib")
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 | #import
26 |
27 | #include "AviUtl/aviutl_plugin_sdk/filter.h"
28 | #include "AviUtl/aviutl_exedit_sdk/aviutl.hpp"
29 | #include "AviUtl/aviutl_exedit_sdk/exedit.hpp"
30 | #include "Common/Tracer.h"
31 | #include "Common/Dialog.h"
32 | #include "Common/MSXML.h"
33 | #include "Common/Hook.h"
34 | #include "Common/AviUtlInternal.h"
35 | #include "Detours.4.0.1/detours.h"
36 | #pragma comment(lib, "Detours.4.0.1/detours.lib")
37 |
38 | #pragma comment(linker,"\"/manifestdependency:type='win32' \
39 | name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
40 | processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
41 |
--------------------------------------------------------------------------------
/UniteWindow/resource.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hebiiro/AviUtl-Plugin-UniteWindow/db5ad9837eb88479afbea34fc84eb3bafd73d607/UniteWindow/resource.h
--------------------------------------------------------------------------------