├── .gitattributes ├── .gitignore ├── CodesLab ├── WebView2Caller.ec ├── WebView2_Caller.dll ├── WebView2_Caller.exp ├── WebView2_Caller.lib ├── browser.exe ├── ewebview2.e ├── ewv2_test.e ├── 更新日志.txt └── 用前阅读.txt ├── LICENSE.txt ├── README.md ├── WebView2_Caller.sln ├── WebView2_Caller ├── WebView2_Caller.vcxproj ├── WebView2_Caller.vcxproj.filters ├── dll_exportres.rc ├── dllmain.cc ├── packages.config └── resource.h └── src ├── wv2_contextmenu.cc ├── wv2_contextmenu.h ├── wv2_controller.cc ├── wv2_controller.h ├── wv2_cookie.cc ├── wv2_cookie.h ├── wv2_download.cc ├── wv2_download.h ├── wv2_env.cc ├── wv2_env.h ├── wv2_frame.cc ├── wv2_frame.h ├── wv2_types.h ├── wv2_utils.cc ├── wv2_utils.h ├── wv2_webrequest.cc ├── wv2_webrequest.h ├── wv2_webview.cc └── wv2_webview.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 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd 364 | /CodesLab/browser.exe.WebView2/EBWebView 365 | -------------------------------------------------------------------------------- /CodesLab/WebView2Caller.ec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Admenri/WebView2Caller/be5beeeb969fe1662798a4e138b6b3ef57199524/CodesLab/WebView2Caller.ec -------------------------------------------------------------------------------- /CodesLab/WebView2_Caller.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Admenri/WebView2Caller/be5beeeb969fe1662798a4e138b6b3ef57199524/CodesLab/WebView2_Caller.dll -------------------------------------------------------------------------------- /CodesLab/WebView2_Caller.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Admenri/WebView2Caller/be5beeeb969fe1662798a4e138b6b3ef57199524/CodesLab/WebView2_Caller.exp -------------------------------------------------------------------------------- /CodesLab/WebView2_Caller.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Admenri/WebView2Caller/be5beeeb969fe1662798a4e138b6b3ef57199524/CodesLab/WebView2_Caller.lib -------------------------------------------------------------------------------- /CodesLab/browser.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Admenri/WebView2Caller/be5beeeb969fe1662798a4e138b6b3ef57199524/CodesLab/browser.exe -------------------------------------------------------------------------------- /CodesLab/ewebview2.e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Admenri/WebView2Caller/be5beeeb969fe1662798a4e138b6b3ef57199524/CodesLab/ewebview2.e -------------------------------------------------------------------------------- /CodesLab/ewv2_test.e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Admenri/WebView2Caller/be5beeeb969fe1662798a4e138b6b3ef57199524/CodesLab/ewv2_test.e -------------------------------------------------------------------------------- /CodesLab/更新日志.txt: -------------------------------------------------------------------------------- 1 | 2023年1月8日 2 | 1.补全WebMessage功能 3 | 4 | 2022年12月22日 5 | 补全一部分注释 6 | 添加一部分功能 7 | 8 | 2022年12月17日 9 | 添加WebMessage事件 10 | 调整js回调方式 11 | 12 | 2022年12月13日 13 | 添加下载功能支持 14 | 修改创建环境的参数格式 15 | 16 | 2022年12月12日 17 | 更新Microsoft.Web.Webview2组件 18 | 增加自定义菜单功能 19 | 增加发送请求功能 20 | 21 | ^_^中间略 22 | 23 | 2022年11月29日 24 | 重构模块结构 25 | 26 | 2022年11月28日 27 | 第一个早期测试版本发布 -------------------------------------------------------------------------------- /CodesLab/用前阅读.txt: -------------------------------------------------------------------------------- 1 | dll源码以Apache-2.0开源:https://github.com/Admenri/WebView2Caller 2 | webview2的处理消息为WM_USER+1 3 | 处理webview2消息的窗口类名为Chrome_MessageWindow 4 | 注意不要在事件中使用同步方法,会卡死 5 | 当然你可以把你的任务分到另一个线程,UI线程作为另一个线程来运行, 6 | 这样就可以实现事件内同步的操作。 7 | 8 | 为什么不写成支持库? 9 | 1. 曾经用VC6写过支持库,不想再回味一遍当年的痛苦了。 10 | 2. 支持库的话就要用到窗口组件了,这样黑月可以直接出局了。 11 | 3. 说不定会出现莫名其妙的编译错误。 12 | 4. 模块替换+更新版本特别方便。 13 | 14 | ——Admenri 2022.12.12 QQ 2755482106 -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WebView2Caller 2 | Microsoft.WebView2.Component for EPL port 3 | 4 | 5 | # Donate 6 | https://afdian.net/a/libacf 7 | -------------------------------------------------------------------------------- /WebView2_Caller.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.32630.194 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WebView2_Caller", "WebView2_Caller\WebView2_Caller.vcxproj", "{745CBF71-9291-462C-8909-E897DF00FD19}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {745CBF71-9291-462C-8909-E897DF00FD19}.Debug|x64.ActiveCfg = Debug|x64 17 | {745CBF71-9291-462C-8909-E897DF00FD19}.Debug|x64.Build.0 = Debug|x64 18 | {745CBF71-9291-462C-8909-E897DF00FD19}.Debug|x86.ActiveCfg = Debug|Win32 19 | {745CBF71-9291-462C-8909-E897DF00FD19}.Debug|x86.Build.0 = Debug|Win32 20 | {745CBF71-9291-462C-8909-E897DF00FD19}.Release|x64.ActiveCfg = Release|x64 21 | {745CBF71-9291-462C-8909-E897DF00FD19}.Release|x64.Build.0 = Release|x64 22 | {745CBF71-9291-462C-8909-E897DF00FD19}.Release|x86.ActiveCfg = Release|Win32 23 | {745CBF71-9291-462C-8909-E897DF00FD19}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {904E77AE-A9F3-429D-A7B8-62A1CEB9FC83} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /WebView2_Caller/WebView2_Caller.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 | {745cbf71-9291-462c-8909-e897df00fd19} 25 | WebView2Caller 26 | 10.0 27 | Static 28 | 29 | 30 | 31 | DynamicLibrary 32 | true 33 | v142 34 | Unicode 35 | Static 36 | 37 | 38 | DynamicLibrary 39 | false 40 | v142 41 | true 42 | Unicode 43 | Static 44 | 45 | 46 | DynamicLibrary 47 | true 48 | v142 49 | Unicode 50 | Static 51 | 52 | 53 | DynamicLibrary 54 | false 55 | v142 56 | true 57 | Unicode 58 | Static 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | true 80 | 81 | 82 | false 83 | $(SolutionDir)CodesLab\ 84 | 85 | 86 | true 87 | 88 | 89 | false 90 | 91 | 92 | 93 | Level3 94 | true 95 | WIN32;_DEBUG;WEBVIEW2CALLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 96 | true 97 | NotUsing 98 | pch.h 99 | 100 | 101 | Windows 102 | true 103 | false 104 | shlwapi.lib;kernel32.lib;user32.lib;shell32.lib;Advapi32.lib 105 | 106 | 107 | 108 | 109 | Level3 110 | true 111 | true 112 | true 113 | WIN32;NDEBUG;WEBVIEW2CALLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 114 | true 115 | NotUsing 116 | pch.h 117 | stdcpp20 118 | 119 | 120 | Windows 121 | true 122 | true 123 | true 124 | false 125 | shlwapi.lib;kernel32.lib;user32.lib;shell32.lib;Advapi32.lib 126 | 127 | 128 | 129 | 130 | Level3 131 | true 132 | _DEBUG;WEBVIEW2CALLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 133 | true 134 | NotUsing 135 | pch.h 136 | 137 | 138 | Windows 139 | true 140 | false 141 | shlwapi.lib;kernel32.lib;user32.lib;shell32.lib;Advapi32.lib 142 | 143 | 144 | 145 | 146 | Level3 147 | true 148 | true 149 | true 150 | NDEBUG;WEBVIEW2CALLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 151 | true 152 | NotUsing 153 | pch.h 154 | 155 | 156 | Windows 157 | true 158 | true 159 | true 160 | false 161 | shlwapi.lib;kernel32.lib;user32.lib;shell32.lib;Advapi32.lib 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /WebView2_Caller/WebView2_Caller.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {c1d08833-01d5-4fb0-996c-e66924e260b1} 10 | 11 | 12 | {f3e6e473-a93c-4250-9c99-87691c6a8c15} 13 | 14 | 15 | 16 | 17 | src 18 | 19 | 20 | src 21 | 22 | 23 | src 24 | 25 | 26 | src 27 | 28 | 29 | src 30 | 31 | 32 | src 33 | 34 | 35 | src 36 | 37 | 38 | src 39 | 40 | 41 | src 42 | 43 | 44 | src 45 | 46 | 47 | 48 | 49 | src 50 | 51 | 52 | src 53 | 54 | 55 | src 56 | 57 | 58 | src 59 | 60 | 61 | src 62 | 63 | 64 | res 65 | 66 | 67 | src 68 | 69 | 70 | src 71 | 72 | 73 | src 74 | 75 | 76 | src 77 | 78 | 79 | src 80 | 81 | 82 | 83 | 84 | res 85 | 86 | 87 | 88 | 89 | e_port 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /WebView2_Caller/dll_exportres.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Admenri/WebView2Caller/be5beeeb969fe1662798a4e138b6b3ef57199524/WebView2_Caller/dll_exportres.rc -------------------------------------------------------------------------------- /WebView2_Caller/dllmain.cc: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : 定义 DLL 应用程序的入口点。 2 | #include 3 | 4 | BOOL APIENTRY DllMain( HMODULE hModule, 5 | DWORD ul_reason_for_call, 6 | LPVOID lpReserved 7 | ) 8 | { 9 | switch (ul_reason_for_call) 10 | { 11 | case DLL_PROCESS_ATTACH: 12 | case DLL_THREAD_ATTACH: 13 | case DLL_THREAD_DETACH: 14 | case DLL_PROCESS_DETACH: 15 | break; 16 | } 17 | return TRUE; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /WebView2_Caller/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /WebView2_Caller/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Admenri/WebView2Caller/be5beeeb969fe1662798a4e138b6b3ef57199524/WebView2_Caller/resource.h -------------------------------------------------------------------------------- /src/wv2_contextmenu.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "wv2_contextmenu.h" 3 | using namespace Microsoft; 4 | 5 | DLL_EXPORTS(Webview_ContextMenuArgs_GetDeferral, BOOL) 6 | (ICoreWebView2ContextMenuRequestedEventArgs* args) { 7 | if (!args) return FALSE; 8 | 9 | ICoreWebView2Deferral* deferral = nullptr; 10 | HRESULT hr = args->GetDeferral(&deferral); 11 | 12 | return SUCCEEDED(hr); 13 | } 14 | 15 | DLL_EXPORTS(Webview_ContextMenuArgs_Handled_Attr, BOOL) 16 | (ICoreWebView2ContextMenuRequestedEventArgs* args, BOOL get, BOOL value) { 17 | if (!args) return FALSE; 18 | 19 | if (get) { 20 | BOOL handled = FALSE; 21 | args->get_Handled(&handled); 22 | return handled; 23 | } else { 24 | return SUCCEEDED(args->put_Handled(value)); 25 | } 26 | } 27 | 28 | DLL_EXPORTS(Webview_ContextMenuArgs_SelectedCommandID_Attr, int) 29 | (ICoreWebView2ContextMenuRequestedEventArgs* args, BOOL get, int value) { 30 | if (!args) return FALSE; 31 | 32 | if (get) { 33 | int handled = 0; 34 | args->get_SelectedCommandId(&handled); 35 | return handled; 36 | } else { 37 | return SUCCEEDED(args->put_SelectedCommandId(value)); 38 | } 39 | } 40 | 41 | DLL_EXPORTS(Webview_ContextMenuArgs_GetPos, BOOL) 42 | (ICoreWebView2ContextMenuRequestedEventArgs* args, POINT* pt) { 43 | if (!args) return FALSE; 44 | 45 | return SUCCEEDED(args->get_Location(pt)); 46 | } 47 | 48 | DLL_EXPORTS(Webview_ContextMenuArgs_GetTargetInfo, int) 49 | (ICoreWebView2ContextMenuRequestedEventArgs* args, int id, LPVOID* ptr, 50 | uint32_t* size) { 51 | if (!args) return FALSE; 52 | 53 | WRL::ComPtr target = nullptr; 54 | HRESULT hr = args->get_ContextMenuTarget(&target); 55 | 56 | COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND kind; 57 | BOOL value = FALSE; 58 | LPWSTR v = nullptr; 59 | 60 | switch (id) { 61 | case 0: 62 | target->get_Kind(&kind); 63 | return kind; 64 | break; 65 | case 1: 66 | target->get_IsEditable(&value); 67 | return value; 68 | break; 69 | case 2: 70 | target->get_IsRequestedForMainFrame(&value); 71 | return value; 72 | break; 73 | case 3: 74 | target->get_PageUri(&v); 75 | *ptr = v; 76 | *size = lstrlenW(v) * 2 + 2; 77 | break; 78 | case 4: 79 | target->get_FrameUri(&v); 80 | *ptr = v; 81 | *size = lstrlenW(v) * 2 + 2; 82 | break; 83 | case 5: 84 | target->get_HasLinkUri(&value); 85 | return value; 86 | break; 87 | case 6: 88 | target->get_LinkUri(&v); 89 | *ptr = v; 90 | *size = lstrlenW(v) * 2 + 2; 91 | break; 92 | case 7: 93 | target->get_HasLinkText(&value); 94 | return value; 95 | break; 96 | case 8: 97 | target->get_LinkText(&v); 98 | *ptr = v; 99 | *size = lstrlenW(v) * 2 + 2; 100 | break; 101 | case 9: 102 | target->get_HasSourceUri(&value); 103 | return value; 104 | break; 105 | case 10: 106 | target->get_SourceUri(&v); 107 | *ptr = v; 108 | *size = lstrlenW(v) * 2 + 2; 109 | break; 110 | case 11: 111 | target->get_HasSelection(&value); 112 | return value; 113 | break; 114 | case 12: 115 | target->get_SelectionText(&v); 116 | *ptr = v; 117 | *size = lstrlenW(v) * 2 + 2; 118 | break; 119 | default: 120 | // unreached 121 | break; 122 | } 123 | 124 | return SUCCEEDED(hr); 125 | } 126 | 127 | DLL_EXPORTS(Webview_ContextMenuArgs_GetItemCollection, BOOL) 128 | (ICoreWebView2ContextMenuRequestedEventArgs* args, LPVOID* ptr) { 129 | if (!args) return FALSE; 130 | 131 | ICoreWebView2ContextMenuItemCollection* items = nullptr; 132 | HRESULT hr = args->get_MenuItems(&items); 133 | 134 | *ptr = items; 135 | 136 | return SUCCEEDED(hr); 137 | } 138 | 139 | 140 | DLL_EXPORTS(MenuItemCollection_GetCount, uint32_t) 141 | (ICoreWebView2ContextMenuItemCollection* args) { 142 | if (!args) return FALSE; 143 | 144 | uint32_t count = 0; 145 | args->get_Count(&count); 146 | 147 | return count; 148 | } 149 | 150 | DLL_EXPORTS(MenuItemCollection_GetValueAt, BOOL) 151 | (ICoreWebView2ContextMenuItemCollection* args, uint32_t index, LPVOID* ptr) { 152 | if (!args) return FALSE; 153 | 154 | ICoreWebView2ContextMenuItem* value = nullptr; 155 | HRESULT hr = args->GetValueAtIndex(index, &value); 156 | 157 | *ptr = value; 158 | 159 | return SUCCEEDED(hr); 160 | } 161 | 162 | DLL_EXPORTS(MenuItemCollection_RemoveAt, BOOL) 163 | (ICoreWebView2ContextMenuItemCollection* args, uint32_t index) { 164 | if (!args) return FALSE; 165 | 166 | return SUCCEEDED(args->RemoveValueAtIndex(index)); 167 | } 168 | 169 | DLL_EXPORTS(MenuItemCollection_InsertAt, BOOL) 170 | (ICoreWebView2ContextMenuItemCollection* args, uint32_t index, 171 | ICoreWebView2ContextMenuItem* item) { 172 | if (!args) return FALSE; 173 | 174 | return SUCCEEDED(args->InsertValueAtIndex(index, item)); 175 | } 176 | 177 | 178 | DLL_EXPORTS(MenuItem_GetName, BOOL) 179 | (ICoreWebView2ContextMenuItem* item, LPVOID* ptr, uint32_t* size) { 180 | if (!item) return FALSE; 181 | 182 | LPWSTR value = nullptr; 183 | HRESULT hr = item->get_Name(&value); 184 | 185 | *ptr = value; 186 | *size = lstrlenW(value); 187 | 188 | return SUCCEEDED(hr); 189 | } 190 | 191 | DLL_EXPORTS(MenuItem_GetLabel, BOOL) 192 | (ICoreWebView2ContextMenuItem* item, LPVOID* ptr, uint32_t* size) { 193 | if (!item) return FALSE; 194 | 195 | LPWSTR value = nullptr; 196 | HRESULT hr = item->get_Label(&value); 197 | 198 | *ptr = value; 199 | *size = lstrlenW(value); 200 | 201 | return SUCCEEDED(hr); 202 | } 203 | 204 | DLL_EXPORTS(MenuItem_GetCommandID, int) 205 | (ICoreWebView2ContextMenuItem* item) { 206 | if (!item) return FALSE; 207 | 208 | int value = 0; 209 | item->get_CommandId(&value); 210 | 211 | return value; 212 | } 213 | 214 | DLL_EXPORTS(MenuItem_GetShortcutKeyDescription, BOOL) 215 | (ICoreWebView2ContextMenuItem* item, LPVOID* ptr, uint32_t* size) { 216 | if (!item) return FALSE; 217 | 218 | LPWSTR value = nullptr; 219 | HRESULT hr = item->get_ShortcutKeyDescription(&value); 220 | 221 | *ptr = value; 222 | *size = lstrlenW(value); 223 | 224 | return SUCCEEDED(hr); 225 | } 226 | 227 | DLL_EXPORTS(MenuItem_GetIcon, BOOL) 228 | (ICoreWebView2ContextMenuItem* obj, LPVOID* pptr, uint32_t* psize) { 229 | if (!obj) return FALSE; 230 | 231 | WRL::ComPtr is = nullptr; 232 | auto ret = SUCCEEDED(obj->get_Icon(&is)); 233 | 234 | if (!is) return FALSE; 235 | 236 | STATSTG stat; 237 | is->Stat(&stat, STATFLAG_NONAME); 238 | 239 | LARGE_INTEGER linfo; 240 | linfo.QuadPart = 0; 241 | is->Seek(linfo, STREAM_SEEK_SET, NULL); 242 | 243 | uint32_t size = stat.cbSize.LowPart; 244 | uint8_t* buf = static_cast(wv2_Utility_Malloc(size)); 245 | ULONG dummy = 0; 246 | is->Read(buf, size, &dummy); 247 | 248 | *pptr = buf; 249 | *psize = size; 250 | 251 | return ret; 252 | } 253 | 254 | DLL_EXPORTS(MenuItem_GetType, int) 255 | (ICoreWebView2ContextMenuItem* item) { 256 | if (!item) return FALSE; 257 | 258 | COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND value; 259 | item->get_Kind(&value); 260 | 261 | return value; 262 | } 263 | 264 | DLL_EXPORTS(MenuItem_Enabled_Attr, BOOL) 265 | (ICoreWebView2ContextMenuItem* item, BOOL get, BOOL value) { 266 | if (!item) return FALSE; 267 | 268 | if (get) { 269 | BOOL value = FALSE; 270 | item->get_IsEnabled(&value); 271 | return value; 272 | } else { 273 | return SUCCEEDED(item->put_IsEnabled(value)); 274 | } 275 | } 276 | 277 | DLL_EXPORTS(MenuItem_Checked_Attr, BOOL) 278 | (ICoreWebView2ContextMenuItem* item, BOOL get, BOOL value) { 279 | if (!item) return FALSE; 280 | 281 | if (get) { 282 | BOOL value = FALSE; 283 | item->get_IsChecked(&value); 284 | return value; 285 | } else { 286 | return SUCCEEDED(item->put_IsChecked(value)); 287 | } 288 | } 289 | 290 | DLL_EXPORTS(MenuItem_GetChildren, BOOL) 291 | (ICoreWebView2ContextMenuItem* item, LPVOID* ptr) { 292 | if (!item) return FALSE; 293 | 294 | ICoreWebView2ContextMenuItemCollection* value = nullptr; 295 | HRESULT hr = item->get_Children(&value); 296 | 297 | *ptr = value; 298 | 299 | return SUCCEEDED(hr); 300 | } 301 | 302 | using ContextMenuSelectedCB = HRESULT(CALLBACK*)(LPVOID item, LPVOID param); 303 | DLL_EXPORTS(MenuItem_Attach_ItemSelected, int64_t) 304 | (ICoreWebView2ContextMenuItem* item, ContextMenuSelectedCB callback, 305 | LPVOID param) { 306 | if (!item) return FALSE; 307 | 308 | EventRegistrationToken token; 309 | 310 | item->add_CustomItemSelected( 311 | WRL::Callback( 312 | [callback, param](ICoreWebView2ContextMenuItem* sender, 313 | IUnknown* args) -> HRESULT { 314 | sender->AddRef(); 315 | 316 | HRESULT hr = callback(sender, param); 317 | 318 | return hr; 319 | }) 320 | .Get(), 321 | &token); 322 | 323 | return token.value; 324 | } 325 | 326 | DLL_EXPORTS(MenuItem_Detach_ItemSelected, BOOL) 327 | (ICoreWebView2ContextMenuItem* item, int64_t value) { 328 | if (!item) return FALSE; 329 | EventRegistrationToken token = {value}; 330 | 331 | return SUCCEEDED(item->remove_CustomItemSelected(token)); 332 | } 333 | -------------------------------------------------------------------------------- /src/wv2_contextmenu.h: -------------------------------------------------------------------------------- 1 | #ifndef WV2_CONTEXT_MENU_H 2 | #define WV2_CONTEXT_MENU_H 3 | #pragma once 4 | 5 | #include "wv2_utils.h" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/wv2_controller.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "wv2_controller.h" 3 | #include "wv2_utils.h" 4 | 5 | using namespace Microsoft; 6 | 7 | DLL_EXPORTS(Controller_Close, BOOL)(ICoreWebView2Controller* controller) { 8 | if (!controller) return FALSE; 9 | 10 | auto ret = SUCCEEDED(controller->Close()); 11 | return ret; 12 | } 13 | 14 | DLL_EXPORTS(Controller_GetWebview2, BOOL) 15 | (ICoreWebView2Controller* controller, LPVOID* retPtr) { 16 | if (!controller) return FALSE; 17 | 18 | ICoreWebView2* wv2 = nullptr; 19 | 20 | auto ret = SUCCEEDED(controller->get_CoreWebView2(&wv2)); 21 | 22 | *retPtr = wv2; 23 | 24 | return ret; 25 | } 26 | 27 | DLL_EXPORTS(Controller_GetVisible, BOOL)(ICoreWebView2Controller* controller) { 28 | if (!controller) return FALSE; 29 | 30 | BOOL ret = FALSE; 31 | 32 | controller->get_IsVisible(&ret); 33 | return ret; 34 | } 35 | 36 | DLL_EXPORTS(Controller_SetVisible, BOOL) 37 | (ICoreWebView2Controller* controller, BOOL visible) { 38 | if (!controller) return FALSE; 39 | 40 | auto ret = SUCCEEDED(controller->put_IsVisible(visible)); 41 | return ret; 42 | } 43 | 44 | DLL_EXPORTS(Controller_GetBounds, BOOL) 45 | (ICoreWebView2Controller* controller, RECT* rect) { 46 | if (!controller) return FALSE; 47 | 48 | auto ret = SUCCEEDED(controller->get_Bounds(rect)); 49 | return ret; 50 | } 51 | 52 | DLL_EXPORTS(Controller_SetBounds, BOOL) 53 | (ICoreWebView2Controller* controller, RECT* rect) { 54 | if (!controller) return FALSE; 55 | 56 | auto ret = SUCCEEDED(controller->put_Bounds(*rect)); 57 | return ret; 58 | } 59 | 60 | DLL_EXPORTS(Controller_GetZoomFactor, BOOL) 61 | (ICoreWebView2Controller* controller, double* zoom) { 62 | if (!controller) return FALSE; 63 | 64 | auto ret = SUCCEEDED(controller->get_ZoomFactor(zoom)); 65 | return ret; 66 | } 67 | 68 | DLL_EXPORTS(Controller_SetZoomFactor, BOOL) 69 | (ICoreWebView2Controller* controller, double zoom) { 70 | if (!controller) return FALSE; 71 | 72 | auto ret = SUCCEEDED(controller->put_ZoomFactor(zoom)); 73 | return ret; 74 | } 75 | 76 | DLL_EXPORTS(Controller_NotifyParentChanged, BOOL) 77 | (ICoreWebView2Controller* controller) { 78 | if (!controller) return FALSE; 79 | 80 | auto ret = SUCCEEDED(controller->NotifyParentWindowPositionChanged()); 81 | return ret; 82 | } 83 | 84 | DLL_EXPORTS(Controller_GetParent, BOOL) 85 | (ICoreWebView2Controller* controller, HWND* zoom) { 86 | if (!controller) return FALSE; 87 | 88 | auto ret = SUCCEEDED(controller->get_ParentWindow(zoom)); 89 | return ret; 90 | } 91 | 92 | DLL_EXPORTS(Controller_SetParent, BOOL) 93 | (ICoreWebView2Controller* controller, HWND zoom) { 94 | if (!controller) return FALSE; 95 | 96 | auto ret = SUCCEEDED(controller->put_ParentWindow(zoom)); 97 | return ret; 98 | } 99 | 100 | struct BGColor { 101 | uint8_t a; 102 | uint8_t r; 103 | uint8_t g; 104 | uint8_t b; 105 | }; 106 | 107 | DLL_EXPORTS(Controller_GetBackgroundColor, BOOL) 108 | (ICoreWebView2Controller* controller, BGColor* cr) { 109 | if (!controller) return FALSE; 110 | 111 | WRL::ComPtr con = nullptr; 112 | controller->QueryInterface(&con); 113 | 114 | auto ret = SUCCEEDED(con->get_DefaultBackgroundColor( 115 | reinterpret_cast(cr))); 116 | return ret; 117 | } 118 | 119 | DLL_EXPORTS(Controller_SetBackgroundColor, BOOL) 120 | (ICoreWebView2Controller* controller, BGColor* cr) { 121 | if (!controller) return FALSE; 122 | 123 | WRL::ComPtr con = nullptr; 124 | controller->QueryInterface(&con); 125 | 126 | auto ret = SUCCEEDED(con->put_DefaultBackgroundColor( 127 | *reinterpret_cast(cr))); 128 | return ret; 129 | } 130 | 131 | using AcceleratorKeyPressedCB = BOOL(CALLBACK*)(LPVOID controller, COREWEBVIEW2_KEY_EVENT_KIND type, 132 | uint32_t vkey, int32_t lparam, uint32_t repeat, uint32_t scancode, BOOL extendkey, BOOL menukeydown, 133 | BOOL keydown, BOOL keyrelease, LPVOID param); 134 | DLL_EXPORTS(Controller_Attach_AcceleratorKeyPressed, int64_t) 135 | (ICoreWebView2Controller* controller, AcceleratorKeyPressedCB callback, 136 | LPVOID param) { 137 | if (!controller) return FALSE; 138 | 139 | EventRegistrationToken token; 140 | 141 | controller->add_AcceleratorKeyPressed( 142 | WRL::Callback( 143 | [callback, param]( 144 | ICoreWebView2Controller* sender, 145 | ICoreWebView2AcceleratorKeyPressedEventArgs* args) -> HRESULT { 146 | sender->AddRef(); 147 | 148 | COREWEBVIEW2_KEY_EVENT_KIND sType; 149 | uint32_t sVkey = 0; 150 | int32_t sLparam = 0; 151 | COREWEBVIEW2_PHYSICAL_KEY_STATUS sStatus; 152 | 153 | args->get_KeyEventKind(&sType); 154 | args->get_VirtualKey(&sVkey); 155 | args->get_KeyEventLParam(&sLparam); 156 | args->get_PhysicalKeyStatus(&sStatus); 157 | 158 | BOOL hr = callback( 159 | sender, sType, sVkey, sLparam, sStatus.RepeatCount, 160 | sStatus.ScanCode, sStatus.IsExtendedKey, sStatus.IsMenuKeyDown, 161 | sStatus.WasKeyDown, sStatus.IsKeyReleased, param); 162 | 163 | args->put_Handled(hr); 164 | 165 | return S_OK; 166 | }) 167 | .Get(), 168 | &token); 169 | 170 | return token.value; 171 | } 172 | 173 | DLL_EXPORTS(Controller_Detach_AcceleratorKeyPressed, BOOL) 174 | (ICoreWebView2Controller* controller, int64_t value) { 175 | if (!controller) return FALSE; 176 | EventRegistrationToken token = {value}; 177 | 178 | return SUCCEEDED(controller->remove_AcceleratorKeyPressed(token)); 179 | } 180 | 181 | 182 | DLL_EXPORTS(Controller_GetAllowExternalDrop, BOOL) 183 | (ICoreWebView2Controller* controller) { 184 | if (!controller) return FALSE; 185 | 186 | WRL::ComPtr con = nullptr; 187 | controller->QueryInterface(&con); 188 | 189 | BOOL value = FALSE; 190 | con->get_AllowExternalDrop(&value); 191 | 192 | return value; 193 | } 194 | 195 | DLL_EXPORTS(Controller_SetAllowExternalDrop, BOOL) 196 | (ICoreWebView2Controller* controller, BOOL allow) { 197 | if (!controller) return FALSE; 198 | 199 | WRL::ComPtr con = nullptr; 200 | controller->QueryInterface(&con); 201 | 202 | return con->put_AllowExternalDrop(allow); 203 | } 204 | 205 | 206 | using ZoomFactorChangedCB = BOOL(CALLBACK*)(LPVOID controller, LPVOID param); 207 | DLL_EXPORTS(Controller_Attach_ZoomFactorChanged, int64_t) 208 | (ICoreWebView2Controller* controller, ZoomFactorChangedCB callback, 209 | LPVOID param) { 210 | if (!controller) return FALSE; 211 | 212 | EventRegistrationToken token; 213 | 214 | controller->add_ZoomFactorChanged( 215 | WRL::Callback( 216 | [callback, param](ICoreWebView2Controller* sender, 217 | IUnknown* args) -> HRESULT { 218 | sender->AddRef(); 219 | 220 | BOOL hr = callback(sender, param); 221 | 222 | return S_OK; 223 | }) 224 | .Get(), 225 | &token); 226 | 227 | return token.value; 228 | } 229 | 230 | DLL_EXPORTS(Controller_Detach_ZoomFactorChanged, BOOL) 231 | (ICoreWebView2Controller* controller, int64_t value) { 232 | if (!controller) return FALSE; 233 | EventRegistrationToken token = {value}; 234 | 235 | return SUCCEEDED(controller->remove_ZoomFactorChanged(token)); 236 | } -------------------------------------------------------------------------------- /src/wv2_controller.h: -------------------------------------------------------------------------------- 1 | #ifndef WV2_CONTROLLER_H 2 | #define WV2_CONTROLLER_H 3 | #pragma once 4 | 5 | #include "wv2_types.h" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/wv2_cookie.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "wv2_cookie.h" 3 | #include "wv2_utils.h" 4 | 5 | using namespace Microsoft; 6 | 7 | DLL_EXPORTS(CookieManager_CreateCookie, BOOL) 8 | (ICoreWebView2CookieManager* ckm, LPWSTR name, LPWSTR value, LPWSTR domain, 9 | LPWSTR path, LPVOID* ptr) { 10 | if (!ckm) return FALSE; 11 | 12 | ICoreWebView2Cookie* ck = nullptr; 13 | auto ret = SUCCEEDED(ckm->CreateCookie(name, value, domain, path, &ck)); 14 | 15 | *ptr = ck; 16 | 17 | return ret; 18 | } 19 | 20 | DLL_EXPORTS(CookieManager_CopyCookie, BOOL) 21 | (ICoreWebView2CookieManager* ckm, ICoreWebView2Cookie* ck, LPVOID* ptr) { 22 | if (!ckm) return FALSE; 23 | 24 | ICoreWebView2Cookie* cck = nullptr; 25 | auto ret = SUCCEEDED(ckm->CopyCookie(ck, &cck)); 26 | 27 | *ptr = cck; 28 | 29 | return ret; 30 | } 31 | 32 | DLL_EXPORTS(CookieList_GetCount, uint32_t) 33 | (ICoreWebView2CookieList* ck) { 34 | if (!ck) return FALSE; 35 | 36 | uint32_t size = 0; 37 | ck->get_Count(&size); 38 | 39 | return size; 40 | } 41 | 42 | DLL_EXPORTS(CookieList_GetCookieAtIndex, BOOL) 43 | (ICoreWebView2CookieList* ck, uint32_t index, LPVOID* ptr) { 44 | if (!ck) return FALSE; 45 | 46 | ICoreWebView2Cookie* ckd = nullptr; 47 | auto ret = SUCCEEDED(ck->GetValueAtIndex(index, &ckd)); 48 | 49 | *ptr = ckd; 50 | 51 | return ret; 52 | } 53 | 54 | 55 | 56 | using GetCookieCB = HRESULT(CALLBACK*)(LPVOID list, LPVOID param); 57 | DLL_EXPORTS(CookieManager_GetCookie, BOOL) 58 | (ICoreWebView2CookieManager* ckm, LPWSTR url, GetCookieCB callback, 59 | LPVOID param) { 60 | if (!ckm) return FALSE; 61 | 62 | ICoreWebView2Cookie* cck = nullptr; 63 | auto ret = SUCCEEDED(ckm->GetCookies( 64 | url, 65 | WRL::Callback( 66 | [callback, param](HRESULT result, 67 | ICoreWebView2CookieList* cookieList) -> HRESULT { 68 | if (cookieList) cookieList->AddRef(); 69 | 70 | return callback(cookieList, param); 71 | }) 72 | .Get())); 73 | 74 | return ret; 75 | } 76 | 77 | DLL_EXPORTS(CookieManager_GetCookie_Sync, BOOL) 78 | (ICoreWebView2CookieManager* ckm, LPWSTR url, LPVOID* ptr, uint32_t* size) { 79 | if (!ckm) return FALSE; 80 | 81 | Waitable* waiter = CreateWaitable(true); 82 | 83 | auto ret = SUCCEEDED(ckm->GetCookies( 84 | url, 85 | WRL::Callback( 86 | [waiter, ptr, size](HRESULT result, 87 | ICoreWebView2CookieList* cookieList) -> HRESULT { 88 | uint32_t count = 0; 89 | cookieList->get_Count(&count); 90 | 91 | LPVOID* buf = 92 | static_cast(wv2_Utility_Malloc(count * sizeof(void*))); 93 | for (size_t i = 0; i < count; i++) { 94 | ICoreWebView2Cookie* ckData = nullptr; 95 | cookieList->GetValueAtIndex(i, &ckData); 96 | buf[i] = ckData; 97 | } 98 | 99 | *ptr = buf; 100 | *size = count; 101 | 102 | ActiveWaitable(waiter); 103 | 104 | return S_OK; 105 | }) 106 | .Get())); 107 | 108 | WaitOfMsgLoop(waiter); 109 | 110 | return ret; 111 | } 112 | 113 | DLL_EXPORTS(CookieManager_SetCookie, BOOL) 114 | (ICoreWebView2CookieManager* ckm, ICoreWebView2Cookie* ck) { 115 | if (!ckm) return FALSE; 116 | 117 | auto ret = SUCCEEDED(ckm->AddOrUpdateCookie(ck)); 118 | 119 | return ret; 120 | } 121 | 122 | DLL_EXPORTS(CookieManager_DeleteCookie, BOOL) 123 | (ICoreWebView2CookieManager* ckm, ICoreWebView2Cookie* ck) { 124 | if (!ckm) return FALSE; 125 | 126 | auto ret = SUCCEEDED(ckm->DeleteCookie(ck)); 127 | 128 | return ret; 129 | } 130 | 131 | DLL_EXPORTS(CookieManager_DeleteCookies, BOOL) 132 | (ICoreWebView2CookieManager* ckm, LPWSTR name, LPWSTR url) { 133 | if (!ckm) return FALSE; 134 | 135 | auto ret = SUCCEEDED(ckm->DeleteCookies(name, url)); 136 | 137 | return ret; 138 | } 139 | 140 | DLL_EXPORTS(CookieManager_DeleteCookieWithParam, BOOL) 141 | (ICoreWebView2CookieManager* ckm, LPWSTR name, LPWSTR domain, LPWSTR path) { 142 | if (!ckm) return FALSE; 143 | 144 | auto ret = SUCCEEDED(ckm->DeleteCookiesWithDomainAndPath(name, domain, path)); 145 | 146 | return ret; 147 | } 148 | 149 | DLL_EXPORTS(CookieManager_DeleteAllCookies, BOOL) 150 | (ICoreWebView2CookieManager* ckm) { 151 | if (!ckm) return FALSE; 152 | 153 | auto ret = SUCCEEDED(ckm->DeleteAllCookies()); 154 | 155 | return ret; 156 | } 157 | 158 | 159 | DLL_EXPORTS(CookieData_GetName, BOOL) 160 | (ICoreWebView2Cookie* ckd, LPVOID* ptr, uint32_t* size) { 161 | if (!ckd) return FALSE; 162 | 163 | LPWSTR str = nullptr; 164 | auto ret = SUCCEEDED(ckd->get_Name(&str)); 165 | 166 | *ptr = str; 167 | *size = lstrlenW(str) * 2 + 2; 168 | 169 | return ret; 170 | } 171 | 172 | DLL_EXPORTS(CookieData_GetValue, BOOL) 173 | (ICoreWebView2Cookie* ckd, LPVOID* ptr, uint32_t* size) { 174 | if (!ckd) return FALSE; 175 | 176 | LPWSTR str = nullptr; 177 | auto ret = SUCCEEDED(ckd->get_Value(&str)); 178 | 179 | *ptr = str; 180 | *size = lstrlenW(str) * 2 + 2; 181 | 182 | return ret; 183 | } 184 | 185 | DLL_EXPORTS(CookieData_GetDomain, BOOL) 186 | (ICoreWebView2Cookie* ckd, LPVOID* ptr, uint32_t* size) { 187 | if (!ckd) return FALSE; 188 | 189 | LPWSTR str = nullptr; 190 | auto ret = SUCCEEDED(ckd->get_Domain(&str)); 191 | 192 | *ptr = str; 193 | *size = lstrlenW(str) * 2 + 2; 194 | 195 | return ret; 196 | } 197 | 198 | DLL_EXPORTS(CookieData_GetPath, BOOL) 199 | (ICoreWebView2Cookie* ckd, LPVOID* ptr, uint32_t* size) { 200 | if (!ckd) return FALSE; 201 | 202 | LPWSTR str = nullptr; 203 | auto ret = SUCCEEDED(ckd->get_Path(&str)); 204 | 205 | *ptr = str; 206 | *size = lstrlenW(str) * 2 + 2; 207 | 208 | return ret; 209 | } 210 | 211 | DLL_EXPORTS(CookieData_SetValue, BOOL) 212 | (ICoreWebView2Cookie* ckd, LPWSTR str) { 213 | if (!ckd) return FALSE; 214 | 215 | return SUCCEEDED(ckd->put_Value(str)); 216 | } 217 | 218 | DLL_EXPORTS(CookieData_GetExpires, double) 219 | (ICoreWebView2Cookie* ckd) { 220 | if (!ckd) return 0; 221 | 222 | double data = 0.0f; 223 | ckd->get_Expires(&data); 224 | 225 | return data; 226 | } 227 | 228 | DLL_EXPORTS(CookieData_SetExpires, BOOL) 229 | (ICoreWebView2Cookie* ckd, double expires) { 230 | if (!ckd) return FALSE; 231 | 232 | auto ret = SUCCEEDED(ckd->put_Expires(expires)); 233 | 234 | return ret; 235 | } 236 | 237 | DLL_EXPORTS(CookieData_GetHTTPOnly, BOOL) 238 | (ICoreWebView2Cookie* ckd) { 239 | if (!ckd) return FALSE; 240 | 241 | BOOL data = FALSE; 242 | ckd->get_IsHttpOnly(&data); 243 | 244 | return data; 245 | } 246 | 247 | DLL_EXPORTS(CookieData_SetHTTPOnly, BOOL) 248 | (ICoreWebView2Cookie* ckd, BOOL value) { 249 | if (!ckd) return FALSE; 250 | 251 | auto ret = SUCCEEDED(ckd->put_IsHttpOnly(value)); 252 | 253 | return ret; 254 | } 255 | 256 | DLL_EXPORTS(CookieData_GetSameSite, COREWEBVIEW2_COOKIE_SAME_SITE_KIND) 257 | (ICoreWebView2Cookie* ckd) { 258 | if (!ckd) return COREWEBVIEW2_COOKIE_SAME_SITE_KIND(); 259 | 260 | COREWEBVIEW2_COOKIE_SAME_SITE_KIND data = COREWEBVIEW2_COOKIE_SAME_SITE_KIND(); 261 | ckd->get_SameSite(&data); 262 | 263 | return data; 264 | } 265 | 266 | DLL_EXPORTS(CookieData_SetSameSite, BOOL) 267 | (ICoreWebView2Cookie* ckd, COREWEBVIEW2_COOKIE_SAME_SITE_KIND value) { 268 | if (!ckd) return FALSE; 269 | 270 | auto ret = SUCCEEDED(ckd->put_SameSite(value)); 271 | 272 | return ret; 273 | } 274 | 275 | DLL_EXPORTS(CookieData_GetSecure, BOOL) 276 | (ICoreWebView2Cookie* ckd) { 277 | if (!ckd) return FALSE; 278 | 279 | BOOL data = FALSE; 280 | ckd->get_IsSecure(&data); 281 | 282 | return data; 283 | } 284 | 285 | DLL_EXPORTS(CookieData_SetSecure, BOOL) 286 | (ICoreWebView2Cookie* ckd, BOOL value) { 287 | if (!ckd) return FALSE; 288 | 289 | auto ret = SUCCEEDED(ckd->put_IsSecure(value)); 290 | 291 | return ret; 292 | } 293 | 294 | DLL_EXPORTS(CookieData_GetSession, BOOL) 295 | (ICoreWebView2Cookie* ckd) { 296 | if (!ckd) return FALSE; 297 | 298 | BOOL data = FALSE; 299 | ckd->get_IsSession(&data); 300 | 301 | return data; 302 | } 303 | -------------------------------------------------------------------------------- /src/wv2_cookie.h: -------------------------------------------------------------------------------- 1 | #ifndef WV2_COOKIE_H 2 | #define WV2_COOKIE_H 3 | #pragma once 4 | 5 | #include "wv2_types.h" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/wv2_download.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "wv2_download.h" 3 | 4 | using namespace Microsoft; 5 | 6 | DLL_EXPORTS(DownloadArgs_GetDeferral, BOOL) 7 | (ICoreWebView2DownloadStartingEventArgs* args, LPVOID* ptr) { 8 | if (!args) return FALSE; 9 | 10 | ICoreWebView2Deferral* deferral = nullptr; 11 | HRESULT hr = args->GetDeferral(&deferral); 12 | 13 | *ptr = deferral; 14 | 15 | return SUCCEEDED(hr); 16 | } 17 | 18 | DLL_EXPORTS(DownloadArgs_Cancel_Attr, BOOL) 19 | (ICoreWebView2DownloadStartingEventArgs* args, BOOL get, BOOL value) { 20 | if (!args) return FALSE; 21 | 22 | if (get) { 23 | BOOL result = FALSE; 24 | args->get_Cancel(&result); 25 | return result; 26 | } else { 27 | return SUCCEEDED(args->put_Cancel(value)); 28 | } 29 | } 30 | 31 | DLL_EXPORTS(DownloadArgs_Handled_Attr, BOOL) 32 | (ICoreWebView2DownloadStartingEventArgs* args, BOOL get, BOOL value) { 33 | if (!args) return FALSE; 34 | 35 | if (get) { 36 | BOOL result = FALSE; 37 | args->get_Handled(&result); 38 | return result; 39 | } else { 40 | return SUCCEEDED(args->put_Handled(value)); 41 | } 42 | } 43 | 44 | DLL_EXPORTS(DownloadArgs_ResultPath_Attr, BOOL) 45 | (ICoreWebView2DownloadStartingEventArgs* args, BOOL get, LPVOID* ptr, uint32_t* size) { 46 | if (!args) return FALSE; 47 | 48 | if (get) { 49 | LPWSTR result = FALSE; 50 | HRESULT hr = args->get_ResultFilePath(&result); 51 | *ptr = result; 52 | *size = lstrlenW(result) * 2 + 2; 53 | return SUCCEEDED(hr); 54 | } else { 55 | return SUCCEEDED(args->put_ResultFilePath(reinterpret_cast(ptr))); 56 | } 57 | } 58 | 59 | DLL_EXPORTS(DownloadArgs_GetOperation, BOOL) 60 | (ICoreWebView2DownloadStartingEventArgs* args, LPVOID* ptr) { 61 | if (!args) return FALSE; 62 | 63 | ICoreWebView2DownloadOperation* p = nullptr; 64 | HRESULT hr = args->get_DownloadOperation(&p); 65 | 66 | *ptr = p; 67 | 68 | return SUCCEEDED(hr); 69 | } 70 | 71 | 72 | 73 | DLL_EXPORTS(DownloadOperation_GetURL, BOOL) 74 | (ICoreWebView2DownloadOperation* obj, LPVOID* ptr, uint32_t *size) { 75 | if (!obj) return FALSE; 76 | 77 | LPWSTR uri = nullptr; 78 | HRESULT hr = obj->get_Uri(&uri); 79 | 80 | *ptr = uri; 81 | *size = lstrlenW(uri) * 2 + 2; 82 | 83 | return SUCCEEDED(hr); 84 | } 85 | 86 | DLL_EXPORTS(DownloadOperation_GetContentDisposition, BOOL) 87 | (ICoreWebView2DownloadOperation* obj, LPVOID* ptr, uint32_t* size) { 88 | if (!obj) return FALSE; 89 | 90 | LPWSTR uri = nullptr; 91 | HRESULT hr = obj->get_ContentDisposition(&uri); 92 | 93 | *ptr = uri; 94 | *size = lstrlenW(uri) * 2 + 2; 95 | 96 | return SUCCEEDED(hr); 97 | } 98 | 99 | DLL_EXPORTS(DownloadOperation_GetMimeType, BOOL) 100 | (ICoreWebView2DownloadOperation* obj, LPVOID* ptr, uint32_t* size) { 101 | if (!obj) return FALSE; 102 | 103 | LPWSTR uri = nullptr; 104 | HRESULT hr = obj->get_MimeType(&uri); 105 | 106 | *ptr = uri; 107 | *size = lstrlenW(uri) * 2 + 2; 108 | 109 | return SUCCEEDED(hr); 110 | } 111 | 112 | DLL_EXPORTS(DownloadOperation_GetEstimatedEndTime, BOOL) 113 | (ICoreWebView2DownloadOperation* obj, LPVOID* ptr, uint32_t* size) { 114 | if (!obj) return FALSE; 115 | 116 | LPWSTR uri = nullptr; 117 | HRESULT hr = obj->get_EstimatedEndTime(&uri); 118 | 119 | *ptr = uri; 120 | *size = lstrlenW(uri) * 2 + 2; 121 | 122 | return SUCCEEDED(hr); 123 | } 124 | 125 | DLL_EXPORTS(DownloadOperation_GetResultPath, BOOL) 126 | (ICoreWebView2DownloadOperation* obj, LPVOID* ptr, uint32_t* size) { 127 | if (!obj) return FALSE; 128 | 129 | LPWSTR uri = nullptr; 130 | HRESULT hr = obj->get_ResultFilePath(&uri); 131 | 132 | *ptr = uri; 133 | *size = lstrlenW(uri) * 2 + 2; 134 | 135 | return SUCCEEDED(hr); 136 | } 137 | 138 | DLL_EXPORTS(DownloadOperation_GetTotalBytes, BOOL) 139 | (ICoreWebView2DownloadOperation* obj, int64_t *value) { 140 | if (!obj) return FALSE; 141 | 142 | HRESULT hr = obj->get_TotalBytesToReceive(value); 143 | 144 | return SUCCEEDED(hr); 145 | } 146 | 147 | DLL_EXPORTS(DownloadOperation_GetReceivedBytes, BOOL) 148 | (ICoreWebView2DownloadOperation* obj, int64_t* value) { 149 | if (!obj) return FALSE; 150 | 151 | HRESULT hr = obj->get_BytesReceived(value); 152 | 153 | return SUCCEEDED(hr); 154 | } 155 | 156 | DLL_EXPORTS(DownloadOperation_GetState, int) 157 | (ICoreWebView2DownloadOperation* obj) { 158 | if (!obj) return FALSE; 159 | 160 | COREWEBVIEW2_DOWNLOAD_STATE value; 161 | obj->get_State(&value); 162 | 163 | return value; 164 | } 165 | 166 | DLL_EXPORTS(DownloadOperation_GetInterruptReason, int) 167 | (ICoreWebView2DownloadOperation* obj) { 168 | if (!obj) return FALSE; 169 | 170 | COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON value; 171 | obj->get_InterruptReason(&value); 172 | 173 | return value; 174 | } 175 | 176 | DLL_EXPORTS(DownloadOperation_GetCanResume, BOOL) 177 | (ICoreWebView2DownloadOperation* obj) { 178 | if (!obj) return FALSE; 179 | 180 | BOOL value = FALSE; 181 | obj->get_CanResume(&value); 182 | 183 | return value; 184 | } 185 | 186 | DLL_EXPORTS(DownloadOperation_Cancel, BOOL) 187 | (ICoreWebView2DownloadOperation* obj) { 188 | if (!obj) return FALSE; 189 | 190 | return SUCCEEDED(obj->Cancel()); 191 | } 192 | 193 | DLL_EXPORTS(DownloadOperation_Pause, BOOL) 194 | (ICoreWebView2DownloadOperation* obj) { 195 | if (!obj) return FALSE; 196 | 197 | return SUCCEEDED(obj->Pause()); 198 | } 199 | 200 | DLL_EXPORTS(DownloadOperation_Resume, BOOL) 201 | (ICoreWebView2DownloadOperation* obj) { 202 | if (!obj) return FALSE; 203 | 204 | return SUCCEEDED(obj->Resume()); 205 | } 206 | 207 | using BytesReceivedChangedCB = HRESULT(CALLBACK*)(LPVOID operation, LPVOID param); 208 | DLL_EXPORTS(DownloadOperation_Attach_BytesReceivedChanged, int64_t) 209 | (ICoreWebView2DownloadOperation* webview, BytesReceivedChangedCB callback, 210 | LPVOID param) { 211 | if (!webview) return FALSE; 212 | 213 | EventRegistrationToken token; 214 | 215 | webview->add_BytesReceivedChanged( 216 | WRL::Callback( 217 | [callback, param](ICoreWebView2DownloadOperation* sender, 218 | IUnknown* args) -> HRESULT { 219 | sender->AddRef(); 220 | 221 | HRESULT hr = callback(sender, param); 222 | 223 | return hr; 224 | }) 225 | .Get(), 226 | &token); 227 | 228 | return token.value; 229 | } 230 | 231 | DLL_EXPORTS(DownloadOperation_Detach_BytesReceivedChanged, BOOL) 232 | (ICoreWebView2DownloadOperation* webview, int64_t value) { 233 | if (!webview) return FALSE; 234 | EventRegistrationToken token = {value}; 235 | 236 | return SUCCEEDED(webview->remove_BytesReceivedChanged(token)); 237 | } 238 | 239 | using EstimatedEndTimeChangedCB = HRESULT(CALLBACK*)(LPVOID operation, 240 | LPVOID param); 241 | DLL_EXPORTS(DownloadOperation_Attach_EstimatedEndTimeChanged, int64_t) 242 | (ICoreWebView2DownloadOperation* webview, EstimatedEndTimeChangedCB callback, 243 | LPVOID param) { 244 | if (!webview) return FALSE; 245 | 246 | EventRegistrationToken token; 247 | 248 | webview->add_EstimatedEndTimeChanged( 249 | WRL::Callback( 250 | [callback, param](ICoreWebView2DownloadOperation* sender, 251 | IUnknown* args) -> HRESULT { 252 | sender->AddRef(); 253 | 254 | HRESULT hr = callback(sender, param); 255 | 256 | return hr; 257 | }) 258 | .Get(), 259 | &token); 260 | 261 | return token.value; 262 | } 263 | 264 | DLL_EXPORTS(DownloadOperation_Detach_EstimatedEndTimeChanged, BOOL) 265 | (ICoreWebView2DownloadOperation* webview, int64_t value) { 266 | if (!webview) return FALSE; 267 | EventRegistrationToken token = {value}; 268 | 269 | return SUCCEEDED(webview->remove_EstimatedEndTimeChanged(token)); 270 | } 271 | 272 | using StateChangedCB = HRESULT(CALLBACK*)(LPVOID operation, 273 | LPVOID param); 274 | DLL_EXPORTS(DownloadOperation_Attach_StateChanged, int64_t) 275 | (ICoreWebView2DownloadOperation* webview, StateChangedCB callback, 276 | LPVOID param) { 277 | if (!webview) return FALSE; 278 | 279 | EventRegistrationToken token; 280 | 281 | webview->add_StateChanged( 282 | WRL::Callback( 283 | [callback, param](ICoreWebView2DownloadOperation* sender, 284 | IUnknown* args) -> HRESULT { 285 | sender->AddRef(); 286 | 287 | HRESULT hr = callback(sender, param); 288 | 289 | return hr; 290 | }) 291 | .Get(), 292 | &token); 293 | 294 | return token.value; 295 | } 296 | 297 | DLL_EXPORTS(DownloadOperation_Detach_StateChanged, BOOL) 298 | (ICoreWebView2DownloadOperation* webview, int64_t value) { 299 | if (!webview) return FALSE; 300 | EventRegistrationToken token = {value}; 301 | 302 | return SUCCEEDED(webview->remove_StateChanged(token)); 303 | } 304 | -------------------------------------------------------------------------------- /src/wv2_download.h: -------------------------------------------------------------------------------- 1 | #ifndef WV2_DOWNLOAD_H 2 | #define WV2_DOWNLOAD_H 3 | #pragma once 4 | 5 | #include "wv2_utils.h" 6 | 7 | #endif -------------------------------------------------------------------------------- /src/wv2_env.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "wv2_env.h" 3 | #include "wv2_utils.h" 4 | 5 | using namespace Microsoft; 6 | 7 | DLL_EXPORTS(Global_EnableHighDPISupport, BOOL)() { 8 | return ::SetProcessDPIAware(); 9 | } 10 | 11 | DLL_EXPORTS(Global_CheckEdgeRuntime, BOOL) 12 | (LPWSTR path, LPVOID* ptr, uint32_t *size) { 13 | LPWSTR ver = nullptr; 14 | HRESULT hr = GetAvailableCoreWebView2BrowserVersionString(path, &ver); 15 | 16 | *ptr = ver; 17 | *size = lstrlenW(ver) * 2 + 2; 18 | 19 | return SUCCEEDED(hr); 20 | } 21 | 22 | struct EnvCreateSettings { 23 | LPCWSTR additional_parameter; 24 | LPCWSTR language; 25 | LPCWSTR version; 26 | BOOL allowSingleSign; 27 | }; 28 | 29 | DLL_EXPORTS(Global_CreateEnv_Sync, BOOL) 30 | (EnvCreateSettings* settings, LPCWSTR path, LPCWSTR userData, LPVOID* retPtr) { 31 | auto options = WRL::Make(); 32 | 33 | if (settings) { 34 | if (settings->additional_parameter && *settings->additional_parameter) 35 | options->put_AdditionalBrowserArguments(settings->additional_parameter); 36 | if (settings->language && *settings->language) 37 | options->put_Language(settings->language); 38 | if (settings->version && *settings->version) 39 | options->put_TargetCompatibleBrowserVersion(settings->version); 40 | options->put_AllowSingleSignOnUsingOSPrimaryAccount( 41 | settings->allowSingleSign); 42 | } 43 | 44 | Waitable* waiter = CreateWaitable(true); 45 | 46 | HRESULT hr = CreateCoreWebView2EnvironmentWithOptions( 47 | path, userData, settings ? options.Get() : nullptr, 48 | WRL::Callback( 49 | [retPtr, waiter](HRESULT result, 50 | ICoreWebView2Environment* env) -> HRESULT { 51 | if (env) { 52 | env->AddRef(); 53 | *retPtr = env; 54 | } 55 | 56 | ActiveWaitable(waiter); 57 | return S_OK; 58 | }) 59 | .Get()); 60 | 61 | WaitOfMsgLoop(waiter); 62 | 63 | return SUCCEEDED(hr); 64 | } 65 | 66 | using CreateControllerCB = HRESULT(CALLBACK*)(LPVOID controller, LPVOID param); 67 | 68 | DLL_EXPORTS(Env_CreateController, BOOL) 69 | (ICoreWebView2Environment* env, HWND hwnd, CreateControllerCB callback, 70 | LPVOID param) { 71 | if (!env) return FALSE; 72 | 73 | HRESULT hr = env->CreateCoreWebView2Controller( 74 | hwnd, 75 | WRL::Callback( 76 | [callback, param]( 77 | HRESULT errorCode, 78 | ICoreWebView2Controller* createdController) -> HRESULT { 79 | if (createdController) { 80 | if (createdController) createdController->AddRef(); 81 | 82 | return callback(createdController, param); 83 | } else 84 | return E_FAIL; 85 | }) 86 | .Get()); 87 | 88 | return SUCCEEDED(hr); 89 | } 90 | 91 | DLL_EXPORTS(Env_CreateController_Sync, BOOL) 92 | (ICoreWebView2Environment* env, HWND hwnd, LPVOID* retPtr) { 93 | if (!env) return FALSE; 94 | Waitable* waiter = CreateWaitable(true); 95 | 96 | HRESULT hr = env->CreateCoreWebView2Controller( 97 | hwnd, 98 | WRL::Callback( 99 | [waiter, retPtr]( 100 | HRESULT errorCode, 101 | ICoreWebView2Controller* createdController) -> HRESULT { 102 | if (createdController) { 103 | if (createdController) createdController->AddRef(); 104 | 105 | *retPtr = createdController; 106 | ActiveWaitable(waiter); 107 | 108 | return S_OK; 109 | } else 110 | return E_FAIL; 111 | }) 112 | .Get()); 113 | 114 | WaitOfMsgLoop(waiter); 115 | 116 | return SUCCEEDED(hr); 117 | } 118 | 119 | struct ControllerSettings { 120 | LPCWSTR profile; 121 | BOOL privateMode; 122 | }; 123 | DLL_EXPORTS(Env_CreateController_Options, BOOL) 124 | (ICoreWebView2Environment10* env, HWND hwnd, ControllerSettings* settings, 125 | CreateControllerCB callback, LPVOID param) { 126 | if (!env) return FALSE; 127 | 128 | WRL::ComPtr options = nullptr; 129 | env->CreateCoreWebView2ControllerOptions(&options); 130 | 131 | if (settings) { 132 | options->put_ProfileName(settings->profile); 133 | options->put_IsInPrivateModeEnabled(settings->privateMode); 134 | } 135 | 136 | HRESULT hr = env->CreateCoreWebView2ControllerWithOptions( 137 | hwnd, options.Get(), 138 | WRL::Callback( 139 | [callback, param]( 140 | HRESULT errorCode, 141 | ICoreWebView2Controller* createdController) -> HRESULT { 142 | if (createdController) { 143 | if (createdController) createdController->AddRef(); 144 | 145 | return callback(createdController, param); 146 | } else 147 | return E_FAIL; 148 | }) 149 | .Get()); 150 | 151 | return SUCCEEDED(hr); 152 | } 153 | 154 | DLL_EXPORTS(Env_CreateController_Options_Sync, BOOL) 155 | (ICoreWebView2Environment10* env, HWND hwnd, ControllerSettings* settings, 156 | LPVOID* retPtr) { 157 | if (!env) return FALSE; 158 | Waitable* waiter = CreateWaitable(true); 159 | 160 | WRL::ComPtr options; 161 | env->CreateCoreWebView2ControllerOptions(&options); 162 | 163 | if (settings) { 164 | options->put_ProfileName(settings->profile); 165 | options->put_IsInPrivateModeEnabled(settings->privateMode); 166 | } 167 | 168 | HRESULT hr = env->CreateCoreWebView2ControllerWithOptions( 169 | hwnd, options.Get(), 170 | WRL::Callback( 171 | [waiter, retPtr]( 172 | HRESULT errorCode, 173 | ICoreWebView2Controller* createdController) -> HRESULT { 174 | if (createdController) { 175 | if (createdController) createdController->AddRef(); 176 | 177 | *retPtr = createdController; 178 | ActiveWaitable(waiter); 179 | 180 | return S_OK; 181 | } else 182 | return E_FAIL; 183 | }) 184 | .Get()); 185 | 186 | WaitOfMsgLoop(waiter); 187 | 188 | return SUCCEEDED(hr); 189 | } 190 | 191 | DLL_EXPORTS(Env_CreateWebResourceResponse, BOOL) 192 | (ICoreWebView2Environment* env, LPVOID pptr, uint32_t psize, int code, 193 | LPWSTR reason, LPWSTR headers, LPVOID* ret) { 194 | if (!env) return FALSE; 195 | 196 | WRL::ComPtr is = nullptr; 197 | HGLOBAL hMem = GlobalAlloc(GMEM_ZEROINIT, psize); 198 | if (!hMem) return FALSE; 199 | 200 | LPVOID pMem = GlobalLock(hMem); 201 | if (!pMem) return FALSE; 202 | 203 | RtlCopyMemory(pMem, pptr, psize); 204 | GlobalUnlock(hMem); 205 | CreateStreamOnHGlobal(hMem, TRUE, &is); 206 | 207 | ICoreWebView2WebResourceResponse* retObj = nullptr; 208 | HRESULT hr = 209 | env->CreateWebResourceResponse(is.Get(), code, reason, headers, &retObj); 210 | 211 | *ret = retObj; 212 | 213 | return SUCCEEDED(hr); 214 | } 215 | 216 | DLL_EXPORTS(Env_CreateWebResourceRequest, BOOL) 217 | (ICoreWebView2Environment2* env, LPWSTR url, LPWSTR method, LPVOID pptr, 218 | uint32_t psize, LPWSTR headers, LPVOID* ret) { 219 | if (!env) return FALSE; 220 | 221 | WRL::ComPtr is = nullptr; 222 | HGLOBAL hMem = GlobalAlloc(GMEM_ZEROINIT, psize); 223 | if (!hMem) return FALSE; 224 | 225 | LPVOID pMem = GlobalLock(hMem); 226 | if (!pMem) return FALSE; 227 | 228 | RtlCopyMemory(pMem, pptr, psize); 229 | GlobalUnlock(hMem); 230 | CreateStreamOnHGlobal(hMem, TRUE, &is); 231 | 232 | ICoreWebView2WebResourceRequest* retObj = nullptr; 233 | HRESULT hr = 234 | env->CreateWebResourceRequest(url, method, is.Get(), headers, &retObj); 235 | 236 | *ret = retObj; 237 | 238 | return SUCCEEDED(hr); 239 | } 240 | 241 | DLL_EXPORTS(Env_CreateContextMenuItem, BOOL) 242 | (ICoreWebView2Environment9* env, LPWSTR label, LPVOID pptr, uint32_t psize, 243 | COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND type, LPVOID* ret) { 244 | if (!env) return FALSE; 245 | 246 | WRL::ComPtr is = nullptr; 247 | HGLOBAL hMem = GlobalAlloc(GMEM_ZEROINIT, psize); 248 | if (!hMem) return FALSE; 249 | 250 | LPVOID pMem = GlobalLock(hMem); 251 | if (!pMem) return FALSE; 252 | 253 | RtlCopyMemory(pMem, pptr, psize); 254 | GlobalUnlock(hMem); 255 | CreateStreamOnHGlobal(hMem, TRUE, &is); 256 | 257 | ICoreWebView2ContextMenuItem* retObj = nullptr; 258 | HRESULT hr = env->CreateContextMenuItem(label, is.Get(), type, &retObj); 259 | 260 | *ret = retObj; 261 | 262 | return SUCCEEDED(hr); 263 | } 264 | -------------------------------------------------------------------------------- /src/wv2_env.h: -------------------------------------------------------------------------------- 1 | #ifndef WV2_ENV_H 2 | #define WV2_ENV_H 3 | #pragma once 4 | 5 | #include "wv2_types.h" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/wv2_frame.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "wv2_frame.h" 3 | using namespace Microsoft; 4 | 5 | using FrameDestroyedCB = HRESULT(CALLBACK*)(LPVOID frame, LPVOID param); 6 | DLL_EXPORTS(Frame_Attach_Destroyed, int64_t) 7 | (ICoreWebView2Frame* frame, FrameDestroyedCB callback, LPVOID param) { 8 | if (!frame) return FALSE; 9 | 10 | EventRegistrationToken token; 11 | 12 | frame->add_Destroyed(WRL::Callback( 13 | [callback, param](ICoreWebView2Frame* sender, 14 | IUnknown* args) -> HRESULT { 15 | sender->AddRef(); 16 | 17 | HRESULT hr = callback(sender, param); 18 | 19 | return hr; 20 | }) 21 | .Get(), 22 | &token); 23 | 24 | return token.value; 25 | } 26 | 27 | DLL_EXPORTS(Frame_Detach_Destroyed, BOOL) 28 | (ICoreWebView2Frame* frame, int64_t value) { 29 | if (!frame) return FALSE; 30 | EventRegistrationToken token = {value}; 31 | 32 | return SUCCEEDED(frame->remove_Destroyed(token)); 33 | } 34 | 35 | 36 | using NameChangedCB = HRESULT(CALLBACK*)(LPVOID frame, LPVOID param); 37 | DLL_EXPORTS(Frame_Attach_NameChanged, int64_t) 38 | (ICoreWebView2Frame* frame, NameChangedCB callback, LPVOID param) { 39 | if (!frame) return FALSE; 40 | 41 | EventRegistrationToken token; 42 | 43 | frame->add_NameChanged( 44 | WRL::Callback( 45 | [callback, param](ICoreWebView2Frame* sender, 46 | IUnknown* args) -> HRESULT { 47 | sender->AddRef(); 48 | 49 | HRESULT hr = callback(sender, param); 50 | 51 | return hr; 52 | }) 53 | .Get(), 54 | &token); 55 | 56 | return token.value; 57 | } 58 | 59 | DLL_EXPORTS(Frame_Detach_NameChanged, BOOL) 60 | (ICoreWebView2Frame* frame, int64_t value) { 61 | if (!frame) return FALSE; 62 | EventRegistrationToken token = {value}; 63 | 64 | return SUCCEEDED(frame->remove_NameChanged(token)); 65 | } 66 | 67 | 68 | DLL_EXPORTS(Frame_GetName, BOOL) 69 | (ICoreWebView2Frame* frame, LPVOID* ptr, uint32_t* size) { 70 | if (!frame) return FALSE; 71 | 72 | LPWSTR value = nullptr; 73 | HRESULT hr = frame->get_Name(&value); 74 | 75 | *ptr = value; 76 | *size = lstrlenW(value) * 2 + 2; 77 | 78 | return SUCCEEDED(hr); 79 | } 80 | 81 | DLL_EXPORTS(Frame_IsDestroyed, BOOL) 82 | (ICoreWebView2Frame* frame) { 83 | if (!frame) return TRUE; 84 | 85 | BOOL isDestroyed = FALSE; 86 | frame->IsDestroyed(&isDestroyed); 87 | 88 | return isDestroyed; 89 | } 90 | 91 | using ExecuteScriptCB = HRESULT(CALLBACK*)(HRESULT code, LPCVOID ptr, 92 | uint32_t size, LPVOID param); 93 | DLL_EXPORTS(Frame_ExecuteScript, BOOL) 94 | (ICoreWebView2Frame2* webview, LPCWSTR script, ExecuteScriptCB callback, 95 | LPVOID param) { 96 | if (!webview) return FALSE; 97 | 98 | auto ret = SUCCEEDED(webview->ExecuteScript( 99 | script, WRL::Callback( 100 | [callback, param](HRESULT errorCode, 101 | LPCWSTR resultObjectAsJson) -> HRESULT { 102 | if (callback) { 103 | uint32_t sizeTmp = lstrlenW(resultObjectAsJson) * 2 + 2; 104 | LPWSTR newStr = 105 | static_cast(wv2_Utility_Malloc(sizeTmp)); 106 | if (newStr) { 107 | lstrcpyW(newStr, resultObjectAsJson); 108 | } 109 | 110 | return callback(errorCode, newStr, sizeTmp, param); 111 | } else 112 | return S_OK; 113 | }) 114 | .Get())); 115 | 116 | return ret; 117 | } 118 | 119 | DLL_EXPORTS(Frame_ExecuteScript_Sync, BOOL) 120 | (ICoreWebView2Frame2* webview, LPCWSTR script, LPCVOID* ptr, uint32_t* size) { 121 | if (!webview) return FALSE; 122 | 123 | Waitable* waiter = CreateWaitable(true); 124 | 125 | auto ret = SUCCEEDED(webview->ExecuteScript( 126 | script, WRL::Callback( 127 | [waiter, ptr, size](HRESULT errorCode, 128 | LPCWSTR resultObjectAsJson) -> HRESULT { 129 | uint32_t sizeTmp = lstrlenW(resultObjectAsJson) * 2 + 2; 130 | LPWSTR newStr = 131 | static_cast(wv2_Utility_Malloc(sizeTmp)); 132 | if (newStr) { 133 | lstrcpyW(newStr, resultObjectAsJson); 134 | 135 | *ptr = newStr; 136 | *size = sizeTmp; 137 | } 138 | 139 | ActiveWaitable(waiter); 140 | 141 | return S_OK; 142 | }) 143 | .Get())); 144 | 145 | WaitOfMsgLoop(waiter); 146 | 147 | return ret; 148 | } 149 | -------------------------------------------------------------------------------- /src/wv2_frame.h: -------------------------------------------------------------------------------- 1 | #ifndef WV2_FRAME_H 2 | #define WV2_FRAME_H 3 | #pragma once 4 | 5 | #include "wv2_utils.h" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/wv2_types.h: -------------------------------------------------------------------------------- 1 | #ifndef WV2_TYPES_H 2 | #define WV2_TYPES_H 3 | #pragma once 4 | 5 | #include "WebView2.h" 6 | #include "WebView2EnvironmentOptions.h" 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #define DLL_EXPORTS(name, type) \ 14 | extern "C" __declspec(dllexport) type __cdecl wv2_##name 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/wv2_utils.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "wv2_utils.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | static inline uint16_t byteswap_ushort(uint16_t number) { 11 | return _byteswap_ushort(number); 12 | } 13 | 14 | using namespace Microsoft; 15 | 16 | DLL_EXPORTS(Deferral_Complete, BOOL)(ICoreWebView2Deferral* deferral) { 17 | auto ret = SUCCEEDED(deferral->Complete()); 18 | deferral->Release(); 19 | return ret; 20 | } 21 | 22 | DLL_EXPORTS(Object_AddRef, uint32_t)(IUnknown* obj) { 23 | if (!obj) return NULL; 24 | 25 | return obj->AddRef(); 26 | } 27 | 28 | DLL_EXPORTS(Object_Release, uint32_t)(IUnknown* obj) { 29 | if (!obj) return NULL; 30 | 31 | return obj->Release(); 32 | } 33 | 34 | /*-------------------------------------------------------------------------------*/ 35 | 36 | #define MSGLOOP_SYNC 37 | #ifdef MSGLOOP_SYNC 38 | 39 | struct Waitable { 40 | BOOL isActive; 41 | BOOL autoRelease; 42 | }; 43 | 44 | Waitable* CreateWaitable(BOOL release_after_wait) { 45 | Waitable* p = new Waitable(); 46 | p->isActive = FALSE; 47 | p->autoRelease = release_after_wait; 48 | return p; 49 | } 50 | 51 | void ReleaseWaitable(Waitable* obj) { 52 | obj->isActive = TRUE; 53 | delete obj; 54 | } 55 | 56 | void ActiveWaitable(Waitable* obj) { 57 | if (!obj) return; 58 | obj->isActive = TRUE; 59 | } 60 | 61 | void WaitOfSleep(Waitable* obj, uint32_t max_ms) { 62 | if (!obj) return; 63 | if (max_ms <= 0) return; 64 | if (obj->isActive) return; 65 | 66 | uint32_t nCount = 0; 67 | while (!obj->isActive) { 68 | Sleep(10); 69 | 70 | nCount++; 71 | if (nCount > max_ms) break; 72 | } 73 | 74 | if (obj->autoRelease) delete obj; 75 | } 76 | 77 | void WaitOfMsgLoop(Waitable* obj) { 78 | if (!obj) return; 79 | if (obj->isActive) return; 80 | 81 | // WebView2 Pump Received Host 82 | // FindWindowEx(HWND_MESSAGE, NULL, L"Chrome_MessageWindow", NULL); 83 | 84 | // WebView2 MessageLoop MSG ID: 85 | // WM_USER + 1 86 | 87 | MSG uiMsg; 88 | while (!obj->isActive) { 89 | if (PeekMessage(&uiMsg, NULL, WM_USER + 1, WM_USER + 1, PM_REMOVE)) { 90 | TranslateMessage(&uiMsg); 91 | DispatchMessage(&uiMsg); 92 | if (uiMsg.message == WM_QUIT) { 93 | break; 94 | } 95 | } 96 | } 97 | 98 | if (obj->autoRelease) ReleaseWaitable(obj); 99 | } 100 | 101 | #else 102 | 103 | struct Waitable { 104 | HANDLE pEvent; 105 | BOOL autoRelease; 106 | }; 107 | 108 | Waitable* CreateWaitable(BOOL release_after_wait) { 109 | Waitable* p = new Waitable(); 110 | p->autoRelease = release_after_wait; 111 | p->pEvent = CreateEvent(nullptr, false, false, nullptr); 112 | return p; 113 | } 114 | 115 | void ReleaseWaitable(Waitable* obj) { 116 | if (obj) CloseHandle(obj->pEvent); 117 | } 118 | 119 | void ActiveWaitable(Waitable* obj) { 120 | if (!obj) return; 121 | SetEvent(obj->pEvent); 122 | } 123 | 124 | void WaitOfMsgLoop(Waitable* obj) { 125 | if (!obj) return; 126 | 127 | DWORD handleIndex = 0; 128 | CoWaitForMultipleHandles(COWAIT_DISPATCH_WINDOW_MESSAGES | 129 | COWAIT_DISPATCH_CALLS | COWAIT_INPUTAVAILABLE, 130 | INFINITE, 1, &obj->pEvent, &handleIndex); 131 | 132 | if (obj->autoRelease) ReleaseWaitable(obj); 133 | } 134 | 135 | #endif 136 | 137 | DLL_EXPORTS(Utility_Malloc, void*)(uint32_t size) { 138 | return LocalAlloc(LMEM_ZEROINIT, size); 139 | } 140 | 141 | DLL_EXPORTS(Utility_Mfree, void)(void* mem) { LocalFree(mem); } 142 | -------------------------------------------------------------------------------- /src/wv2_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef WV2_UTILS_H 2 | #define WV2_UTILS_H 3 | #pragma once 4 | 5 | #include "wv2_types.h" 6 | #include 7 | 8 | struct Waitable; 9 | Waitable* CreateWaitable(BOOL release_after_wait); 10 | void ReleaseWaitable(Waitable* obj); 11 | void ActiveWaitable(Waitable* obj); 12 | void WaitOfMsgLoop(Waitable* obj); 13 | 14 | DLL_EXPORTS(Utility_Malloc, void*)(uint32_t size); 15 | DLL_EXPORTS(Utility_Mfree, void)(void* mem); 16 | 17 | namespace conv { 18 | 19 | LPWSTR ToUnicode(const char* str); 20 | LPSTR ToAnsi(const wchar_t* str); 21 | 22 | } // namespace conv 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/wv2_webrequest.cc: -------------------------------------------------------------------------------- 1 | #include "wv2_webrequest.h" 2 | 3 | #include 4 | #include 5 | 6 | using namespace Microsoft; 7 | 8 | DLL_EXPORTS(ResourceRequestArgs_GetDeferral, BOOL) 9 | (ICoreWebView2WebResourceRequestedEventArgs* args, LPVOID* ptr) { 10 | if (!args) return FALSE; 11 | 12 | ICoreWebView2Deferral* deferral = nullptr; 13 | auto ret = SUCCEEDED(args->GetDeferral(&deferral)); 14 | 15 | *ptr = deferral; 16 | 17 | return ret; 18 | } 19 | 20 | DLL_EXPORTS(ResourceRequestArgs_GetResourceContext, int) 21 | (ICoreWebView2WebResourceRequestedEventArgs* args) { 22 | if (!args) return FALSE; 23 | 24 | COREWEBVIEW2_WEB_RESOURCE_CONTEXT type; 25 | args->get_ResourceContext(&type); 26 | 27 | return type; 28 | } 29 | 30 | DLL_EXPORTS(ResourceRequestArgs_GetRequest, BOOL) 31 | (ICoreWebView2WebResourceRequestedEventArgs* args, LPVOID* ptr) { 32 | if (!args) return FALSE; 33 | 34 | ICoreWebView2WebResourceRequest* request = nullptr; 35 | auto ret = SUCCEEDED(args->get_Request(&request)); 36 | 37 | *ptr = request; 38 | 39 | return ret; 40 | } 41 | 42 | DLL_EXPORTS(ResourceRequestArgs_GetResponse, BOOL) 43 | (ICoreWebView2WebResourceRequestedEventArgs* args, LPVOID* ptr) { 44 | if (!args) return FALSE; 45 | 46 | ICoreWebView2WebResourceResponse* response = nullptr; 47 | auto ret = SUCCEEDED(args->get_Response(&response)); 48 | 49 | *ptr = response; 50 | 51 | return ret; 52 | } 53 | 54 | DLL_EXPORTS(ResourceRequestArgs_SetResponse, BOOL) 55 | (ICoreWebView2WebResourceRequestedEventArgs* args, 56 | ICoreWebView2WebResourceResponse* ptr) { 57 | if (!args) return FALSE; 58 | 59 | return SUCCEEDED(args->put_Response(ptr)); 60 | } 61 | 62 | 63 | 64 | DLL_EXPORTS(ResourceRequest_GetURL, BOOL) 65 | (ICoreWebView2WebResourceRequest* obj, LPVOID* ptr, uint32_t *size) { 66 | if (!obj) return FALSE; 67 | 68 | LPWSTR value = nullptr; 69 | 70 | auto ret = SUCCEEDED(obj->get_Uri(&value)); 71 | 72 | *ptr = value; 73 | *size = lstrlenW(value) * 2 + 2; 74 | 75 | return ret; 76 | } 77 | 78 | DLL_EXPORTS(ResourceRequest_SetURL, BOOL) 79 | (ICoreWebView2WebResourceRequest* obj, LPWSTR uri) { 80 | if (!obj) return FALSE; 81 | 82 | return SUCCEEDED(obj->put_Uri(uri)); 83 | } 84 | 85 | DLL_EXPORTS(ResourceRequest_GetMethod, BOOL) 86 | (ICoreWebView2WebResourceRequest* obj, LPVOID* ptr, uint32_t* size) { 87 | if (!obj) return FALSE; 88 | 89 | LPWSTR value = nullptr; 90 | 91 | auto ret = SUCCEEDED(obj->get_Method(&value)); 92 | 93 | *ptr = value; 94 | *size = lstrlenW(value) * 2 + 2; 95 | 96 | return ret; 97 | } 98 | 99 | DLL_EXPORTS(ResourceRequest_SetMethod, BOOL) 100 | (ICoreWebView2WebResourceRequest* obj, LPWSTR m) { 101 | if (!obj) return FALSE; 102 | 103 | return SUCCEEDED(obj->put_Method(m)); 104 | } 105 | 106 | DLL_EXPORTS(ResourceRequest_GetData, BOOL) 107 | (ICoreWebView2WebResourceRequest* obj, LPVOID* pptr, uint32_t* psize) { 108 | if (!obj) return FALSE; 109 | 110 | WRL::ComPtr is = nullptr; 111 | auto ret = SUCCEEDED(obj->get_Content(&is)); 112 | 113 | if (!is) return FALSE; 114 | 115 | STATSTG stat; 116 | is->Stat(&stat, STATFLAG_NONAME); 117 | 118 | LARGE_INTEGER linfo; 119 | linfo.QuadPart = 0; 120 | is->Seek(linfo, STREAM_SEEK_SET, NULL); 121 | 122 | uint32_t size = stat.cbSize.LowPart; 123 | uint8_t* buf = static_cast(wv2_Utility_Malloc(size)); 124 | ULONG dummy = 0; 125 | is->Read(buf, size, &dummy); 126 | 127 | *pptr = buf; 128 | *psize = size; 129 | 130 | return ret; 131 | } 132 | 133 | DLL_EXPORTS(ResourceRequest_SetData, BOOL) 134 | (ICoreWebView2WebResourceRequest* obj, LPVOID pptr, uint32_t psize) { 135 | if (!obj) return FALSE; 136 | 137 | WRL::ComPtr is = nullptr; 138 | HGLOBAL hMem = GlobalAlloc(GMEM_ZEROINIT, psize); 139 | if (!hMem) return FALSE; 140 | 141 | LPVOID pMem = GlobalLock(hMem); 142 | if (!pMem) return FALSE; 143 | 144 | RtlCopyMemory(pMem, pptr, psize); 145 | GlobalUnlock(hMem); 146 | CreateStreamOnHGlobal(hMem, TRUE, &is); 147 | 148 | auto ret = SUCCEEDED(obj->put_Content(is.Get())); 149 | 150 | return ret; 151 | } 152 | 153 | DLL_EXPORTS(ResourceRequest_GetHeaders, BOOL) 154 | (ICoreWebView2WebResourceRequest* obj, LPVOID* ptr) { 155 | if (!obj) return FALSE; 156 | 157 | ICoreWebView2HttpRequestHeaders* header; 158 | auto ret = SUCCEEDED(obj->get_Headers(&header)); 159 | 160 | *ptr = header; 161 | 162 | return ret; 163 | } 164 | 165 | 166 | 167 | DLL_EXPORTS(ResourceResponse_GetReasonPhrase, BOOL) 168 | (ICoreWebView2WebResourceResponse* obj, LPVOID* ptr, uint32_t* size) { 169 | if (!obj) return FALSE; 170 | 171 | LPWSTR value = nullptr; 172 | 173 | auto ret = SUCCEEDED(obj->get_ReasonPhrase(&value)); 174 | 175 | *ptr = value; 176 | *size = lstrlenW(value) * 2 + 2; 177 | 178 | return ret; 179 | } 180 | 181 | DLL_EXPORTS(ResourceResponse_SetReasonPhrase, BOOL) 182 | (ICoreWebView2WebResourceResponse* obj, LPWSTR uri) { 183 | if (!obj) return FALSE; 184 | 185 | return SUCCEEDED(obj->put_ReasonPhrase(uri)); 186 | } 187 | 188 | DLL_EXPORTS(ResourceResponse_GetStatusCode, int) 189 | (ICoreWebView2WebResourceResponse* obj) { 190 | if (!obj) return FALSE; 191 | 192 | int code = 0; 193 | obj->get_StatusCode(&code); 194 | 195 | return code; 196 | } 197 | 198 | DLL_EXPORTS(ResourceResponse_SetStatusCode, BOOL) 199 | (ICoreWebView2WebResourceResponse* obj, int code) { 200 | if (!obj) return FALSE; 201 | 202 | return SUCCEEDED(obj->put_StatusCode(code)); 203 | } 204 | 205 | DLL_EXPORTS(ResourceResponse_GetData, BOOL) 206 | (ICoreWebView2WebResourceResponse* obj, LPVOID* pptr, uint32_t* psize) { 207 | if (!obj) return FALSE; 208 | 209 | WRL::ComPtr is = nullptr; 210 | auto ret = SUCCEEDED(obj->get_Content(&is)); 211 | 212 | STATSTG stat; 213 | is->Stat(&stat, STATFLAG_NONAME); 214 | 215 | LARGE_INTEGER linfo; 216 | linfo.QuadPart = 0; 217 | is->Seek(linfo, STREAM_SEEK_SET, NULL); 218 | 219 | uint32_t size = stat.cbSize.LowPart; 220 | uint8_t* buf = static_cast(wv2_Utility_Malloc(size)); 221 | ULONG dummy = 0; 222 | is->Read(buf, size, &dummy); 223 | 224 | *pptr = buf; 225 | *psize = size; 226 | 227 | return ret; 228 | } 229 | 230 | DLL_EXPORTS(ResourceResponse_SetData, BOOL) 231 | (ICoreWebView2WebResourceResponse* obj, LPVOID pptr, uint32_t psize) { 232 | if (!obj) return FALSE; 233 | 234 | WRL::ComPtr is = nullptr; 235 | HGLOBAL hMem = GlobalAlloc(GMEM_ZEROINIT, psize); 236 | if (!hMem) return FALSE; 237 | 238 | LPVOID pMem = GlobalLock(hMem); 239 | if (!pMem) return FALSE; 240 | 241 | RtlCopyMemory(pMem, pptr, psize); 242 | GlobalUnlock(hMem); 243 | CreateStreamOnHGlobal(hMem, TRUE, &is); 244 | 245 | auto ret = SUCCEEDED(obj->put_Content(is.Get())); 246 | 247 | return ret; 248 | } 249 | 250 | DLL_EXPORTS(ResourceResponse_GetHeaders, BOOL) 251 | (ICoreWebView2WebResourceResponse* obj, LPVOID* ptr) { 252 | if (!obj) return FALSE; 253 | 254 | ICoreWebView2HttpResponseHeaders* header; 255 | auto ret = SUCCEEDED(obj->get_Headers(&header)); 256 | 257 | *ptr = header; 258 | 259 | return ret; 260 | } 261 | 262 | 263 | 264 | 265 | DLL_EXPORTS(Webview_HTTPRequestHeader_GetHeader, BOOL) 266 | (ICoreWebView2HttpRequestHeaders* header, LPWSTR name, LPVOID* ptr, 267 | uint32_t* size) { 268 | if (!header) return FALSE; 269 | 270 | LPWSTR value = nullptr; 271 | auto ret = SUCCEEDED(header->GetHeader(name, &value)); 272 | 273 | *ptr = value; 274 | *size = lstrlenW(value) * 2 + 2; 275 | 276 | return ret; 277 | } 278 | 279 | DLL_EXPORTS(Webview_HTTPRequestHeader_Contains, BOOL) 280 | (ICoreWebView2HttpRequestHeaders* header, LPWSTR name) { 281 | if (!header) return FALSE; 282 | 283 | BOOL ret = FALSE; 284 | header->Contains(name, &ret); 285 | 286 | return ret; 287 | } 288 | 289 | DLL_EXPORTS(Webview_HTTPRequestHeader_SetHeader, BOOL) 290 | (ICoreWebView2HttpRequestHeaders* header, LPWSTR name, LPWSTR value) { 291 | if (!header) return FALSE; 292 | 293 | return SUCCEEDED(header->SetHeader(name, value)); 294 | } 295 | 296 | DLL_EXPORTS(Webview_HTTPRequestHeader_RemoveHeader, BOOL) 297 | (ICoreWebView2HttpRequestHeaders* header, LPWSTR name) { 298 | if (!header) return FALSE; 299 | 300 | return SUCCEEDED(header->RemoveHeader(name)); 301 | } 302 | 303 | DLL_EXPORTS(Webview_HTTPRequestHeader_GetRawData, BOOL) 304 | (ICoreWebView2HttpRequestHeaders* header, LPVOID* arrayPtr, uint32_t* size) { 305 | if (!header) return FALSE; 306 | 307 | ICoreWebView2HttpHeadersCollectionIterator* iter = nullptr; 308 | auto ret = SUCCEEDED(header->GetIterator(&iter)); 309 | if (!iter) return FALSE; 310 | 311 | std::vector> data; 312 | 313 | *size = 0; 314 | BOOL hasData = FALSE; 315 | while (SUCCEEDED(iter->get_HasCurrentHeader(&hasData)) && hasData) { 316 | ++(*size); 317 | 318 | std::pair pair; 319 | iter->GetCurrentHeader(&pair.first, &pair.second); 320 | data.push_back(std::move(pair)); 321 | 322 | iter->MoveNext(&hasData); 323 | } 324 | 325 | LPSTR buf = 326 | static_cast(wv2_Utility_Malloc((*size) * 2 * sizeof(void*))); 327 | for (size_t i = 0; i < data.size(); i++) { 328 | memcpy(buf + i * 2 * sizeof(void*), &data[i].first, sizeof(void*)); 329 | memcpy(buf + i * 2 * sizeof(void*) + sizeof(void*), &data[i].second, 330 | sizeof(void*)); 331 | } 332 | 333 | *arrayPtr = buf; 334 | 335 | return ret; 336 | } 337 | 338 | DLL_EXPORTS(Webview_HTTPRequestHeader_GetHeaders, BOOL) 339 | (ICoreWebView2HttpRequestHeaders* header, LPWSTR name, LPVOID* arrayPtr, 340 | uint32_t* size) { 341 | if (!header) return FALSE; 342 | 343 | ICoreWebView2HttpHeadersCollectionIterator* iter = nullptr; 344 | auto ret = SUCCEEDED(header->GetHeaders(name, &iter)); 345 | if (!iter) return FALSE; 346 | 347 | std::vector> data; 348 | 349 | *size = 0; 350 | BOOL hasData = FALSE; 351 | while (SUCCEEDED(iter->get_HasCurrentHeader(&hasData)) && hasData) { 352 | ++(*size); 353 | 354 | std::pair pair; 355 | iter->GetCurrentHeader(&pair.first, &pair.second); 356 | data.push_back(std::move(pair)); 357 | 358 | iter->MoveNext(&hasData); 359 | } 360 | 361 | LPSTR buf = 362 | static_cast(wv2_Utility_Malloc((*size) * 2 * sizeof(void*))); 363 | for (size_t i = 0; i < data.size(); i++) { 364 | memcpy(buf + i * 2 * sizeof(void*), &data[i].first, sizeof(void*)); 365 | memcpy(buf + i * 2 * sizeof(void*) + sizeof(void*), &data[i].second, 366 | sizeof(void*)); 367 | } 368 | 369 | *arrayPtr = buf; 370 | 371 | return ret; 372 | } 373 | 374 | 375 | 376 | DLL_EXPORTS(Webview_HTTPResponseHeader_GetHeader, BOOL) 377 | (ICoreWebView2HttpResponseHeaders* header, LPWSTR name, LPVOID* ptr, 378 | uint32_t* size) { 379 | if (!header) return FALSE; 380 | 381 | LPWSTR value = nullptr; 382 | auto ret = SUCCEEDED(header->GetHeader(name, &value)); 383 | 384 | *ptr = value; 385 | *size = lstrlenW(value) * 2 + 2; 386 | 387 | return ret; 388 | } 389 | 390 | DLL_EXPORTS(Webview_HTTPResponseHeader_Contains, BOOL) 391 | (ICoreWebView2HttpResponseHeaders* header, LPWSTR name) { 392 | if (!header) return FALSE; 393 | 394 | BOOL ret = FALSE; 395 | header->Contains(name, &ret); 396 | 397 | return ret; 398 | } 399 | 400 | DLL_EXPORTS(Webview_HTTPResponseHeader_AppendHeader, BOOL) 401 | (ICoreWebView2HttpResponseHeaders* header, LPWSTR name, LPWSTR value) { 402 | if (!header) return FALSE; 403 | 404 | return SUCCEEDED(header->AppendHeader(name, value)); 405 | } 406 | 407 | DLL_EXPORTS(Webview_HTTPResponseHeader_GetRawData, BOOL) 408 | (ICoreWebView2HttpResponseHeaders* header, LPVOID* arrayPtr, uint32_t* size) { 409 | if (!header) return FALSE; 410 | 411 | ICoreWebView2HttpHeadersCollectionIterator* iter = nullptr; 412 | auto ret = SUCCEEDED(header->GetIterator(&iter)); 413 | if (!iter) return FALSE; 414 | 415 | std::vector> data; 416 | 417 | *size = 0; 418 | BOOL hasData = FALSE; 419 | while (SUCCEEDED(iter->get_HasCurrentHeader(&hasData)) && hasData) { 420 | ++(*size); 421 | 422 | std::pair pair; 423 | iter->GetCurrentHeader(&pair.first, &pair.second); 424 | data.push_back(std::move(pair)); 425 | 426 | iter->MoveNext(&hasData); 427 | } 428 | 429 | LPSTR buf = 430 | static_cast(wv2_Utility_Malloc((*size) * 2 * sizeof(void*))); 431 | for (size_t i = 0; i < data.size(); i++) { 432 | memcpy(buf + i * 2 * sizeof(void*), &data[i].first, sizeof(void*)); 433 | memcpy(buf + i * 2 * sizeof(void*) + sizeof(void*), &data[i].second, 434 | sizeof(void*)); 435 | } 436 | 437 | *arrayPtr = buf; 438 | 439 | return ret; 440 | } 441 | 442 | DLL_EXPORTS(Webview_HTTPResponseHeader_GetHeaders, BOOL) 443 | (ICoreWebView2HttpResponseHeaders* header, LPWSTR name, LPVOID* arrayPtr, 444 | uint32_t* size) { 445 | if (!header) return FALSE; 446 | 447 | ICoreWebView2HttpHeadersCollectionIterator* iter = nullptr; 448 | auto ret = SUCCEEDED(header->GetHeaders(name, &iter)); 449 | if (!iter) return FALSE; 450 | 451 | std::vector> data; 452 | 453 | *size = 0; 454 | BOOL hasData = FALSE; 455 | while (SUCCEEDED(iter->get_HasCurrentHeader(&hasData)) && hasData) { 456 | ++(*size); 457 | 458 | std::pair pair; 459 | iter->GetCurrentHeader(&pair.first, &pair.second); 460 | data.push_back(std::move(pair)); 461 | 462 | iter->MoveNext(&hasData); 463 | } 464 | 465 | LPSTR buf = 466 | static_cast(wv2_Utility_Malloc((*size) * 2 * sizeof(void*))); 467 | for (size_t i = 0; i < data.size(); i++) { 468 | memcpy(buf + i * 2 * sizeof(void*), &data[i].first, sizeof(void*)); 469 | memcpy(buf + i * 2 * sizeof(void*) + sizeof(void*), &data[i].second, 470 | sizeof(void*)); 471 | } 472 | 473 | *arrayPtr = buf; 474 | 475 | return ret; 476 | } 477 | 478 | 479 | 480 | DLL_EXPORTS(ResourceResponseView_GetReasonPhrase, BOOL) 481 | (ICoreWebView2WebResourceResponseView* obj, LPVOID* ptr, uint32_t* size) { 482 | if (!obj) return FALSE; 483 | 484 | LPWSTR value = nullptr; 485 | 486 | auto ret = SUCCEEDED(obj->get_ReasonPhrase(&value)); 487 | 488 | *ptr = value; 489 | *size = lstrlenW(value) * 2 + 2; 490 | 491 | return ret; 492 | } 493 | 494 | DLL_EXPORTS(ResourceResponseView_GetStatusCode, int) 495 | (ICoreWebView2WebResourceResponseView* obj) { 496 | if (!obj) return FALSE; 497 | 498 | int code = 0; 499 | obj->get_StatusCode(&code); 500 | 501 | return code; 502 | } 503 | 504 | using ResourceResponseViewGetDataCB = HRESULT(CALLBACK*)(LPVOID ptr, uint32_t size, LPVOID param); 505 | DLL_EXPORTS(ResourceResponseView_GetData, BOOL) 506 | (ICoreWebView2WebResourceResponseView* obj, 507 | ResourceResponseViewGetDataCB callback, LPVOID param) { 508 | if (!obj) return FALSE; 509 | 510 | auto ret = SUCCEEDED(obj->GetContent( 511 | WRL::Callback< 512 | ICoreWebView2WebResourceResponseViewGetContentCompletedHandler>( 513 | [callback, param](HRESULT errorCode, IStream* content) -> HRESULT { 514 | if (content) { 515 | STATSTG stat; 516 | content->Stat(&stat, STATFLAG_NONAME); 517 | 518 | LARGE_INTEGER linfo; 519 | linfo.QuadPart = 0; 520 | content->Seek(linfo, STREAM_SEEK_SET, NULL); 521 | 522 | uint32_t size = stat.cbSize.LowPart; 523 | uint8_t* buf = static_cast(wv2_Utility_Malloc(size)); 524 | ULONG dummy = 0; 525 | content->Read(buf, size, &dummy); 526 | 527 | return callback(buf, size, param); 528 | } 529 | return callback(nullptr, 0, param); 530 | }) 531 | .Get())); 532 | 533 | return ret; 534 | } 535 | 536 | DLL_EXPORTS(ResourceResponseView_GetData_Sync, BOOL) 537 | (ICoreWebView2WebResourceResponseView* obj, LPVOID* pptr, uint32_t* psize) { 538 | if (!obj) return FALSE; 539 | 540 | Waitable* waiter = CreateWaitable(true); 541 | 542 | WRL::ComPtr is = nullptr; 543 | auto ret = SUCCEEDED(obj->GetContent( 544 | WRL::Callback< 545 | ICoreWebView2WebResourceResponseViewGetContentCompletedHandler>( 546 | [waiter, &is](HRESULT errorCode, IStream* content) -> HRESULT { 547 | if (content) 548 | is = content; 549 | ActiveWaitable(waiter); 550 | return S_OK; 551 | }) 552 | .Get())); 553 | 554 | WaitOfMsgLoop(waiter); 555 | 556 | if (is) return FALSE; 557 | 558 | STATSTG stat; 559 | is->Stat(&stat, STATFLAG_NONAME); 560 | 561 | LARGE_INTEGER linfo; 562 | linfo.QuadPart = 0; 563 | is->Seek(linfo, STREAM_SEEK_SET, NULL); 564 | 565 | uint32_t size = stat.cbSize.LowPart; 566 | uint8_t* buf = static_cast(wv2_Utility_Malloc(size)); 567 | ULONG dummy = 0; 568 | is->Read(buf, size, &dummy); 569 | 570 | *pptr = buf; 571 | *psize = size; 572 | 573 | return ret; 574 | } 575 | 576 | DLL_EXPORTS(ResourceResponseView_GetHeaders, BOOL) 577 | (ICoreWebView2WebResourceResponseView* obj, LPVOID* ptr) { 578 | if (!obj) return FALSE; 579 | 580 | ICoreWebView2HttpResponseHeaders* header; 581 | auto ret = SUCCEEDED(obj->get_Headers(&header)); 582 | 583 | *ptr = header; 584 | 585 | return ret; 586 | } 587 | 588 | 589 | 590 | -------------------------------------------------------------------------------- /src/wv2_webrequest.h: -------------------------------------------------------------------------------- 1 | #ifndef WV2_WEBREQUEST_H 2 | #define WV2_WEBREQUEST_H 3 | #pragma once 4 | 5 | #include "wv2_utils.h" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/wv2_webview.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "wv2_controller.h" 3 | #include "wv2_types.h" 4 | #include "wv2_utils.h" 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #pragma comment(lib, "Shlwapi.lib") 11 | 12 | using namespace Microsoft; 13 | 14 | DLL_EXPORTS(Webview_CanGoBack, BOOL)(ICoreWebView2* webview) { 15 | if (!webview) return FALSE; 16 | 17 | BOOL ret = FALSE; 18 | 19 | webview->get_CanGoBack(&ret); 20 | 21 | return ret; 22 | } 23 | 24 | DLL_EXPORTS(Webview_CanGoForward, BOOL)(ICoreWebView2* webview) { 25 | if (!webview) return FALSE; 26 | 27 | BOOL ret = FALSE; 28 | 29 | webview->get_CanGoForward(&ret); 30 | 31 | return ret; 32 | } 33 | 34 | DLL_EXPORTS(Webview_GoBack, BOOL)(ICoreWebView2* webview) { 35 | if (!webview) return FALSE; 36 | 37 | return SUCCEEDED(webview->GoBack()); 38 | } 39 | 40 | DLL_EXPORTS(Webview_GoForward, BOOL)(ICoreWebView2* webview) { 41 | if (!webview) return FALSE; 42 | 43 | return SUCCEEDED(webview->GoForward()); 44 | } 45 | 46 | DLL_EXPORTS(Webview_Reload, BOOL)(ICoreWebView2* webview) { 47 | if (!webview) return FALSE; 48 | 49 | return SUCCEEDED(webview->Reload()); 50 | } 51 | 52 | DLL_EXPORTS(Webview_Stop, BOOL)(ICoreWebView2* webview) { 53 | if (!webview) return FALSE; 54 | 55 | return SUCCEEDED(webview->Stop()); 56 | } 57 | 58 | DLL_EXPORTS(Webview_Navigate, BOOL)(ICoreWebView2* webview, LPCWSTR url) { 59 | if (!webview) return FALSE; 60 | 61 | // Check uri 62 | std::wstring uri(url); 63 | HRESULT hr = webview->Navigate(uri.c_str()); 64 | if (hr == E_INVALIDARG) { 65 | if (uri.find(L' ') == std::wstring::npos && 66 | uri.find(L'.') != std::wstring::npos) { 67 | hr = webview->Navigate((L"http://" + uri).c_str()); 68 | } else 69 | return FALSE; 70 | } 71 | 72 | return SUCCEEDED(hr); 73 | } 74 | 75 | DLL_EXPORTS(Webview_NavigateToString, BOOL) 76 | (ICoreWebView2* webview, LPCWSTR html) { 77 | if (!webview) return FALSE; 78 | 79 | return SUCCEEDED(webview->NavigateToString(html)); 80 | } 81 | 82 | using ExecuteScriptCB = HRESULT(CALLBACK*)(HRESULT code, LPCVOID ptr, uint32_t size, LPVOID param); 83 | DLL_EXPORTS(Webview_ExecuteScript, BOOL) 84 | (ICoreWebView2* webview, LPCWSTR script, ExecuteScriptCB callback, 85 | LPVOID param) { 86 | if (!webview) return FALSE; 87 | 88 | auto ret = SUCCEEDED(webview->ExecuteScript( 89 | script, WRL::Callback( 90 | [callback, param](HRESULT errorCode, 91 | LPCWSTR resultObjectAsJson) -> HRESULT { 92 | if (resultObjectAsJson) { 93 | if (callback) { 94 | uint32_t sizeTmp = lstrlenW(resultObjectAsJson) * 2 + 2; 95 | LPWSTR newStr = 96 | static_cast(wv2_Utility_Malloc(sizeTmp)); 97 | if (newStr) { 98 | lstrcpyW(newStr, resultObjectAsJson); 99 | } 100 | 101 | return callback(errorCode, newStr, sizeTmp, param); 102 | } 103 | } else 104 | callback(errorCode, 0, 0, param); 105 | return S_OK; 106 | }) 107 | .Get())); 108 | 109 | return ret; 110 | } 111 | 112 | DLL_EXPORTS(Webview_ExecuteScript_Sync, BOOL) 113 | (ICoreWebView2* webview, LPCWSTR script, LPCVOID* ptr, uint32_t* size) { 114 | if (!webview) return FALSE; 115 | 116 | Waitable* waiter = CreateWaitable(true); 117 | 118 | auto ret = SUCCEEDED(webview->ExecuteScript( 119 | script, WRL::Callback( 120 | [waiter, ptr, size](HRESULT errorCode, 121 | LPCWSTR resultObjectAsJson) -> HRESULT { 122 | if (!ptr || !size) return S_OK; 123 | if (resultObjectAsJson && errorCode == S_OK) { 124 | uint32_t sizeTmp = lstrlenW(resultObjectAsJson) * 2 + 2; 125 | LPWSTR newStr = 126 | static_cast(wv2_Utility_Malloc(sizeTmp)); 127 | if (newStr) { 128 | lstrcpyW(newStr, resultObjectAsJson); 129 | 130 | *ptr = newStr; 131 | *size = sizeTmp; 132 | } 133 | } else { 134 | *ptr = nullptr; 135 | *size = 0; 136 | } 137 | 138 | ActiveWaitable(waiter); 139 | 140 | return errorCode; 141 | }) 142 | .Get())); 143 | 144 | WaitOfMsgLoop(waiter); 145 | 146 | return ret; 147 | } 148 | 149 | DLL_EXPORTS(Webview_GetURL, BOOL) 150 | (ICoreWebView2* webview, LPVOID* ptr, uint32_t* size) { 151 | if (!webview) return FALSE; 152 | 153 | LPWSTR source = nullptr; 154 | auto ret = SUCCEEDED(webview->get_Source(&source)); 155 | 156 | *ptr = source; 157 | *size = lstrlenW(source) * 2 + 2; 158 | 159 | return ret; 160 | } 161 | 162 | DLL_EXPORTS(Webview_GetDocumentTitle, BOOL) 163 | (ICoreWebView2* webview, LPVOID* ptr, uint32_t* size) { 164 | if (!webview) return FALSE; 165 | 166 | LPWSTR source = nullptr; 167 | auto ret = SUCCEEDED(webview->get_DocumentTitle(&source)); 168 | 169 | *ptr = source; 170 | *size = lstrlenW(source) * 2 + 2; 171 | 172 | return ret; 173 | } 174 | 175 | using CallDevtoolsProtocolsMethodCB = HRESULT(CALLBACK*)(LPVOID result, uint32_t size, LPVOID param); 176 | DLL_EXPORTS(Webview_CallDevtoolsProtocolsMethod, BOOL) 177 | (ICoreWebView2* webview, LPWSTR method, LPWSTR paramJSON, 178 | CallDevtoolsProtocolsMethodCB callback, LPVOID param) { 179 | if (!webview) return FALSE; 180 | 181 | LPWSTR source = nullptr; 182 | auto ret = SUCCEEDED(webview->CallDevToolsProtocolMethod( 183 | method, paramJSON, 184 | WRL::Callback( 185 | [callback, param](HRESULT errorCode, 186 | LPCWSTR returnObjectAsJson) -> HRESULT { 187 | if (callback) { 188 | uint32_t sizeTmp = lstrlenW(returnObjectAsJson) * 2 + 2; 189 | LPWSTR newStr = static_cast(wv2_Utility_Malloc(sizeTmp)); 190 | if (newStr) { 191 | lstrcpyW(newStr, returnObjectAsJson); 192 | } 193 | 194 | return callback(newStr, sizeTmp, param); 195 | } else 196 | return S_OK; 197 | }) 198 | .Get())); 199 | 200 | return ret; 201 | } 202 | 203 | DLL_EXPORTS(Webview_CallDevtoolsProtocolsMethod_Sync, BOOL) 204 | (ICoreWebView2* webview, LPWSTR method, LPWSTR paramJSON, LPCVOID* ptr, 205 | uint32_t* size) { 206 | if (!webview) return FALSE; 207 | 208 | Waitable* waiter = CreateWaitable(true); 209 | 210 | auto ret = SUCCEEDED(webview->CallDevToolsProtocolMethod( 211 | method, paramJSON, 212 | WRL::Callback( 213 | [waiter, ptr, size](HRESULT errorCode, 214 | LPCWSTR resultObjectAsJson) -> HRESULT { 215 | uint32_t sizeTmp = lstrlenW(resultObjectAsJson) * 2 + 2; 216 | LPWSTR newStr = 217 | static_cast(wv2_Utility_Malloc(sizeTmp)); 218 | if (newStr) { 219 | lstrcpyW(newStr, resultObjectAsJson); 220 | 221 | *ptr = newStr; 222 | *size = sizeTmp; 223 | } 224 | 225 | ActiveWaitable(waiter); 226 | 227 | return S_OK; 228 | }) 229 | .Get())); 230 | 231 | WaitOfMsgLoop(waiter); 232 | 233 | return ret; 234 | } 235 | 236 | DLL_EXPORTS(Webview_GetBrowserProcessID, uint32_t)(ICoreWebView2* webview) { 237 | if (!webview) return FALSE; 238 | 239 | uint32_t pid = 0; 240 | webview->get_BrowserProcessId(&pid); 241 | 242 | return pid; 243 | } 244 | 245 | using CapturePreviewCB = HRESULT(CALLBACK*)(LPVOID lpMem, uint32_t size, LPVOID param); 246 | DLL_EXPORTS(Webview_CapturePreview, BOOL) 247 | (ICoreWebView2* webview, COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT format, 248 | CapturePreviewCB callback, LPVOID param) { 249 | if (!webview) return FALSE; 250 | 251 | IStream* is = SHCreateMemStream(nullptr, 0); 252 | 253 | HRESULT hr = webview->CapturePreview( 254 | format, is, 255 | WRL::Callback( 256 | [is, callback, param](HRESULT errorCode) -> HRESULT { 257 | STATSTG stat; 258 | is->Stat(&stat, STATFLAG_NONAME); 259 | 260 | LARGE_INTEGER linfo; 261 | linfo.QuadPart = 0; 262 | is->Seek(linfo, STREAM_SEEK_SET, NULL); 263 | 264 | uint32_t size = stat.cbSize.LowPart; 265 | uint8_t* buf = static_cast(wv2_Utility_Malloc(size)); 266 | ULONG dummy = 0; 267 | is->Read(buf, size, &dummy); 268 | 269 | HRESULT hr = callback(buf, size, param); 270 | 271 | wv2_Utility_Mfree(buf); 272 | 273 | is->Release(); 274 | return hr; 275 | }) 276 | .Get()); 277 | 278 | return SUCCEEDED(hr); 279 | } 280 | 281 | DLL_EXPORTS(Webview_CapturePreview_Sync, BOOL) 282 | (ICoreWebView2* webview, COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT format, LPVOID *ptr, uint32_t *psize) { 283 | if (!webview) return FALSE; 284 | 285 | Waitable* waiter = CreateWaitable(true); 286 | 287 | IStream* is = SHCreateMemStream(nullptr, 0); 288 | 289 | HRESULT hr = webview->CapturePreview( 290 | format, is, 291 | WRL::Callback( 292 | [waiter, is, ptr, psize](HRESULT errorCode) -> HRESULT { 293 | STATSTG stat; 294 | is->Stat(&stat, STATFLAG_NONAME); 295 | 296 | LARGE_INTEGER linfo; 297 | linfo.QuadPart = 0; 298 | is->Seek(linfo, STREAM_SEEK_SET, NULL); 299 | 300 | uint32_t size = stat.cbSize.LowPart; 301 | uint8_t* buf = static_cast(wv2_Utility_Malloc(size)); 302 | 303 | ULONG dummy = 0; 304 | is->Read(buf, size, &dummy); 305 | 306 | *ptr = buf; 307 | *psize = size; 308 | 309 | is->Release(); 310 | 311 | ActiveWaitable(waiter); 312 | return S_OK; 313 | }) 314 | .Get()); 315 | 316 | WaitOfMsgLoop(waiter); 317 | 318 | return SUCCEEDED(hr); 319 | } 320 | 321 | DLL_EXPORTS(Webview_OpenDevTools, uint32_t)(ICoreWebView2* webview) { 322 | if (!webview) return FALSE; 323 | 324 | return SUCCEEDED(webview->OpenDevToolsWindow()); 325 | } 326 | 327 | 328 | 329 | DLL_EXPORTS(Webview_NewWindowRequestArgs_GetURL, BOOL) 330 | (ICoreWebView2NewWindowRequestedEventArgs* args, LPVOID* ptr, uint32_t* size) { 331 | if (!args) return FALSE; 332 | 333 | LPWSTR url = nullptr; 334 | auto ret = SUCCEEDED(args->get_Uri(&url)); 335 | 336 | *ptr = url; 337 | *size = lstrlenW(url) * 2 + 2; 338 | 339 | return ret; 340 | } 341 | 342 | DLL_EXPORTS(Webview_NewWindowRequestArgs_SetNewWindow, BOOL) 343 | (ICoreWebView2NewWindowRequestedEventArgs* args, ICoreWebView2* window) { 344 | if (!args) return FALSE; 345 | 346 | return SUCCEEDED(args->put_NewWindow(window)); 347 | } 348 | 349 | DLL_EXPORTS(Webview_NewWindowRequestArgs_GetNewWindow, BOOL) 350 | (ICoreWebView2NewWindowRequestedEventArgs* args, LPVOID* ptr) { 351 | if (!args) return FALSE; 352 | 353 | ICoreWebView2* window = nullptr; 354 | 355 | auto ret = SUCCEEDED(args->get_NewWindow(&window)); 356 | 357 | *ptr = window; 358 | 359 | return ret; 360 | } 361 | 362 | DLL_EXPORTS(Webview_NewWindowRequestArgs_SetHandled, BOOL) 363 | (ICoreWebView2NewWindowRequestedEventArgs* args, BOOL handle) { 364 | if (!args) return FALSE; 365 | 366 | return SUCCEEDED(args->put_Handled(handle)); 367 | } 368 | 369 | DLL_EXPORTS(Webview_NewWindowRequestArgs_GetHandled, BOOL) 370 | (ICoreWebView2NewWindowRequestedEventArgs* args) { 371 | if (!args) return FALSE; 372 | 373 | BOOL ret = FALSE; 374 | 375 | args->get_Handled(&ret); 376 | 377 | return ret; 378 | } 379 | 380 | DLL_EXPORTS(Webview_NewWindowRequestArgs_GetDeferral, BOOL) 381 | (ICoreWebView2NewWindowRequestedEventArgs* args, LPVOID* ptr) { 382 | if (!args) return FALSE; 383 | 384 | ICoreWebView2Deferral* deferral = nullptr; 385 | 386 | auto ret = SUCCEEDED(args->GetDeferral(&deferral)); 387 | 388 | *ptr = deferral; 389 | 390 | return ret; 391 | } 392 | 393 | struct NewWindowFeatures { 394 | BOOL hasPos; 395 | BOOL hasSize; 396 | uint32_t left; 397 | uint32_t top; 398 | uint32_t height; 399 | uint32_t width; 400 | BOOL menuBar; 401 | BOOL statusBar; 402 | BOOL toolBar; 403 | BOOL scrollBar; 404 | }; 405 | 406 | DLL_EXPORTS(Webview_NewWindowRequestArgs_GetFeatures, BOOL) 407 | (ICoreWebView2NewWindowRequestedEventArgs* args, NewWindowFeatures* pFeatures) { 408 | if (!args) return FALSE; 409 | 410 | ICoreWebView2WindowFeatures* features = nullptr; 411 | 412 | auto ret = SUCCEEDED(args->get_WindowFeatures(&features)); 413 | 414 | if (pFeatures) { 415 | features->get_HasPosition(&pFeatures->hasPos); 416 | features->get_HasSize(&pFeatures->hasSize); 417 | features->get_Left(&pFeatures->left); 418 | features->get_Top(&pFeatures->top); 419 | features->get_Height(&pFeatures->height); 420 | features->get_Width(&pFeatures->width); 421 | features->get_ShouldDisplayMenuBar(&pFeatures->menuBar); 422 | features->get_ShouldDisplayStatus(&pFeatures->statusBar); 423 | features->get_ShouldDisplayToolbar(&pFeatures->toolBar); 424 | features->get_ShouldDisplayScrollBars(&pFeatures->scrollBar); 425 | } 426 | 427 | return ret; 428 | } 429 | 430 | using NewWindowRequestCB = HRESULT(CALLBACK*)(LPVOID wv, LPVOID args, LPVOID param); 431 | DLL_EXPORTS(Webview_Attach_NewWindowRequest, int64_t) 432 | (ICoreWebView2* webview, NewWindowRequestCB callback, LPVOID param) { 433 | if (!webview) return FALSE; 434 | 435 | EventRegistrationToken token; 436 | 437 | webview->add_NewWindowRequested( 438 | WRL::Callback( 439 | [callback, param]( 440 | ICoreWebView2* sender, 441 | ICoreWebView2NewWindowRequestedEventArgs* args) -> HRESULT { 442 | sender->AddRef(); 443 | args->AddRef(); 444 | return callback(sender, args, param); 445 | }) 446 | .Get(), 447 | &token); 448 | 449 | return token.value; 450 | } 451 | 452 | DLL_EXPORTS(Webview_Detach_NewWindowRequest, BOOL) 453 | (ICoreWebView2* webview, int64_t value) { 454 | if (!webview) return FALSE; 455 | EventRegistrationToken token = {value}; 456 | 457 | return SUCCEEDED(webview->remove_NewWindowRequested(token)); 458 | } 459 | 460 | 461 | using WindowCloseRequestCB = HRESULT(CALLBACK*)(LPVOID wv, LPVOID param); 462 | DLL_EXPORTS(Webview_Attach_WindowCloseRequest, int64_t) 463 | (ICoreWebView2* webview, WindowCloseRequestCB callback, LPVOID param) { 464 | if (!webview) return FALSE; 465 | 466 | EventRegistrationToken token; 467 | 468 | webview->add_WindowCloseRequested( 469 | WRL::Callback( 470 | [callback, param](ICoreWebView2* sender, IUnknown* args) -> HRESULT { 471 | sender->AddRef(); 472 | return callback(sender, param); 473 | }) 474 | .Get(), 475 | &token); 476 | 477 | return token.value; 478 | } 479 | 480 | DLL_EXPORTS(Webview_Detach_WindowCloseRequest, BOOL) 481 | (ICoreWebView2* webview, int64_t value) { 482 | if (!webview) return FALSE; 483 | EventRegistrationToken token = {value}; 484 | 485 | return SUCCEEDED(webview->remove_WindowCloseRequested(token)); 486 | } 487 | 488 | 489 | using SourceChangedCB = HRESULT(CALLBACK*)(LPVOID wv, BOOL isNewDoc, LPVOID param); 490 | DLL_EXPORTS(Webview_Attach_SourceChanged, int64_t) 491 | (ICoreWebView2* webview, SourceChangedCB callback, LPVOID param) { 492 | if (!webview) return FALSE; 493 | 494 | EventRegistrationToken token; 495 | 496 | webview->add_SourceChanged( 497 | WRL::Callback( 498 | [callback, param]( 499 | ICoreWebView2* sender, 500 | ICoreWebView2SourceChangedEventArgs* args) -> HRESULT { 501 | BOOL newDoc = FALSE; 502 | args->get_IsNewDocument(&newDoc); 503 | sender->AddRef(); 504 | return callback(sender, newDoc, param); 505 | }) 506 | .Get(), 507 | &token); 508 | 509 | return token.value; 510 | } 511 | 512 | DLL_EXPORTS(Webview_Detach_SourceChanged, BOOL) 513 | (ICoreWebView2* webview, int64_t value) { 514 | if (!webview) return FALSE; 515 | EventRegistrationToken token = {value}; 516 | 517 | return SUCCEEDED(webview->remove_SourceChanged(token)); 518 | } 519 | 520 | using DocumentTitleChangedCB = HRESULT(CALLBACK*)(LPVOID wv, 521 | LPVOID param); 522 | DLL_EXPORTS(Webview_Attach_DocumentTitleChanged, int64_t) 523 | (ICoreWebView2* webview, DocumentTitleChangedCB callback, LPVOID param) { 524 | if (!webview) return FALSE; 525 | 526 | EventRegistrationToken token; 527 | 528 | webview->add_DocumentTitleChanged( 529 | WRL::Callback( 530 | [callback, param](ICoreWebView2* sender, IUnknown* args) -> HRESULT { 531 | sender->AddRef(); 532 | return callback(sender, param); 533 | }) 534 | .Get(), 535 | &token); 536 | 537 | return token.value; 538 | } 539 | 540 | DLL_EXPORTS(Webview_Detach_DocumentTitleChanged, BOOL) 541 | (ICoreWebView2* webview, int64_t value) { 542 | if (!webview) return FALSE; 543 | EventRegistrationToken token = {value}; 544 | 545 | return SUCCEEDED(webview->remove_DocumentTitleChanged(token)); 546 | } 547 | 548 | DLL_EXPORTS(Webview_NavigationStartingEventArgs_GetURL, BOOL) 549 | (ICoreWebView2NavigationStartingEventArgs* args, LPVOID* ptr, uint32_t* size) { 550 | if (!args) return FALSE; 551 | 552 | LPWSTR url = nullptr; 553 | auto ret = SUCCEEDED(args->get_Uri(&url)); 554 | 555 | *ptr = url; 556 | *size = lstrlenW(url) * 2 + 2; 557 | return ret; 558 | } 559 | 560 | 561 | DLL_EXPORTS(Webview_NavigationStartingEventArgs_PutCancel, BOOL) 562 | (ICoreWebView2NavigationStartingEventArgs* args, BOOL cancel) { 563 | if (!args) return FALSE; 564 | 565 | auto ret = SUCCEEDED(args->put_Cancel(cancel)); 566 | return ret; 567 | } 568 | 569 | DLL_EXPORTS(Webview_NavigationStartingEventArgs_GetRequestHeader, BOOL) 570 | (ICoreWebView2NavigationStartingEventArgs* args, LPVOID* ptr) { 571 | if (!args) return FALSE; 572 | 573 | ICoreWebView2HttpRequestHeaders* header = nullptr; 574 | auto ret = SUCCEEDED(args->get_RequestHeaders(&header)); 575 | 576 | *ptr = header; 577 | 578 | return ret; 579 | } 580 | 581 | using NavigationStartingCB = HRESULT(CALLBACK*)(LPVOID wv, LPVOID args, BOOL user, BOOL redirect, uint64_t navId, LPVOID param); 582 | DLL_EXPORTS(Webview_Attach_NavigationStarting, int64_t) 583 | (ICoreWebView2* webview, NavigationStartingCB callback, LPVOID param) { 584 | if (!webview) return FALSE; 585 | 586 | EventRegistrationToken token; 587 | 588 | webview->add_NavigationStarting( 589 | WRL::Callback( 590 | [callback, param]( 591 | ICoreWebView2* sender, 592 | ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT { 593 | sender->AddRef(); 594 | args->AddRef(); 595 | 596 | BOOL success = FALSE, redirect = FALSE; 597 | uint64_t navId = 0; 598 | args->get_IsUserInitiated(&success); 599 | args->get_NavigationId(&navId); 600 | args->get_IsRedirected(&redirect); 601 | 602 | HRESULT hr = 603 | callback(sender, args, success, redirect, navId, param); 604 | 605 | return hr; 606 | }) 607 | .Get(), 608 | &token); 609 | 610 | return token.value; 611 | } 612 | 613 | DLL_EXPORTS(Webview_Detach_NavigationStarting, BOOL) 614 | (ICoreWebView2* webview, int64_t value) { 615 | if (!webview) return FALSE; 616 | EventRegistrationToken token = {value}; 617 | 618 | return SUCCEEDED(webview->remove_NavigationStarting(token)); 619 | } 620 | 621 | using NavigationCompletedCB = HRESULT(CALLBACK*)(LPVOID wv, BOOL success, int status, uint64_t navId, 622 | LPVOID param); 623 | DLL_EXPORTS(Webview_Attach_NavigationCompleted, int64_t) 624 | (ICoreWebView2* webview, NavigationCompletedCB callback, LPVOID param) { 625 | if (!webview) return FALSE; 626 | 627 | EventRegistrationToken token; 628 | 629 | webview->add_NavigationCompleted( 630 | WRL::Callback( 631 | [callback, param]( 632 | ICoreWebView2* sender, 633 | ICoreWebView2NavigationCompletedEventArgs* args) -> HRESULT { 634 | sender->AddRef(); 635 | 636 | BOOL success = FALSE; 637 | uint64_t navId = 0; 638 | int status = 0; 639 | args->get_IsSuccess(&success); 640 | args->get_NavigationId(&navId); 641 | args->get_WebErrorStatus( 642 | reinterpret_cast(&status)); 643 | 644 | HRESULT hr = callback(sender, success, status, navId, param); 645 | 646 | return hr; 647 | }) 648 | .Get(), 649 | &token); 650 | 651 | return token.value; 652 | } 653 | 654 | DLL_EXPORTS(Webview_Detach_NavigationCompleted, BOOL) 655 | (ICoreWebView2* webview, int64_t value) { 656 | if (!webview) return FALSE; 657 | EventRegistrationToken token = {value}; 658 | 659 | return SUCCEEDED(webview->remove_NavigationCompleted(token)); 660 | } 661 | 662 | 663 | DLL_EXPORTS(Webview_GetFullscreenMode, BOOL) 664 | (ICoreWebView2* webview) { 665 | if (!webview) return FALSE; 666 | 667 | BOOL ret = FALSE; 668 | webview->get_ContainsFullScreenElement(&ret); 669 | 670 | return ret; 671 | } 672 | 673 | using ContainsFullScreenElementChangedCB = HRESULT(CALLBACK*)(LPVOID wv,LPVOID param); 674 | DLL_EXPORTS(Webview_Attach_ContainsFullScreenElementChanged, int64_t) 675 | (ICoreWebView2* webview, ContainsFullScreenElementChangedCB callback, 676 | LPVOID param) { 677 | if (!webview) return FALSE; 678 | 679 | EventRegistrationToken token; 680 | 681 | webview->add_ContainsFullScreenElementChanged( 682 | WRL::Callback( 683 | [callback, param](ICoreWebView2* sender, IUnknown* args) -> HRESULT { 684 | sender->AddRef(); 685 | 686 | HRESULT hr = callback(sender, param); 687 | 688 | return hr; 689 | }) 690 | .Get(), 691 | &token); 692 | 693 | return token.value; 694 | } 695 | 696 | DLL_EXPORTS(Webview_Detach_ContainsFullScreenElementChanged, BOOL) 697 | (ICoreWebView2* webview, int64_t value) { 698 | if (!webview) return FALSE; 699 | EventRegistrationToken token = {value}; 700 | 701 | return SUCCEEDED(webview->remove_ContainsFullScreenElementChanged(token)); 702 | } 703 | 704 | struct WebView2Settings { 705 | BOOL enableScripts; 706 | BOOL enableWebMessage; 707 | BOOL enableDefaultDialogs; 708 | BOOL enableStatusBar; 709 | BOOL enableDevTools; 710 | BOOL enableDefaultContextMenu; 711 | BOOL enableHostJSObject; 712 | BOOL enableZoomControl; 713 | BOOL enableBuiltInError; 714 | BOOL enableBrowserAcceleratorKeys; 715 | BOOL enablePasswdAutoSave; 716 | BOOL enableAutoFillin; 717 | BOOL enablePinchZoom; 718 | BOOL enableSwipeNavigation; 719 | COREWEBVIEW2_PDF_TOOLBAR_ITEMS hiddenPdfToolbar; 720 | }; 721 | 722 | DLL_EXPORTS(Webview_GetSettings, BOOL) 723 | (ICoreWebView2* webview, WebView2Settings* pset) { 724 | if (!webview) return FALSE; 725 | 726 | WRL::ComPtr settings = nullptr; 727 | auto ret = SUCCEEDED(webview->get_Settings(&settings)); 728 | 729 | WRL::ComPtr target = nullptr; 730 | settings->QueryInterface(&target); 731 | 732 | if (pset) { 733 | target->get_IsScriptEnabled(&pset->enableScripts); 734 | target->get_IsWebMessageEnabled(&pset->enableWebMessage); 735 | target->get_AreDefaultScriptDialogsEnabled(&pset->enableDefaultDialogs); 736 | target->get_IsStatusBarEnabled(&pset->enableStatusBar); 737 | target->get_AreDevToolsEnabled(&pset->enableDevTools); 738 | target->get_AreDefaultContextMenusEnabled(&pset->enableDefaultContextMenu); 739 | target->get_AreHostObjectsAllowed(&pset->enableHostJSObject); 740 | target->get_IsZoomControlEnabled(&pset->enableZoomControl); 741 | target->get_IsBuiltInErrorPageEnabled(&pset->enableBuiltInError); 742 | target->get_AreBrowserAcceleratorKeysEnabled( 743 | &pset->enableBrowserAcceleratorKeys); 744 | target->get_IsPasswordAutosaveEnabled(&pset->enablePasswdAutoSave); 745 | target->get_IsGeneralAutofillEnabled(&pset->enableAutoFillin); 746 | target->get_IsPinchZoomEnabled(&pset->enablePinchZoom); 747 | target->get_IsSwipeNavigationEnabled(&pset->enableSwipeNavigation); 748 | target->get_HiddenPdfToolbarItems(&pset->hiddenPdfToolbar); 749 | } 750 | 751 | return ret; 752 | } 753 | 754 | DLL_EXPORTS(Webview_SetSettings, BOOL) 755 | (ICoreWebView2* webview, WebView2Settings* pset) { 756 | if (!webview) return FALSE; 757 | 758 | WRL::ComPtr settings = nullptr; 759 | auto ret = SUCCEEDED(webview->get_Settings(&settings)); 760 | 761 | WRL::ComPtr target = nullptr; 762 | settings->QueryInterface(&target); 763 | 764 | if (pset) { 765 | target->put_IsScriptEnabled(pset->enableScripts); 766 | target->put_IsWebMessageEnabled(pset->enableWebMessage); 767 | target->put_AreDefaultScriptDialogsEnabled(pset->enableDefaultDialogs); 768 | target->put_IsStatusBarEnabled(pset->enableStatusBar); 769 | target->put_AreDevToolsEnabled(pset->enableDevTools); 770 | target->put_AreDefaultContextMenusEnabled(pset->enableDefaultContextMenu); 771 | target->put_AreHostObjectsAllowed(pset->enableHostJSObject); 772 | target->put_IsZoomControlEnabled(pset->enableZoomControl); 773 | target->put_IsBuiltInErrorPageEnabled(pset->enableBuiltInError); 774 | target->put_AreBrowserAcceleratorKeysEnabled( 775 | pset->enableBrowserAcceleratorKeys); 776 | target->put_IsPasswordAutosaveEnabled(pset->enablePasswdAutoSave); 777 | target->put_IsGeneralAutofillEnabled(pset->enableAutoFillin); 778 | target->put_IsPinchZoomEnabled(pset->enablePinchZoom); 779 | target->put_IsSwipeNavigationEnabled(pset->enableSwipeNavigation); 780 | target->put_HiddenPdfToolbarItems(pset->hiddenPdfToolbar); 781 | } 782 | 783 | return ret; 784 | } 785 | 786 | DLL_EXPORTS(Webview_GetUserAgent, BOOL) 787 | (ICoreWebView2* webview, LPVOID* ptr, uint32_t* size) { 788 | if (!webview) return FALSE; 789 | 790 | WRL::ComPtr settings = nullptr; 791 | auto ret = SUCCEEDED(webview->get_Settings(&settings)); 792 | 793 | WRL::ComPtr rsettings = nullptr; 794 | settings->QueryInterface(&rsettings); 795 | 796 | LPWSTR strptr = nullptr; 797 | rsettings->get_UserAgent(&strptr); 798 | 799 | *ptr = strptr; 800 | *size = lstrlenW(strptr) * 2 + 2; 801 | 802 | return ret; 803 | } 804 | 805 | DLL_EXPORTS(Webview_SetUserAgent, BOOL) 806 | (ICoreWebView2* webview, LPWSTR ua) { 807 | if (!webview) return FALSE; 808 | 809 | WRL::ComPtr settings = nullptr; 810 | auto ret = SUCCEEDED(webview->get_Settings(&settings)); 811 | 812 | WRL::ComPtr rsettings = nullptr; 813 | settings->QueryInterface(&rsettings); 814 | 815 | rsettings->put_UserAgent(ua); 816 | 817 | return ret; 818 | } 819 | 820 | DLL_EXPORTS(Webview_GetCookieManager, BOOL) 821 | (ICoreWebView2* webview, LPVOID* ptr) { 822 | if (!webview) return FALSE; 823 | 824 | WRL::ComPtr tmpWv = nullptr; 825 | webview->QueryInterface(&tmpWv); 826 | 827 | ICoreWebView2CookieManager* ckManager = nullptr; 828 | auto ret = SUCCEEDED(tmpWv->get_CookieManager(&ckManager)); 829 | 830 | *ptr = ckManager; 831 | 832 | return ret; 833 | } 834 | 835 | DLL_EXPORTS(Webview_GetEnvironment, BOOL) 836 | (ICoreWebView2* webview, LPVOID* ptr) { 837 | if (!webview) return FALSE; 838 | 839 | WRL::ComPtr tmpWv = nullptr; 840 | webview->QueryInterface(&tmpWv); 841 | 842 | ICoreWebView2Environment* env = nullptr; 843 | auto ret = SUCCEEDED(tmpWv->get_Environment(&env)); 844 | 845 | *ptr = env; 846 | 847 | return ret; 848 | } 849 | 850 | DLL_EXPORTS(Webview_OpenTaskManager, BOOL) 851 | (ICoreWebView2* webview) { 852 | if (!webview) return FALSE; 853 | 854 | WRL::ComPtr tmpWv = nullptr; 855 | webview->QueryInterface(&tmpWv); 856 | 857 | auto ret = SUCCEEDED(tmpWv->OpenTaskManagerWindow()); 858 | 859 | return ret; 860 | } 861 | 862 | 863 | 864 | DLL_EXPORTS(Webview_PermissionRequestArgs_GetURL, BOOL) 865 | (ICoreWebView2PermissionRequestedEventArgs* args, LPVOID* ptr, uint32_t* size) { 866 | if (!args) return FALSE; 867 | 868 | LPWSTR url = nullptr; 869 | 870 | auto ret = SUCCEEDED(args->get_Uri(&url)); 871 | 872 | *ptr = url; 873 | *size = lstrlenW(url) * 2 + 2; 874 | 875 | return ret; 876 | } 877 | 878 | DLL_EXPORTS(Webview_PermissionRequestArgs_GetType, int) 879 | (ICoreWebView2PermissionRequestedEventArgs* args) { 880 | if (!args) return FALSE; 881 | 882 | COREWEBVIEW2_PERMISSION_KIND type; 883 | 884 | args->get_PermissionKind(&type); 885 | 886 | return type; 887 | } 888 | 889 | DLL_EXPORTS(Webview_PermissionRequestArgs_GetState, int) 890 | (ICoreWebView2PermissionRequestedEventArgs* args) { 891 | if (!args) return FALSE; 892 | 893 | COREWEBVIEW2_PERMISSION_STATE state; 894 | 895 | args->get_State(&state); 896 | 897 | return state; 898 | } 899 | 900 | DLL_EXPORTS(Webview_PermissionRequestArgs_SetState, int) 901 | (ICoreWebView2PermissionRequestedEventArgs* args, 902 | COREWEBVIEW2_PERMISSION_STATE state) { 903 | if (!args) return FALSE; 904 | 905 | return SUCCEEDED(args->put_State(state)); 906 | } 907 | 908 | 909 | DLL_EXPORTS(Webview_PermissionRequestArgs_GetDeferral, BOOL) 910 | (ICoreWebView2PermissionRequestedEventArgs* args, LPVOID* ptr) { 911 | if (!args) return FALSE; 912 | 913 | ICoreWebView2Deferral* deferral = nullptr; 914 | 915 | auto ret = SUCCEEDED(args->GetDeferral(&deferral)); 916 | 917 | *ptr = deferral; 918 | 919 | return ret; 920 | } 921 | 922 | using PermissionRequestedCB = HRESULT(CALLBACK*)(LPVOID wv, BOOL userInitiated, LPVOID args, LPVOID param); 923 | DLL_EXPORTS(Webview_Attach_PermissionRequested, int64_t) 924 | (ICoreWebView2* webview, PermissionRequestedCB callback, 925 | LPVOID param) { 926 | if (!webview) return FALSE; 927 | 928 | EventRegistrationToken token; 929 | 930 | webview->add_PermissionRequested( 931 | WRL::Callback( 932 | [callback, param]( 933 | ICoreWebView2* sender, 934 | ICoreWebView2PermissionRequestedEventArgs* args) 935 | -> HRESULT { 936 | sender->AddRef(); 937 | args->AddRef(); 938 | 939 | BOOL ui = FALSE; 940 | args->get_IsUserInitiated(&ui); 941 | 942 | HRESULT hr = callback(sender, ui, args, param); 943 | 944 | return hr; 945 | }) 946 | .Get(), 947 | &token); 948 | 949 | return token.value; 950 | } 951 | 952 | DLL_EXPORTS(Webview_Detach_PermissionRequested, BOOL) 953 | (ICoreWebView2* webview, int64_t value) { 954 | if (!webview) return FALSE; 955 | EventRegistrationToken token = {value}; 956 | 957 | return SUCCEEDED(webview->remove_PermissionRequested(token)); 958 | } 959 | 960 | DLL_EXPORTS(Webview_IsDefaultDownloadDialogOpen, BOOL) 961 | (ICoreWebView2* webview) { 962 | if (!webview) return FALSE; 963 | 964 | WRL::ComPtr tmpWv = nullptr; 965 | webview->QueryInterface(&tmpWv); 966 | 967 | BOOL ret = FALSE; 968 | 969 | tmpWv->get_IsDefaultDownloadDialogOpen(&ret); 970 | 971 | return ret; 972 | } 973 | 974 | DLL_EXPORTS(Webview_OpenDefaultDownloadDialog, BOOL) 975 | (ICoreWebView2* webview) { 976 | if (!webview) return FALSE; 977 | 978 | WRL::ComPtr tmpWv = nullptr; 979 | webview->QueryInterface(&tmpWv); 980 | 981 | return SUCCEEDED(tmpWv->OpenDefaultDownloadDialog()); 982 | } 983 | 984 | DLL_EXPORTS(Webview_CloseDefaultDownloadDialog, BOOL) 985 | (ICoreWebView2* webview) { 986 | if (!webview) return FALSE; 987 | 988 | WRL::ComPtr tmpWv = nullptr; 989 | webview->QueryInterface(&tmpWv); 990 | 991 | return SUCCEEDED(tmpWv->CloseDefaultDownloadDialog()); 992 | } 993 | 994 | DLL_EXPORTS(Webview_GetDefaultDownloadDialogMargin, BOOL) 995 | (ICoreWebView2* webview, POINT* pt) { 996 | if (!webview) return FALSE; 997 | 998 | WRL::ComPtr tmpWv = nullptr; 999 | webview->QueryInterface(&tmpWv); 1000 | 1001 | return SUCCEEDED(tmpWv->get_DefaultDownloadDialogMargin(pt)); 1002 | } 1003 | 1004 | DLL_EXPORTS(Webview_SetDefaultDownloadDialogMargin, BOOL) 1005 | (ICoreWebView2* webview, POINT* pt) { 1006 | if (!webview) return FALSE; 1007 | 1008 | WRL::ComPtr tmpWv = nullptr; 1009 | webview->QueryInterface(&tmpWv); 1010 | 1011 | return SUCCEEDED(tmpWv->put_DefaultDownloadDialogMargin(*pt)); 1012 | } 1013 | 1014 | 1015 | DLL_EXPORTS(Webview_GetProfile, BOOL) 1016 | (ICoreWebView2* webview, LPVOID* ptr) { 1017 | if (!webview) return FALSE; 1018 | 1019 | WRL::ComPtr tmpWv = nullptr; 1020 | webview->QueryInterface(&tmpWv); 1021 | 1022 | ICoreWebView2Profile* profile = nullptr; 1023 | 1024 | auto ret = SUCCEEDED(tmpWv->get_Profile(&profile)); 1025 | 1026 | *ptr = profile; 1027 | 1028 | return ret; 1029 | } 1030 | 1031 | DLL_EXPORTS(Profile_GetName, BOOL) 1032 | (ICoreWebView2Profile* profile, LPVOID* ptr, uint32_t* size) { 1033 | if (!profile) return FALSE; 1034 | 1035 | LPWSTR value = nullptr; 1036 | auto ret = SUCCEEDED(profile->get_ProfileName(&value)); 1037 | 1038 | *ptr = value; 1039 | *size = lstrlenW(value) * 2 + 2; 1040 | 1041 | return ret; 1042 | } 1043 | 1044 | DLL_EXPORTS(Profile_GetPrivateInMode, BOOL) 1045 | (ICoreWebView2Profile* profile) { 1046 | if (!profile) return FALSE; 1047 | 1048 | BOOL value = FALSE; 1049 | profile->get_IsInPrivateModeEnabled(&value); 1050 | 1051 | return value; 1052 | } 1053 | 1054 | DLL_EXPORTS(Profile_GetPath, BOOL) 1055 | (ICoreWebView2Profile* profile, LPVOID* ptr, uint32_t* size) { 1056 | if (!profile) return FALSE; 1057 | 1058 | LPWSTR value = nullptr; 1059 | auto ret = SUCCEEDED(profile->get_ProfilePath(&value)); 1060 | 1061 | *ptr = value; 1062 | *size = lstrlenW(value) * 2 + 2; 1063 | 1064 | return ret; 1065 | } 1066 | 1067 | DLL_EXPORTS(Profile_GetDefaultDownloadPath, BOOL) 1068 | (ICoreWebView2Profile* profile, LPVOID* ptr, uint32_t* size) { 1069 | if (!profile) return FALSE; 1070 | 1071 | LPWSTR value = nullptr; 1072 | auto ret = SUCCEEDED(profile->get_DefaultDownloadFolderPath(&value)); 1073 | 1074 | *ptr = value; 1075 | *size = lstrlenW(value) * 2 + 2; 1076 | 1077 | return ret; 1078 | } 1079 | 1080 | DLL_EXPORTS(Profile_SetDefaultDownloadPath, BOOL) 1081 | (ICoreWebView2Profile* profile, LPWSTR path) { 1082 | if (!profile) return FALSE; 1083 | 1084 | return SUCCEEDED(profile->put_DefaultDownloadFolderPath(path)); 1085 | } 1086 | 1087 | DLL_EXPORTS(Profile_GetColorTheme, int) 1088 | (ICoreWebView2Profile* profile) { 1089 | if (!profile) return FALSE; 1090 | 1091 | COREWEBVIEW2_PREFERRED_COLOR_SCHEME value; 1092 | profile->get_PreferredColorScheme(&value); 1093 | 1094 | return value; 1095 | } 1096 | 1097 | DLL_EXPORTS(Profile_SetColorTheme, BOOL) 1098 | (ICoreWebView2Profile* profile, COREWEBVIEW2_PREFERRED_COLOR_SCHEME value) { 1099 | if (!profile) return FALSE; 1100 | 1101 | return SUCCEEDED(profile->put_PreferredColorScheme(value)); 1102 | } 1103 | 1104 | using ClearBrowsingDataCB = HRESULT(CALLBACK*)(HRESULT code, LPVOID param); 1105 | DLL_EXPORTS(Profile_ClearBrowsingData, BOOL) 1106 | (ICoreWebView2Profile* profile, COREWEBVIEW2_BROWSING_DATA_KINDS type, 1107 | ClearBrowsingDataCB callback, LPVOID param) { 1108 | if (!profile) return FALSE; 1109 | 1110 | WRL::ComPtr tmpPf = nullptr; 1111 | profile->QueryInterface(&tmpPf); 1112 | 1113 | auto ret = SUCCEEDED(tmpPf->ClearBrowsingData( 1114 | type, WRL::Callback( 1115 | [callback, param](HRESULT errorCode) -> HRESULT { 1116 | return callback(errorCode, param); 1117 | }) 1118 | .Get())); 1119 | 1120 | return ret; 1121 | } 1122 | 1123 | DLL_EXPORTS(Profile_ClearBrowsingData_Sync, BOOL) 1124 | (ICoreWebView2Profile* profile, COREWEBVIEW2_BROWSING_DATA_KINDS type) { 1125 | if (!profile) return FALSE; 1126 | 1127 | WRL::ComPtr tmpPf = nullptr; 1128 | profile->QueryInterface(&tmpPf); 1129 | 1130 | Waitable* waiter = CreateWaitable(true); 1131 | 1132 | auto ret = SUCCEEDED(tmpPf->ClearBrowsingData( 1133 | type, WRL::Callback( 1134 | [waiter](HRESULT errorCode) -> HRESULT { 1135 | ActiveWaitable(waiter); 1136 | return S_OK; 1137 | }) 1138 | .Get())); 1139 | 1140 | WaitOfMsgLoop(waiter); 1141 | 1142 | return ret; 1143 | } 1144 | 1145 | DLL_EXPORTS(Profile_ClearBrowsingDataInTimeRange, BOOL) 1146 | (ICoreWebView2Profile* profile, COREWEBVIEW2_BROWSING_DATA_KINDS type, 1147 | double start, double end, ClearBrowsingDataCB callback, LPVOID param) { 1148 | if (!profile) return FALSE; 1149 | 1150 | WRL::ComPtr tmpPf = nullptr; 1151 | profile->QueryInterface(&tmpPf); 1152 | 1153 | auto ret = SUCCEEDED(tmpPf->ClearBrowsingDataInTimeRange( 1154 | type, start, end, 1155 | WRL::Callback( 1156 | [callback, param](HRESULT errorCode) -> HRESULT { 1157 | return callback(errorCode, param); 1158 | }) 1159 | .Get())); 1160 | 1161 | return ret; 1162 | } 1163 | 1164 | DLL_EXPORTS(Profile_ClearBrowsingDataInTimeRange_Sync, BOOL) 1165 | (ICoreWebView2Profile* profile, COREWEBVIEW2_BROWSING_DATA_KINDS type, 1166 | double start, double end) { 1167 | if (!profile) return FALSE; 1168 | 1169 | WRL::ComPtr tmpPf = nullptr; 1170 | profile->QueryInterface(&tmpPf); 1171 | 1172 | Waitable* waiter = CreateWaitable(true); 1173 | 1174 | auto ret = SUCCEEDED(tmpPf->ClearBrowsingDataInTimeRange( 1175 | type, start, end, 1176 | WRL::Callback( 1177 | [waiter](HRESULT errorCode) -> HRESULT { 1178 | ActiveWaitable(waiter); 1179 | return S_OK; 1180 | }) 1181 | .Get())); 1182 | 1183 | WaitOfMsgLoop(waiter); 1184 | 1185 | return ret; 1186 | } 1187 | 1188 | DLL_EXPORTS(Profile_ClearAllBrowsingData, BOOL) 1189 | (ICoreWebView2Profile* profile, ClearBrowsingDataCB callback, LPVOID param) { 1190 | if (!profile) return FALSE; 1191 | 1192 | WRL::ComPtr tmpPf = nullptr; 1193 | profile->QueryInterface(&tmpPf); 1194 | 1195 | auto ret = SUCCEEDED(tmpPf->ClearBrowsingDataAll( 1196 | WRL::Callback( 1197 | [callback, param](HRESULT errorCode) -> HRESULT { 1198 | return callback(errorCode, param); 1199 | }) 1200 | .Get())); 1201 | 1202 | return ret; 1203 | } 1204 | 1205 | DLL_EXPORTS(Profile_ClearAllBrowsingData_Sync, BOOL) 1206 | (ICoreWebView2Profile* profile) { 1207 | if (!profile) return FALSE; 1208 | 1209 | WRL::ComPtr tmpPf = nullptr; 1210 | profile->QueryInterface(&tmpPf); 1211 | 1212 | Waitable* waiter = CreateWaitable(true); 1213 | 1214 | auto ret = SUCCEEDED(tmpPf->ClearBrowsingDataAll( 1215 | WRL::Callback( 1216 | [waiter](HRESULT errorCode) -> HRESULT { 1217 | ActiveWaitable(waiter); 1218 | return S_OK; 1219 | }) 1220 | .Get())); 1221 | 1222 | WaitOfMsgLoop(waiter); 1223 | 1224 | return ret; 1225 | } 1226 | 1227 | DLL_EXPORTS(Webview_AddWebResourceRequestedFilter, BOOL) 1228 | (ICoreWebView2* webview, LPWSTR uri, COREWEBVIEW2_WEB_RESOURCE_CONTEXT type) { 1229 | if (!webview) return FALSE; 1230 | 1231 | return SUCCEEDED(webview->AddWebResourceRequestedFilter(uri, type)); 1232 | } 1233 | 1234 | DLL_EXPORTS(Webview_RemoveWebResourceRequestedFilter, BOOL) 1235 | (ICoreWebView2* webview, LPWSTR uri, COREWEBVIEW2_WEB_RESOURCE_CONTEXT type) { 1236 | if (!webview) return FALSE; 1237 | 1238 | return SUCCEEDED(webview->RemoveWebResourceRequestedFilter(uri, type)); 1239 | } 1240 | 1241 | using WebResourceRequestedCB = HRESULT(CALLBACK*)(LPVOID wv, LPVOID args, LPVOID param); 1242 | DLL_EXPORTS(Webview_Attach_WebResourceRequested, int64_t) 1243 | (ICoreWebView2* webview, WebResourceRequestedCB callback, LPVOID param) { 1244 | if (!webview) return FALSE; 1245 | 1246 | EventRegistrationToken token; 1247 | 1248 | webview->add_WebResourceRequested( 1249 | WRL::Callback( 1250 | [callback, param]( 1251 | ICoreWebView2* sender, 1252 | ICoreWebView2WebResourceRequestedEventArgs* args) -> HRESULT { 1253 | sender->AddRef(); 1254 | args->AddRef(); 1255 | 1256 | HRESULT hr = callback(sender, args, param); 1257 | 1258 | return hr; 1259 | }) 1260 | .Get(), 1261 | &token); 1262 | 1263 | return token.value; 1264 | } 1265 | 1266 | DLL_EXPORTS(Webview_Detach_WebResourceRequested, BOOL) 1267 | (ICoreWebView2* webview, int64_t value) { 1268 | if (!webview) return FALSE; 1269 | EventRegistrationToken token = {value}; 1270 | 1271 | return SUCCEEDED(webview->remove_WebResourceRequested(token)); 1272 | } 1273 | 1274 | 1275 | using WebResourceResponseReceivedCB = HRESULT(CALLBACK*)(LPVOID wv, LPVOID request, LPVOID response, 1276 | LPVOID param); 1277 | DLL_EXPORTS(Webview_Attach_WebResourceResponseReceived, int64_t) 1278 | (ICoreWebView2* webview, WebResourceResponseReceivedCB callback, LPVOID param) { 1279 | if (!webview) return FALSE; 1280 | 1281 | EventRegistrationToken token; 1282 | 1283 | WRL::ComPtr tmpWv = nullptr; 1284 | webview->QueryInterface(&tmpWv); 1285 | 1286 | tmpWv->add_WebResourceResponseReceived( 1287 | WRL::Callback( 1288 | [callback, param](ICoreWebView2* sender, 1289 | ICoreWebView2WebResourceResponseReceivedEventArgs* 1290 | args) -> HRESULT { 1291 | sender->AddRef(); 1292 | 1293 | ICoreWebView2WebResourceRequest* request = nullptr; 1294 | ICoreWebView2WebResourceResponseView* response = nullptr; 1295 | args->get_Request(&request); 1296 | args->get_Response(&response); 1297 | 1298 | HRESULT hr = callback(sender, request, response, param); 1299 | 1300 | return hr; 1301 | }) 1302 | .Get(), 1303 | &token); 1304 | 1305 | return token.value; 1306 | } 1307 | 1308 | DLL_EXPORTS(Webview_Detach_WebResourceResponseReceived, BOOL) 1309 | (ICoreWebView2* webview, int64_t value) { 1310 | if (!webview) return FALSE; 1311 | EventRegistrationToken token = {value}; 1312 | 1313 | WRL::ComPtr tmpWv = nullptr; 1314 | webview->QueryInterface(&tmpWv); 1315 | 1316 | return SUCCEEDED(tmpWv->remove_WebResourceResponseReceived(token)); 1317 | } 1318 | 1319 | 1320 | DLL_EXPORTS(Webview_SetMute, BOOL) 1321 | (ICoreWebView2* webview, BOOL mute) { 1322 | if (!webview) return FALSE; 1323 | 1324 | WRL::ComPtr tmpWv = nullptr; 1325 | webview->QueryInterface(&tmpWv); 1326 | 1327 | return SUCCEEDED(tmpWv->put_IsMuted(mute)); 1328 | } 1329 | 1330 | DLL_EXPORTS(Webview_GetMute, BOOL) 1331 | (ICoreWebView2* webview) { 1332 | if (!webview) return FALSE; 1333 | 1334 | WRL::ComPtr tmpWv = nullptr; 1335 | webview->QueryInterface(&tmpWv); 1336 | 1337 | BOOL mute = FALSE; 1338 | 1339 | tmpWv->get_IsMuted(&mute); 1340 | 1341 | return mute; 1342 | } 1343 | 1344 | 1345 | DLL_EXPORTS(Webview_GetAudioPlaying, BOOL) 1346 | (ICoreWebView2* webview) { 1347 | if (!webview) return FALSE; 1348 | 1349 | WRL::ComPtr tmpWv = nullptr; 1350 | webview->QueryInterface(&tmpWv); 1351 | 1352 | BOOL ret = FALSE; 1353 | tmpWv->get_IsDocumentPlayingAudio(&ret); 1354 | 1355 | return ret; 1356 | } 1357 | 1358 | using IsDocumentPlayingAudioChangedCB = HRESULT(CALLBACK*)(LPVOID webview, BOOL audiable, LPVOID param); 1359 | DLL_EXPORTS(Webview_Attach_IsDocumentPlayingAudioChanged, int64_t) 1360 | (ICoreWebView2* webview, IsDocumentPlayingAudioChangedCB callback, 1361 | LPVOID param) { 1362 | if (!webview) return FALSE; 1363 | 1364 | EventRegistrationToken token; 1365 | 1366 | WRL::ComPtr tmpWv = nullptr; 1367 | webview->QueryInterface(&tmpWv); 1368 | 1369 | tmpWv->add_IsDocumentPlayingAudioChanged( 1370 | WRL::Callback( 1371 | [callback, param](ICoreWebView2* sender, IUnknown* args) -> HRESULT { 1372 | sender->AddRef(); 1373 | 1374 | WRL::ComPtr tmpWv_ = nullptr; 1375 | sender->QueryInterface(&tmpWv_); 1376 | 1377 | BOOL audible = FALSE; 1378 | tmpWv_->get_IsDocumentPlayingAudio(&audible); 1379 | 1380 | HRESULT hr = callback(sender, audible, param); 1381 | 1382 | return hr; 1383 | }) 1384 | .Get(), 1385 | &token); 1386 | 1387 | return token.value; 1388 | } 1389 | 1390 | DLL_EXPORTS(Webview_Detach_IsDocumentPlayingAudioChanged, BOOL) 1391 | (ICoreWebView2* webview, int64_t value) { 1392 | if (!webview) return FALSE; 1393 | EventRegistrationToken token = {value}; 1394 | 1395 | WRL::ComPtr tmpWv = nullptr; 1396 | webview->QueryInterface(&tmpWv); 1397 | 1398 | return SUCCEEDED(tmpWv->remove_IsDocumentPlayingAudioChanged(token)); 1399 | } 1400 | 1401 | using PreloadScriptCB = HRESULT(CALLBACK*)(LPVOID ptr, uint32_t size, LPVOID param); 1402 | DLL_EXPORTS(Webview_AddPreloadScript, BOOL) 1403 | (ICoreWebView2* webview, LPWSTR script, PreloadScriptCB callback, 1404 | LPVOID param) { 1405 | if (!webview) return FALSE; 1406 | 1407 | HRESULT hr = webview->AddScriptToExecuteOnDocumentCreated( 1408 | script, 1409 | WRL::Callback< 1410 | ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler>( 1411 | [callback, param](HRESULT errorCode, LPCWSTR id) -> HRESULT { 1412 | if (callback) { 1413 | uint32_t sizeTmp = lstrlenW(id) * 2 + 2; 1414 | LPWSTR newStr = static_cast(wv2_Utility_Malloc(sizeTmp)); 1415 | if (newStr) { 1416 | lstrcpyW(newStr, id); 1417 | } 1418 | return callback(newStr, sizeTmp, param); 1419 | } 1420 | return S_OK; 1421 | }) 1422 | .Get()); 1423 | 1424 | return SUCCEEDED(hr); 1425 | } 1426 | 1427 | DLL_EXPORTS(Webview_AddPreloadScript_Sync, BOOL) 1428 | (ICoreWebView2* webview, LPWSTR script, LPVOID* ptr, uint32_t* size) { 1429 | if (!webview) return FALSE; 1430 | 1431 | Waitable* waiter = CreateWaitable(true); 1432 | 1433 | HRESULT hr = webview->AddScriptToExecuteOnDocumentCreated( 1434 | script, 1435 | WRL::Callback< 1436 | ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler>( 1437 | [waiter, ptr, size](HRESULT errorCode, LPCWSTR id) -> HRESULT { 1438 | uint32_t sizeTmp = lstrlenW(id) * 2 + 2; 1439 | LPWSTR newStr = static_cast(wv2_Utility_Malloc(sizeTmp)); 1440 | if (newStr) { 1441 | lstrcpyW(newStr, id); 1442 | } 1443 | 1444 | *ptr = newStr; 1445 | *size = sizeTmp; 1446 | 1447 | ActiveWaitable(waiter); 1448 | 1449 | return S_OK; 1450 | }) 1451 | .Get()); 1452 | 1453 | WaitOfMsgLoop(waiter); 1454 | 1455 | return SUCCEEDED(hr); 1456 | } 1457 | 1458 | DLL_EXPORTS(Webview_RemovePreloadScript, BOOL) 1459 | (ICoreWebView2* webview, LPWSTR id) { 1460 | if (!webview) return FALSE; 1461 | 1462 | return SUCCEEDED(webview->RemoveScriptToExecuteOnDocumentCreated(id)); 1463 | } 1464 | 1465 | DLL_EXPORTS(Webview_PostWebMessageAsString, BOOL) 1466 | (ICoreWebView2* webview, LPWSTR str) { 1467 | if (!webview) return FALSE; 1468 | 1469 | return SUCCEEDED(webview->PostWebMessageAsString(str)); 1470 | } 1471 | 1472 | DLL_EXPORTS(Webview_PostWebMessageAsJSON, BOOL) 1473 | (ICoreWebView2* webview, LPWSTR str) { 1474 | if (!webview) return FALSE; 1475 | 1476 | return SUCCEEDED(webview->PostWebMessageAsJson(str)); 1477 | } 1478 | 1479 | 1480 | DLL_EXPORTS(Webview_WebMessageReceivedArgs_GetURL, BOOL) 1481 | (ICoreWebView2WebMessageReceivedEventArgs* webview, LPWSTR* ptr, 1482 | uint32_t* size) { 1483 | if (!webview) return FALSE; 1484 | 1485 | LPWSTR source = nullptr; 1486 | HRESULT hr = webview->get_Source(&source); 1487 | 1488 | *ptr = source; 1489 | *size = lstrlenW(source) * 2 + 2; 1490 | 1491 | return SUCCEEDED(hr); 1492 | } 1493 | 1494 | DLL_EXPORTS(Webview_WebMessageReceivedArgs_GetMessageAsJSON, BOOL) 1495 | (ICoreWebView2WebMessageReceivedEventArgs* webview, LPWSTR* ptr, 1496 | uint32_t* size) { 1497 | if (!webview) return FALSE; 1498 | 1499 | LPWSTR source = nullptr; 1500 | HRESULT hr = webview->get_WebMessageAsJson(&source); 1501 | 1502 | *ptr = source; 1503 | *size = lstrlenW(source) * 2 + 2; 1504 | 1505 | return SUCCEEDED(hr); 1506 | } 1507 | 1508 | DLL_EXPORTS(Webview_WebMessageReceivedArgs_TryGetString, BOOL) 1509 | (ICoreWebView2WebMessageReceivedEventArgs* webview, LPWSTR* ptr, 1510 | uint32_t* size) { 1511 | if (!webview) return FALSE; 1512 | 1513 | LPWSTR source = nullptr; 1514 | HRESULT hr = webview->TryGetWebMessageAsString(&source); 1515 | 1516 | *ptr = source; 1517 | *size = lstrlenW(source) * 2 + 2; 1518 | 1519 | return SUCCEEDED(hr); 1520 | } 1521 | 1522 | using WebMessageReceivedCB = HRESULT(CALLBACK*)(LPVOID webview, LPVOID args, 1523 | LPVOID param); 1524 | DLL_EXPORTS(Webview_Attach_WebMessageReceived, int64_t) 1525 | (ICoreWebView2* webview, WebMessageReceivedCB callback, LPVOID param) { 1526 | if (!webview) return FALSE; 1527 | 1528 | EventRegistrationToken token; 1529 | 1530 | webview->add_WebMessageReceived( 1531 | WRL::Callback( 1532 | [callback, param]( 1533 | ICoreWebView2* sender, 1534 | ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT { 1535 | sender->AddRef(); 1536 | args->AddRef(); 1537 | 1538 | HRESULT hr = callback(sender, args, param); 1539 | 1540 | return hr; 1541 | }) 1542 | .Get(), 1543 | &token); 1544 | 1545 | return token.value; 1546 | } 1547 | 1548 | DLL_EXPORTS(Webview_Detach_WebMessageReceived, BOOL) 1549 | (ICoreWebView2* webview, int64_t value) { 1550 | if (!webview) return FALSE; 1551 | EventRegistrationToken token = {value}; 1552 | 1553 | return SUCCEEDED(webview->remove_WebMessageReceived(token)); 1554 | } 1555 | 1556 | 1557 | 1558 | using ScriptDialogOpeningCB = HRESULT(CALLBACK*)(LPVOID webview, LPVOID args, LPVOID param); 1559 | DLL_EXPORTS(Webview_Attach_ScriptDialogOpening, int64_t) 1560 | (ICoreWebView2* webview, ScriptDialogOpeningCB callback, LPVOID param) { 1561 | if (!webview) return FALSE; 1562 | 1563 | EventRegistrationToken token; 1564 | 1565 | webview->add_ScriptDialogOpening( 1566 | WRL::Callback( 1567 | [callback, param]( 1568 | ICoreWebView2* sender, 1569 | ICoreWebView2ScriptDialogOpeningEventArgs* args) -> HRESULT { 1570 | sender->AddRef(); 1571 | args->AddRef(); 1572 | 1573 | HRESULT hr = callback(sender, args, param); 1574 | 1575 | return hr; 1576 | }) 1577 | .Get(), 1578 | &token); 1579 | 1580 | return token.value; 1581 | } 1582 | 1583 | DLL_EXPORTS(Webview_Detach_ScriptDialogOpening, BOOL) 1584 | (ICoreWebView2* webview, int64_t value) { 1585 | if (!webview) return FALSE; 1586 | EventRegistrationToken token = {value}; 1587 | 1588 | return SUCCEEDED(webview->remove_ScriptDialogOpening(token)); 1589 | } 1590 | 1591 | DLL_EXPORTS(Webview_ScriptDialogOpeningArgs_GetURL, BOOL) 1592 | (ICoreWebView2ScriptDialogOpeningEventArgs* args, LPVOID* ptr, uint32_t* size) { 1593 | if (!args) return FALSE; 1594 | 1595 | LPWSTR uri = nullptr; 1596 | HRESULT hr = args->get_Uri(&uri); 1597 | 1598 | *ptr = uri; 1599 | *size = lstrlenW(uri) * 2 + 2; 1600 | 1601 | return SUCCEEDED(hr); 1602 | } 1603 | 1604 | DLL_EXPORTS(Webview_ScriptDialogOpeningArgs_GetMessage, BOOL) 1605 | (ICoreWebView2ScriptDialogOpeningEventArgs* args, LPVOID* ptr, uint32_t* size) { 1606 | if (!args) return FALSE; 1607 | 1608 | LPWSTR uri = nullptr; 1609 | HRESULT hr = args->get_Message(&uri); 1610 | 1611 | *ptr = uri; 1612 | *size = lstrlenW(uri) * 2 + 2; 1613 | 1614 | return SUCCEEDED(hr); 1615 | } 1616 | 1617 | DLL_EXPORTS(Webview_ScriptDialogOpeningArgs_GetDefaultText, BOOL) 1618 | (ICoreWebView2ScriptDialogOpeningEventArgs* args, LPVOID* ptr, uint32_t* size) { 1619 | if (!args) return FALSE; 1620 | 1621 | LPWSTR uri = nullptr; 1622 | HRESULT hr = args->get_DefaultText(&uri); 1623 | 1624 | *ptr = uri; 1625 | *size = lstrlenW(uri) * 2 + 2; 1626 | 1627 | return SUCCEEDED(hr); 1628 | } 1629 | 1630 | DLL_EXPORTS(Webview_ScriptDialogOpeningArgs_GetResultText, BOOL) 1631 | (ICoreWebView2ScriptDialogOpeningEventArgs* args, LPVOID* ptr, uint32_t* size) { 1632 | if (!args) return FALSE; 1633 | 1634 | LPWSTR uri = nullptr; 1635 | HRESULT hr = args->get_ResultText(&uri); 1636 | 1637 | *ptr = uri; 1638 | *size = lstrlenW(uri) * 2 + 2; 1639 | 1640 | return SUCCEEDED(hr); 1641 | } 1642 | 1643 | DLL_EXPORTS(Webview_ScriptDialogOpeningArgs_GetType, int) 1644 | (ICoreWebView2ScriptDialogOpeningEventArgs* args) { 1645 | if (!args) return FALSE; 1646 | 1647 | COREWEBVIEW2_SCRIPT_DIALOG_KIND type; 1648 | args->get_Kind(&type); 1649 | 1650 | return type; 1651 | } 1652 | 1653 | DLL_EXPORTS(Webview_ScriptDialogOpeningArgs_Accept, BOOL) 1654 | (ICoreWebView2ScriptDialogOpeningEventArgs* args) { 1655 | if (!args) return FALSE; 1656 | 1657 | return SUCCEEDED(args->Accept()); 1658 | } 1659 | 1660 | DLL_EXPORTS(Webview_ScriptDialogOpeningArgs_SetResultText, BOOL) 1661 | (ICoreWebView2ScriptDialogOpeningEventArgs* args, LPWSTR text) { 1662 | if (!args) return FALSE; 1663 | 1664 | return SUCCEEDED(args->put_ResultText(text)); 1665 | } 1666 | 1667 | DLL_EXPORTS(Webview_ScriptDialogOpeningArgs_GetDeferral, BOOL) 1668 | (ICoreWebView2ScriptDialogOpeningEventArgs* args, LPVOID* ptr) { 1669 | if (!args) return FALSE; 1670 | 1671 | ICoreWebView2Deferral* deferral = nullptr; 1672 | HRESULT hr = args->GetDeferral(&deferral); 1673 | 1674 | *ptr = deferral; 1675 | 1676 | return SUCCEEDED(hr); 1677 | } 1678 | 1679 | 1680 | using FaviconChangedCB = HRESULT(CALLBACK*)(LPVOID webview, LPVOID param); 1681 | DLL_EXPORTS(Webview_Attach_FaviconChanged, int64_t) 1682 | (ICoreWebView2* webview, FaviconChangedCB callback, LPVOID param) { 1683 | if (!webview) return FALSE; 1684 | 1685 | EventRegistrationToken token; 1686 | 1687 | WRL::ComPtr tmpWv = nullptr; 1688 | webview->QueryInterface(&tmpWv); 1689 | 1690 | tmpWv->add_FaviconChanged( 1691 | WRL::Callback( 1692 | [callback, param]( 1693 | ICoreWebView2* sender, 1694 | IUnknown* args) -> HRESULT { 1695 | sender->AddRef(); 1696 | 1697 | HRESULT hr = callback(sender, param); 1698 | 1699 | return hr; 1700 | }) 1701 | .Get(), 1702 | &token); 1703 | 1704 | return token.value; 1705 | } 1706 | 1707 | DLL_EXPORTS(Webview_Detach_FaviconChanged, BOOL) 1708 | (ICoreWebView2* webview, int64_t value) { 1709 | if (!webview) return FALSE; 1710 | EventRegistrationToken token = {value}; 1711 | 1712 | WRL::ComPtr tmpWv = nullptr; 1713 | webview->QueryInterface(&tmpWv); 1714 | 1715 | return SUCCEEDED(tmpWv->remove_FaviconChanged(token)); 1716 | } 1717 | 1718 | DLL_EXPORTS(Webview_GetFaviconURL, BOOL) 1719 | (ICoreWebView2* webview, LPVOID* ptr, uint32_t* size) { 1720 | if (!webview) return FALSE; 1721 | 1722 | WRL::ComPtr tmpWv = nullptr; 1723 | webview->QueryInterface(&tmpWv); 1724 | 1725 | LPWSTR value = nullptr; 1726 | HRESULT hr = tmpWv->get_FaviconUri(&value); 1727 | 1728 | *ptr = value; 1729 | *size = lstrlenW(value) * 2 + 2; 1730 | 1731 | return SUCCEEDED(hr); 1732 | } 1733 | 1734 | 1735 | using BasicAuthenticationRequestedCB = HRESULT(CALLBACK*)(LPVOID webview, LPVOID args, LPVOID param); 1736 | DLL_EXPORTS(Webview_Attach_BasicAuthenticationRequested, int64_t) 1737 | (ICoreWebView2* webview, BasicAuthenticationRequestedCB callback, 1738 | LPVOID param) { 1739 | if (!webview) return FALSE; 1740 | 1741 | EventRegistrationToken token; 1742 | 1743 | WRL::ComPtr tmpWv = nullptr; 1744 | webview->QueryInterface(&tmpWv); 1745 | 1746 | tmpWv->add_BasicAuthenticationRequested( 1747 | WRL::Callback( 1748 | [callback, param](ICoreWebView2* sender, 1749 | ICoreWebView2BasicAuthenticationRequestedEventArgs* 1750 | args) -> HRESULT { 1751 | sender->AddRef(); 1752 | args->AddRef(); 1753 | 1754 | HRESULT hr = callback(sender, args, param); 1755 | 1756 | return hr; 1757 | }) 1758 | .Get(), 1759 | &token); 1760 | 1761 | return token.value; 1762 | } 1763 | 1764 | DLL_EXPORTS(Webview_Detach_BasicAuthenticationRequested, BOOL) 1765 | (ICoreWebView2* webview, int64_t value) { 1766 | if (!webview) return FALSE; 1767 | EventRegistrationToken token = {value}; 1768 | 1769 | WRL::ComPtr tmpWv = nullptr; 1770 | webview->QueryInterface(&tmpWv); 1771 | 1772 | return SUCCEEDED(tmpWv->remove_BasicAuthenticationRequested(token)); 1773 | } 1774 | 1775 | 1776 | DLL_EXPORTS(Webview_BasicAuthenticationRequestedArgs_GetDeferral, BOOL) 1777 | (ICoreWebView2BasicAuthenticationRequestedEventArgs* args, LPVOID* ptr) { 1778 | if (!args) return FALSE; 1779 | 1780 | ICoreWebView2Deferral* deferral = nullptr; 1781 | HRESULT hr = args->GetDeferral(&deferral); 1782 | 1783 | *ptr = deferral; 1784 | 1785 | return SUCCEEDED(hr); 1786 | } 1787 | 1788 | DLL_EXPORTS(Webview_BasicAuthenticationRequestedArgs_GetURL, BOOL) 1789 | (ICoreWebView2BasicAuthenticationRequestedEventArgs* args, LPVOID* ptr, uint32_t *size) { 1790 | if (!args) return FALSE; 1791 | 1792 | LPWSTR value = nullptr; 1793 | HRESULT hr = args->get_Uri(&value); 1794 | 1795 | *ptr = value; 1796 | *size = lstrlenW(value) * 2 + 2; 1797 | 1798 | return SUCCEEDED(hr); 1799 | } 1800 | 1801 | DLL_EXPORTS(Webview_BasicAuthenticationRequestedArgs_GetChallenge, BOOL) 1802 | (ICoreWebView2BasicAuthenticationRequestedEventArgs* args, LPVOID* ptr, uint32_t *size) { 1803 | if (!args) return FALSE; 1804 | 1805 | LPWSTR value = nullptr; 1806 | HRESULT hr = args->get_Challenge(&value); 1807 | 1808 | *ptr = value; 1809 | *size = lstrlenW(value) * 2 + 2; 1810 | 1811 | return SUCCEEDED(hr); 1812 | } 1813 | 1814 | DLL_EXPORTS(Webview_BasicAuthenticationRequestedArgs_GetCancel, BOOL) 1815 | (ICoreWebView2BasicAuthenticationRequestedEventArgs* args) { 1816 | if (!args) return FALSE; 1817 | 1818 | BOOL value = FALSE; 1819 | args->get_Cancel(&value); 1820 | 1821 | return value; 1822 | } 1823 | 1824 | DLL_EXPORTS(Webview_BasicAuthenticationRequestedArgs_SetCancel, BOOL) 1825 | (ICoreWebView2BasicAuthenticationRequestedEventArgs* args, BOOL value) { 1826 | if (!args) return FALSE; 1827 | 1828 | return SUCCEEDED(args->put_Cancel(value)); 1829 | } 1830 | 1831 | DLL_EXPORTS(Webview_BasicAuthenticationRequestedArgs_UserName_Attr, BOOL) 1832 | (ICoreWebView2BasicAuthenticationRequestedEventArgs* args, LPVOID* ptr, 1833 | uint32_t* size) { 1834 | if (!args) return FALSE; 1835 | 1836 | ICoreWebView2BasicAuthenticationResponse* response = nullptr; 1837 | HRESULT hr = args->get_Response(&response); 1838 | 1839 | if (ptr && size) { 1840 | LPWSTR value = nullptr; 1841 | response->get_UserName(&value); 1842 | 1843 | *ptr = value; 1844 | *size = lstrlenW(value) * 2 + 2; 1845 | } else { 1846 | response->put_UserName(reinterpret_cast(ptr)); 1847 | } 1848 | 1849 | return SUCCEEDED(hr); 1850 | } 1851 | 1852 | DLL_EXPORTS(Webview_BasicAuthenticationRequestedArgs_Password_Attr, BOOL) 1853 | (ICoreWebView2BasicAuthenticationRequestedEventArgs* args, LPVOID* ptr, 1854 | uint32_t* size) { 1855 | if (!args) return FALSE; 1856 | 1857 | ICoreWebView2BasicAuthenticationResponse* response = nullptr; 1858 | HRESULT hr = args->get_Response(&response); 1859 | 1860 | if (ptr && size) { 1861 | LPWSTR value = nullptr; 1862 | response->get_Password(&value); 1863 | 1864 | *ptr = value; 1865 | *size = lstrlenW(value) * 2 + 2; 1866 | } else { 1867 | response->put_Password(reinterpret_cast(ptr)); 1868 | } 1869 | 1870 | return SUCCEEDED(hr); 1871 | } 1872 | 1873 | 1874 | using FrameCreatedCB = HRESULT(CALLBACK*)(LPVOID webview, LPVOID frame, LPVOID param); 1875 | DLL_EXPORTS(Webview_Attach_FrameCreated, int64_t) 1876 | (ICoreWebView2* webview, FrameCreatedCB callback, LPVOID param) { 1877 | if (!webview) return FALSE; 1878 | 1879 | EventRegistrationToken token; 1880 | 1881 | WRL::ComPtr tmpWv = nullptr; 1882 | webview->QueryInterface(&tmpWv); 1883 | 1884 | tmpWv->add_FrameCreated( 1885 | WRL::Callback( 1886 | [callback, param]( 1887 | ICoreWebView2* sender, 1888 | ICoreWebView2FrameCreatedEventArgs* args) -> HRESULT { 1889 | sender->AddRef(); 1890 | 1891 | ICoreWebView2Frame* frame = nullptr; 1892 | args->get_Frame(&frame); 1893 | 1894 | HRESULT hr = callback(sender, frame, param); 1895 | 1896 | return hr; 1897 | }) 1898 | .Get(), 1899 | &token); 1900 | 1901 | return token.value; 1902 | } 1903 | 1904 | DLL_EXPORTS(Webview_Detach_FrameCreated, BOOL) 1905 | (ICoreWebView2* webview, int64_t value) { 1906 | if (!webview) return FALSE; 1907 | EventRegistrationToken token = {value}; 1908 | 1909 | WRL::ComPtr tmpWv = nullptr; 1910 | webview->QueryInterface(&tmpWv); 1911 | 1912 | return SUCCEEDED(tmpWv->remove_FrameCreated(token)); 1913 | } 1914 | 1915 | 1916 | DLL_EXPORTS(Webview_NavigateRequest, BOOL) 1917 | (ICoreWebView2_15* webview, ICoreWebView2WebResourceRequest *obj) { 1918 | if (!webview) return FALSE; 1919 | 1920 | HRESULT hr = webview->NavigateWithWebResourceRequest(obj); 1921 | 1922 | return SUCCEEDED(hr); 1923 | } 1924 | 1925 | 1926 | using ContextMenuRequestedCB = HRESULT(CALLBACK*)(LPVOID webview, LPVOID args, 1927 | LPVOID param); 1928 | DLL_EXPORTS(Webview_Attach_ContextMenuRequested, int64_t) 1929 | (ICoreWebView2* webview, ContextMenuRequestedCB callback, LPVOID param) { 1930 | if (!webview) return FALSE; 1931 | 1932 | EventRegistrationToken token; 1933 | 1934 | WRL::ComPtr tmpWv = nullptr; 1935 | webview->QueryInterface(&tmpWv); 1936 | 1937 | tmpWv->add_ContextMenuRequested( 1938 | WRL::Callback( 1939 | [callback, param]( 1940 | ICoreWebView2* sender, 1941 | ICoreWebView2ContextMenuRequestedEventArgs* args) -> HRESULT { 1942 | sender->AddRef(); 1943 | args->AddRef(); 1944 | 1945 | HRESULT hr = callback(sender, args, param); 1946 | 1947 | return hr; 1948 | }) 1949 | .Get(), 1950 | &token); 1951 | 1952 | return token.value; 1953 | } 1954 | 1955 | DLL_EXPORTS(Webview_Detach_ContextMenuRequested, BOOL) 1956 | (ICoreWebView2* webview, int64_t value) { 1957 | if (!webview) return FALSE; 1958 | EventRegistrationToken token = {value}; 1959 | 1960 | WRL::ComPtr tmpWv = nullptr; 1961 | webview->QueryInterface(&tmpWv); 1962 | 1963 | return SUCCEEDED(tmpWv->remove_ContextMenuRequested(token)); 1964 | } 1965 | 1966 | 1967 | using DownloadStartingCB = HRESULT(CALLBACK*)(LPVOID webview, LPVOID args, LPVOID param); 1968 | DLL_EXPORTS(Webview_Attach_DownloadStarting, int64_t) 1969 | (ICoreWebView2* webview, DownloadStartingCB callback, LPVOID param) { 1970 | if (!webview) return FALSE; 1971 | 1972 | EventRegistrationToken token; 1973 | 1974 | WRL::ComPtr tmpWv = nullptr; 1975 | webview->QueryInterface(&tmpWv); 1976 | 1977 | tmpWv->add_DownloadStarting( 1978 | WRL::Callback( 1979 | [callback, param]( 1980 | ICoreWebView2* sender, 1981 | ICoreWebView2DownloadStartingEventArgs* args) -> HRESULT { 1982 | sender->AddRef(); 1983 | args->AddRef(); 1984 | 1985 | HRESULT hr = callback(sender, args, param); 1986 | 1987 | return hr; 1988 | }) 1989 | .Get(), 1990 | &token); 1991 | 1992 | return token.value; 1993 | } 1994 | 1995 | DLL_EXPORTS(Webview_Detach_DownloadStarting, BOOL) 1996 | (ICoreWebView2* webview, int64_t value) { 1997 | if (!webview) return FALSE; 1998 | EventRegistrationToken token = {value}; 1999 | 2000 | WRL::ComPtr tmpWv = nullptr; 2001 | webview->QueryInterface(&tmpWv); 2002 | 2003 | return SUCCEEDED(tmpWv->remove_DownloadStarting(token)); 2004 | } 2005 | 2006 | 2007 | using ContentLoadingCB = HRESULT(CALLBACK*)(LPVOID webview, BOOL isErrorPage, 2008 | uint64_t navId, LPVOID param); 2009 | DLL_EXPORTS(Webview_Attach_ContentLoading, int64_t) 2010 | (ICoreWebView2* webview, ContentLoadingCB callback, LPVOID param) { 2011 | if (!webview) return FALSE; 2012 | 2013 | EventRegistrationToken token; 2014 | 2015 | WRL::ComPtr tmpWv = nullptr; 2016 | webview->QueryInterface(&tmpWv); 2017 | 2018 | tmpWv->add_ContentLoading( 2019 | WRL::Callback( 2020 | [callback, param]( 2021 | ICoreWebView2* sender, 2022 | ICoreWebView2ContentLoadingEventArgs* args) -> HRESULT { 2023 | sender->AddRef(); 2024 | 2025 | BOOL isErr = FALSE; 2026 | uint64_t nav = 0; 2027 | 2028 | args->get_IsErrorPage(&isErr); 2029 | args->get_NavigationId(&nav); 2030 | 2031 | HRESULT hr = callback(sender, isErr, nav, param); 2032 | 2033 | return hr; 2034 | }) 2035 | .Get(), 2036 | &token); 2037 | 2038 | return token.value; 2039 | } 2040 | 2041 | DLL_EXPORTS(Webview_Detach_ContentLoading, BOOL) 2042 | (ICoreWebView2* webview, int64_t value) { 2043 | if (!webview) return FALSE; 2044 | EventRegistrationToken token = {value}; 2045 | 2046 | WRL::ComPtr tmpWv = nullptr; 2047 | webview->QueryInterface(&tmpWv); 2048 | 2049 | return SUCCEEDED(tmpWv->remove_ContentLoading(token)); 2050 | } 2051 | 2052 | 2053 | using StatusBarTextChangedCB = HRESULT(CALLBACK*)(LPVOID webview, LPVOID param); 2054 | DLL_EXPORTS(Webview_Attach_StatusBarTextChanged, int64_t) 2055 | (ICoreWebView2* webview, StatusBarTextChangedCB callback, LPVOID param) { 2056 | if (!webview) return FALSE; 2057 | 2058 | EventRegistrationToken token; 2059 | 2060 | WRL::ComPtr tmpWv = nullptr; 2061 | webview->QueryInterface(&tmpWv); 2062 | 2063 | tmpWv->add_StatusBarTextChanged( 2064 | WRL::Callback( 2065 | [callback, param]( 2066 | ICoreWebView2* sender, 2067 | IUnknown* args) -> HRESULT { 2068 | sender->AddRef(); 2069 | 2070 | HRESULT hr = callback(sender, param); 2071 | 2072 | return hr; 2073 | }) 2074 | .Get(), 2075 | &token); 2076 | 2077 | return token.value; 2078 | } 2079 | 2080 | DLL_EXPORTS(Webview_Detach_StatusBarTextChanged, BOOL) 2081 | (ICoreWebView2* webview, int64_t value) { 2082 | if (!webview) return FALSE; 2083 | EventRegistrationToken token = {value}; 2084 | 2085 | WRL::ComPtr tmpWv = nullptr; 2086 | webview->QueryInterface(&tmpWv); 2087 | 2088 | return SUCCEEDED(tmpWv->remove_StatusBarTextChanged(token)); 2089 | } 2090 | 2091 | DLL_EXPORTS(Webview_GetStatusBarText, BOOL) 2092 | (ICoreWebView2* webview, LPVOID* ptr, uint32_t* size) { 2093 | if (!webview) return FALSE; 2094 | 2095 | WRL::ComPtr tmpWv = nullptr; 2096 | webview->QueryInterface(&tmpWv); 2097 | 2098 | LPWSTR value = nullptr; 2099 | HRESULT hr = tmpWv->get_StatusBarText(&value); 2100 | 2101 | *ptr = value; 2102 | *size = lstrlenW(value) * 2 + 2; 2103 | 2104 | return SUCCEEDED(hr); 2105 | } 2106 | 2107 | 2108 | using ClientCertificateRequestedCB = HRESULT(CALLBACK*)(LPVOID webview, LPVOID args, LPVOID param); 2109 | DLL_EXPORTS(Webview_Attach_ClientCertificateRequested, int64_t) 2110 | (ICoreWebView2* webview, ClientCertificateRequestedCB callback, LPVOID param) { 2111 | if (!webview) return FALSE; 2112 | 2113 | EventRegistrationToken token; 2114 | 2115 | WRL::ComPtr tmpWv = nullptr; 2116 | webview->QueryInterface(&tmpWv); 2117 | 2118 | tmpWv->add_ClientCertificateRequested( 2119 | WRL::Callback( 2120 | [callback, param](ICoreWebView2* sender, 2121 | ICoreWebView2ClientCertificateRequestedEventArgs* 2122 | args) -> HRESULT { 2123 | sender->AddRef(); 2124 | args->AddRef(); 2125 | 2126 | HRESULT hr = callback(sender, args, param); 2127 | 2128 | return hr; 2129 | }) 2130 | .Get(), 2131 | &token); 2132 | 2133 | return token.value; 2134 | } 2135 | 2136 | DLL_EXPORTS(Webview_Detach_ClientCertificateRequested, BOOL) 2137 | (ICoreWebView2* webview, int64_t value) { 2138 | if (!webview) return FALSE; 2139 | EventRegistrationToken token = {value}; 2140 | 2141 | WRL::ComPtr tmpWv = nullptr; 2142 | webview->QueryInterface(&tmpWv); 2143 | 2144 | return SUCCEEDED(tmpWv->remove_ClientCertificateRequested(token)); 2145 | } 2146 | 2147 | 2148 | DLL_EXPORTS(Webview_ClientCert_GetDeferral, BOOL) 2149 | (ICoreWebView2ClientCertificateRequestedEventArgs* args, LPVOID* ptr) { 2150 | if (!args) return FALSE; 2151 | 2152 | ICoreWebView2Deferral* deferral = nullptr; 2153 | HRESULT hr = args->GetDeferral(&deferral); 2154 | 2155 | *ptr = deferral; 2156 | 2157 | return SUCCEEDED(hr); 2158 | } 2159 | -------------------------------------------------------------------------------- /src/wv2_webview.h: -------------------------------------------------------------------------------- 1 | #ifndef WV2_WEBVIEW_H 2 | #define WV2_WEBVIEW_H 3 | #pragma once 4 | 5 | #include "wv2_types.h" 6 | 7 | #endif 8 | --------------------------------------------------------------------------------