first commit
This commit is contained in:
commit
abff7464e0
18 files changed
+1361
No files matched your search
@@ -0,0 +1,6 @@
|
||||
---
|
||||
BasedOnStyle: Microsoft
|
||||
IndentWidth: 4
|
||||
|
||||
SortIncludes: true
|
||||
ColumnLimit: 80
|
||||
@@ -0,0 +1,18 @@
|
||||
CompileFlags:
|
||||
Add: [
|
||||
-DUNICODE,
|
||||
-D_UNICODE,
|
||||
-DFANY_DEBUG,
|
||||
"-std=c++17",
|
||||
"-IC:\\Users\\SonnyCalcr\\EDisk\\CppCodes\\Win32Codes\\DirectWriteExperiment\\includes", # you should replace this to your own include path of this project
|
||||
"-IC:\\Users\\SonnyCalcr\\EDisk\\CppCodes\\Win32Codes\\DirectWriteExperiment\\fmt\\include", # you should replace this to your own include path of fmt
|
||||
"-IC:\\Users\\SonnyCalcr\\.nuget\\packages\\microsoft.web.webview2\\1.0.3124.44\\build\\native\\include",
|
||||
"-IC:\\Users\\SonnyCalcr\\.nuget\\packages\\microsoft.windows.implementationlibrary\\1.0.240803.1\\include",
|
||||
-Wno-microsoft-goto,
|
||||
-Wno-nonportable-include-path,
|
||||
-Wno-microsoft-extra-qualification,
|
||||
# -Wno-unused-value,
|
||||
] # ignore some specific warnings
|
||||
CompilationDatabase: build/ # Search build/ directory for compile_commands.json
|
||||
# Diagnostics:
|
||||
# UnusedIncludes: None # ignore unused includes
|
||||
@@ -0,0 +1,2 @@
|
||||
build/
|
||||
log.*
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "fmt"]
|
||||
path = fmt
|
||||
url = https://github.com/fmtlib/fmt.git
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"Debug snippets": {
|
||||
"scope": "c,cpp",
|
||||
"prefix": "dbug",
|
||||
"body": [
|
||||
"#ifdef FANY_DEBUG",
|
||||
"#endif",
|
||||
],
|
||||
"description": "Add debug macro"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
cmake_minimum_required(VERSION 3.25.0)
|
||||
|
||||
set(PROJECT_NAME "fanimeui")
|
||||
|
||||
project(${PROJECT_NAME} VERSION 1.0)
|
||||
|
||||
add_subdirectory(fmt)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
|
||||
add_definitions(
|
||||
/D_UNICODE=1
|
||||
/DUNICODE=1
|
||||
)
|
||||
|
||||
# add_definitions(
|
||||
# /DFANY_DEBUG=1
|
||||
# )
|
||||
|
||||
include_directories("./includes/")
|
||||
|
||||
set(HEADER_FILES
|
||||
./includes/main.h
|
||||
)
|
||||
|
||||
set(SRC_FILES
|
||||
"src/webview2/MainWindow.cpp"
|
||||
)
|
||||
|
||||
add_executable(fanimeui WIN32
|
||||
${HEADER_FILES}
|
||||
${SRC_FILES}
|
||||
)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES VS_GLOBAL_WebView2LoaderPreference "Static")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES VS_USER_PROPS "${CMAKE_SOURCE_DIR}/FanIME_UI.props")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES VS_PACKAGE_REFERENCES "Microsoft.Web.WebView2_1.0.3124.44;Microsoft.Windows.ImplementationLibrary_1.0.240803.1")
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} fmt::fmt)
|
||||
@@ -0,0 +1,29 @@
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
|
||||
<ItemGroup Condition="'$(MSBuildProjectExtension)' == '.vcxproj'">
|
||||
<ProjectCapability Include="PackageReferences" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.vcxproj'">
|
||||
<!-- NuGet 包恢复配置 -->
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
<NuGetPackageImportStamp>true</NuGetPackageImportStamp>
|
||||
|
||||
<!-- 目标平台和框架配置 -->
|
||||
<Platform Condition="'$(Platform)' == ''">x64</Platform>
|
||||
<TargetFramework>native</TargetFramework>
|
||||
|
||||
<!-- NuGet 包路径配置 -->
|
||||
<NuGetPackageRoot Condition="'$(NuGetPackageRoot)' == ''">$(UserProfile)\.nuget\packages</NuGetPackageRoot>
|
||||
|
||||
<!-- WebView2 配置 -->
|
||||
<WebView2LoaderPreference>Static</WebView2LoaderPreference>
|
||||
|
||||
<!-- NuGet 目标框架配置 -->
|
||||
<NuGetTargetMoniker Condition="'$(NuGetTargetMoniker)' == ''">native,Version=v0.0</NuGetTargetMoniker>
|
||||
<RuntimeIdentifiers Condition="'$(RuntimeIdentifiers)' == ''">win;win-x86;win-x64;win-arm;win-arm64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,7 @@
|
||||
# Win32 direct2d and some webview experiment
|
||||
|
||||
Try to figure out all needed rendering things about Windows TSF input method.
|
||||
|
||||

|
||||
|
||||

|
||||
Binary file not shown.
|
After Width: | Height: | Size: 820 KiB |
Submodule
+1
Submodule server/fmt added at b2dfcb2b80.
@@ -0,0 +1,142 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>横向候选框</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin-top: 0px;
|
||||
margin-left: 0px;
|
||||
background-color: #202020;
|
||||
padding: 2px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: fit-content;
|
||||
user-select: none;
|
||||
border: 2px solid #9b9b9b2e;
|
||||
}
|
||||
|
||||
.pinyin-row {
|
||||
padding-right: 1px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.candidates-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding-right: 1px;
|
||||
margin: 0 1px;
|
||||
}
|
||||
|
||||
.cand:hover {
|
||||
border-radius: 6px;
|
||||
background-color: #414141;
|
||||
}
|
||||
|
||||
.row-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.first {
|
||||
background-color: #3e3e3eb9;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.first::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
height: 16px;
|
||||
width: 3px;
|
||||
background: linear-gradient(to bottom, #ff7eb3, #ff758c, #ff5a5f);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.text {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
color: #e9e8e8;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="pinyin-row">
|
||||
<div class="row pinyin">
|
||||
<div class="text">ni'uo</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="candidates-row">
|
||||
<!--1Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand first">
|
||||
<div class="text">1. 你说什么</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--2Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">2. 笔画</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--3Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">3. 量子</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--4Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">4. 牛魔</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--5Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">5. 仙人</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--6Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">6. 可恨</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--7Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">7. 木槿</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--8Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">8. 无量</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,143 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>垂直候选框</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.container {
|
||||
/* margin-top: 50px;
|
||||
margin-left: 50px; */
|
||||
margin-top: 0px;
|
||||
margin-left: 0px;
|
||||
background-color: #202020;
|
||||
padding: 2px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5);
|
||||
width: 100px;
|
||||
user-select: none;
|
||||
border: 2px solid #9b9b9b2e;
|
||||
}
|
||||
|
||||
.row {
|
||||
justify-content: space-between;
|
||||
padding: 2px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.cand:hover {
|
||||
border-radius: 6px;
|
||||
background-color: #414141;
|
||||
}
|
||||
|
||||
.row-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* .cand:hover::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
height: 16px;
|
||||
width: 3px;
|
||||
background: linear-gradient(to bottom, #ff7eb3, #ff758c, #ff5a5f);
|
||||
border-radius: 8px;
|
||||
} */
|
||||
|
||||
.first {
|
||||
background-color: #3e3e3eb9;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.first::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
height: 16px;
|
||||
width: 3px;
|
||||
background: linear-gradient(to bottom, #ff7eb3, #ff758c, #ff5a5f);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.text {
|
||||
padding-left: 8px;
|
||||
color: #e9e8e8;
|
||||
}
|
||||
</style>
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<!--0Anchor-->
|
||||
<div class="row pinyin">
|
||||
<div class="text">ni'uo</div>
|
||||
</div>
|
||||
<!--1Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand first">
|
||||
<div class="text">1. 你说</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--2Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">2. 笔画</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--3Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">3. 量子</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--4Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">4. 牛魔</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--5Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">5. 仙人</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--6Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">6. 可恨</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--7Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">7. 木槿</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--8Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">8. 无量</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--9Anchor-->
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
@@ -0,0 +1,26 @@
|
||||
# generate compile to exe files
|
||||
$currentDirectory = Get-Location
|
||||
$cmakeListsPath = Join-Path -Path $currentDirectory -ChildPath "CMakeLists.txt"
|
||||
|
||||
if (-not (Test-Path $cmakeListsPath))
|
||||
{
|
||||
Write-Host("No CMakeLists.txt in current directory, please check.")
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "Start generating and compiling..."
|
||||
|
||||
$buildFolderPath = ".\build"
|
||||
|
||||
if (-not (Test-Path $buildFolderPath))
|
||||
{
|
||||
New-Item -ItemType Directory -Path $buildFolderPath | Out-Null
|
||||
Write-Host "build folder created."
|
||||
}
|
||||
|
||||
cmake -G "Visual Studio 17 2022" -A x64 -S . -B ./build/
|
||||
|
||||
if ($LASTEXITCODE -eq 0)
|
||||
{
|
||||
cmake --build ./build/ --config DEBUG
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#
|
||||
# generate, compile and run exe files
|
||||
#
|
||||
|
||||
function getExePathFromCMakeLists()
|
||||
{
|
||||
$content = Get-Content -Path "./CMakeLists.txt"
|
||||
$lastLine = ""
|
||||
$contentContainedExeName = ""
|
||||
foreach($line in $content)
|
||||
{
|
||||
if ($line.StartsWith("add_executable"))
|
||||
{
|
||||
$index = $line.IndexOf("(")
|
||||
$contentContainedExeName = $line.Substring($index + 1)
|
||||
if ([string]::IsNullOrEmpty($contentContainedExeName))
|
||||
{
|
||||
$lastLine = $line
|
||||
continue
|
||||
}
|
||||
break
|
||||
} elseif ($lastLine.StartsWith("add_executable"))
|
||||
{
|
||||
$contentContainedExeName = $line
|
||||
break
|
||||
}
|
||||
$lastLine = $line
|
||||
}
|
||||
$result = -split $contentContainedExeName
|
||||
$exePath = "./build/DEBUG/" + $result[0] + ".exe"
|
||||
return $exePath
|
||||
}
|
||||
|
||||
$currentDirectory = Get-Location
|
||||
$cmakeListsPath = Join-Path -Path $currentDirectory -ChildPath "CMakeLists.txt"
|
||||
|
||||
if (-not (Test-Path $cmakeListsPath))
|
||||
{
|
||||
Write-Host("No CMakeLists.txt in current directory, please check.")
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "Start generating and compiling..."
|
||||
|
||||
$buildFolderPath = ".\build"
|
||||
|
||||
if (-not (Test-Path $buildFolderPath))
|
||||
{
|
||||
New-Item -ItemType Directory -Path $buildFolderPath | Out-Null
|
||||
Write-Host "build folder created."
|
||||
}
|
||||
|
||||
cmake -G "Visual Studio 17 2022" -A x64 -S . -B ./build/
|
||||
|
||||
if ($LASTEXITCODE -eq 0)
|
||||
{
|
||||
cmake --build ./build/ --config DEBUG
|
||||
if ($LASTEXITCODE -eq 0)
|
||||
{
|
||||
$exePath = getExePathFromCMakeLists
|
||||
Write-Host "start running as follows..."
|
||||
Write-Host "=================================================="
|
||||
Invoke-Expression $exePath
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# run exe file that has already been compiled before
|
||||
#
|
||||
|
||||
|
||||
function getExePathFromCMakeLists()
|
||||
{
|
||||
$content = Get-Content -Path "./CMakeLists.txt"
|
||||
$lastLine = ""
|
||||
$contentContainedExeName = ""
|
||||
foreach($line in $content)
|
||||
{
|
||||
if ($line.StartsWith("add_executable"))
|
||||
{
|
||||
$index = $line.IndexOf("(")
|
||||
$contentContainedExeName = $line.Substring($index + 1)
|
||||
if ([string]::IsNullOrEmpty($contentContainedExeName))
|
||||
{
|
||||
$lastLine = $line
|
||||
continue
|
||||
}
|
||||
break
|
||||
} elseif ($lastLine.StartsWith("add_executable"))
|
||||
{
|
||||
$contentContainedExeName = $line
|
||||
break
|
||||
}
|
||||
$lastLine = $line
|
||||
}
|
||||
$result = -split $contentContainedExeName
|
||||
$exePath = "./build/DEBUG/" + $result[0] + ".exe"
|
||||
return $exePath
|
||||
}
|
||||
|
||||
$exePath = getExePathFromCMakeLists
|
||||
Write-Host "start running as follows..."
|
||||
Write-Host "=================================================="
|
||||
Invoke-Expression $exePath
|
||||
@@ -0,0 +1,252 @@
|
||||
#include <d2d1.h>
|
||||
#include <dwmapi.h>
|
||||
#include <dwrite.h>
|
||||
#include <minwindef.h>
|
||||
#include <windef.h>
|
||||
#include <windows.h>
|
||||
|
||||
#pragma comment(lib, "d2d1")
|
||||
#pragma comment(lib, "dwrite")
|
||||
#pragma comment(lib, "dwmapi.lib")
|
||||
|
||||
ID2D1Factory *pD2DFactory = nullptr;
|
||||
ID2D1HwndRenderTarget *pRenderTarget = nullptr;
|
||||
ID2D1SolidColorBrush *pBrush = nullptr;
|
||||
IDWriteFactory *pDWriteFactory = nullptr;
|
||||
IDWriteTextFormat *pTextFormat = nullptr;
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
FLOAT GetWindowScale(HWND hwnd);
|
||||
|
||||
bool InitD2DAndDWrite()
|
||||
{
|
||||
|
||||
HRESULT hr = D2D1CreateFactory( //
|
||||
D2D1_FACTORY_TYPE_SINGLE_THREADED, //
|
||||
&pD2DFactory //
|
||||
);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
hr = DWriteCreateFactory( //
|
||||
DWRITE_FACTORY_TYPE_SHARED, //
|
||||
__uuidof(IDWriteFactory), //
|
||||
reinterpret_cast<IUnknown **>(&pDWriteFactory) //
|
||||
);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
hr = pDWriteFactory->CreateTextFormat(L"Segoe UI", //
|
||||
nullptr, //
|
||||
DWRITE_FONT_WEIGHT_NORMAL, //
|
||||
DWRITE_FONT_STYLE_NORMAL, //
|
||||
DWRITE_FONT_STRETCH_NORMAL, //
|
||||
24.0f, //
|
||||
L"en-us", //
|
||||
&pTextFormat //
|
||||
);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InitD2DRenderTarget(HWND hwnd)
|
||||
{
|
||||
if (!pD2DFactory)
|
||||
return false;
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(hwnd, &rc);
|
||||
|
||||
auto renderTargetProps = D2D1::RenderTargetProperties( //
|
||||
D2D1_RENDER_TARGET_TYPE_DEFAULT, //
|
||||
D2D1::PixelFormat( //
|
||||
DXGI_FORMAT_UNKNOWN, //
|
||||
D2D1_ALPHA_MODE_PREMULTIPLIED //
|
||||
) //
|
||||
);
|
||||
auto hwndRenderTargetProps = D2D1::HwndRenderTargetProperties( //
|
||||
hwnd, //
|
||||
D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top), //
|
||||
D2D1_PRESENT_OPTIONS_IMMEDIATELY //
|
||||
);
|
||||
|
||||
HRESULT hr = pD2DFactory->CreateHwndRenderTarget( //
|
||||
renderTargetProps, //
|
||||
hwndRenderTargetProps, //
|
||||
&pRenderTarget //
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pRenderTarget->CreateSolidColorBrush( //
|
||||
D2D1::ColorF(D2D1::ColorF::White), //
|
||||
&pBrush //
|
||||
);
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
void OnPaint(HWND hwnd)
|
||||
{
|
||||
if (!pRenderTarget)
|
||||
return;
|
||||
|
||||
pRenderTarget->BeginDraw();
|
||||
|
||||
// Clear baakground to transparent
|
||||
// pRenderTarget->Clear(D2D1::ColorF(0, 0, 0, 0));
|
||||
pRenderTarget->Clear(D2D1::ColorF(25 / 255.0, 25 / 255.0, 25 / 255.0, 0.5));
|
||||
|
||||
/*
|
||||
FLOAT scale = GetWindowScale(hwnd);
|
||||
|
||||
D2D1_RECT_F borderRect = D2D1::RectF( //
|
||||
static_cast<FLOAT>(0), //
|
||||
static_cast<FLOAT>(0), //
|
||||
static_cast<FLOAT>(600 / scale), //
|
||||
static_cast<FLOAT>(600 / scale) //
|
||||
);
|
||||
pBrush->SetColor(D2D1::ColorF(D2D1::ColorF::White, 1.0f));
|
||||
E
|
||||
pRenderTarget->FillRectangle(D2D1::RectF(50, 50, 400, 300), pBrush)
|
||||
|
||||
pBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 1.0f));
|
||||
|
||||
pRenderTarget->FillRectangle(D2D1::RectF(200, 200, 500, 400), pBrush);
|
||||
|
||||
pBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Green, 0.3f));
|
||||
|
||||
pRenderTarget->FillRectangle(D2D1::RectF(300, 100, 600, 250), pBrush);
|
||||
|
||||
pBrush->SetColor(D2D1::ColorF(D2D1::ColorF::White, 1.0f)); //
|
||||
pRenderTarget->DrawTextW( //
|
||||
L"Transparent Window and Direct2D", //
|
||||
31, //
|
||||
pTextFormat, //
|
||||
D2D1::RectF(5, 5, 600, 200), //
|
||||
pBrush //
|
||||
);
|
||||
*/
|
||||
|
||||
HRESULT hr = pRenderTarget->EndDraw();
|
||||
if (hr == D2DERR_RECREATE_TARGET)
|
||||
{
|
||||
pRenderTarget->Release();
|
||||
InitD2DRenderTarget(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
HWND CreateTransparentWindow(HINSTANCE hInstance)
|
||||
{
|
||||
WNDCLASS wc = {0};
|
||||
wc.lpfnWndProc = WndProc;
|
||||
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.hInstance = hInstance;
|
||||
wc.lpszClassName = L"TransparentWindowClass";
|
||||
|
||||
if (!RegisterClass(&wc))
|
||||
return nullptr;
|
||||
|
||||
HWND hwnd = CreateWindowEx(WS_EX_LAYERED, //
|
||||
wc.lpszClassName, //
|
||||
L"TransparentWindow", //
|
||||
WS_POPUP, //
|
||||
100, 100, 600, 600, //
|
||||
nullptr, nullptr, hInstance, nullptr);
|
||||
|
||||
if (hwnd)
|
||||
{
|
||||
SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA);
|
||||
|
||||
MARGINS mar = {-1};
|
||||
DwmExtendFrameIntoClientArea(hwnd, &mar);
|
||||
}
|
||||
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_CREATE:
|
||||
InitD2DRenderTarget(hwnd);
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
case WM_DISPLAYCHANGE:
|
||||
OnPaint(hwnd);
|
||||
ValidateRect(hwnd, nullptr);
|
||||
return 0;
|
||||
case WM_MOUSEMOVE: {
|
||||
float x = (float)LOWORD(lParam);
|
||||
float y = (float)HIWORD(lParam);
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(hwnd, &rc);
|
||||
if (x >= rc.left && x <= rc.right && y >= rc.top && y <= rc.bottom)
|
||||
{
|
||||
SetCursor(LoadCursor(nullptr, IDC_ARROW));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
LPWSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||
|
||||
if (!InitD2DAndDWrite())
|
||||
return -1;
|
||||
|
||||
HWND hwnd = CreateTransparentWindow(hInstance);
|
||||
|
||||
if (!hwnd)
|
||||
return -1;
|
||||
|
||||
ShowWindow(hwnd, nCmdShow);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, nullptr, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
if (pBrush)
|
||||
pBrush->Release();
|
||||
if (pRenderTarget)
|
||||
pRenderTarget->Release();
|
||||
if (pDWriteFactory)
|
||||
pDWriteFactory->Release();
|
||||
if (pTextFormat)
|
||||
pTextFormat->Release();
|
||||
if (pD2DFactory)
|
||||
pD2DFactory->Release();
|
||||
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
|
||||
FLOAT GetWindowScale(HWND hwnd)
|
||||
{
|
||||
UINT dpi = GetDpiForWindow(hwnd);
|
||||
FLOAT scale = dpi / 96.0f;
|
||||
return scale;
|
||||
}
|
||||
@@ -0,0 +1,574 @@
|
||||
#include "WebView2.h"
|
||||
#include "fmt/core.h"
|
||||
#include "fmt/xchar.h"
|
||||
#include <chrono>
|
||||
#include <dwmapi.h>
|
||||
#include <fstream>
|
||||
#include <intsafe.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <synchapi.h>
|
||||
#include <tchar.h>
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
#include <winnt.h>
|
||||
#include <winuser.h>
|
||||
#include <wrl.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
//
|
||||
// Message define
|
||||
//
|
||||
UINT WM_SHOW_MAIN_WINDOW;
|
||||
UINT WM_HIDE_MAIN_WINDOW;
|
||||
UINT WM_MOVE_CANDIDATE_WINDOW;
|
||||
|
||||
static TCHAR szWindowClass[] = _T("global_candidate_window");
|
||||
static TCHAR szTitle[] = _T("WebView sample");
|
||||
|
||||
std::wstring candStr = L"";
|
||||
|
||||
static std::wstring HTMLString = LR"(
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vertical Candidate Window</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.container {
|
||||
/* margin-top: 50px;
|
||||
margin-left: 50px; */
|
||||
margin-top: 0px;
|
||||
margin-left: 0px;
|
||||
background-color: #202020;
|
||||
padding: 2px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5);
|
||||
width: 100px;
|
||||
user-select: none;
|
||||
border: 2px solid #9b9b9b2e;
|
||||
}
|
||||
|
||||
.row {
|
||||
justify-content: space-between;
|
||||
padding: 2px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.cand:hover {
|
||||
border-radius: 6px;
|
||||
background-color: #414141;
|
||||
}
|
||||
|
||||
.row-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* .cand:hover::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
height: 16px;
|
||||
width: 3px;
|
||||
background: linear-gradient(to bottom, #ff7eb3, #ff758c, #ff5a5f);
|
||||
border-radius: 8px;
|
||||
} */
|
||||
|
||||
.first {
|
||||
background-color: #3e3e3eb9;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.first::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
height: 16px;
|
||||
width: 3px;
|
||||
background: linear-gradient(to bottom, #ff7eb3, #ff758c, #ff5a5f);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.text {
|
||||
padding-left: 8px;
|
||||
color: #e9e8e8;
|
||||
}
|
||||
</style>
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row pinyin">
|
||||
<div class="text">ni'uo</div>
|
||||
</div>
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand first">
|
||||
<div class="text">1. 你说</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">2. 笔画</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">3. 量子</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">4. 牛魔</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">5. 仙人</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">6. 可恨</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">7. 木槿</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">8. 无量</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
)";
|
||||
|
||||
static std::wstring BodyString = LR"(
|
||||
<div class="container">
|
||||
<!--0Anchor-->
|
||||
<div class="row pinyin">
|
||||
<div class="text">{0}</div>
|
||||
</div>
|
||||
<!--1Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand first">
|
||||
<div class="text">{1}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--2Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">{2}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--3Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">{3}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--4Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">{4}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--5Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">{5}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--6Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">{6}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--7Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">{7}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--8Anchor-->
|
||||
<div class="row-wrapper">
|
||||
<div class="row cand">
|
||||
<div class="text">{8}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--9Anchor-->
|
||||
</div>
|
||||
)";
|
||||
|
||||
HINSTANCE hInst = 0;
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
static ComPtr<ICoreWebView2Controller> webviewController;
|
||||
static ComPtr<ICoreWebView2> webview;
|
||||
ComPtr<ICoreWebView2_3> webview3;
|
||||
ComPtr<ICoreWebView2Controller2> webviewController2;
|
||||
|
||||
void LogMessageW(const wchar_t *message)
|
||||
{
|
||||
std::time_t now = std::time(nullptr);
|
||||
std::tm *localTime = std::localtime(&now);
|
||||
|
||||
wchar_t timeBuffer[80];
|
||||
wcsftime(timeBuffer, sizeof(timeBuffer) / sizeof(wchar_t),
|
||||
L"%Y-%m-%d %H:%M:%S", localTime);
|
||||
|
||||
std::wstring logfilePath = L"C:"
|
||||
L"\\Users\\SonnyCalcr\\EDisk\\CppCodes\\Win32Cod"
|
||||
L"es\\DirectWriteExperiment\\log.txt";
|
||||
std::wofstream logFile(logfilePath, std::ios_base::app);
|
||||
if (logFile.is_open())
|
||||
{
|
||||
logFile.imbue(std::locale("Chinese_China.65001"));
|
||||
logFile << L"[" << timeBuffer << L"] " << message;
|
||||
logFile << std::endl;
|
||||
logFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateHtmlContentWithJavaScript(ComPtr<ICoreWebView2> webview,
|
||||
const std::wstring &newContent)
|
||||
{
|
||||
if (webview != nullptr)
|
||||
{
|
||||
std::wstring script =
|
||||
L"document.body.innerHTML = `" + newContent + L"`;";
|
||||
webview->ExecuteScript(script.c_str(), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureDomUpdateTime(ComPtr<ICoreWebView2> webview)
|
||||
{
|
||||
std::wstring script =
|
||||
LR"(document.body.innerHTML = '<div>1. 原来</div> <div>2. 如此</div> <div>3. 竟然</div> <div>4. 这样</div> <div>5. 可恶</div> <div>6. 棋盘</div> <div>7. 磨合</div> <div>8. 樱花</div> </body>';)";
|
||||
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
webview->ExecuteScript(script.c_str(), nullptr);
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
auto duration =
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(end - start);
|
||||
std::wstring message =
|
||||
L"DOM update time: " + std::to_wstring(duration.count()) + L" μs";
|
||||
LogMessageW(message.c_str());
|
||||
}
|
||||
|
||||
void inflateCandidateWindow(std::wstring &str)
|
||||
{
|
||||
std::wstringstream wss(str);
|
||||
std::wstring token;
|
||||
std::vector<std::wstring> words;
|
||||
|
||||
while (std::getline(wss, token, L','))
|
||||
{
|
||||
words.push_back(token);
|
||||
}
|
||||
|
||||
int size = words.size();
|
||||
|
||||
while (words.size() < 9)
|
||||
{
|
||||
words.push_back(L"");
|
||||
}
|
||||
|
||||
std::wstring result = fmt::format( //
|
||||
BodyString, //
|
||||
words[0], //
|
||||
words[1], //
|
||||
words[2], //
|
||||
words[3], //
|
||||
words[4], //
|
||||
words[5], //
|
||||
words[6], //
|
||||
words[7], //
|
||||
words[8] //
|
||||
); //
|
||||
|
||||
if (size < 9)
|
||||
{
|
||||
result = result.substr( //
|
||||
0, //
|
||||
result.find(fmt::format(L"<!--{}Anchor-->", size)) //
|
||||
) //
|
||||
+ //
|
||||
L"</div>"; //
|
||||
}
|
||||
|
||||
UpdateHtmlContentWithJavaScript(webview, result);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
|
||||
if (message == WM_SHOW_MAIN_WINDOW)
|
||||
{
|
||||
ShowWindow(hWnd, SW_SHOWNOACTIVATE);
|
||||
return 0;
|
||||
}
|
||||
if (message == WM_HIDE_MAIN_WINDOW)
|
||||
{
|
||||
ShowWindow(hWnd, SW_HIDE);
|
||||
if (candStr.find(L",") == 1)
|
||||
{
|
||||
inflateCandidateWindow(candStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateHtmlContentWithJavaScript(webview, L"");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_MOUSEACTIVATE:
|
||||
// Stop the window from being activated by mouse click
|
||||
return MA_NOACTIVATE;
|
||||
case WM_COPYDATA: {
|
||||
COPYDATASTRUCT *pcds = (COPYDATASTRUCT *)lParam;
|
||||
if (pcds->dwData == 0)
|
||||
{
|
||||
POINT *pt = (POINT *)pcds->lpData;
|
||||
MoveWindow( //
|
||||
hWnd, //
|
||||
pt->x, //
|
||||
pt->y + 3, //
|
||||
(108 + 15) * 1.5, //
|
||||
(246 + 15) * 1.5, //
|
||||
TRUE //
|
||||
); //
|
||||
}
|
||||
else if (pcds->dwData == 1)
|
||||
{
|
||||
WCHAR *p = (WCHAR *)pcds->lpData;
|
||||
std::wstring str = p;
|
||||
candStr = str;
|
||||
#ifdef FANY_DEBUG
|
||||
LogMessageW(str.c_str());
|
||||
#endif
|
||||
inflateCandidateWindow(str);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case WM_ACTIVATE: {
|
||||
if (LOWORD(wParam) != WA_INACTIVE)
|
||||
{
|
||||
ShowWindow(hWnd, SW_SHOWNOACTIVATE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_DESTROY: {
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitWebview(HWND hWnd)
|
||||
{
|
||||
CreateCoreWebView2EnvironmentWithOptions(
|
||||
nullptr, nullptr, nullptr,
|
||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
||||
[hWnd](HRESULT result, ICoreWebView2Environment *env) -> HRESULT {
|
||||
if (result != S_OK)
|
||||
{
|
||||
MessageBox(hWnd, L"Failed to create WebView2 environment.",
|
||||
L"Error", MB_OK);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Create a CoreWebView2Controller and get the associated
|
||||
// CoreWebView2
|
||||
env->CreateCoreWebView2Controller(
|
||||
hWnd,
|
||||
Callback<
|
||||
ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
|
||||
[hWnd](HRESULT result,
|
||||
ICoreWebView2Controller *controller) -> HRESULT {
|
||||
if (controller == nullptr || FAILED(result))
|
||||
{
|
||||
MessageBox(
|
||||
hWnd,
|
||||
L"Failed to create WebView2 controller.",
|
||||
L"Error", MB_OK);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
webviewController = controller;
|
||||
webviewController->get_CoreWebView2(
|
||||
webview.GetAddressOf());
|
||||
|
||||
if (webview == nullptr)
|
||||
{
|
||||
MessageBox(hWnd,
|
||||
L"Failed to get WebView2 instance.",
|
||||
L"Error", MB_OK);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Add a few settings for the webview
|
||||
ICoreWebView2Settings *settings;
|
||||
webview->get_Settings(&settings);
|
||||
settings->put_IsScriptEnabled(TRUE);
|
||||
settings->put_AreDefaultScriptDialogsEnabled(TRUE);
|
||||
settings->put_IsWebMessageEnabled(TRUE);
|
||||
settings->put_AreHostObjectsAllowed(TRUE);
|
||||
|
||||
if (webview->QueryInterface(
|
||||
IID_PPV_ARGS(&webview3)) == S_OK)
|
||||
{
|
||||
webview3->SetVirtualHostNameToFolderMapping(
|
||||
L"appassets",
|
||||
L"C:"
|
||||
L"\\Users\\SonnyCalcr\\AppData\\Roaming\\Po"
|
||||
L"tPla"
|
||||
L"yerMini64\\Capture",
|
||||
COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY_CORS);
|
||||
}
|
||||
|
||||
if (controller->QueryInterface(
|
||||
IID_PPV_ARGS(&webviewController2)) == S_OK)
|
||||
{
|
||||
COREWEBVIEW2_COLOR backgroundColor = {0, 0, 0,
|
||||
0};
|
||||
webviewController2->put_DefaultBackgroundColor(
|
||||
backgroundColor);
|
||||
}
|
||||
|
||||
// Resize WebView to fit the bounds of the parent
|
||||
// window
|
||||
RECT bounds;
|
||||
GetClientRect(hWnd, &bounds);
|
||||
webviewController->put_Bounds(bounds);
|
||||
// Navigate to a simple HTML string
|
||||
auto hr =
|
||||
webview->NavigateToString(HTMLString.c_str());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
MessageBox(hWnd,
|
||||
L"Failed to navigate to string.",
|
||||
L"Error", MB_OK);
|
||||
}
|
||||
|
||||
// webview->OpenDevToolsWindow();
|
||||
|
||||
return S_OK;
|
||||
})
|
||||
.Get());
|
||||
return S_OK;
|
||||
})
|
||||
.Get());
|
||||
}
|
||||
|
||||
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance,
|
||||
_In_ LPSTR lpCmdLine, _In_ int nCmdShow)
|
||||
{
|
||||
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||
|
||||
WM_SHOW_MAIN_WINDOW = RegisterWindowMessage(L"WM_SHOW_MAIN_WINDOW");
|
||||
WM_HIDE_MAIN_WINDOW = RegisterWindowMessage(L"WM_HIDE_MAIN_WINDOW");
|
||||
WM_MOVE_CANDIDATE_WINDOW =
|
||||
RegisterWindowMessage(L"WM_MOVE_CANDIDATE_WINDOW");
|
||||
|
||||
WNDCLASSEX wcex;
|
||||
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = WndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = hInstance;
|
||||
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = szWindowClass;
|
||||
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
|
||||
|
||||
if (!RegisterClassEx(&wcex))
|
||||
{
|
||||
MessageBox(NULL, _T("Call to RegisterClassEx failed!"),
|
||||
_T("Windows Desktop Guided Tour"), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Store instance handle in our global variable
|
||||
hInst = hInstance;
|
||||
|
||||
HWND hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOOLWINDOW | //
|
||||
WS_EX_NOACTIVATE | //
|
||||
WS_EX_TOPMOST, //
|
||||
szWindowClass, //
|
||||
L"fanycandidatewindow", //
|
||||
WS_POPUP, //
|
||||
100, //
|
||||
100, //
|
||||
(108 + 15) * 1.5, //
|
||||
(246 + 15) * 1.5, //
|
||||
nullptr, nullptr, hInstance, nullptr);
|
||||
|
||||
if (!hWnd)
|
||||
{
|
||||
MessageBox(NULL, _T("Call to CreateWindow failed!"),
|
||||
_T("Windows Desktop Guided Tour"), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
MoveWindow(hWnd, -1000, 100, (108 + 15) * 1.5, (246 + 15) * 1.5, TRUE);
|
||||
ShowWindow(hWnd, SW_SHOW);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
InitWebview(hWnd);
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
Reference in new issue
Block a user