This commit is contained in:
coco
2026-07-03 16:05:30 +08:00
commit df489d5640
1101 changed files with 779140 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
#ifndef RENDER_GDI_H
#define RENDER_GDI_H
#include <windows.h>
class CRenderGDI {
public:
CRenderGDI()
:m_hView(nullptr)
,m_hDC(nullptr)
,m_hBitmap(nullptr)
,m_pixels(nullptr)
,m_width(0)
,m_height(0)
{}
~CRenderGDI()
{
if (m_hDC)
::DeleteDC(m_hDC);
if (m_hBitmap)
::DeleteObject(m_hBitmap);
}
virtual bool init(HWND hView)
{
m_hView = hView;
m_hDC = ::CreateCompatibleDC(0);
RECT rect;
::GetClientRect(hView, &rect);
resize(rect.right, rect.bottom);
return true;
}
virtual void destroy()
{
delete this;
}
virtual void resize(unsigned int w, unsigned int h)
{
if (m_width == w && m_height == h)
return;
m_width = w;
m_height = h;
m_pixels = nullptr;
}
void renderOnBlinkPaint(wkeWebView webView, HDC hBlinkDC, int x, int y, int cx, int cy)
{
if (m_pixels == nullptr) {
if (m_width != cx || m_height != cy)
return;
createBitmap();
}
HDC hScreenDC = ::GetDC(m_hView);
::BitBlt(m_hDC, x, y, m_width, m_height, hBlinkDC, x, y, SRCCOPY);
::BitBlt(hScreenDC, x, y, m_width, m_height, m_hDC, x, y, SRCCOPY);
::ReleaseDC(m_hView, hScreenDC);
}
void renderOnWindowPaint(wkeWebView webView, HDC hScreenDC)
{
if (m_pixels == nullptr) {
return;
}
::BitBlt(hScreenDC, 0, 0, m_width, m_height, m_hDC, 0, 0, SRCCOPY);
}
void createBitmap()
{
BITMAPINFO bi;
memset(&bi, 0, sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = int(m_width);
bi.bmiHeader.biHeight = -int(m_height);
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
HBITMAP hbmp = ::CreateDIBSection(0, &bi, DIB_RGB_COLORS, &m_pixels, nullptr, 0);
::SelectObject(m_hDC, hbmp);
if (m_hBitmap)
::DeleteObject(m_hBitmap);
m_hBitmap = hbmp;
}
private:
HWND m_hView;
HBITMAP m_hBitmap;
HDC m_hDC;
unsigned int m_width;
unsigned int m_height;
void* m_pixels;
};
#endif
+57
View File
@@ -0,0 +1,57 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by mb_demo.rc
//
// #define IDS_APP_TITLE 103
// #define IDR_MAINFRAME 128
// #define IDD_MB_DEMO_DIALOG 102
// #define IDD_ABOUTBOX 103
// #define IDM_ABOUT 104
// #define IDM_EXIT 105
// #define IDI_MB_DEMO 107
// #define IDI_SMALL 108
// #define IDC_MB_DEMO 109
// #define IDC_MYICON 2
//
// #ifndef IDC_STATIC
// #define IDC_STATIC -1
// #endif
#define IDC_MYICON 2
#define IDC_MB_DEMO 101
#define IDD_WKEBROWSER_DIALOG 102
#define IDS_APP_TITLE 103
#define IDD_ABOUTBOX 104
#define IDM_ABOUT 105
#define IDM_MB_SIMPLE 106
#define IDM_EXIT 107
#define IDI_WKEBROWSER 108
#define IDI_SMALL 109
#define IDC_WKEBROWSER 110
#define IDR_MAINFRAME 128
#define ID_FILE_GOBACK 32771
#define ID_FILE_GOFORWARD 32772
#define ID_ZOOM_IN 32800
#define ID_ZOOM_OUT 32801
#define ID_RESET_ZOOM 32802
#define ID_TAKE_SCREENSHOT 32803
#define ID_SET_EDITABLE 32804
#define ID_URL_SF 32805
#define ID_URL_GITHUB 32806
#define ID_Menu 32902
#define ID_TOOLS_VIEWCOOKIE 32903
#define IDC_STATIC -1
// 新对象的下一组默认值
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 130
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif
+427
View File
@@ -0,0 +1,427 @@
/**
Copyright (c) 2018 weolar
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <shellapi.h>
#include <shlwapi.h>
#include <stdbool.h>
#include <stdio.h>
#include <Commctrl.h>
#include <windowsx.h>
#include <xstring>
#include <vector>
#include "..\miniblink\\wke.h"
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "imm32.lib")
int APIENTRY wkeBrowserMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
typedef struct {
wkeWebView window;
std::wstring url;
} Application;
Application app;
std::string utf16ToUtf8(LPCWSTR lpszSrc)
{
std::string sResult;
int nUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpszSrc, -1, NULL, 0, NULL, NULL);
char* pUTF8 = new char[nUTF8Len + 1];
ZeroMemory(pUTF8, nUTF8Len + 1);
WideCharToMultiByte(CP_UTF8, 0, lpszSrc, -1, pUTF8, nUTF8Len, NULL, NULL);
sResult = pUTF8;
delete[] pUTF8;
return sResult;
}
std::wstring utf8ToUtf16(const std::string& utf8String)
{
std::wstring sResult;
int nUTF8Len = MultiByteToWideChar(CP_UTF8, 0, utf8String.c_str(), -1, NULL, NULL);
wchar_t* pUTF8 = new wchar_t[nUTF8Len + 1];
ZeroMemory(pUTF8, nUTF8Len + 1);
MultiByteToWideChar(CP_UTF8, 0, utf8String.c_str(), -1, pUTF8, nUTF8Len);
sResult = pUTF8;
delete[] pUTF8;
return sResult;
}
//// 回调:点击了关闭、返回 true 将销毁窗口,返回 false 什么都不做。
//bool handleWindowClosing(wkeWebView webWindow, void* param)
//{
// Application* app = (Application*)param;
// return IDYES == MessageBoxW(NULL, L"确定要退出程序吗?", L"wkexe", MB_YESNO | MB_ICONQUESTION);
//}
//
//// 回调:窗口已销毁
//void handleWindowDestroy(wkeWebView webWindow, void* param)
//{
// Application* app = (Application*)param;
// app->window = NULL;
// PostQuitMessage(0);
//}
//
//// 回调:文档加载成功
//void handleDocumentReady(wkeWebView webWindow, void* param)
//{
// wkeShowWindow(webWindow, true);
//}
//
//// 回调:页面标题改变
//void handleTitleChanged(wkeWebView webWindow, void* param, const wkeString title)
//{
// wkeSetWindowTitleW(webWindow, wkeGetStringW(title));
//}
//
//// 回调:创建新的页面,比如说调用了 window.open 或者点击了 <a target="_blank" .../>
//wkeWebView onCreateView(wkeWebView webWindow, void* param, wkeNavigationType navType, const wkeString url, const wkeWindowFeatures* features)
//{
// wkeWebView newWindow = wkeCreateWebWindow(WKE_WINDOW_TYPE_POPUP, NULL, features->x, features->y, features->width, features->height);
// wkeShowWindow(newWindow, true);
// return newWindow;
//}
//
//void readJsFile(const wchar_t* path, std::vector<char>* buffer)
//{
// HANDLE hFile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// if (INVALID_HANDLE_VALUE == hFile) {
// DebugBreak();
// return;
// }
//
// DWORD fileSizeHigh;
// const DWORD bufferSize = ::GetFileSize(hFile, &fileSizeHigh);
//
// DWORD numberOfBytesRead = 0;
// buffer->resize(bufferSize);
// BOOL b = ::ReadFile(hFile, &buffer->at(0), bufferSize, &numberOfBytesRead, nullptr);
// ::CloseHandle(hFile);
// b = b;
//}
//
//std::wstring getResourcesPath(const std::wstring& name)
//{
// std::wstring result;
// std::wstring temp;
// std::vector<wchar_t> path;
// path.resize(MAX_PATH + 1);
// ::GetModuleFileName(nullptr, &path[0], MAX_PATH);
//
// ::PathRemoveFileSpecW(&path[0]);
// temp += &path[0];
// temp += L"\\";
//
// result = temp + name;
// if (!::PathFileExists(result.c_str())) {
// result = temp + L"..\\";
// result += name;
// }
// return result;
//}
//
//const char kPreHead[] = "http://hook.test/";
//
//bool onLoadUrlBegin(wkeWebView webView, void* param, const char* url, void *job)
//{
// const char* pos = strstr(url, kPreHead);
// if (pos) {
// const utf8* decodeURL = wkeUtilDecodeURLEscape(url);
// if (!decodeURL)
// return false;
// std::string urlString(decodeURL);
// std::string localPath = urlString.substr(sizeof(kPreHead) - 1);
//
// std::wstring path = getResourcesPath(utf8ToUtf16(localPath));
// std::vector<char> buffer;
//
// readJsFile(path.c_str(), &buffer);
//
// wkeNetSetData(job, buffer.data(), buffer.size());
//
// return true;
// } else if (strncmp(url, "http://localhost:12222", 22) == 0) {
// wkeNetSetMIMEType(job, (char*)"text/html");
// wkeNetSetData(job, (char*)"\"test1111\"", 10);
// return true;
// } else if (strcmp(url, "http://www.baidu.com/") == 0) {
// wkeNetHookRequest(job);
// }
// return false;
//}
//
//void onLoadUrlEnd(wkeWebView webView, void* param, const char *url, void *job, void* buf, int len)
//{
// const wchar_t *str = L"百度一下";
// const wchar_t *str1 = L"HOOK一下";
//
// int slen = ::WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
// if (slen == 0) return;
//
// char utf81[100];
// ::WideCharToMultiByte(CP_UTF8, 0, str, -1, &utf81[0], slen, NULL, NULL);
//
// slen = ::WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
// if (slen == 0) return;
//
// char utf82[100];
// ::WideCharToMultiByte(CP_UTF8, 0, str1, -1, &utf82[0], slen, NULL, NULL);
//
// const char *b = strstr(static_cast<const char*>(buf), &utf81[0]);
// memcpy((void *)b, &utf82, slen);
// return;
//}
void blinkMaximize()
{
HWND hwnd = wkeGetWindowHandle(app.window);
static bool isMax = true;
if (isMax)
::PostMessageW(hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
else
::PostMessageW(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
isMax = !isMax;
}
void blinkMinimize()
{
HWND hwnd = wkeGetWindowHandle(app.window);
::PostMessageW(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
}
void blinkClose()
{
HWND hwnd = wkeGetWindowHandle(app.window);
::PostMessageW(hwnd, WM_CLOSE, 0, 0);
}
HWND getHWND()
{
return wkeGetWindowHandle(app.window);
}
// 互相调用:CPP调用JS
const char* callJSFunc(jsExecState es, char *funcName, char *param)
{
jsValue f = jsGetGlobal(es, funcName);
jsValue val = jsString(es, param);
jsValue callRet = jsCallGlobal(es, f, &val, 1);
return jsToString(es, callRet);
}
// 互相调用:JS调用CPP
jsValue JS_CALL js_msgBox(jsExecState es)
{
const wchar_t* text = jsToStringW(es, jsArg(es, 0));
const wchar_t* title = jsToStringW(es, jsArg(es, 1));
::MessageBoxW(NULL, text, title, 0);
return jsStringW(es, L"C++返回字符串");
}
// 以下设置窗口拖动区域
static bool g_isMoving = false;
static RECT g_moveRect = { 0 };
void setMoveWindowArea(int x, int y, int w, int h)
{
g_moveRect.left = x;
g_moveRect.top = y;
g_moveRect.right = x + w;
g_moveRect.bottom = y + h;
g_isMoving = true;
}
LRESULT CALLBACK subClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
// if (g_isMoving && (uMsg == WM_NCHITTEST)) {
// POINT pt = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
// ::ScreenToClient(hWnd, &pt);
// if (::PtInRect(&g_moveRect, pt))
// return HTCAPTION;
//
// }
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
jsValue onMsg(jsExecState es, void* param)
{
int argCount = jsArgCount(es);
if (argCount < 1)
return jsUndefined();
jsType type = jsArgType(es, 0);
if (JSTYPE_STRING != type)
return jsUndefined();
jsValue arg0 = jsArg(es, 0);
std::string msgOutput = "eMsg:";
std::string msg = jsToTempString(es, arg0);
msgOutput = msgOutput + msg;
msgOutput += "\n";
OutputDebugStringA(msgOutput.c_str());
if ("close" == msg) {
blinkClose();
} else if ("max" == msg) {
blinkMaximize();
} else if ("min" == msg) {
blinkMinimize();
}
return jsUndefined();
}
//bool createECharsTest()
//{
// wkeWebView webview = wkeCreateWebWindow(WKE_WINDOW_TYPE_TRANSPARENT, NULL, 0, 0, 640, 480);
// wkeSetWindowTitleW(webview, L"miniblink ECharsTest");
// wkeOnDocumentReady(webview, handleDocumentReady, nullptr);
// wkeOnLoadUrlBegin(webview, onLoadUrlBegin, nullptr);
// wkeOnLoadUrlEnd(webview, onLoadUrlEnd, nullptr);
// wkeMoveToCenter(webview);
// wkeLoadURL(webview, "http://hook.test/resources/view/map.html");
//
// return true;
//}
//jsValue WKE_CALL_TYPE onShellExec(jsExecState es, void* param)
//{
// if (0 == jsArgCount(es))
// return jsUndefined();
// jsValue arg0 = jsArg(es, 0);
// if (!jsIsString(arg0))
// return jsUndefined();
//
// std::string path;
// path = jsToTempString(es, arg0);
// if ("runEchars" == path) {
// createECharsTest();
// } else if ("wkeBrowser" == path) {
// wkeBrowserMain(nullptr, nullptr, nullptr, TRUE);
// }
//
// path += "\n";
// OutputDebugStringA(path.c_str());
//
// return jsUndefined();
//}
//
//void WKE_CALL_TYPE onDidCreateScriptContextCallback(wkeWebView webView, void* param, wkeWebFrameHandle frameId, void* context, int extensionGroup, int worldId)
//{
//
//}
//
//bool createWebWindow(Application* app)
//{
// app->window = wkeCreateWebWindow(WKE_WINDOW_TYPE_POPUP, NULL, 0, 0, 1920, 1024);
// if (!app->window)
// return false;
//
// //SetWindowSubclass(wkeGetWindowHandle(app->window), subClassProc, 0, 0);
// setMoveWindowArea(0, 0, 1920, 1024); // 设置窗口可拖动区域,用于无边框窗体
//
// wkeSetWindowTitleW(app->window, L"miniblink demo");
//
// wkeOnDidCreateScriptContext(app->window, onDidCreateScriptContextCallback, app);
// wkeOnWindowClosing(app->window, handleWindowClosing, app);
// wkeOnWindowDestroy(app->window, handleWindowDestroy, app);
// wkeOnDocumentReady(app->window, handleDocumentReady, app);
// wkeOnTitleChanged(app->window, handleTitleChanged, app);
// wkeOnCreateView(app->window, onCreateView, app);
// wkeOnLoadUrlBegin(app->window, onLoadUrlBegin, app);
// wkeOnLoadUrlEnd(app->window, onLoadUrlEnd, app);
// wkeSetDebugConfig(app->window, "decodeUrlRequest", nullptr);
//
// //wkeJsBindFunction("eMsg", &onMsg, nullptr, 5);
// //wkeJsBindFunction("eShellExec", &onShellExec, nullptr, 3);
// wkeMoveToCenter(app->window);
// wkeLoadURLW(app->window, app->url.c_str());
//
// return true;
//}
/*
int WINAPI wWinMain(
__in HINSTANCE hInstance,
__in_opt HINSTANCE hPrevInstance,
__in LPWSTR lpCmdLine,
__in int nCmdShow
)
{
std::vector<wchar_t> tempPath;
tempPath.resize(MAX_PATH);
::GetModuleFileNameW(nullptr, &tempPath[0], MAX_PATH);
::PathRemoveFileSpec(&tempPath[0]);
std::vector<wchar_t> mbPath = tempPath;
::PathAppendW(&mbPath[0], L"node.dll");
if (!::PathFileExists(&mbPath[0])) {
::PathAppendW(&tempPath[0], L"..\\..\\");
mbPath = tempPath;
::PathAppendW(&mbPath[0], L"node.dll");
if (!::PathFileExists(&mbPath[0])) {
::MessageBoxW(NULL, L"请把node.dll放exe目录下", L"错误", MB_OK);
return 0;
}
}
wkeSetWkeDllPath(&mbPath[0]);
//wkeInitialize();
runApp(&app);
//wkeFinalize();
return 0;
}
*/
void test()
{
/*
std::vector<wchar_t> tempPath;
tempPath.resize(MAX_PATH);
::GetModuleFileNameW(nullptr, &tempPath[0], MAX_PATH);
::PathRemoveFileSpec(&tempPath[0]);
std::vector<wchar_t> mbPath = tempPath;
::PathAppendW(&mbPath[0], L"node.dll");
*/
wkeSetWkeDllPath(L"D:\\node.dll"); wkeInitialize();
//runApp(&app);
wkeFinalize();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff