diff --git a/finclip-win32-demo.cpp b/finclip-win32-demo.cpp index eb04815..c8938fa 100644 --- a/finclip-win32-demo.cpp +++ b/finclip-win32-demo.cpp @@ -1,7 +1,6 @@ -// FinClip.cpp : Defines the entry point for the application. +// FinClip.cpp : Defines the entry point for the application. // #include "Resource.h" -#include "vendor/finclip/include/finclip_api.h" #include "vendor/finclip/include/finclip_wrapper.h" // Windows Header Files #include @@ -17,18 +16,20 @@ #include #include -#define MAX_LOADSTRING 100 #pragma comment(lib, "FinClipSDKWrapper.lib") +#define MAX_LOADSTRING 100 + using namespace std; using json = nlohmann::json; - +using namespace com::finogeeks::finclip::wrapper; HINSTANCE hInst; HWND gHwnd; // current instance WCHAR szTitle[MAX_LOADSTRING]; // The title bar text WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name ATOM MyRegisterClass(HINSTANCE hInstance); +ATOM MyRegisterClass1(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HWND hWnd_appkey; @@ -40,6 +41,9 @@ HWND hWnd_container; HWND hWnd_applet; BOOL is_initialized = FALSE; RECT g_rect_; +std::string offline_base_path; +std::string offline_applet_path; + std::string utf8_encode(const std::wstring &wstr, int CP = CP_UTF8) { if (wstr.empty()) return std::string(); @@ -94,6 +98,7 @@ class CustomApi : public IApi { int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { + SetProcessDPIAware(); UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); @@ -101,7 +106,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, LoadStringW(hInstance, IDC_FINCLIPWIN32DEMO, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); - + MyRegisterClass1(hInstance); if (!InitInstance(hInstance, nCmdShow)) { return FALSE; } @@ -173,15 +178,22 @@ ATOM MyRegisterClass1(HINSTANCE hInstance) { BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // Store instance handle in our global variable DWORD dwStyle = - WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX; //ôʽ + WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX; //���ô�����ʽ HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 1000, 800, nullptr, nullptr, hInstance, nullptr); - + HMONITOR hmon = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); + MONITORINFO mi = {sizeof(mi)}; + if (!GetMonitorInfo(hmon, &mi)) + return FALSE; if (!hWnd) { return FALSE; } + int width = 450; + int height = 500; + SetWindowPos(hWnd, NULL, mi.rcMonitor.left, mi.rcMonitor.top, width, height, + SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); gHwnd = hWnd; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); @@ -191,7 +203,7 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { void init_finclipsdk(int app_store, std::wstring wappkey, std::wstring wsecret, std::wstring wdomain) { - if (is_initialized) { + if (is_initialized != 0) { return; } @@ -210,11 +222,14 @@ void init_finclipsdk(int app_store, std::wstring wappkey, std::wstring wsecret, config->SetEncryptType(1); config->SetFinger(""); config->SetAppWindowStyle(1); - + config->SetOfflineApplet(offline_applet_path.data()); + config->SetOfflineBaseLibrary(offline_base_path.data()); + config->SetStartFlag(StartFlags::kAppletSync); + config->SetShowLoading(0); configpacker->AddConfig(config); - CustomApi *c_api = new CustomApi(); + auto *c_api = new CustomApi(); configpacker->RegisterApi(c_api); - CustomWebApi *c_web_api = new CustomWebApi(); + auto *c_web_api = new CustomWebApi(); configpacker->RegisterApi(c_web_api); Initialize(hInst, configpacker); is_initialized = TRUE; @@ -242,9 +257,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, WCHAR appid[1024]; GetWindowText(hWnd_appid, appid, 1023); std::wstring wappid(appid); - - InvokeWebApi(utf8_encode(wappid).c_str(), "test_custom_api", - "{params:'a'}"); + CleanCache(); + // if (hWnd_container) { + // DestroyWindow(hWnd_container); + // } + // InvokeWebApi(utf8_encode(wappid).c_str(), "test_custom_api", + // "{params:'a'}"); break; } if (LOWORD(wParam) == IDM_START_APPLET) { @@ -264,23 +282,23 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, std::wstring wdomain(domain); std::wstring wtype(type); if (wappkey.length() == 0) { - MessageBox(NULL, L"appKey", L"ʾ", 0); + MessageBox(NULL, L"������appKey", L"��ʾ", 0); return 0; } if (wsecret.length() == 0) { - MessageBox(NULL, L"Secret", L"ʾ", 0); + MessageBox(NULL, L"������Secret", L"��ʾ", 0); return 0; } if (wappid.length() == 0) { - MessageBox(NULL, L"appid", L"ʾ", 0); + MessageBox(NULL, L"������appid", L"��ʾ", 0); return 0; } if (wdomain.length() == 0) { - MessageBox(NULL, L"domain", L"ʾ", 0); + MessageBox(NULL, L"������domain", L"��ʾ", 0); return 0; } if (wtype.length() == 0) { - MessageBox(NULL, L"type", L"ʾ", 0); + MessageBox(NULL, L"������type", L"��ʾ", 0); return 0; } int appstore = 1; @@ -288,56 +306,112 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, IFinConfigPacker *configpacker = factory->GetFinConfigPacker(); IFinConfig *config = configpacker->GetConfig(appstore); config->SetAppWindowStyle(std::stol(wtype)); - //->SetAppWindowStyle(std::stol(wtype)); IFinPacker *packer = factory->GetFinPacker(); packer->BeginPacker(); packer->Add("appId", utf8_encode(wappid).c_str()); packer->Add("query", "1"); packer->EndPacker(); int len = packer->GetBufferSize() + 1; - unsigned char *ret = new unsigned char[len]; + auto *ret = new unsigned char[len]; memset(ret, 0, len); packer->Dump(ret, &len); delete[] ret; + if (hWnd_container == nullptr) { + // hWnd_container = CreateWindowW(L"child_finclip", L"���Դ���", + // WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, + // 0, 1920, 1080, NULL, NULL, + // hInst, NULL); + hWnd_container = CreateWindowW(L"child_finclip", L"���Դ���", + WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, + 1024, 768, NULL, NULL, hInst, NULL); + } HRESULT hr = StartApplet(hWnd_container, appstore, utf8_encode(wappid).c_str(), "", - packer, finclip_applet_callback); + packer, "", finclip_applet_callback); + if (hr == S_OK) { } // SetWindowPos(h, NULL, 0, 300, 400, 436, 0); packer->Release(); } break; - case WM_SHOWWINDOW: { - WCHAR key[1024]; - GetWindowText(hWnd_appkey, key, 1023); - WCHAR secret[1024]; - GetWindowText(hWnd_secret, secret, 1023); - WCHAR appid[1024]; - GetWindowText(hWnd_appid, appid, 1023); - WCHAR domain[1024]; - GetWindowText(hWnd_domain, domain, 1023); - std::wstring wappkey(key); - std::wstring wsecret(secret); - std::wstring wappid(appid); - std::wstring wdomain(domain); - init_finclipsdk(1, wappkey, wsecret, wdomain); - } break; - case WM_SYSCOMMAND: { - int i = 0; - int j = 0; - ::SetWindowPos(hWnd_container, NULL, 450, 10, 450, 750, 0); - /*InvalidateRect(hWnd_container, NULL, TRUE); - UpdateWindow(hWnd_container);*/ + case WM_CLOSE: { + if (hWnd == hWnd_container) { + hWnd_container = NULL; + } break; } + + case WM_SHOWWINDOW: { + if (hWnd == hWnd_container) { + /*RECT rc; + GetWindowRect(hWnd, &rc); + auto left = 0; + auto top = 0; + auto width = rc.right - rc.left; + auto height = rc.bottom - rc.top; + WCHAR appid[1024]; + GetWindowText(hWnd_appid, appid, 1023); + SetAppletPos(utf8_encode(std::wstring(appid)).c_str(), 1, 0, top, width, + height); + */ + } else { + WCHAR key[1024]; + GetWindowText(hWnd_appkey, key, 1023); + WCHAR secret[1024]; + GetWindowText(hWnd_secret, secret, 1023); + WCHAR appid[1024]; + GetWindowText(hWnd_appid, appid, 1023); + WCHAR domain[1024]; + GetWindowText(hWnd_domain, domain, 1023); + std::wstring wappkey(key); + std::wstring wsecret(secret); + std::wstring wappid(appid); + std::wstring wdomain(domain); + init_finclipsdk(1, wappkey, wsecret, wdomain); + } + } break; + case WM_SIZE: { + WCHAR type[1024]; + GetWindowText(hWnd_type, type, 1023); + std::wstring wtype(type); + if (wtype == L"1") { + UINT width = LOWORD(lParam); + UINT height = HIWORD(lParam); + WCHAR appid[1024]; + GetWindowText(hWnd_appid, appid, 1023); + RECT rect; + GetClientRect(hWnd_container, &rect); + SetAppletPos(utf8_encode(std::wstring(appid)).c_str(), 0, 0, + rect.right - rect.left, rect.bottom - rect.top, true); + } + + break; + } + // case WM_PAINT: + // { + // // WCHAR type[1024]; + // // GetWindowText(hWnd_type, type, 1023); + // // std::wstring wtype(type); + // // if (wtype == L"1") { + // // RECT rect; + // // GetClientRect(hWnd_container, &rect); + // // WCHAR appid[1024]; + // // GetWindowText(hWnd_appid, appid, 1023); + // // SetAppletPos( + // // utf8_encode(std::wstring(appid)).c_str(), 0, 0, rect.right - + // rect.left, rect.bottom - rect.top, + // // true); + // // } + // break; + // } case WM_DESTROY: { - FinClipShutdown(); PostQuitMessage(0); break; } case WM_CREATE: { - + if (hWnd_appkey) + return DefWindowProcW(hWnd, message, wParam, lParam); CreateWindowW(L"static", L"AppKEY", WS_CHILD | WS_VISIBLE, 20, 20, 60, 30, hWnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL); @@ -352,18 +426,26 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, CreateWindowW(L"static", L"window_type", WS_CHILD | WS_VISIBLE, 20, 180, 60, 30, hWnd, (HMENU)2, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - hWnd_container = CreateWindowW(L"static", L"", WS_CHILD | WS_VISIBLE, 450, - 10, 450, 750, hWnd, (HMENU)2, - ((LPCREATESTRUCT)lParam)->hInstance, NULL); + HMONITOR hmon = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); + MONITORINFO mi = {sizeof(mi)}; + if (!GetMonitorInfo(hmon, &mi)) + return false; + auto left = mi.rcMonitor.left; + auto top = mi.rcMonitor.top; + auto width = mi.rcMonitor.right - mi.rcMonitor.left; + auto height = mi.rcMonitor.bottom - mi.rcMonitor.top; + // hWnd_container = CreateWindowW(L"static", L"", WS_CHILD | WS_VISIBLE, + // left, + // top, width, height, hWnd, (HMENU)2, + // ((LPCREATESTRUCT)lParam)->hInstance, NULL); wstring domain(L"https://finchat-mop-b.finogeeks.club"); wstring appkey(L"22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk="); wstring appid(L"60e3c059949a5300014d0c07"); wstring secret(L"ae55433be2f62915"); - // exe, config.jsonexeͬһĿ¼ - // vs, config.jsonFinclip/ + // ��exe����, config.json����exeͬһĿ¼ + // ��vs����, config.json����Finclip/ auto path = std::filesystem::current_path(); if (std::filesystem::exists("config.json")) { std::ifstream t("config.json"); @@ -390,7 +472,16 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, auto s = field.value().get(); secret = wstring(s.begin(), s.end()); } - t.close(); + field = obj.find("offline_applet_path"); + if (field != obj.end() && field.value().is_string()) { + auto s = field.value().get(); + offline_applet_path = string(s.begin(), s.end()); + } + field = obj.find("offline_base_path"); + if (field != obj.end() && field.value().is_string()) { + auto s = field.value().get(); + offline_base_path = string(s.begin(), s.end()); + } } hWnd_appkey = CreateWindowW( L"EDIT", appkey.c_str(), WS_VISIBLE | WS_CHILD | WS_BORDER | ES_LEFT, diff --git a/vendor/finclip/.gitignore b/vendor/finclip/.gitignore index 66e2f1f..629e141 100644 --- a/vendor/finclip/.gitignore +++ b/vendor/finclip/.gitignore @@ -1,2 +1,3 @@ +*.zip /lib -*.bz2 \ No newline at end of file +*.bz2 diff --git a/vendor/finclip/include/finclip_api.h b/vendor/finclip/include/finclip_api.h index 7b33111..264ad27 100644 --- a/vendor/finclip/include/finclip_api.h +++ b/vendor/finclip/include/finclip_api.h @@ -14,6 +14,20 @@ #define FIN_OK 0 #define FIN_FAIL 1 #include +namespace com::finogeeks::finclip::wrapper { + +/** + * @brief 启动机制设置 + * kAsync: 异步启动 + * kBaseLibrarySync: 基础库同步加载 + * kAppletSync: 小程序同步加载 + */ +enum StartFlags +{ + kAsync = 0, + kBaseLibrarySync = 1 << 0, + kAppletSync = 1 << 1, +}; /** * @brief 自定义API类型,分别用于小程序和jssdk * @@ -250,6 +264,30 @@ public: * @return void */ virtual void SetAppWindowStyle(int type) = 0; + /** + * @brief 离线基础库zip包路径 + * @param path + * @return void + */ + virtual void SetOfflineBaseLibrary(const char* path) = 0; + /** + * @brief 离线小程序zip包路径 + * @param path + * @return void + */ + virtual void SetOfflineApplet(const char* path) = 0; + /** + * @brief 设置小程序窗口类型 + * @param type 0:独立窗口,1:子窗口 + * @return void + */ + virtual void SetShowLoading(int type) = 0; + /** + * @brief 设置启动机制 + * @param flag: StartFlags + * @return void + */ + virtual void SetStartFlag(int flag) = 0; }; /* * 接口注入api @@ -352,4 +390,5 @@ public: */ virtual IFinPacker* GetFinPacker() = 0; }; +} // namespace com::finogeeks::finclip::wrapper #endif // !__H_FINCLIPAPI_H__ diff --git a/vendor/finclip/include/finclip_wrapper.h b/vendor/finclip/include/finclip_wrapper.h index 7920a8f..d6c8a2f 100644 --- a/vendor/finclip/include/finclip_wrapper.h +++ b/vendor/finclip/include/finclip_wrapper.h @@ -2,7 +2,7 @@ #define __H_FINCLIP_WRAPPER_H__ #include "finclip_api.h" #include - +namespace com::finogeeks::finclip::wrapper { #ifdef __cplusplus extern "C" { #endif @@ -68,10 +68,11 @@ DLL_EXPORT int FINSTDMETHODCALLTYPE CleanCache(); * @param appId 小程序appId * @param param 打开参数 * @param callback 打开小程序回调 + * @param exe_path 空: 当前目录的finclip.exe,否则:指定路径, 例如d:\finclip.exe * @return 0表示成功,1表示失败 */ DLL_EXPORT int FINSTDMETHODCALLTYPE StartApplet(HWND hWnd, int appstore, const char* appid, const char* page_path, - IFinPacker* params, FinClipSDKCallback callback); + IFinPacker* params, const char* exe_path, FinClipSDKCallback callback); /** * @brief Set the Applet Pos object * @@ -83,8 +84,8 @@ DLL_EXPORT int FINSTDMETHODCALLTYPE StartApplet(HWND hWnd, int appstore, const c * @param height * @return DLL_EXPORT */ -DLL_EXPORT void FINSTDMETHODCALLTYPE SetAppletPos(const char* appid, int appstore, int left, int top, int width, - int height); +DLL_EXPORT void FINSTDMETHODCALLTYPE SetAppletPos(const char* appid, int left, int top, int width, int height, + bool repaint); /** * @brief @@ -95,7 +96,9 @@ DLL_EXPORT int FINSTDMETHODCALLTYPE FinClipShutdown(); DLL_EXPORT int FINSTDMETHODCALLTYPE InvokeWebApi(const char* app_id, const char* api_name, const char* params); +DLL_EXPORT int FINSTDMETHODCALLTYPE CloseApplet(const char* appid); #ifdef __cplusplus } #endif +} // namespace com::finogeeks::finclip::wrapper #endif