// TerminalDisplayDlg.cpp : ʵÏÖÎļþ // #include "stdafx.h" #include "Servo.h" #include "TerminalDisplayDlg.h" #include "afxdialogex.h" #define TIMER_ID_HIDE 1 // CTerminalDisplayDlg ¶Ô»°¿ò IMPLEMENT_DYNAMIC(CTerminalDisplayDlg, CDialogEx) CTerminalDisplayDlg::CTerminalDisplayDlg(CWnd* pParent /*=NULL*/) : CDialogEx(IDD_DIALOG_TERMINAL_DISPLAY, pParent) { m_crBkgnd = RGB(0x3d, 0x0, 0xd0); m_hbrBkgnd = nullptr; } CTerminalDisplayDlg::~CTerminalDisplayDlg() { } void CTerminalDisplayDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_BUTTON_CLOSE, m_btnClose); } BEGIN_MESSAGE_MAP(CTerminalDisplayDlg, CDialogEx) ON_WM_CTLCOLOR() ON_WM_DESTROY() ON_WM_SIZE() ON_WM_CREATE() ON_WM_TIMER() ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CTerminalDisplayDlg::OnBnClickedButtonClose) ON_WM_NCHITTEST() END_MESSAGE_MAP() // CTerminalDisplayDlg ÏûÏ¢´¦Àí³ÌÐò void CTerminalDisplayDlg::SetTemplateHtml(const char* pszFilepath) { m_strFilepath = pszFilepath; } BOOL CTerminalDisplayDlg::OnInitDialog() { CDialogEx::OnInitDialog(); CString strIcon1; strIcon1.Format(_T("%s\\Res\\close_white_24.ico"), theApp.m_strAppDir); HICON hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(), strIcon1, IMAGE_ICON, 24, 24, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); m_btnClose.SetIcon(hIcon, hIcon, 24); m_btnClose.SetBkgndColor(BS_HOVER, RGB(232, 17, 35)); m_btnClose.SetBkgndColor(BS_PRESS, RGB(162, 34, 44)); UpdateCloseBtn(); return TRUE; // return TRUE unless you set the focus to a control // Òì³£: OCX ÊôÐÔÒ³Ó¦·µ»Ø FALSE } HBRUSH CTerminalDisplayDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); if (nCtlColor == CTLCOLOR_STATIC) { pDC->SetBkColor(m_crBkgnd); } if (m_hbrBkgnd == nullptr) { m_hbrBkgnd = CreateSolidBrush(m_crBkgnd); } return m_hbrBkgnd; } void CTerminalDisplayDlg::OnDestroy() { CDialogEx::OnDestroy(); if (m_hbrBkgnd != nullptr) { ::DeleteObject(m_hbrBkgnd); } } void CTerminalDisplayDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); if (m_webviewController == nullptr) return; Resize(); } void CTerminalDisplayDlg::Resize() { CWnd* pItem; CRect rcClient, rcItem; GetClientRect(&rcClient); rcClient.top += 38; m_webviewController->put_Bounds(rcClient); m_btnClose.MoveWindow(rcClient.right - 38, 0, 38, 38); } void CTerminalDisplayDlg::ShowText(const char* pszText, unsigned int duration/* = -1*/) { if (m_webWiew == nullptr) return; std::string strMsg = pszText; std::wstring wstrMsg(strMsg.begin(), strMsg.end()); size_t size = (wstrMsg.size() + 1) * sizeof(wchar_t); wchar_t* memory = (wchar_t*)CoTaskMemAlloc(size); if (memory == nullptr) return; wcsncpy_s(memory, wstrMsg.size() + 1, wstrMsg.c_str(), wstrMsg.size()); wil::unique_cotaskmem_string message(memory); m_webWiew->PostWebMessageAsString(message.get()); ShowWindow(SW_SHOW); m_webviewController->put_IsVisible(TRUE); SetTimer(TIMER_ID_HIDE, duration, nullptr); } int CTerminalDisplayDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialogEx::OnCreate(lpCreateStruct) == -1) return -1; HWND hWnd = this->m_hWnd; // Step 3 - Create a single WebView within the parent window // Locate the browser and set up the environment for WebView CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr, Callback( [hWnd, this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT { // Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd env->CreateCoreWebView2Controller(hWnd, Callback( [hWnd, this](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT { if (controller != nullptr) { this->m_webviewController = controller; this->m_webviewController->get_CoreWebView2(&this->m_webWiew); } else { OutputDebugString(_T("WebView2 Controller ´´½¨Ê§°Ü£¡\n")); return E_FAIL; } // Add a few settings for the webview // The demo step is redundant since the values are the default settings wil::com_ptr settings; this->m_webWiew->get_Settings(&settings); settings->put_IsScriptEnabled(TRUE); settings->put_AreDefaultScriptDialogsEnabled(TRUE); settings->put_IsWebMessageEnabled(TRUE); // Resize WebView to fit the bounds of the parent window RECT bounds; ::GetClientRect(hWnd, &bounds); this->m_webviewController->put_Bounds(bounds); Resize(); EventRegistrationToken token; // Step 5 - Scripting // Schedule an async task to add initialization script that freezes the Object object this->m_webWiew->AddScriptToExecuteOnDocumentCreated(L"Object.freeze(Object);", nullptr); // Schedule an async task to get the document URL this->m_webWiew->ExecuteScript(L"window.document.URL;", Callback( [](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT { LPCWSTR URL = resultObjectAsJson; return S_OK; }).Get()); // Step 6 - Communication between host and web content // Set an event handler for the host to return received message back to the web content this->m_webWiew->add_WebMessageReceived(Callback( [this](ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT { wil::unique_cotaskmem_string message; args->TryGetWebMessageAsString(&message); this->ProcessWebViewMessage(message); return S_OK; }).Get(), &token); if (!m_strFilepath.empty()) { wchar_t url[512]; swprintf(url, 512, L"file:///%hs", m_strFilepath.c_str()); m_webWiew->Navigate(url); } return S_OK; }).Get()); return S_OK; }).Get()); return 0; } void CTerminalDisplayDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ if (TIMER_ID_HIDE == nIDEvent) { KillTimer(TIMER_ID_HIDE); ShowWindow(SW_HIDE); } CDialogEx::OnTimer(nIDEvent); } void CTerminalDisplayDlg::OnBnClickedButtonClose() { ShowWindow(SW_HIDE); } LRESULT CTerminalDisplayDlg::OnNcHitTest(CPoint point) { return HTCAPTION; return CDialogEx::OnNcHitTest(point); } void CTerminalDisplayDlg::ProcessWebViewMessage(wil::unique_cotaskmem_string& message) { // ת»»ÎªCString LPCWSTR wideStr = message.get(); int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, nullptr, 0, nullptr, nullptr); if (bufferSize == 0)return; char* charStr = new char[bufferSize]; WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, charStr, bufferSize, nullptr, nullptr); CString strMsg = charStr; delete[] charStr; // È¡header, body CString strHeader, strBody; int n = strMsg.Find(":"); if (n < 0) return; strHeader = strMsg.Left(n); strBody = strMsg.Right(strMsg.GetLength() - n - 1); // ±³¾°É« if (strHeader.CompareNoCase("backgroundColor") == 0) { int n1 = strBody.Find("rgb("); int n2 = strBody.Find(","); int n3 = strBody.Find(",", n2+1); int n4 = strBody.Find(")"); if (n1 >= 0 && n2 > 0 && n3 > 0 && n4 > 0) { CString strRed, strGreen, strBlue; strRed = strBody.Mid(n1 + 4, n2 - n1 - 4); strGreen = strBody.Mid(n2 + 1, n3 - n2 - 1); strBlue = strBody.Mid(n3 + 1, n4 - n3 - 1); m_crBkgnd = RGB(atoi(strRed), atoi(strGreen), atoi(strBlue)); if (m_hbrBkgnd != nullptr) { ::DeleteObject(m_hbrBkgnd); m_hbrBkgnd = nullptr; Invalidate(); } UpdateCloseBtn(); } } } void CTerminalDisplayDlg::UpdateCloseBtn() { m_btnClose.SetFrameColor(BS_NORMAL, m_crBkgnd); m_btnClose.SetFrameColor(BS_HOVER, m_crBkgnd); m_btnClose.SetFrameColor(BS_PRESS, m_crBkgnd); m_btnClose.SetBkgndColor(BS_NORMAL, m_crBkgnd); m_btnClose.Invalidate(); }