diff --git a/.gitignore b/.gitignore index 07ec76d6f..834963f2e 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ weasel.props *.swp .vs Thumbs.db +/.idea +/cmake-build-debug diff --git a/RimeWithWeasel/RimeWithWeasel.cpp b/RimeWithWeasel/RimeWithWeasel.cpp index a9a11f0ee..00ad95135 100644 --- a/RimeWithWeasel/RimeWithWeasel.cpp +++ b/RimeWithWeasel/RimeWithWeasel.cpp @@ -4,10 +4,6 @@ #include #include #include -#include -#include -#include -#include #include @@ -17,7 +13,10 @@ int expand_ibus_modifier(int m) } RimeWithWeaselHandler::RimeWithWeaselHandler(weasel::UI *ui) - : m_ui(ui), m_active_session(0), m_disabled(true) + : m_ui(ui) + , m_active_session(0) + , m_disabled(true) + , _UpdateUICallback(NULL) { _Setup(); } @@ -252,6 +251,35 @@ void RimeWithWeaselHandler::_ReadClientInfo(UINT session_id, LPWSTR buffer) RimeSetOption(session_id, "soft_cursor", Bool(!inline_preedit)); } +void RimeWithWeaselHandler::_GetCandidateInfo(weasel::CandidateInfo & cinfo, RimeContext & ctx) +{ + cinfo.candies.resize(ctx.menu.num_candidates); + cinfo.comments.resize(ctx.menu.num_candidates); + cinfo.labels.resize(ctx.menu.num_candidates); + for (int i = 0; i < ctx.menu.num_candidates; ++i) + { + cinfo.candies[i].str = utf8towcs(ctx.menu.candidates[i].text); + if (ctx.menu.candidates[i].comment) + { + cinfo.comments[i].str = utf8towcs(ctx.menu.candidates[i].comment); + } + if (RIME_STRUCT_HAS_MEMBER(ctx, ctx.select_labels) && ctx.select_labels) + { + cinfo.labels[i].str = utf8towcs(ctx.select_labels[i]); + } + else if (ctx.menu.select_keys) + { + cinfo.labels[i].str = std::wstring(1, ctx.menu.select_keys[i]); + } + else + { + cinfo.labels[i].str = std::to_wstring((i + 1) % 10); + } + } + cinfo.highlighted = ctx.menu.highlighted_candidate_index; + cinfo.currentPage = ctx.menu.page_no; +} + void RimeWithWeaselHandler::StartMaintenance() { Finalize(); @@ -267,6 +295,12 @@ void RimeWithWeaselHandler::EndMaintenance() } } +void RimeWithWeaselHandler::OnUpdateUI(std::function const &cb) +{ + _UpdateUICallback = cb; +} + + bool RimeWithWeaselHandler::_IsDeployerRunning() { HANDLE hMutex = CreateMutex(NULL, TRUE, L"WeaselDeployerMutex"); @@ -284,71 +318,15 @@ void RimeWithWeaselHandler::_UpdateUI(UINT session_id) weasel::Status weasel_status; weasel::Context weasel_context; + bool is_tsf = _IsSessionTSF(session_id); + if (session_id == 0) weasel_status.disabled = m_disabled; - RIME_STRUCT(RimeStatus, status); - if (RimeGetStatus(session_id, &status)) - { - std::string schema_id = status.schema_id; - if (schema_id != m_last_schema_id) - { - m_last_schema_id = schema_id; - _LoadSchemaSpecificSettings(schema_id); - } - weasel_status.schema_name = utf8towcs(status.schema_name); - weasel_status.ascii_mode = !!status.is_ascii_mode; - weasel_status.composing = !!status.is_composing; - weasel_status.disabled = !!status.is_disabled; - RimeFreeStatus(&status); - } + _GetStatus(weasel_status, session_id); - RIME_STRUCT(RimeContext, ctx); - if (RimeGetContext(session_id, &ctx)) - { - if (ctx.composition.length > 0) - { - weasel_context.preedit.str = utf8towcs(ctx.composition.preedit); - if (ctx.composition.sel_start < ctx.composition.sel_end) - { - weasel::TextAttribute attr; - attr.type = weasel::HIGHLIGHTED; - attr.range.start = utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start); - attr.range.end = utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end); - - weasel_context.preedit.attributes.push_back(attr); - } - } - if (ctx.menu.num_candidates) - { - weasel::CandidateInfo &cinfo(weasel_context.cinfo); - cinfo.candies.resize(ctx.menu.num_candidates); - cinfo.comments.resize(ctx.menu.num_candidates); - cinfo.labels.resize(ctx.menu.num_candidates); - for (int i = 0; i < ctx.menu.num_candidates; ++i) - { - cinfo.candies[i].str = utf8towcs(ctx.menu.candidates[i].text); - if (ctx.menu.candidates[i].comment) - { - cinfo.comments[i].str = utf8towcs(ctx.menu.candidates[i].comment); - } - if (RIME_STRUCT_HAS_MEMBER(ctx, ctx.select_labels) && ctx.select_labels) - { - cinfo.labels[i].str = utf8towcs(ctx.select_labels[i]); - } - else if (ctx.menu.select_keys) - { - cinfo.labels[i].str = std::wstring(1, ctx.menu.select_keys[i]); - } - else - { - cinfo.labels[i].str = std::to_wstring((i + 1) % 10); - } - } - cinfo.highlighted = ctx.menu.highlighted_candidate_index; - cinfo.currentPage = ctx.menu.page_no; - } - RimeFreeContext(&ctx); + if (!is_tsf) { + _GetContext(weasel_context, session_id); } if (!m_ui) return; @@ -356,16 +334,20 @@ void RimeWithWeaselHandler::_UpdateUI(UINT session_id) m_ui->style().client_caps |= weasel::INLINE_PREEDIT_CAPABLE; else m_ui->style().client_caps &= ~weasel::INLINE_PREEDIT_CAPABLE; + + if (weasel_status.composing) { m_ui->Update(weasel_context, weasel_status); - m_ui->Show(); + if (!is_tsf) m_ui->Show(); } else if (!_ShowMessage(weasel_context, weasel_status)) { m_ui->Hide(); m_ui->Update(weasel_context, weasel_status); } + + if (_UpdateUICallback) _UpdateUICallback(); m_message_type.clear(); m_message_value.clear(); @@ -458,7 +440,7 @@ bool RimeWithWeaselHandler::_Respond(UINT session_id, EatLine eat) actions.insert("ctx"); switch (m_ui->style().preedit_type) { - case weasel::PREVIEW: + case weasel::UIStyle::PREVIEW: if (ctx.commit_text_preview != NULL) { std::string first = ctx.commit_text_preview; @@ -469,7 +451,7 @@ bool RimeWithWeaselHandler::_Respond(UINT session_id, EatLine eat) break; } // no preview, fall back to composition - case weasel::COMPOSITION: + case weasel::UIStyle::COMPOSITION: messages.push_back(std::string("ctx.preedit=") + ctx.composition.preedit + '\n'); if (ctx.composition.sel_start <= ctx.composition.sel_end) { @@ -480,6 +462,17 @@ bool RimeWithWeaselHandler::_Respond(UINT session_id, EatLine eat) break; } } + if (ctx.menu.num_candidates) + { + weasel::CandidateInfo cinfo; + std::wstringstream ss; + boost::archive::text_woarchive oa(ss); + _GetCandidateInfo(cinfo, ctx); + + oa << cinfo; + + messages.push_back(std::string("ctx.cand=") + wcstoutf8(ss.str().c_str()) + '\n'); + } RimeFreeContext(&ctx); } @@ -487,6 +480,18 @@ bool RimeWithWeaselHandler::_Respond(UINT session_id, EatLine eat) actions.insert("config"); messages.push_back(std::string("config.inline_preedit=") + std::to_string((int)m_ui->style().inline_preedit) + '\n'); + // style + bool has_synced = RimeGetOption(session_id, "__synced"); + if (!has_synced) { + std::wstringstream ss; + boost::archive::text_woarchive oa(ss); + oa << m_ui->style(); + + actions.insert("style"); + messages.push_back(std::string("style=") + wcstoutf8(ss.str().c_str()) + '\n'); + RimeSetOption(session_id, "__synced", true); + } + // summarize if (actions.empty()) @@ -519,6 +524,7 @@ static inline COLORREF blend_colors(COLORREF fcolor, COLORREF bcolor) static void _UpdateUIStyle(RimeConfig* config, weasel::UI* ui, bool initialize) { if (!ui) return; + weasel::UIStyle &style(ui->style()); const int BUF_SIZE = 99; @@ -538,9 +544,9 @@ static void _UpdateUIStyle(RimeConfig* config, weasel::UI* ui, bool initialize) if (RimeConfigGetString(config, "style/preedit_type", preedit_type, sizeof(preedit_type) - 1)) { if (!std::strcmp(preedit_type, "composition")) - style.preedit_type = weasel::COMPOSITION; + style.preedit_type = weasel::UIStyle::COMPOSITION; else if (!std::strcmp(preedit_type, "preview")) - style.preedit_type = weasel::PREVIEW; + style.preedit_type = weasel::UIStyle::PREVIEW; } Bool display_tray_icon = False; if (RimeConfigGetBool(config, "style/display_tray_icon", &display_tray_icon) || initialize) @@ -550,13 +556,13 @@ static void _UpdateUIStyle(RimeConfig* config, weasel::UI* ui, bool initialize) Bool horizontal = False; if (RimeConfigGetBool(config, "style/horizontal", &horizontal) || initialize) { - style.layout_type = horizontal ? weasel::LAYOUT_HORIZONTAL : weasel::LAYOUT_VERTICAL; + style.layout_type = horizontal ? weasel::UIStyle::LAYOUT_HORIZONTAL : weasel::UIStyle::LAYOUT_VERTICAL; } Bool fullscreen = False; if (RimeConfigGetBool(config, "style/fullscreen", &fullscreen) && fullscreen) { - style.layout_type = (style.layout_type == weasel::LAYOUT_HORIZONTAL) - ? weasel::LAYOUT_HORIZONTAL_FULLSCREEN : weasel::LAYOUT_VERTICAL_FULLSCREEN; + style.layout_type = (style.layout_type == weasel::UIStyle::LAYOUT_HORIZONTAL) + ? weasel::UIStyle::LAYOUT_HORIZONTAL_FULLSCREEN : weasel::UIStyle::LAYOUT_VERTICAL_FULLSCREEN; } char label_text_format[128] = { 0 }; if (RimeConfigGetString(config, "style/label_format", label_text_format, sizeof(label_text_format) - 1)) @@ -568,13 +574,13 @@ static void _UpdateUIStyle(RimeConfig* config, weasel::UI* ui, bool initialize) if (RimeConfigGetString(config, "style/layout/type", layout_type, sizeof(layout_type) - 1)) { if (!std::strcmp(layout_type, "vertical")) - style.layout_type = weasel::LAYOUT_VERTICAL; + style.layout_type = weasel::UIStyle::LAYOUT_VERTICAL; else if (!std::strcmp(layout_type, "horizontal")) - style.layout_type = weasel::LAYOUT_HORIZONTAL; + style.layout_type = weasel::UIStyle::LAYOUT_HORIZONTAL; if (!std::strcmp(layout_type, "vertical+fullscreen")) - style.layout_type = weasel::LAYOUT_VERTICAL_FULLSCREEN; + style.layout_type = weasel::UIStyle::LAYOUT_VERTICAL_FULLSCREEN; else if (!std::strcmp(layout_type, "horizontal+fullscreen")) - style.layout_type = weasel::LAYOUT_HORIZONTAL_FULLSCREEN; + style.layout_type = weasel::UIStyle::LAYOUT_HORIZONTAL_FULLSCREEN; else LOG(WARNING) << "Invalid style type: " << layout_type; } @@ -658,3 +664,58 @@ static void _LoadAppOptions(RimeConfig* config, AppOptionsByAppName& app_options } RimeConfigEnd(&app_iter); } + +void RimeWithWeaselHandler::_GetStatus(weasel::Status & stat, UINT session_id) +{ + RIME_STRUCT(RimeStatus, status); + if (RimeGetStatus(session_id, &status)) + { + std::string schema_id = status.schema_id; + if (schema_id != m_last_schema_id) + { + m_last_schema_id = schema_id; + RimeSetOption(session_id, "__synced", false); // Sync new schema options with front end + _LoadSchemaSpecificSettings(schema_id); + } + stat.schema_name = utf8towcs(status.schema_name); + stat.ascii_mode = !!status.is_ascii_mode; + stat.composing = !!status.is_composing; + stat.disabled = !!status.is_disabled; + RimeFreeStatus(&status); + } + +} + +void RimeWithWeaselHandler::_GetContext(weasel::Context & weasel_context, UINT session_id) +{ + RIME_STRUCT(RimeContext, ctx); + if (RimeGetContext(session_id, &ctx)) + { + if (ctx.composition.length > 0) + { + weasel_context.preedit.str = utf8towcs(ctx.composition.preedit); + if (ctx.composition.sel_start < ctx.composition.sel_end) + { + weasel::TextAttribute attr; + attr.type = weasel::HIGHLIGHTED; + attr.range.start = utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start); + attr.range.end = utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end); + + weasel_context.preedit.attributes.push_back(attr); + } + } + if (ctx.menu.num_candidates) + { + weasel::CandidateInfo &cinfo(weasel_context.cinfo); + _GetCandidateInfo(cinfo, ctx); + } + RimeFreeContext(&ctx); + } +} + +bool RimeWithWeaselHandler::_IsSessionTSF(UINT session_id) +{ + static char client_type[20] = { 0 }; + RimeGetProperty(session_id, "client_type", client_type, sizeof(client_type) - 1); + return std::string(client_type) == "tsf"; +} diff --git a/RimeWithWeasel/WeaselUtility.cpp b/RimeWithWeasel/WeaselUtility.cpp index 48eb51e4c..b0887373d 100644 --- a/RimeWithWeasel/WeaselUtility.cpp +++ b/RimeWithWeasel/WeaselUtility.cpp @@ -1,29 +1,6 @@ #include "stdafx.h" #include -const char* wcstoutf8(const WCHAR* wstr) -{ - const int buffer_len = 1024; - static char buffer[buffer_len]; - memset(buffer, 0, sizeof(buffer)); - WideCharToMultiByte(CP_UTF8, 0, wstr, -1, buffer, buffer_len - 1, NULL, NULL); - return buffer; -} - -const WCHAR* utf8towcs(const char* utf8_str) -{ - const int buffer_len = 4096; - static WCHAR buffer[buffer_len]; - memset(buffer, 0, sizeof(buffer)); - MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1, buffer, buffer_len - 1); - return buffer; -} - -int utf8towcslen(const char* utf8_str, int utf8_len) -{ - return MultiByteToWideChar(CP_UTF8, 0, utf8_str, utf8_len, NULL, 0); -} - std::wstring WeaselUserDataPath() { WCHAR path[MAX_PATH] = {0}; const WCHAR KEY[] = L"Software\\Rime\\Weasel"; diff --git a/RimeWithWeasel/stdafx.h b/RimeWithWeasel/stdafx.h index 9e0b8a060..b539a1a28 100644 --- a/RimeWithWeasel/stdafx.h +++ b/RimeWithWeasel/stdafx.h @@ -13,7 +13,14 @@ #pragma warning(disable : 4819) #include +#include +#include #pragma warning(default : 4819) +#include +#include +#include +#include +#include using boost::interprocess::wbufferstream; diff --git a/WeaselIPC/ContextUpdater.cpp b/WeaselIPC/ContextUpdater.cpp index 32d716eeb..fb6802eb2 100644 --- a/WeaselIPC/ContextUpdater.cpp +++ b/WeaselIPC/ContextUpdater.cpp @@ -1,5 +1,7 @@ #include "stdafx.h" #include +#include + #include "Deserializer.h" #include "ContextUpdater.h" @@ -13,7 +15,7 @@ Deserializer::Ptr ContextUpdater::Create(ResponseParser* pTarget) } ContextUpdater::ContextUpdater(ResponseParser* pTarget) -: Deserializer(pTarget) + : Deserializer(pTarget) { } @@ -76,38 +78,10 @@ void ContextUpdater::_StoreText(Text& target, Deserializer::KeyType k, std::wstr void ContextUpdater::_StoreCand(Deserializer::KeyType k, std::wstring const& value) { CandidateInfo& cinfo = m_pTarget->p_context->cinfo; - if(k.size() < 3) - return; - if (k[2] == L"length") - { - cinfo.clear(); - int size = _wtoi(value.c_str()); - cinfo.candies.resize(size); - return; - } - if (k[2] == L"cursor") - { - int cur = _wtoi(value.c_str()); - cinfo.highlighted = cur; - return; - } - if (k[2] == L"page") - { - std::vector vec; - split(vec, value, L"/"); - if (vec.size() == 0) - return; - int i = _wtoi(vec[0].c_str()); - cinfo.currentPage = i; - int n = (vec.size() >= 2) ? _wtoi(vec[1].c_str()) : 0; - cinfo.totalPages = n; - return; - } + std::wstringstream ss(value); + boost::archive::text_wiarchive ia(ss); - size_t idx = _wtoi(k[2].c_str()); - if (idx >= cinfo.candies.size()) - return; - cinfo.candies[idx].str = value; + ia >> cinfo; } // StatusUpdater diff --git a/WeaselIPC/Deserializer.cpp b/WeaselIPC/Deserializer.cpp index c4a931a42..b62389725 100644 --- a/WeaselIPC/Deserializer.cpp +++ b/WeaselIPC/Deserializer.cpp @@ -4,6 +4,7 @@ #include "Committer.h" #include "ContextUpdater.h" #include "Configurator.h" +#include "Styler.h" using namespace weasel; @@ -22,6 +23,7 @@ void Deserializer::Initialize(ResponseParser* pTarget) Define(L"ctx", ContextUpdater::Create); Define(L"status", StatusUpdater::Create); Define(L"config", Configurator::Create); + Define(L"style", Styler::Create); } // loaded by default diff --git a/WeaselIPC/ResponseParser.cpp b/WeaselIPC/ResponseParser.cpp index 2e376f671..5095705ee 100644 --- a/WeaselIPC/ResponseParser.cpp +++ b/WeaselIPC/ResponseParser.cpp @@ -5,8 +5,8 @@ using namespace weasel; -ResponseParser::ResponseParser(std::wstring* commit, Context* context, Status* status, Config* config) - : p_commit(commit), p_context(context), p_status(status), p_config(config) +ResponseParser::ResponseParser(std::wstring* commit, Context* context, Status* status, Config* config, UIStyle* style) + : p_commit(commit), p_context(context), p_status(status), p_config(config), p_style(style) { Deserializer::Initialize(this); } diff --git a/WeaselIPC/Styler.cpp b/WeaselIPC/Styler.cpp new file mode 100644 index 000000000..8a28330ef --- /dev/null +++ b/WeaselIPC/Styler.cpp @@ -0,0 +1,30 @@ +#include "stdafx.h" +#include "Deserializer.h" +#include "Styler.h" + +using namespace weasel; + +Styler::Styler(weasel::ResponseParser * pTarget) + : Deserializer(pTarget) +{ +} + +Styler::~Styler() +{ +} + +void Styler::Store(weasel::Deserializer::KeyType const & key, std::wstring const & value) +{ + if (!m_pTarget->p_style) return; + + UIStyle &sty = *m_pTarget->p_style; + std::wstringstream ss(value); + boost::archive::text_wiarchive ia(ss); + + ia >> sty; +} + +weasel::Deserializer::Ptr Styler::Create(weasel::ResponseParser * pTarget) +{ + return Deserializer::Ptr(new Styler(pTarget)); +} diff --git a/WeaselIPC/Styler.h b/WeaselIPC/Styler.h new file mode 100644 index 000000000..089344053 --- /dev/null +++ b/WeaselIPC/Styler.h @@ -0,0 +1,16 @@ +#pragma once + +namespace weasel { + class Deserializr; +} + +class Styler : public weasel::Deserializer +{ +public: + Styler(weasel::ResponseParser* pTarget); + virtual ~Styler(); + // store data + virtual void Store(weasel::Deserializer::KeyType const& key, std::wstring const& value); + // factory method + static weasel::Deserializer::Ptr Create(weasel::ResponseParser* pTarget); +}; diff --git a/WeaselIPC/WeaselClientImpl.h b/WeaselIPC/WeaselClientImpl.h index fad6a8edc..ede5e7dbb 100644 --- a/WeaselIPC/WeaselClientImpl.h +++ b/WeaselIPC/WeaselClientImpl.h @@ -36,16 +36,8 @@ namespace weasel bool _Connected() const { return channel.Connected(); } bool _Active() const { return channel.Connected() && session_id != 0; } - //inline WCHAR* _GetSendBuffer() const { - // return reinterpret_cast(channel.GetBuffer()); - //} - private: UINT session_id; - //HANDLE pipe; - //bool has_cnt; - - //std::unique_ptr buffer; std::wstring app_name; bool is_ime; diff --git a/WeaselIPC/WeaselIPC.vcxproj b/WeaselIPC/WeaselIPC.vcxproj index cd4f4b8a3..d41c3f8b0 100644 --- a/WeaselIPC/WeaselIPC.vcxproj +++ b/WeaselIPC/WeaselIPC.vcxproj @@ -254,6 +254,7 @@ Create Create + @@ -265,6 +266,7 @@ + diff --git a/WeaselIPC/WeaselIPC.vcxproj.filters b/WeaselIPC/WeaselIPC.vcxproj.filters index cf64849ba..4a49f74c3 100644 --- a/WeaselIPC/WeaselIPC.vcxproj.filters +++ b/WeaselIPC/WeaselIPC.vcxproj.filters @@ -48,6 +48,9 @@ Source Files + + Source Files\Deserializer + @@ -83,6 +86,9 @@ Header Files + + Header Files\Deserializer + diff --git a/WeaselIPC/stdafx.h b/WeaselIPC/stdafx.h index 603d1d897..937b37e0c 100644 --- a/WeaselIPC/stdafx.h +++ b/WeaselIPC/stdafx.h @@ -17,6 +17,7 @@ #include #include #include +#include #pragma warning(default: 4819) #pragma warning(default: 4996) @@ -24,5 +25,6 @@ #include #include #include +#include using boost::interprocess::wbufferstream; diff --git a/WeaselUI/SystemTraySDK.cpp b/WeaselServer/SystemTraySDK.cpp similarity index 96% rename from WeaselUI/SystemTraySDK.cpp rename to WeaselServer/SystemTraySDK.cpp index 6c6a53d0e..2ec5c296c 100644 --- a/WeaselUI/SystemTraySDK.cpp +++ b/WeaselServer/SystemTraySDK.cpp @@ -1,1127 +1,1127 @@ -// TrayIcon.cpp: implementation of the CSystemTray class. -// -// NON-MFC VERSION -// -// This class is a light wrapper around the windows system tray stuff. It -// adds an icon to the system tray with the specified ToolTip text and -// callback notification value, which is sent back to the Parent window. -// -// Updated: 21 Sep 2000 - Added GetDoWndAnimation - animation only occurs if the system -// settings allow it (Matthew Ellis). Updated the GetTrayWndRect -// function to include more fallback logic (Matthew Ellis) -// -// Updated: 4 Aug 2003 - Fixed bug that was stopping icon from being recreated when -// Explorer crashed -// Fixed resource leak in SetIcon -// Animate() now checks for empty icon list - Anton Treskunov -// Added the virutal CustomizeMenu() method - Anton Treskunov -// -// 2007-11-14 GONG Chen - made modifications to enable Unicode support. -// -// Written by Chris Maunder (cmaunder@mail.com) -// Copyright (c) 1999-2003. -// -///////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "SystemTraySDK.h" - -#ifdef _DEBUG -#undef THIS_FILE -static char THIS_FILE[]=__FILE__; -#define new DEBUG_NEW -#endif - -#ifndef ASSERT -#include -#define ASSERT assert -#endif - -#ifndef _countof -#define _countof(x) (sizeof(x)/sizeof(x[0])) -#endif - -// 2007-11-14 GONG -//#ifdef _UNICODE -//#error "Unicode not yet suported" -//#endif - -#define TRAYICON_CLASS _T("TrayIconClass") - -// The option here is to maintain a list of all TrayIcon windows, -// and iterate through them, instead of only allowing a single -// TrayIcon per application -CSystemTray* CSystemTray::m_pThis = NULL; - -const UINT_PTR CSystemTray::m_nTimerID = 4567; -UINT CSystemTray::m_nMaxTooltipLength = 64; // This may change... -const UINT CSystemTray::m_nTaskbarCreatedMsg = ::RegisterWindowMessage(_T("TaskbarCreated")); -HWND CSystemTray::m_hWndInvisible; - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CSystemTray::CSystemTray() -{ - Initialise(); -} - -CSystemTray::CSystemTray(HINSTANCE hInst, // Handle to application instance - HWND hParent, // The window that will recieve tray notifications - UINT uCallbackMessage, // the callback message to send to parent - LPCTSTR szToolTip, // tray icon tooltip - HICON icon, // Handle to icon - UINT uID, // Identifier of tray icon - BOOL bHidden /*=FALSE*/, // Hidden on creation? - LPCTSTR szBalloonTip /*=NULL*/, // Ballon tip (w2k only) - LPCTSTR szBalloonTitle /*=NULL*/, // Balloon tip title (w2k) - DWORD dwBalloonIcon /*=NIIF_NONE*/,// Ballon tip icon (w2k) - UINT uBalloonTimeout /*=10*/) // Balloon timeout (w2k) -{ - Initialise(); - Create(hInst, hParent, uCallbackMessage, szToolTip, icon, uID, bHidden, - szBalloonTip, szBalloonTitle, dwBalloonIcon, uBalloonTimeout); -} - -void CSystemTray::Initialise() -{ - // If maintaining a list of all TrayIcon windows (instead of - // only allowing a single TrayIcon per application) then add - // this TrayIcon to the list - m_pThis = this; - - memset(&m_tnd, 0, sizeof(m_tnd)); - m_bEnabled = FALSE; - m_bHidden = TRUE; - m_bRemoved = TRUE; - - m_DefaultMenuItemID = 0; - m_DefaultMenuItemByPos = TRUE; - - m_bShowIconPending = FALSE; - - m_uIDTimer = 0; - m_hSavedIcon = NULL; - - m_hTargetWnd = NULL; - m_uCreationFlags = 0; - -#ifdef SYSTEMTRAY_USEW2K - OSVERSIONINFO os = { sizeof(os) }; - GetVersionEx(&os); - m_bWin2K = ( VER_PLATFORM_WIN32_NT == os.dwPlatformId && os.dwMajorVersion >= 5 ); -#else - m_bWin2K = FALSE; -#endif -} - -ATOM CSystemTray::RegisterClass(HINSTANCE hInstance) -{ - WNDCLASSEX wcex; - - wcex.cbSize = sizeof(WNDCLASSEX); - - wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; - wcex.lpfnWndProc = (WNDPROC)WindowProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInstance; - wcex.hIcon = 0; - wcex.hCursor = 0; - wcex.hbrBackground = 0; - wcex.lpszMenuName = 0; - wcex.lpszClassName = TRAYICON_CLASS; - wcex.hIconSm = 0; - - return RegisterClassEx(&wcex); -} - -BOOL CSystemTray::Create(HINSTANCE hInst, HWND hParent, UINT uCallbackMessage, - LPCTSTR szToolTip, HICON icon, UINT uID, BOOL bHidden /*=FALSE*/, - LPCTSTR szBalloonTip /*=NULL*/, - LPCTSTR szBalloonTitle /*=NULL*/, - DWORD dwBalloonIcon /*=NIIF_NONE*/, - UINT uBalloonTimeout /*=10*/) -{ -#ifdef _WIN32_WCE - m_bEnabled = TRUE; -#else - // this is only for Windows 95 (or higher) - m_bEnabled = (GetVersion() & 0xff) >= 4; - if (!m_bEnabled) - { - ASSERT(FALSE); - return FALSE; - } -#endif - - m_nMaxTooltipLength = _countof(m_tnd.szTip); - - // Make sure we avoid conflict with other messages - ASSERT(uCallbackMessage >= WM_APP); - - // Tray only supports tooltip text up to m_nMaxTooltipLength) characters - ASSERT(_tcslen(szToolTip) <= m_nMaxTooltipLength); - - m_hInstance = hInst; - - RegisterClass(hInst); - - // Create an invisible window - m_hWnd = ::CreateWindow(TRAYICON_CLASS, _T(""), WS_POPUP, - CW_USEDEFAULT,CW_USEDEFAULT, - CW_USEDEFAULT,CW_USEDEFAULT, - NULL, 0, - hInst, 0); - - // load up the NOTIFYICONDATA structure - //m_tnd.cbSize = sizeof(NOTIFYICONDATA); - m_tnd.cbSize = NOTIFYICONDATA_V2_SIZE; // 2012-01-05 GONG Chen, XP compatibility - m_tnd.hWnd = (hParent)? hParent : m_hWnd; - m_tnd.uID = uID; - m_tnd.hIcon = icon; - m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; - m_tnd.uCallbackMessage = uCallbackMessage; - -// 2007-11-14 GONG - _tcsncpy_s(m_tnd.szTip, _countof(m_tnd.szTip), szToolTip, m_nMaxTooltipLength); - -#ifdef SYSTEMTRAY_USEW2K - if (m_bWin2K && szBalloonTip) - { -#if _MSC_VER < 0x1000 - // The balloon tooltip text can be up to 255 chars long. -// ASSERT(AfxIsValidString(szBalloonTip)); - ASSERT(lstrlen(szBalloonTip) < 256); -#endif - - // The balloon title text can be up to 63 chars long. - if (szBalloonTitle) - { -// ASSERT(AfxIsValidString(szBalloonTitle)); - ASSERT(lstrlen(szBalloonTitle) < 64); - } - - // dwBalloonIcon must be valid. - ASSERT(NIIF_NONE == dwBalloonIcon || NIIF_INFO == dwBalloonIcon || - NIIF_WARNING == dwBalloonIcon || NIIF_ERROR == dwBalloonIcon); - - // The timeout must be between 10 and 30 seconds. - ASSERT(uBalloonTimeout >= 10 && uBalloonTimeout <= 30); - - m_tnd.uFlags |= NIF_INFO; - - _tcsncpy_s(m_tnd.szInfo, _countof(m_tnd.szInfo), szBalloonTip, 255); - if (szBalloonTitle) - _tcsncpy_s(m_tnd.szInfoTitle, _countof(m_tnd.szInfoTitle), szBalloonTitle, 63); - else - m_tnd.szInfoTitle[0] = _T('\0'); - m_tnd.uTimeout = uBalloonTimeout * 1000; // convert time to ms - m_tnd.dwInfoFlags = dwBalloonIcon; - } -#endif - - m_bHidden = bHidden; - m_hTargetWnd = m_tnd.hWnd; - -#ifdef SYSTEMTRAY_USEW2K - if (m_bWin2K && m_bHidden) - { - m_tnd.uFlags = NIF_STATE; - m_tnd.dwState = NIS_HIDDEN; - m_tnd.dwStateMask = NIS_HIDDEN; - } -#endif - - m_uCreationFlags = m_tnd.uFlags; // Store in case we need to recreate in OnTaskBarCreate - - BOOL bResult = TRUE; - if (!m_bHidden || m_bWin2K) - { - bResult = Shell_NotifyIcon(NIM_ADD, &m_tnd); - m_bShowIconPending = m_bHidden = m_bRemoved = !bResult; - } - -#ifdef SYSTEMTRAY_USEW2K - if (m_bWin2K && szBalloonTip) - { - // Zero out the balloon text string so that later operations won't redisplay - // the balloon. - m_tnd.szInfo[0] = _T('\0'); - } -#endif - - - return bResult; -} - -CSystemTray::~CSystemTray() -{ - RemoveIcon(); - m_IconList.clear(); - if (m_hWnd) - ::DestroyWindow(m_hWnd); -} - -///////////////////////////////////////////////////////////////////////////// -// CSystemTray icon manipulation - -void CSystemTray::SetFocus() -{ -#ifdef SYSTEMTRAY_USEW2K - Shell_NotifyIcon ( NIM_SETFOCUS, &m_tnd ); -#endif -} - -BOOL CSystemTray::MoveToRight() -{ - RemoveIcon(); - return AddIcon(); -} - -BOOL CSystemTray::AddIcon() -{ - if (!m_bRemoved) - RemoveIcon(); - - if (m_bEnabled) - { - m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; - if (!Shell_NotifyIcon(NIM_ADD, &m_tnd)) - m_bShowIconPending = TRUE; - else - m_bRemoved = m_bHidden = FALSE; - } - return (m_bRemoved == FALSE); -} - -BOOL CSystemTray::RemoveIcon() -{ - m_bShowIconPending = FALSE; - - if (!m_bEnabled || m_bRemoved) - return TRUE; - - m_tnd.uFlags = 0; - if (Shell_NotifyIcon(NIM_DELETE, &m_tnd)) - m_bRemoved = m_bHidden = TRUE; - - return (m_bRemoved == TRUE); -} - -BOOL CSystemTray::HideIcon() -{ - if (!m_bEnabled || m_bRemoved || m_bHidden) - return TRUE; - -#ifdef SYSTEMTRAY_USEW2K - if (m_bWin2K) - { - m_tnd.uFlags = NIF_STATE; - m_tnd.dwState = NIS_HIDDEN; - m_tnd.dwStateMask = NIS_HIDDEN; - - m_bHidden = Shell_NotifyIcon( NIM_MODIFY, &m_tnd); - } - else -#endif - RemoveIcon(); - - return (m_bHidden == TRUE); -} - -BOOL CSystemTray::ShowIcon() -{ - if (m_bRemoved) - return AddIcon(); - - if (!m_bHidden) - return TRUE; - -#ifdef SYSTEMTRAY_USEW2K - if (m_bWin2K) - { - m_tnd.uFlags = NIF_STATE; - m_tnd.dwState = 0; - m_tnd.dwStateMask = NIS_HIDDEN; - Shell_NotifyIcon ( NIM_MODIFY, &m_tnd ); - } - else -#endif - AddIcon(); - - return (m_bHidden == FALSE); -} - -BOOL CSystemTray::SetIcon(HICON hIcon) -{ - if (!m_bEnabled) - return FALSE; - - m_tnd.uFlags = NIF_ICON; - m_tnd.hIcon = hIcon; - - if (m_bHidden) - return TRUE; - else - return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); -} - -BOOL CSystemTray::SetIcon(LPCTSTR lpszIconName) -{ - HICON hIcon = (HICON) ::LoadImage(m_hInstance, - lpszIconName, - IMAGE_ICON, - 0, 0, - LR_LOADFROMFILE); - - if (!hIcon) - return FALSE; - BOOL returnCode = SetIcon(hIcon); - ::DestroyIcon(hIcon); - return returnCode; -} - -BOOL CSystemTray::SetIcon(UINT nIDResource) -{ - HICON hIcon = (HICON) ::LoadImage(m_hInstance, - MAKEINTRESOURCE(nIDResource), - IMAGE_ICON, - 0, 0, - LR_DEFAULTCOLOR); - - BOOL returnCode = SetIcon(hIcon); - ::DestroyIcon(hIcon); - return returnCode; -} - -BOOL CSystemTray::SetStandardIcon(LPCTSTR lpIconName) -{ - HICON hIcon = ::LoadIcon(NULL, lpIconName); - - return SetIcon(hIcon); -} - -BOOL CSystemTray::SetStandardIcon(UINT nIDResource) -{ - HICON hIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(nIDResource)); - - return SetIcon(hIcon); -} - -HICON CSystemTray::GetIcon() const -{ - return (m_bEnabled)? m_tnd.hIcon : NULL; -} - -BOOL CSystemTray::SetIconList(UINT uFirstIconID, UINT uLastIconID) -{ - if (uFirstIconID > uLastIconID) - return FALSE; - - UINT uIconArraySize = uLastIconID - uFirstIconID + 1; - - m_IconList.clear(); - try - { - for (UINT i = uFirstIconID; i <= uLastIconID; i++) - m_IconList.push_back(::LoadIcon(m_hInstance, MAKEINTRESOURCE(i))); - } - catch (...) - { - m_IconList.clear(); - return FALSE; - } - - return TRUE; -} - -BOOL CSystemTray::SetIconList(HICON* pHIconList, UINT nNumIcons) -{ - m_IconList.clear(); - - try { - for (UINT i = 0; i <= nNumIcons; i++) - m_IconList.push_back(pHIconList[i]); - } - catch (...) - { - m_IconList.clear(); - return FALSE; - } - - return TRUE; -} - -BOOL CSystemTray::Animate(UINT nDelayMilliSeconds, int nNumSeconds /*=-1*/) -{ - if (m_IconList.empty()) - return FALSE; - - StopAnimation(); - - m_nCurrentIcon = 0; - time(&m_StartTime); - m_nAnimationPeriod = nNumSeconds; - m_hSavedIcon = GetIcon(); - - // Setup a timer for the animation - m_uIDTimer = ::SetTimer(m_hWnd, m_nTimerID, nDelayMilliSeconds, NULL); - return (m_uIDTimer != 0); -} - -BOOL CSystemTray::StepAnimation() -{ - if (!m_IconList.size()) - return FALSE; - - m_nCurrentIcon++; - if (m_nCurrentIcon >= (int)m_IconList.size()) - m_nCurrentIcon = 0; - - return SetIcon(m_IconList[m_nCurrentIcon]); -} - -BOOL CSystemTray::StopAnimation() -{ - BOOL bResult = FALSE; - - if (m_uIDTimer) - bResult = ::KillTimer(m_hWnd, m_uIDTimer); - m_uIDTimer = 0; - - if (m_hSavedIcon) - SetIcon(m_hSavedIcon); - m_hSavedIcon = NULL; - - return bResult; -} - -///////////////////////////////////////////////////////////////////////////// -// CSystemTray tooltip text manipulation - -BOOL CSystemTray::SetTooltipText(LPCTSTR pszTip) -{ - ASSERT(_tcslen(pszTip) < m_nMaxTooltipLength); - - if (!m_bEnabled) - return FALSE; - - m_tnd.uFlags = NIF_TIP; - _tcsncpy_s(m_tnd.szTip, _countof(m_tnd.szTip), pszTip, m_nMaxTooltipLength-1); - - if (m_bHidden) - return TRUE; - else - return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); -} - -BOOL CSystemTray::SetTooltipText(UINT nID) -{ - TCHAR strBuffer[1024]; - ASSERT(1024 >= m_nMaxTooltipLength); - - if (!LoadString(m_hInstance, nID, strBuffer, m_nMaxTooltipLength-1)) - return FALSE; - - return SetTooltipText(strBuffer); -} - -LPTSTR CSystemTray::GetTooltipText() const -{ - if (!m_bEnabled) - return FALSE; - - static TCHAR strBuffer[1024]; - ASSERT(1024 >= m_nMaxTooltipLength); - -// 2007-11-14 GONG -//#ifdef _UNICODE -// strBuffer[0] = _T('\0'); -// MultiByteToWideChar(CP_ACP, 0, m_tnd.szTip, -1, strBuffer, m_nMaxTooltipLength, NULL, NULL); -//#else -// strncpy(strBuffer, m_tnd.szTip, m_nMaxTooltipLength-1); -//#endif - _tcsncpy_s(strBuffer, _countof(strBuffer), m_tnd.szTip, m_nMaxTooltipLength-1); - - return strBuffer; -} - -////////////////////////////////////////////////////////////////////////// -// -// Function: ShowBalloon -// -// Description: -// Shows a balloon tooltip over the tray icon. -// -// Input: -// szText: [in] Text for the balloon tooltip. -// szTitle: [in] Title for the balloon. This text is shown in bold above -// the tooltip text (szText). Pass "" if you don't want a title. -// dwIcon: [in] Specifies an icon to appear in the balloon. Legal values are: -// NIIF_NONE: No icon -// NIIF_INFO: Information -// NIIF_WARNING: Exclamation -// NIIF_ERROR: Critical error (red circle with X) -// uTimeout: [in] Number of seconds for the balloon to remain visible. Can -// be between 10 and 30 inclusive. -// -// Returns: -// TRUE if successful, FALSE if not. -// -////////////////////////////////////////////////////////////////////////// -// Added by Michael Dunn, November 1999 -////////////////////////////////////////////////////////////////////////// - -BOOL CSystemTray::ShowBalloon(LPCTSTR szText, - LPCTSTR szTitle /*=NULL*/, - DWORD dwIcon /*=NIIF_NONE*/, - UINT uTimeout /*=10*/ ) -{ -#ifndef SYSTEMTRAY_USEW2K - return FALSE; -#else - // Bail out if we're not on Win 2K. - if (!m_bWin2K) - return FALSE; - - // Verify input parameters. - - // The balloon tooltip text can be up to 255 chars long. -// ASSERT(AfxIsValidString(szText)); - ASSERT(lstrlen(szText) < 256); - - // The balloon title text can be up to 63 chars long. - if (szTitle) - { -// ASSERT(AfxIsValidString( szTitle)); - ASSERT(lstrlen(szTitle) < 64); - } - - // dwBalloonIcon must be valid. - ASSERT(NIIF_NONE == dwIcon || NIIF_INFO == dwIcon || - NIIF_WARNING == dwIcon || NIIF_ERROR == dwIcon); - - // The timeout must be between 10 and 30 seconds. - ASSERT(uTimeout >= 10 && uTimeout <= 30); - - - m_tnd.uFlags = NIF_INFO; - _tcsncpy_s(m_tnd.szInfo, _countof(m_tnd.szInfo), szText, 256); - if (szTitle) - _tcsncpy_s(m_tnd.szInfoTitle, _countof(m_tnd.szInfoTitle), szTitle, 64); - else - m_tnd.szInfoTitle[0] = _T('\0'); - m_tnd.dwInfoFlags = dwIcon; - m_tnd.uTimeout = uTimeout * 1000; // convert time to ms - - BOOL bSuccess = Shell_NotifyIcon (NIM_MODIFY, &m_tnd); - - // Zero out the balloon text string so that later operations won't redisplay - // the balloon. - m_tnd.szInfo[0] = _T('\0'); - - return bSuccess; -#endif -} - -///////////////////////////////////////////////////////////////////////////// -// CSystemTray notification window stuff - -BOOL CSystemTray::SetNotificationWnd(HWND hNotifyWnd) -{ - if (!m_bEnabled) - return FALSE; - - // Make sure Notification window is valid - if (!hNotifyWnd || !::IsWindow(hNotifyWnd)) - { - ASSERT(FALSE); - return FALSE; - } - - m_tnd.hWnd = hNotifyWnd; - m_tnd.uFlags = 0; - - if (m_bHidden) - return TRUE; - else - return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); -} - -HWND CSystemTray::GetNotificationWnd() const -{ - return m_tnd.hWnd; -} - -// Hatr added - -// Change or retrive the window to send menu commands to -BOOL CSystemTray::SetTargetWnd(HWND hTargetWnd) -{ - m_hTargetWnd = hTargetWnd; - return TRUE; -} // CSystemTray::SetTargetWnd() - -HWND CSystemTray::GetTargetWnd() const -{ - if (m_hTargetWnd) - return m_hTargetWnd; - else - return m_tnd.hWnd; -} // CSystemTray::GetTargetWnd() - -///////////////////////////////////////////////////////////////////////////// -// CSystemTray notification message stuff - -BOOL CSystemTray::SetCallbackMessage(UINT uCallbackMessage) -{ - if (!m_bEnabled) - return FALSE; - - // Make sure we avoid conflict with other messages - ASSERT(uCallbackMessage >= WM_APP); - - m_tnd.uCallbackMessage = uCallbackMessage; - m_tnd.uFlags = NIF_MESSAGE; - - if (m_bHidden) - return TRUE; - else - return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); -} - -UINT CSystemTray::GetCallbackMessage() const -{ - return m_tnd.uCallbackMessage; -} - -///////////////////////////////////////////////////////////////////////////// -// CSystemTray menu manipulation - -BOOL CSystemTray::SetMenuDefaultItem(UINT uItem, BOOL bByPos) -{ -#ifdef _WIN32_WCE - return FALSE; -#else - if ((m_DefaultMenuItemID == uItem) && (m_DefaultMenuItemByPos == bByPos)) - return TRUE; - - m_DefaultMenuItemID = uItem; - m_DefaultMenuItemByPos = bByPos; - - HMENU hMenu = ::LoadMenu(m_hInstance, MAKEINTRESOURCE(m_tnd.uID)); - if (!hMenu) - return FALSE; - - HMENU hSubMenu = ::GetSubMenu(hMenu, 0); - if (!hSubMenu) - { - ::DestroyMenu(hMenu); - return FALSE; - } - - ::SetMenuDefaultItem(hSubMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos); - - ::DestroyMenu(hSubMenu); - ::DestroyMenu(hMenu); - - return TRUE; -#endif -} - -void CSystemTray::GetMenuDefaultItem(UINT& uItem, BOOL& bByPos) -{ - uItem = m_DefaultMenuItemID; - bByPos = m_DefaultMenuItemByPos; -} - -///////////////////////////////////////////////////////////////////////////// -// CSystemTray message handlers - -/* If we were in MFC this is what we'd use... -BEGIN_MESSAGE_MAP(CSystemTray, CWnd) - //{{AFX_MSG_MAP(CSystemTray) - ON_WM_TIMER() - //}}AFX_MSG_MAP -#ifndef _WIN32_WCE - ON_WM_SETTINGCHANGE() -#endif - ON_REGISTERED_MESSAGE(WM_TASKBARCREATED, OnTaskbarCreated) -END_MESSAGE_MAP() -*/ - -LRESULT CSystemTray::OnTimer(UINT nIDEvent) -{ - if (nIDEvent != m_uIDTimer) - { - ASSERT(FALSE); - return 0L; - } - - time_t CurrentTime; - time(&CurrentTime); - - time_t period = CurrentTime - m_StartTime; - if (m_nAnimationPeriod > 0 && m_nAnimationPeriod < period) - { - StopAnimation(); - return 0L; - } - - StepAnimation(); - - return 0L; -} - -// This is called whenever the taskbar is created (eg after explorer crashes -// and restarts. Please note that the WM_TASKBARCREATED message is only passed -// to TOP LEVEL windows (like WM_QUERYNEWPALETTE) -LRESULT CSystemTray::OnTaskbarCreated(WPARAM wParam, LPARAM lParam) -{ - InstallIconPending(); - return 0L; -} - -#ifndef _WIN32_WCE -LRESULT CSystemTray::OnSettingChange(UINT uFlags, LPCTSTR lpszSection) -{ - if (uFlags == SPI_SETWORKAREA) - InstallIconPending(); - return 0L; -} -#endif - -LRESULT CSystemTray::OnTrayNotification(WPARAM wParam, LPARAM lParam) -{ - //Return quickly if its not for this tray icon - if (wParam != m_tnd.uID) - return 0L; - - HWND hTargetWnd = GetTargetWnd(); - if (!hTargetWnd) - return 0L; - - // Clicking with right button brings up a context menu -#if defined(_WIN32_WCE) //&& _WIN32_WCE < 211 - BOOL bAltPressed = ((GetKeyState(VK_MENU) & (1 << (sizeof(SHORT)*8-1))) != 0); - if (LOWORD(lParam) == WM_LBUTTONUP && bAltPressed) -#else - if (LOWORD(lParam) == WM_RBUTTONUP) -#endif - { - HMENU hMenu = ::LoadMenu(m_hInstance, MAKEINTRESOURCE(m_tnd.uID)); - if (!hMenu) - return 0; - - HMENU hSubMenu = ::GetSubMenu(hMenu, 0); - if (!hSubMenu) - { - ::DestroyMenu(hMenu); //Be sure to Destroy Menu Before Returning - return 0; - } - -#ifndef _WIN32_WCE - // Make chosen menu item the default (bold font) - ::SetMenuDefaultItem(hSubMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos); -#endif - - CustomizeMenu(hSubMenu); - - // Display and track the popup menu - POINT pos; -#ifdef _WIN32_WCE - DWORD messagepos = ::GetMessagePos(); - pos.x = GET_X_LPARAM(messagepos); - pos.y = GET_Y_LPARAM(messagepos); -#else - GetCursorPos(&pos); -#endif - - ::SetForegroundWindow(m_tnd.hWnd); - ::TrackPopupMenu(hSubMenu, 0, pos.x, pos.y, 0, hTargetWnd, NULL); - - // BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly" - ::PostMessage(m_tnd.hWnd, WM_NULL, 0, 0); - - DestroyMenu(hMenu); - } -#if defined(_WIN32_WCE) //&& _WIN32_WCE < 211 - if (LOWORD(lParam) == WM_LBUTTONDBLCLK && bAltPressed) -#else - else if (LOWORD(lParam) == WM_LBUTTONDBLCLK) -#endif - { - // double click received, the default action is to execute default menu item - ::SetForegroundWindow(m_tnd.hWnd); - - UINT uItem; - if (m_DefaultMenuItemByPos) - { - HMENU hMenu = ::LoadMenu(m_hInstance, MAKEINTRESOURCE(m_tnd.uID)); - if (!hMenu) - return 0; - - HMENU hSubMenu = ::GetSubMenu(hMenu, 0); - if (!hSubMenu) - return 0; - uItem = ::GetMenuItemID(hSubMenu, m_DefaultMenuItemID); - - DestroyMenu(hMenu); - } - else - uItem = m_DefaultMenuItemID; - - ::PostMessage(hTargetWnd, WM_COMMAND, uItem, 0); - } - - return 1; -} - -// This is the global (static) callback function for all TrayIcon windows -LRESULT PASCAL CSystemTray::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // The option here is to maintain a list of all TrayIcon windows, - // and iterate through them. If you do this, remove these 3 lines. - CSystemTray* pTrayIcon = m_pThis; - if (pTrayIcon->GetSafeHwnd() != hWnd) - return ::DefWindowProc(hWnd, message, wParam, lParam); - - // If maintaining a list of TrayIcon windows, then the following... - // pTrayIcon = GetFirstTrayIcon() - // while (pTrayIcon != NULL) - // { - // if (pTrayIcon->GetSafeHwnd() != hWnd) continue; - - // Taskbar has been recreated - all TrayIcons must process this. - if (message == CSystemTray::m_nTaskbarCreatedMsg) - return pTrayIcon->OnTaskbarCreated(wParam, lParam); - - // Animation timer - if (message == WM_TIMER && wParam == pTrayIcon->GetTimerID()) - return pTrayIcon->OnTimer(wParam); - - // Settings changed - if (message == WM_SETTINGCHANGE && wParam == pTrayIcon->GetTimerID()) - return pTrayIcon->OnSettingChange(wParam, (LPCTSTR) lParam); - - // Is the message from the icon for this TrayIcon? - if (message == pTrayIcon->GetCallbackMessage()) - return pTrayIcon->OnTrayNotification(wParam, lParam); - - // pTrayIcon = GetNextTrayIcon(); - // } - - // Message has not been processed, so default. - return ::DefWindowProc(hWnd, message, wParam, lParam); -} - -void CSystemTray::InstallIconPending() -{ - // Is the icon display pending, and it's not been set as "hidden"? - if (!m_bShowIconPending || m_bHidden) - return; - - // Reset the flags to what was used at creation - m_tnd.uFlags = m_uCreationFlags; - - // Try and recreate the icon - m_bHidden = !Shell_NotifyIcon(NIM_ADD, &m_tnd); - - // If it's STILL hidden, then have another go next time... - m_bShowIconPending = !m_bHidden; - - ASSERT(m_bHidden == FALSE); -} - -///////////////////////////////////////////////////////////////////////////// -// For minimising/maximising from system tray - -BOOL CALLBACK FindTrayWnd(HWND hwnd, LPARAM lParam) -{ - TCHAR szClassName[256]; - GetClassName(hwnd, szClassName, 255); - - // Did we find the Main System Tray? If so, then get its size and keep going - if (_tcscmp(szClassName, _T("TrayNotifyWnd")) == 0) - { - LPRECT lpRect = (LPRECT) lParam; - ::GetWindowRect(hwnd, lpRect); - return TRUE; - } - - // Did we find the System Clock? If so, then adjust the size of the rectangle - // we have and quit (clock will be found after the system tray) - if (_tcscmp(szClassName, _T("TrayClockWClass")) == 0) - { - LPRECT lpRect = (LPRECT) lParam; - RECT rectClock; - ::GetWindowRect(hwnd, &rectClock); - // if clock is above system tray adjust accordingly - if (rectClock.bottom < lpRect->bottom-5) // 10 = random fudge factor. - lpRect->top = rectClock.bottom; - else - lpRect->right = rectClock.left; - return FALSE; - } - - return TRUE; -} - -#ifndef _WIN32_WCE -void CSystemTray::GetTrayWndRect(LPRECT lprect) -{ -#define DEFAULT_RECT_WIDTH 150 -#define DEFAULT_RECT_HEIGHT 30 - - HWND hShellTrayWnd = FindWindow(_T("Shell_TrayWnd"), NULL); - if (hShellTrayWnd) - { - GetWindowRect(hShellTrayWnd, lprect); - EnumChildWindows(hShellTrayWnd, FindTrayWnd, (LPARAM)lprect); - return; - } - // OK, we failed to get the rect from the quick hack. Either explorer isn't - // running or it's a new version of the shell with the window class names - // changed (how dare Microsoft change these undocumented class names!) So, we - // try to find out what side of the screen the taskbar is connected to. We - // know that the system tray is either on the right or the bottom of the - // taskbar, so we can make a good guess at where to minimize to - APPBARDATA appBarData; - appBarData.cbSize=sizeof(appBarData); - if (SHAppBarMessage(ABM_GETTASKBARPOS,&appBarData)) - { - // We know the edge the taskbar is connected to, so guess the rect of the - // system tray. Use various fudge factor to make it look good - switch(appBarData.uEdge) - { - case ABE_LEFT: - case ABE_RIGHT: - // We want to minimize to the bottom of the taskbar - lprect->top = appBarData.rc.bottom-100; - lprect->bottom = appBarData.rc.bottom-16; - lprect->left = appBarData.rc.left; - lprect->right = appBarData.rc.right; - break; - - case ABE_TOP: - case ABE_BOTTOM: - // We want to minimize to the right of the taskbar - lprect->top = appBarData.rc.top; - lprect->bottom = appBarData.rc.bottom; - lprect->left = appBarData.rc.right-100; - lprect->right = appBarData.rc.right-16; - break; - } - return; - } - - // Blimey, we really aren't in luck. It's possible that a third party shell - // is running instead of explorer. This shell might provide support for the - // system tray, by providing a Shell_TrayWnd window (which receives the - // messages for the icons) So, look for a Shell_TrayWnd window and work out - // the rect from that. Remember that explorer's taskbar is the Shell_TrayWnd, - // and stretches either the width or the height of the screen. We can't rely - // on the 3rd party shell's Shell_TrayWnd doing the same, in fact, we can't - // rely on it being any size. The best we can do is just blindly use the - // window rect, perhaps limiting the width and height to, say 150 square. - // Note that if the 3rd party shell supports the same configuraion as - // explorer (the icons hosted in NotifyTrayWnd, which is a child window of - // Shell_TrayWnd), we would already have caught it above - if (hShellTrayWnd) - { - ::GetWindowRect(hShellTrayWnd, lprect); - if (lprect->right - lprect->left > DEFAULT_RECT_WIDTH) - lprect->left = lprect->right - DEFAULT_RECT_WIDTH; - if (lprect->bottom - lprect->top > DEFAULT_RECT_HEIGHT) - lprect->top = lprect->bottom - DEFAULT_RECT_HEIGHT; - - return; - } - - // OK. Haven't found a thing. Provide a default rect based on the current work - // area - SystemParametersInfo(SPI_GETWORKAREA,0,lprect, 0); - lprect->left = lprect->right - DEFAULT_RECT_WIDTH; - lprect->top = lprect->bottom - DEFAULT_RECT_HEIGHT; -} - -// Check to see if the animation has been disabled (Matthew Ellis ) -BOOL CSystemTray::GetDoWndAnimation() -{ - ANIMATIONINFO ai; - - ai.cbSize=sizeof(ai); - SystemParametersInfo(SPI_GETANIMATION,sizeof(ai),&ai,0); - - return ai.iMinAnimate?TRUE:FALSE; -} -#endif - -BOOL CSystemTray::RemoveTaskbarIcon(HWND hWnd) -{ - // Create static invisible window - if (!::IsWindow(m_hWndInvisible)) - { -// 2007-11-14 GONG - m_hWndInvisible = CreateWindowEx(0, _T("Static"), _T(""), WS_POPUP, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL, 0, NULL, 0); - - if (!m_hWndInvisible) - return FALSE; - } - - SetParent(hWnd, m_hWndInvisible); - - return TRUE; -} - -void CSystemTray::MinimiseToTray(HWND hWnd) -{ -#ifndef _WIN32_WCE - if (GetDoWndAnimation()) - { - RECT rectFrom, rectTo; - - GetWindowRect(hWnd, &rectFrom); - GetTrayWndRect(&rectTo); - - DrawAnimatedRects(hWnd, IDANI_CAPTION, &rectFrom, &rectTo); - } - - RemoveTaskbarIcon(hWnd); - SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) &~ WS_VISIBLE); -#endif -} - -void CSystemTray::MaximiseFromTray(HWND hWnd) -{ -#ifndef _WIN32_WCE - if (GetDoWndAnimation()) - { - RECT rectTo; - ::GetWindowRect(hWnd, &rectTo); - - RECT rectFrom; - GetTrayWndRect(&rectFrom); - - ::SetParent(hWnd, NULL); - DrawAnimatedRects(hWnd, IDANI_CAPTION, &rectFrom, &rectTo); - } - else - ::SetParent(hWnd, NULL); - - SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) | WS_VISIBLE); - RedrawWindow(hWnd, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME | - RDW_INVALIDATE | RDW_ERASE); - - // Move focus away and back again to ensure taskbar icon is recreated - if (::IsWindow(m_hWndInvisible)) - SetActiveWindow(m_hWndInvisible); - SetActiveWindow(hWnd); - SetForegroundWindow(hWnd); -#endif +// TrayIcon.cpp: implementation of the CSystemTray class. +// +// NON-MFC VERSION +// +// This class is a light wrapper around the windows system tray stuff. It +// adds an icon to the system tray with the specified ToolTip text and +// callback notification value, which is sent back to the Parent window. +// +// Updated: 21 Sep 2000 - Added GetDoWndAnimation - animation only occurs if the system +// settings allow it (Matthew Ellis). Updated the GetTrayWndRect +// function to include more fallback logic (Matthew Ellis) +// +// Updated: 4 Aug 2003 - Fixed bug that was stopping icon from being recreated when +// Explorer crashed +// Fixed resource leak in SetIcon +// Animate() now checks for empty icon list - Anton Treskunov +// Added the virutal CustomizeMenu() method - Anton Treskunov +// +// 2007-11-14 GONG Chen - made modifications to enable Unicode support. +// +// Written by Chris Maunder (cmaunder@mail.com) +// Copyright (c) 1999-2003. +// +///////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "SystemTraySDK.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char THIS_FILE[]=__FILE__; +#define new DEBUG_NEW +#endif + +#ifndef ASSERT +#include +#define ASSERT assert +#endif + +#ifndef _countof +#define _countof(x) (sizeof(x)/sizeof(x[0])) +#endif + +// 2007-11-14 GONG +//#ifdef _UNICODE +//#error "Unicode not yet suported" +//#endif + +#define TRAYICON_CLASS _T("TrayIconClass") + +// The option here is to maintain a list of all TrayIcon windows, +// and iterate through them, instead of only allowing a single +// TrayIcon per application +CSystemTray* CSystemTray::m_pThis = NULL; + +const UINT_PTR CSystemTray::m_nTimerID = 4567; +UINT CSystemTray::m_nMaxTooltipLength = 64; // This may change... +const UINT CSystemTray::m_nTaskbarCreatedMsg = ::RegisterWindowMessage(_T("TaskbarCreated")); +HWND CSystemTray::m_hWndInvisible; + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CSystemTray::CSystemTray() +{ + Initialise(); +} + +CSystemTray::CSystemTray(HINSTANCE hInst, // Handle to application instance + HWND hParent, // The window that will recieve tray notifications + UINT uCallbackMessage, // the callback message to send to parent + LPCTSTR szToolTip, // tray icon tooltip + HICON icon, // Handle to icon + UINT uID, // Identifier of tray icon + BOOL bHidden /*=FALSE*/, // Hidden on creation? + LPCTSTR szBalloonTip /*=NULL*/, // Ballon tip (w2k only) + LPCTSTR szBalloonTitle /*=NULL*/, // Balloon tip title (w2k) + DWORD dwBalloonIcon /*=NIIF_NONE*/,// Ballon tip icon (w2k) + UINT uBalloonTimeout /*=10*/) // Balloon timeout (w2k) +{ + Initialise(); + Create(hInst, hParent, uCallbackMessage, szToolTip, icon, uID, bHidden, + szBalloonTip, szBalloonTitle, dwBalloonIcon, uBalloonTimeout); +} + +void CSystemTray::Initialise() +{ + // If maintaining a list of all TrayIcon windows (instead of + // only allowing a single TrayIcon per application) then add + // this TrayIcon to the list + m_pThis = this; + + memset(&m_tnd, 0, sizeof(m_tnd)); + m_bEnabled = FALSE; + m_bHidden = TRUE; + m_bRemoved = TRUE; + + m_DefaultMenuItemID = 0; + m_DefaultMenuItemByPos = TRUE; + + m_bShowIconPending = FALSE; + + m_uIDTimer = 0; + m_hSavedIcon = NULL; + + m_hTargetWnd = NULL; + m_uCreationFlags = 0; + +#ifdef SYSTEMTRAY_USEW2K + OSVERSIONINFO os = { sizeof(os) }; + GetVersionEx(&os); + m_bWin2K = ( VER_PLATFORM_WIN32_NT == os.dwPlatformId && os.dwMajorVersion >= 5 ); +#else + m_bWin2K = FALSE; +#endif +} + +ATOM CSystemTray::RegisterClass(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + wcex.lpfnWndProc = (WNDPROC)WindowProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = 0; + wcex.hCursor = 0; + wcex.hbrBackground = 0; + wcex.lpszMenuName = 0; + wcex.lpszClassName = TRAYICON_CLASS; + wcex.hIconSm = 0; + + return RegisterClassEx(&wcex); +} + +BOOL CSystemTray::Create(HINSTANCE hInst, HWND hParent, UINT uCallbackMessage, + LPCTSTR szToolTip, HICON icon, UINT uID, BOOL bHidden /*=FALSE*/, + LPCTSTR szBalloonTip /*=NULL*/, + LPCTSTR szBalloonTitle /*=NULL*/, + DWORD dwBalloonIcon /*=NIIF_NONE*/, + UINT uBalloonTimeout /*=10*/) +{ +#ifdef _WIN32_WCE + m_bEnabled = TRUE; +#else + // this is only for Windows 95 (or higher) + m_bEnabled = (GetVersion() & 0xff) >= 4; + if (!m_bEnabled) + { + ASSERT(FALSE); + return FALSE; + } +#endif + + m_nMaxTooltipLength = _countof(m_tnd.szTip); + + // Make sure we avoid conflict with other messages + ASSERT(uCallbackMessage >= WM_APP); + + // Tray only supports tooltip text up to m_nMaxTooltipLength) characters + ASSERT(_tcslen(szToolTip) <= m_nMaxTooltipLength); + + m_hInstance = hInst; + + RegisterClass(hInst); + + // Create an invisible window + m_hWnd = ::CreateWindow(TRAYICON_CLASS, _T(""), WS_POPUP, + CW_USEDEFAULT,CW_USEDEFAULT, + CW_USEDEFAULT,CW_USEDEFAULT, + NULL, 0, + hInst, 0); + + // load up the NOTIFYICONDATA structure + //m_tnd.cbSize = sizeof(NOTIFYICONDATA); + m_tnd.cbSize = NOTIFYICONDATA_V2_SIZE; // 2012-01-05 GONG Chen, XP compatibility + m_tnd.hWnd = (hParent)? hParent : m_hWnd; + m_tnd.uID = uID; + m_tnd.hIcon = icon; + m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + m_tnd.uCallbackMessage = uCallbackMessage; + +// 2007-11-14 GONG + _tcsncpy_s(m_tnd.szTip, _countof(m_tnd.szTip), szToolTip, m_nMaxTooltipLength); + +#ifdef SYSTEMTRAY_USEW2K + if (m_bWin2K && szBalloonTip) + { +#if _MSC_VER < 0x1000 + // The balloon tooltip text can be up to 255 chars long. +// ASSERT(AfxIsValidString(szBalloonTip)); + ASSERT(lstrlen(szBalloonTip) < 256); +#endif + + // The balloon title text can be up to 63 chars long. + if (szBalloonTitle) + { +// ASSERT(AfxIsValidString(szBalloonTitle)); + ASSERT(lstrlen(szBalloonTitle) < 64); + } + + // dwBalloonIcon must be valid. + ASSERT(NIIF_NONE == dwBalloonIcon || NIIF_INFO == dwBalloonIcon || + NIIF_WARNING == dwBalloonIcon || NIIF_ERROR == dwBalloonIcon); + + // The timeout must be between 10 and 30 seconds. + ASSERT(uBalloonTimeout >= 10 && uBalloonTimeout <= 30); + + m_tnd.uFlags |= NIF_INFO; + + _tcsncpy_s(m_tnd.szInfo, _countof(m_tnd.szInfo), szBalloonTip, 255); + if (szBalloonTitle) + _tcsncpy_s(m_tnd.szInfoTitle, _countof(m_tnd.szInfoTitle), szBalloonTitle, 63); + else + m_tnd.szInfoTitle[0] = _T('\0'); + m_tnd.uTimeout = uBalloonTimeout * 1000; // convert time to ms + m_tnd.dwInfoFlags = dwBalloonIcon; + } +#endif + + m_bHidden = bHidden; + m_hTargetWnd = m_tnd.hWnd; + +#ifdef SYSTEMTRAY_USEW2K + if (m_bWin2K && m_bHidden) + { + m_tnd.uFlags = NIF_STATE; + m_tnd.dwState = NIS_HIDDEN; + m_tnd.dwStateMask = NIS_HIDDEN; + } +#endif + + m_uCreationFlags = m_tnd.uFlags; // Store in case we need to recreate in OnTaskBarCreate + + BOOL bResult = TRUE; + if (!m_bHidden || m_bWin2K) + { + bResult = Shell_NotifyIcon(NIM_ADD, &m_tnd); + m_bShowIconPending = m_bHidden = m_bRemoved = !bResult; + } + +#ifdef SYSTEMTRAY_USEW2K + if (m_bWin2K && szBalloonTip) + { + // Zero out the balloon text string so that later operations won't redisplay + // the balloon. + m_tnd.szInfo[0] = _T('\0'); + } +#endif + + + return bResult; +} + +CSystemTray::~CSystemTray() +{ + RemoveIcon(); + m_IconList.clear(); + if (m_hWnd) + ::DestroyWindow(m_hWnd); +} + +///////////////////////////////////////////////////////////////////////////// +// CSystemTray icon manipulation + +void CSystemTray::SetFocus() +{ +#ifdef SYSTEMTRAY_USEW2K + Shell_NotifyIcon ( NIM_SETFOCUS, &m_tnd ); +#endif +} + +BOOL CSystemTray::MoveToRight() +{ + RemoveIcon(); + return AddIcon(); +} + +BOOL CSystemTray::AddIcon() +{ + if (!m_bRemoved) + RemoveIcon(); + + if (m_bEnabled) + { + m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + if (!Shell_NotifyIcon(NIM_ADD, &m_tnd)) + m_bShowIconPending = TRUE; + else + m_bRemoved = m_bHidden = FALSE; + } + return (m_bRemoved == FALSE); +} + +BOOL CSystemTray::RemoveIcon() +{ + m_bShowIconPending = FALSE; + + if (!m_bEnabled || m_bRemoved) + return TRUE; + + m_tnd.uFlags = 0; + if (Shell_NotifyIcon(NIM_DELETE, &m_tnd)) + m_bRemoved = m_bHidden = TRUE; + + return (m_bRemoved == TRUE); +} + +BOOL CSystemTray::HideIcon() +{ + if (!m_bEnabled || m_bRemoved || m_bHidden) + return TRUE; + +#ifdef SYSTEMTRAY_USEW2K + if (m_bWin2K) + { + m_tnd.uFlags = NIF_STATE; + m_tnd.dwState = NIS_HIDDEN; + m_tnd.dwStateMask = NIS_HIDDEN; + + m_bHidden = Shell_NotifyIcon( NIM_MODIFY, &m_tnd); + } + else +#endif + RemoveIcon(); + + return (m_bHidden == TRUE); +} + +BOOL CSystemTray::ShowIcon() +{ + if (m_bRemoved) + return AddIcon(); + + if (!m_bHidden) + return TRUE; + +#ifdef SYSTEMTRAY_USEW2K + if (m_bWin2K) + { + m_tnd.uFlags = NIF_STATE; + m_tnd.dwState = 0; + m_tnd.dwStateMask = NIS_HIDDEN; + Shell_NotifyIcon ( NIM_MODIFY, &m_tnd ); + } + else +#endif + AddIcon(); + + return (m_bHidden == FALSE); +} + +BOOL CSystemTray::SetIcon(HICON hIcon) +{ + if (!m_bEnabled) + return FALSE; + + m_tnd.uFlags = NIF_ICON; + m_tnd.hIcon = hIcon; + + if (m_bHidden) + return TRUE; + else + return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); +} + +BOOL CSystemTray::SetIcon(LPCTSTR lpszIconName) +{ + HICON hIcon = (HICON) ::LoadImage(m_hInstance, + lpszIconName, + IMAGE_ICON, + 0, 0, + LR_LOADFROMFILE); + + if (!hIcon) + return FALSE; + BOOL returnCode = SetIcon(hIcon); + ::DestroyIcon(hIcon); + return returnCode; +} + +BOOL CSystemTray::SetIcon(UINT nIDResource) +{ + HICON hIcon = (HICON) ::LoadImage(m_hInstance, + MAKEINTRESOURCE(nIDResource), + IMAGE_ICON, + 0, 0, + LR_DEFAULTCOLOR); + + BOOL returnCode = SetIcon(hIcon); + ::DestroyIcon(hIcon); + return returnCode; +} + +BOOL CSystemTray::SetStandardIcon(LPCTSTR lpIconName) +{ + HICON hIcon = ::LoadIcon(NULL, lpIconName); + + return SetIcon(hIcon); +} + +BOOL CSystemTray::SetStandardIcon(UINT nIDResource) +{ + HICON hIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(nIDResource)); + + return SetIcon(hIcon); +} + +HICON CSystemTray::GetIcon() const +{ + return (m_bEnabled)? m_tnd.hIcon : NULL; +} + +BOOL CSystemTray::SetIconList(UINT uFirstIconID, UINT uLastIconID) +{ + if (uFirstIconID > uLastIconID) + return FALSE; + + UINT uIconArraySize = uLastIconID - uFirstIconID + 1; + + m_IconList.clear(); + try + { + for (UINT i = uFirstIconID; i <= uLastIconID; i++) + m_IconList.push_back(::LoadIcon(m_hInstance, MAKEINTRESOURCE(i))); + } + catch (...) + { + m_IconList.clear(); + return FALSE; + } + + return TRUE; +} + +BOOL CSystemTray::SetIconList(HICON* pHIconList, UINT nNumIcons) +{ + m_IconList.clear(); + + try { + for (UINT i = 0; i <= nNumIcons; i++) + m_IconList.push_back(pHIconList[i]); + } + catch (...) + { + m_IconList.clear(); + return FALSE; + } + + return TRUE; +} + +BOOL CSystemTray::Animate(UINT nDelayMilliSeconds, int nNumSeconds /*=-1*/) +{ + if (m_IconList.empty()) + return FALSE; + + StopAnimation(); + + m_nCurrentIcon = 0; + time(&m_StartTime); + m_nAnimationPeriod = nNumSeconds; + m_hSavedIcon = GetIcon(); + + // Setup a timer for the animation + m_uIDTimer = ::SetTimer(m_hWnd, m_nTimerID, nDelayMilliSeconds, NULL); + return (m_uIDTimer != 0); +} + +BOOL CSystemTray::StepAnimation() +{ + if (!m_IconList.size()) + return FALSE; + + m_nCurrentIcon++; + if (m_nCurrentIcon >= (int)m_IconList.size()) + m_nCurrentIcon = 0; + + return SetIcon(m_IconList[m_nCurrentIcon]); +} + +BOOL CSystemTray::StopAnimation() +{ + BOOL bResult = FALSE; + + if (m_uIDTimer) + bResult = ::KillTimer(m_hWnd, m_uIDTimer); + m_uIDTimer = 0; + + if (m_hSavedIcon) + SetIcon(m_hSavedIcon); + m_hSavedIcon = NULL; + + return bResult; +} + +///////////////////////////////////////////////////////////////////////////// +// CSystemTray tooltip text manipulation + +BOOL CSystemTray::SetTooltipText(LPCTSTR pszTip) +{ + ASSERT(_tcslen(pszTip) < m_nMaxTooltipLength); + + if (!m_bEnabled) + return FALSE; + + m_tnd.uFlags = NIF_TIP; + _tcsncpy_s(m_tnd.szTip, _countof(m_tnd.szTip), pszTip, m_nMaxTooltipLength-1); + + if (m_bHidden) + return TRUE; + else + return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); +} + +BOOL CSystemTray::SetTooltipText(UINT nID) +{ + TCHAR strBuffer[1024]; + ASSERT(1024 >= m_nMaxTooltipLength); + + if (!LoadString(m_hInstance, nID, strBuffer, m_nMaxTooltipLength-1)) + return FALSE; + + return SetTooltipText(strBuffer); +} + +LPTSTR CSystemTray::GetTooltipText() const +{ + if (!m_bEnabled) + return FALSE; + + static TCHAR strBuffer[1024]; + ASSERT(1024 >= m_nMaxTooltipLength); + +// 2007-11-14 GONG +//#ifdef _UNICODE +// strBuffer[0] = _T('\0'); +// MultiByteToWideChar(CP_ACP, 0, m_tnd.szTip, -1, strBuffer, m_nMaxTooltipLength, NULL, NULL); +//#else +// strncpy(strBuffer, m_tnd.szTip, m_nMaxTooltipLength-1); +//#endif + _tcsncpy_s(strBuffer, _countof(strBuffer), m_tnd.szTip, m_nMaxTooltipLength-1); + + return strBuffer; +} + +////////////////////////////////////////////////////////////////////////// +// +// Function: ShowBalloon +// +// Description: +// Shows a balloon tooltip over the tray icon. +// +// Input: +// szText: [in] Text for the balloon tooltip. +// szTitle: [in] Title for the balloon. This text is shown in bold above +// the tooltip text (szText). Pass "" if you don't want a title. +// dwIcon: [in] Specifies an icon to appear in the balloon. Legal values are: +// NIIF_NONE: No icon +// NIIF_INFO: Information +// NIIF_WARNING: Exclamation +// NIIF_ERROR: Critical error (red circle with X) +// uTimeout: [in] Number of seconds for the balloon to remain visible. Can +// be between 10 and 30 inclusive. +// +// Returns: +// TRUE if successful, FALSE if not. +// +////////////////////////////////////////////////////////////////////////// +// Added by Michael Dunn, November 1999 +////////////////////////////////////////////////////////////////////////// + +BOOL CSystemTray::ShowBalloon(LPCTSTR szText, + LPCTSTR szTitle /*=NULL*/, + DWORD dwIcon /*=NIIF_NONE*/, + UINT uTimeout /*=10*/ ) +{ +#ifndef SYSTEMTRAY_USEW2K + return FALSE; +#else + // Bail out if we're not on Win 2K. + if (!m_bWin2K) + return FALSE; + + // Verify input parameters. + + // The balloon tooltip text can be up to 255 chars long. +// ASSERT(AfxIsValidString(szText)); + ASSERT(lstrlen(szText) < 256); + + // The balloon title text can be up to 63 chars long. + if (szTitle) + { +// ASSERT(AfxIsValidString( szTitle)); + ASSERT(lstrlen(szTitle) < 64); + } + + // dwBalloonIcon must be valid. + ASSERT(NIIF_NONE == dwIcon || NIIF_INFO == dwIcon || + NIIF_WARNING == dwIcon || NIIF_ERROR == dwIcon); + + // The timeout must be between 10 and 30 seconds. + ASSERT(uTimeout >= 10 && uTimeout <= 30); + + + m_tnd.uFlags = NIF_INFO; + _tcsncpy_s(m_tnd.szInfo, _countof(m_tnd.szInfo), szText, 256); + if (szTitle) + _tcsncpy_s(m_tnd.szInfoTitle, _countof(m_tnd.szInfoTitle), szTitle, 64); + else + m_tnd.szInfoTitle[0] = _T('\0'); + m_tnd.dwInfoFlags = dwIcon; + m_tnd.uTimeout = uTimeout * 1000; // convert time to ms + + BOOL bSuccess = Shell_NotifyIcon (NIM_MODIFY, &m_tnd); + + // Zero out the balloon text string so that later operations won't redisplay + // the balloon. + m_tnd.szInfo[0] = _T('\0'); + + return bSuccess; +#endif +} + +///////////////////////////////////////////////////////////////////////////// +// CSystemTray notification window stuff + +BOOL CSystemTray::SetNotificationWnd(HWND hNotifyWnd) +{ + if (!m_bEnabled) + return FALSE; + + // Make sure Notification window is valid + if (!hNotifyWnd || !::IsWindow(hNotifyWnd)) + { + ASSERT(FALSE); + return FALSE; + } + + m_tnd.hWnd = hNotifyWnd; + m_tnd.uFlags = 0; + + if (m_bHidden) + return TRUE; + else + return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); +} + +HWND CSystemTray::GetNotificationWnd() const +{ + return m_tnd.hWnd; +} + +// Hatr added + +// Change or retrive the window to send menu commands to +BOOL CSystemTray::SetTargetWnd(HWND hTargetWnd) +{ + m_hTargetWnd = hTargetWnd; + return TRUE; +} // CSystemTray::SetTargetWnd() + +HWND CSystemTray::GetTargetWnd() const +{ + if (m_hTargetWnd) + return m_hTargetWnd; + else + return m_tnd.hWnd; +} // CSystemTray::GetTargetWnd() + +///////////////////////////////////////////////////////////////////////////// +// CSystemTray notification message stuff + +BOOL CSystemTray::SetCallbackMessage(UINT uCallbackMessage) +{ + if (!m_bEnabled) + return FALSE; + + // Make sure we avoid conflict with other messages + ASSERT(uCallbackMessage >= WM_APP); + + m_tnd.uCallbackMessage = uCallbackMessage; + m_tnd.uFlags = NIF_MESSAGE; + + if (m_bHidden) + return TRUE; + else + return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); +} + +UINT CSystemTray::GetCallbackMessage() const +{ + return m_tnd.uCallbackMessage; +} + +///////////////////////////////////////////////////////////////////////////// +// CSystemTray menu manipulation + +BOOL CSystemTray::SetMenuDefaultItem(UINT uItem, BOOL bByPos) +{ +#ifdef _WIN32_WCE + return FALSE; +#else + if ((m_DefaultMenuItemID == uItem) && (m_DefaultMenuItemByPos == bByPos)) + return TRUE; + + m_DefaultMenuItemID = uItem; + m_DefaultMenuItemByPos = bByPos; + + HMENU hMenu = ::LoadMenu(m_hInstance, MAKEINTRESOURCE(m_tnd.uID)); + if (!hMenu) + return FALSE; + + HMENU hSubMenu = ::GetSubMenu(hMenu, 0); + if (!hSubMenu) + { + ::DestroyMenu(hMenu); + return FALSE; + } + + ::SetMenuDefaultItem(hSubMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos); + + ::DestroyMenu(hSubMenu); + ::DestroyMenu(hMenu); + + return TRUE; +#endif +} + +void CSystemTray::GetMenuDefaultItem(UINT& uItem, BOOL& bByPos) +{ + uItem = m_DefaultMenuItemID; + bByPos = m_DefaultMenuItemByPos; +} + +///////////////////////////////////////////////////////////////////////////// +// CSystemTray message handlers + +/* If we were in MFC this is what we'd use... +BEGIN_MESSAGE_MAP(CSystemTray, CWnd) + //{{AFX_MSG_MAP(CSystemTray) + ON_WM_TIMER() + //}}AFX_MSG_MAP +#ifndef _WIN32_WCE + ON_WM_SETTINGCHANGE() +#endif + ON_REGISTERED_MESSAGE(WM_TASKBARCREATED, OnTaskbarCreated) +END_MESSAGE_MAP() +*/ + +LRESULT CSystemTray::OnTimer(UINT nIDEvent) +{ + if (nIDEvent != m_uIDTimer) + { + ASSERT(FALSE); + return 0L; + } + + time_t CurrentTime; + time(&CurrentTime); + + time_t period = CurrentTime - m_StartTime; + if (m_nAnimationPeriod > 0 && m_nAnimationPeriod < period) + { + StopAnimation(); + return 0L; + } + + StepAnimation(); + + return 0L; +} + +// This is called whenever the taskbar is created (eg after explorer crashes +// and restarts. Please note that the WM_TASKBARCREATED message is only passed +// to TOP LEVEL windows (like WM_QUERYNEWPALETTE) +LRESULT CSystemTray::OnTaskbarCreated(WPARAM wParam, LPARAM lParam) +{ + InstallIconPending(); + return 0L; +} + +#ifndef _WIN32_WCE +LRESULT CSystemTray::OnSettingChange(UINT uFlags, LPCTSTR lpszSection) +{ + if (uFlags == SPI_SETWORKAREA) + InstallIconPending(); + return 0L; +} +#endif + +LRESULT CSystemTray::OnTrayNotification(WPARAM wParam, LPARAM lParam) +{ + //Return quickly if its not for this tray icon + if (wParam != m_tnd.uID) + return 0L; + + HWND hTargetWnd = GetTargetWnd(); + if (!hTargetWnd) + return 0L; + + // Clicking with right button brings up a context menu +#if defined(_WIN32_WCE) //&& _WIN32_WCE < 211 + BOOL bAltPressed = ((GetKeyState(VK_MENU) & (1 << (sizeof(SHORT)*8-1))) != 0); + if (LOWORD(lParam) == WM_LBUTTONUP && bAltPressed) +#else + if (LOWORD(lParam) == WM_RBUTTONUP) +#endif + { + HMENU hMenu = ::LoadMenu(m_hInstance, MAKEINTRESOURCE(m_tnd.uID)); + if (!hMenu) + return 0; + + HMENU hSubMenu = ::GetSubMenu(hMenu, 0); + if (!hSubMenu) + { + ::DestroyMenu(hMenu); //Be sure to Destroy Menu Before Returning + return 0; + } + +#ifndef _WIN32_WCE + // Make chosen menu item the default (bold font) + ::SetMenuDefaultItem(hSubMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos); +#endif + + CustomizeMenu(hSubMenu); + + // Display and track the popup menu + POINT pos; +#ifdef _WIN32_WCE + DWORD messagepos = ::GetMessagePos(); + pos.x = GET_X_LPARAM(messagepos); + pos.y = GET_Y_LPARAM(messagepos); +#else + GetCursorPos(&pos); +#endif + + ::SetForegroundWindow(m_tnd.hWnd); + ::TrackPopupMenu(hSubMenu, 0, pos.x, pos.y, 0, hTargetWnd, NULL); + + // BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly" + ::PostMessage(m_tnd.hWnd, WM_NULL, 0, 0); + + DestroyMenu(hMenu); + } +#if defined(_WIN32_WCE) //&& _WIN32_WCE < 211 + if (LOWORD(lParam) == WM_LBUTTONDBLCLK && bAltPressed) +#else + else if (LOWORD(lParam) == WM_LBUTTONDBLCLK) +#endif + { + // double click received, the default action is to execute default menu item + ::SetForegroundWindow(m_tnd.hWnd); + + UINT uItem; + if (m_DefaultMenuItemByPos) + { + HMENU hMenu = ::LoadMenu(m_hInstance, MAKEINTRESOURCE(m_tnd.uID)); + if (!hMenu) + return 0; + + HMENU hSubMenu = ::GetSubMenu(hMenu, 0); + if (!hSubMenu) + return 0; + uItem = ::GetMenuItemID(hSubMenu, m_DefaultMenuItemID); + + DestroyMenu(hMenu); + } + else + uItem = m_DefaultMenuItemID; + + ::PostMessage(hTargetWnd, WM_COMMAND, uItem, 0); + } + + return 1; +} + +// This is the global (static) callback function for all TrayIcon windows +LRESULT PASCAL CSystemTray::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + // The option here is to maintain a list of all TrayIcon windows, + // and iterate through them. If you do this, remove these 3 lines. + CSystemTray* pTrayIcon = m_pThis; + if (pTrayIcon->GetSafeHwnd() != hWnd) + return ::DefWindowProc(hWnd, message, wParam, lParam); + + // If maintaining a list of TrayIcon windows, then the following... + // pTrayIcon = GetFirstTrayIcon() + // while (pTrayIcon != NULL) + // { + // if (pTrayIcon->GetSafeHwnd() != hWnd) continue; + + // Taskbar has been recreated - all TrayIcons must process this. + if (message == CSystemTray::m_nTaskbarCreatedMsg) + return pTrayIcon->OnTaskbarCreated(wParam, lParam); + + // Animation timer + if (message == WM_TIMER && wParam == pTrayIcon->GetTimerID()) + return pTrayIcon->OnTimer(wParam); + + // Settings changed + if (message == WM_SETTINGCHANGE && wParam == pTrayIcon->GetTimerID()) + return pTrayIcon->OnSettingChange(wParam, (LPCTSTR) lParam); + + // Is the message from the icon for this TrayIcon? + if (message == pTrayIcon->GetCallbackMessage()) + return pTrayIcon->OnTrayNotification(wParam, lParam); + + // pTrayIcon = GetNextTrayIcon(); + // } + + // Message has not been processed, so default. + return ::DefWindowProc(hWnd, message, wParam, lParam); +} + +void CSystemTray::InstallIconPending() +{ + // Is the icon display pending, and it's not been set as "hidden"? + if (!m_bShowIconPending || m_bHidden) + return; + + // Reset the flags to what was used at creation + m_tnd.uFlags = m_uCreationFlags; + + // Try and recreate the icon + m_bHidden = !Shell_NotifyIcon(NIM_ADD, &m_tnd); + + // If it's STILL hidden, then have another go next time... + m_bShowIconPending = !m_bHidden; + + ASSERT(m_bHidden == FALSE); +} + +///////////////////////////////////////////////////////////////////////////// +// For minimising/maximising from system tray + +BOOL CALLBACK FindTrayWnd(HWND hwnd, LPARAM lParam) +{ + TCHAR szClassName[256]; + GetClassName(hwnd, szClassName, 255); + + // Did we find the Main System Tray? If so, then get its size and keep going + if (_tcscmp(szClassName, _T("TrayNotifyWnd")) == 0) + { + LPRECT lpRect = (LPRECT) lParam; + ::GetWindowRect(hwnd, lpRect); + return TRUE; + } + + // Did we find the System Clock? If so, then adjust the size of the rectangle + // we have and quit (clock will be found after the system tray) + if (_tcscmp(szClassName, _T("TrayClockWClass")) == 0) + { + LPRECT lpRect = (LPRECT) lParam; + RECT rectClock; + ::GetWindowRect(hwnd, &rectClock); + // if clock is above system tray adjust accordingly + if (rectClock.bottom < lpRect->bottom-5) // 10 = random fudge factor. + lpRect->top = rectClock.bottom; + else + lpRect->right = rectClock.left; + return FALSE; + } + + return TRUE; +} + +#ifndef _WIN32_WCE +void CSystemTray::GetTrayWndRect(LPRECT lprect) +{ +#define DEFAULT_RECT_WIDTH 150 +#define DEFAULT_RECT_HEIGHT 30 + + HWND hShellTrayWnd = FindWindow(_T("Shell_TrayWnd"), NULL); + if (hShellTrayWnd) + { + GetWindowRect(hShellTrayWnd, lprect); + EnumChildWindows(hShellTrayWnd, FindTrayWnd, (LPARAM)lprect); + return; + } + // OK, we failed to get the rect from the quick hack. Either explorer isn't + // running or it's a new version of the shell with the window class names + // changed (how dare Microsoft change these undocumented class names!) So, we + // try to find out what side of the screen the taskbar is connected to. We + // know that the system tray is either on the right or the bottom of the + // taskbar, so we can make a good guess at where to minimize to + APPBARDATA appBarData; + appBarData.cbSize=sizeof(appBarData); + if (SHAppBarMessage(ABM_GETTASKBARPOS,&appBarData)) + { + // We know the edge the taskbar is connected to, so guess the rect of the + // system tray. Use various fudge factor to make it look good + switch(appBarData.uEdge) + { + case ABE_LEFT: + case ABE_RIGHT: + // We want to minimize to the bottom of the taskbar + lprect->top = appBarData.rc.bottom-100; + lprect->bottom = appBarData.rc.bottom-16; + lprect->left = appBarData.rc.left; + lprect->right = appBarData.rc.right; + break; + + case ABE_TOP: + case ABE_BOTTOM: + // We want to minimize to the right of the taskbar + lprect->top = appBarData.rc.top; + lprect->bottom = appBarData.rc.bottom; + lprect->left = appBarData.rc.right-100; + lprect->right = appBarData.rc.right-16; + break; + } + return; + } + + // Blimey, we really aren't in luck. It's possible that a third party shell + // is running instead of explorer. This shell might provide support for the + // system tray, by providing a Shell_TrayWnd window (which receives the + // messages for the icons) So, look for a Shell_TrayWnd window and work out + // the rect from that. Remember that explorer's taskbar is the Shell_TrayWnd, + // and stretches either the width or the height of the screen. We can't rely + // on the 3rd party shell's Shell_TrayWnd doing the same, in fact, we can't + // rely on it being any size. The best we can do is just blindly use the + // window rect, perhaps limiting the width and height to, say 150 square. + // Note that if the 3rd party shell supports the same configuraion as + // explorer (the icons hosted in NotifyTrayWnd, which is a child window of + // Shell_TrayWnd), we would already have caught it above + if (hShellTrayWnd) + { + ::GetWindowRect(hShellTrayWnd, lprect); + if (lprect->right - lprect->left > DEFAULT_RECT_WIDTH) + lprect->left = lprect->right - DEFAULT_RECT_WIDTH; + if (lprect->bottom - lprect->top > DEFAULT_RECT_HEIGHT) + lprect->top = lprect->bottom - DEFAULT_RECT_HEIGHT; + + return; + } + + // OK. Haven't found a thing. Provide a default rect based on the current work + // area + SystemParametersInfo(SPI_GETWORKAREA,0,lprect, 0); + lprect->left = lprect->right - DEFAULT_RECT_WIDTH; + lprect->top = lprect->bottom - DEFAULT_RECT_HEIGHT; +} + +// Check to see if the animation has been disabled (Matthew Ellis ) +BOOL CSystemTray::GetDoWndAnimation() +{ + ANIMATIONINFO ai; + + ai.cbSize=sizeof(ai); + SystemParametersInfo(SPI_GETANIMATION,sizeof(ai),&ai,0); + + return ai.iMinAnimate?TRUE:FALSE; +} +#endif + +BOOL CSystemTray::RemoveTaskbarIcon(HWND hWnd) +{ + // Create static invisible window + if (!::IsWindow(m_hWndInvisible)) + { +// 2007-11-14 GONG + m_hWndInvisible = CreateWindowEx(0, _T("Static"), _T(""), WS_POPUP, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL, 0, NULL, 0); + + if (!m_hWndInvisible) + return FALSE; + } + + SetParent(hWnd, m_hWndInvisible); + + return TRUE; +} + +void CSystemTray::MinimiseToTray(HWND hWnd) +{ +#ifndef _WIN32_WCE + if (GetDoWndAnimation()) + { + RECT rectFrom, rectTo; + + GetWindowRect(hWnd, &rectFrom); + GetTrayWndRect(&rectTo); + + DrawAnimatedRects(hWnd, IDANI_CAPTION, &rectFrom, &rectTo); + } + + RemoveTaskbarIcon(hWnd); + SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) &~ WS_VISIBLE); +#endif +} + +void CSystemTray::MaximiseFromTray(HWND hWnd) +{ +#ifndef _WIN32_WCE + if (GetDoWndAnimation()) + { + RECT rectTo; + ::GetWindowRect(hWnd, &rectTo); + + RECT rectFrom; + GetTrayWndRect(&rectFrom); + + ::SetParent(hWnd, NULL); + DrawAnimatedRects(hWnd, IDANI_CAPTION, &rectFrom, &rectTo); + } + else + ::SetParent(hWnd, NULL); + + SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) | WS_VISIBLE); + RedrawWindow(hWnd, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME | + RDW_INVALIDATE | RDW_ERASE); + + // Move focus away and back again to ensure taskbar icon is recreated + if (::IsWindow(m_hWndInvisible)) + SetActiveWindow(m_hWndInvisible); + SetActiveWindow(hWnd); + SetForegroundWindow(hWnd); +#endif } \ No newline at end of file diff --git a/WeaselUI/SystemTraySDK.h b/WeaselServer/SystemTraySDK.h similarity index 96% rename from WeaselUI/SystemTraySDK.h rename to WeaselServer/SystemTraySDK.h index e700250a3..085878099 100644 --- a/WeaselUI/SystemTraySDK.h +++ b/WeaselServer/SystemTraySDK.h @@ -1,201 +1,201 @@ -// TrayIcon.h: interface for the CSystemTray class. -// -// Written by Chris Maunder (cmaunder@mail.com) -// Copyright (c) 1998. -// -// This code may be used in compiled form in any way you desire. This -// file may be redistributed unmodified by any means PROVIDING it is -// not sold for profit without the authors written consent, and -// providing that this notice and the authors name is included. If -// the source code in this file is used in any commercial application -// then acknowledgement must be made to the author of this file -// (in whatever form you wish). -// -// This file is provided "as is" with no expressed or implied warranty. -// -// Expect bugs. -// -// Please use and enjoy. Please let me know of any bugs/mods/improvements -// that you have found/implemented and I will fix/incorporate them into this -// file. -// -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_TRAYICON_H__43104212_F2C1_11D2_A9E9_8EA47C000000__INCLUDED_) -#define AFX_TRAYICON_H__43104212_F2C1_11D2_A9E9_8EA47C000000__INCLUDED_ - -#ifndef _WIN32_IE -#define _WIN32_IE 0x0501 -#endif - -#include - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -// The debugger can't handle symbols more than 255 characters long. -// STL often creates symbols longer than that. -// When symbols are longer than 255 characters, the warning is disabled. -#if _MSC_VER < 1400 -#pragma warning(disable: 4786) -#endif // _MSC_VER < 1400 - -#include -#include -typedef std::vector ICONVECTOR; - -#ifdef NOTIFYICONDATA_V1_SIZE // If NOTIFYICONDATA_V1_SIZE, then we can use fun stuff -#define SYSTEMTRAY_USEW2K -#else -#define NIIF_NONE 0 -#endif - -class CSystemTray -{ -// Construction/destruction -public: - CSystemTray(); - CSystemTray(HINSTANCE hInst, HWND hParent, UINT uCallbackMessage, - LPCTSTR szTip, HICON icon, UINT uID, - BOOL bhidden = FALSE, - LPCTSTR szBalloonTip = NULL, LPCTSTR szBalloonTitle = NULL, - DWORD dwBalloonIcon = NIIF_NONE, UINT uBalloonTimeout = 10); - virtual ~CSystemTray(); - -// Operations -public: - BOOL Enabled() { return m_bEnabled; } - BOOL Visible() { return !m_bHidden; } - - // Create the tray icon - BOOL Create(HINSTANCE hInst, HWND hParent, UINT uCallbackMessage, LPCTSTR szTip, - HICON icon, UINT uID, BOOL bHidden = FALSE, - LPCTSTR szBalloonTip = NULL, LPCTSTR szBalloonTitle = NULL, - DWORD dwBalloonIcon = NIIF_NONE, UINT uBalloonTimeout = 10); - - // Change or retrieve the Tooltip text - BOOL SetTooltipText(LPCTSTR pszTooltipText); - BOOL SetTooltipText(UINT nID); - LPTSTR GetTooltipText() const; - - // Change or retrieve the icon displayed - BOOL SetIcon(HICON hIcon); - BOOL SetIcon(LPCTSTR lpszIconName); - BOOL SetIcon(UINT nIDResource); - BOOL SetStandardIcon(LPCTSTR lpIconName); - BOOL SetStandardIcon(UINT nIDResource); - HICON GetIcon() const; - - void SetFocus(); - BOOL HideIcon(); - BOOL ShowIcon(); - BOOL AddIcon(); - BOOL RemoveIcon(); - BOOL MoveToRight(); - - BOOL ShowBalloon(LPCTSTR szText, LPCTSTR szTitle = NULL, - DWORD dwIcon = NIIF_NONE, UINT uTimeout = 10); - - // For icon animation - BOOL SetIconList(UINT uFirstIconID, UINT uLastIconID); - BOOL SetIconList(HICON* pHIconList, UINT nNumIcons); - BOOL Animate(UINT nDelayMilliSeconds, int nNumSeconds = -1); - BOOL StepAnimation(); - BOOL StopAnimation(); - - // Change menu default item - void GetMenuDefaultItem(UINT& uItem, BOOL& bByPos); - BOOL SetMenuDefaultItem(UINT uItem, BOOL bByPos); - - // Change or retrieve the window to send icon notification messages to - BOOL SetNotificationWnd(HWND hNotifyWnd); - HWND GetNotificationWnd() const; - - // Change or retrieve the window to send menu commands to - BOOL SetTargetWnd(HWND hTargetWnd); - HWND GetTargetWnd() const; - - // Change or retrieve notification messages sent to the window - BOOL SetCallbackMessage(UINT uCallbackMessage); - UINT GetCallbackMessage() const; - - HWND GetSafeHwnd() const { return (this)? m_hWnd : NULL; } - UINT_PTR GetTimerID() const { return m_nTimerID; } - - // Static functions -public: - static void MinimiseToTray(HWND hWnd); - static void MaximiseFromTray(HWND hWnd); - -public: - // Default handler for tray notification message - virtual LRESULT OnTrayNotification(WPARAM uID, LPARAM lEvent); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSystemTray) - //}}AFX_VIRTUAL - -// Static callback functions and data -public: - static LRESULT PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); - static CSystemTray* m_pThis; - -// Implementation -protected: - void Initialise(); - void InstallIconPending(); - ATOM RegisterClass(HINSTANCE hInstance); - - virtual void CustomizeMenu(HMENU) {} - -// Implementation -protected: - NOTIFYICONDATA m_tnd; - HINSTANCE m_hInstance; - HWND m_hWnd; - HWND m_hTargetWnd; // Window that menu commands are sent - - BOOL m_bEnabled; // does O/S support tray icon? - BOOL m_bHidden; // Has the icon been hidden? - BOOL m_bRemoved; // Has the icon been removed? - BOOL m_bShowIconPending; // Show the icon once tha taskbar has been created - BOOL m_bWin2K; // Use new W2K features? - - ICONVECTOR m_IconList; - UINT_PTR m_uIDTimer; - int m_nCurrentIcon; - time_t m_StartTime; - int m_nAnimationPeriod; - HICON m_hSavedIcon; - UINT m_DefaultMenuItemID; - BOOL m_DefaultMenuItemByPos; - UINT m_uCreationFlags; - -// Static data -protected: - static BOOL RemoveTaskbarIcon(HWND hWnd); - - static const UINT_PTR m_nTimerID; - static UINT m_nMaxTooltipLength; - static const UINT m_nTaskbarCreatedMsg; - static HWND m_hWndInvisible; - - static BOOL GetW2K(); -#ifndef _WIN32_WCE - static void GetTrayWndRect(LPRECT lprect); - static BOOL GetDoWndAnimation(); -#endif - -// message map functions -public: - LRESULT OnTimer(UINT nIDEvent); - LRESULT OnTaskbarCreated(WPARAM wParam, LPARAM lParam); -#ifndef _WIN32_WCE - LRESULT OnSettingChange(UINT uFlags, LPCTSTR lpszSection); -#endif -}; - - -#endif // !defined(AFX_TRAYICON_H__43104212_F2C1_11D2_A9E9_8EA47C000000__INCLUDED_) +// TrayIcon.h: interface for the CSystemTray class. +// +// Written by Chris Maunder (cmaunder@mail.com) +// Copyright (c) 1998. +// +// This code may be used in compiled form in any way you desire. This +// file may be redistributed unmodified by any means PROVIDING it is +// not sold for profit without the authors written consent, and +// providing that this notice and the authors name is included. If +// the source code in this file is used in any commercial application +// then acknowledgement must be made to the author of this file +// (in whatever form you wish). +// +// This file is provided "as is" with no expressed or implied warranty. +// +// Expect bugs. +// +// Please use and enjoy. Please let me know of any bugs/mods/improvements +// that you have found/implemented and I will fix/incorporate them into this +// file. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_TRAYICON_H__43104212_F2C1_11D2_A9E9_8EA47C000000__INCLUDED_) +#define AFX_TRAYICON_H__43104212_F2C1_11D2_A9E9_8EA47C000000__INCLUDED_ + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0501 +#endif + +#include + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +// The debugger can't handle symbols more than 255 characters long. +// STL often creates symbols longer than that. +// When symbols are longer than 255 characters, the warning is disabled. +#if _MSC_VER < 1400 +#pragma warning(disable: 4786) +#endif // _MSC_VER < 1400 + +#include +#include +typedef std::vector ICONVECTOR; + +#ifdef NOTIFYICONDATA_V1_SIZE // If NOTIFYICONDATA_V1_SIZE, then we can use fun stuff +#define SYSTEMTRAY_USEW2K +#else +#define NIIF_NONE 0 +#endif + +class CSystemTray +{ +// Construction/destruction +public: + CSystemTray(); + CSystemTray(HINSTANCE hInst, HWND hParent, UINT uCallbackMessage, + LPCTSTR szTip, HICON icon, UINT uID, + BOOL bhidden = FALSE, + LPCTSTR szBalloonTip = NULL, LPCTSTR szBalloonTitle = NULL, + DWORD dwBalloonIcon = NIIF_NONE, UINT uBalloonTimeout = 10); + virtual ~CSystemTray(); + +// Operations +public: + BOOL Enabled() { return m_bEnabled; } + BOOL Visible() { return !m_bHidden; } + + // Create the tray icon + BOOL Create(HINSTANCE hInst, HWND hParent, UINT uCallbackMessage, LPCTSTR szTip, + HICON icon, UINT uID, BOOL bHidden = FALSE, + LPCTSTR szBalloonTip = NULL, LPCTSTR szBalloonTitle = NULL, + DWORD dwBalloonIcon = NIIF_NONE, UINT uBalloonTimeout = 10); + + // Change or retrieve the Tooltip text + BOOL SetTooltipText(LPCTSTR pszTooltipText); + BOOL SetTooltipText(UINT nID); + LPTSTR GetTooltipText() const; + + // Change or retrieve the icon displayed + BOOL SetIcon(HICON hIcon); + BOOL SetIcon(LPCTSTR lpszIconName); + BOOL SetIcon(UINT nIDResource); + BOOL SetStandardIcon(LPCTSTR lpIconName); + BOOL SetStandardIcon(UINT nIDResource); + HICON GetIcon() const; + + void SetFocus(); + BOOL HideIcon(); + BOOL ShowIcon(); + BOOL AddIcon(); + BOOL RemoveIcon(); + BOOL MoveToRight(); + + BOOL ShowBalloon(LPCTSTR szText, LPCTSTR szTitle = NULL, + DWORD dwIcon = NIIF_NONE, UINT uTimeout = 10); + + // For icon animation + BOOL SetIconList(UINT uFirstIconID, UINT uLastIconID); + BOOL SetIconList(HICON* pHIconList, UINT nNumIcons); + BOOL Animate(UINT nDelayMilliSeconds, int nNumSeconds = -1); + BOOL StepAnimation(); + BOOL StopAnimation(); + + // Change menu default item + void GetMenuDefaultItem(UINT& uItem, BOOL& bByPos); + BOOL SetMenuDefaultItem(UINT uItem, BOOL bByPos); + + // Change or retrieve the window to send icon notification messages to + BOOL SetNotificationWnd(HWND hNotifyWnd); + HWND GetNotificationWnd() const; + + // Change or retrieve the window to send menu commands to + BOOL SetTargetWnd(HWND hTargetWnd); + HWND GetTargetWnd() const; + + // Change or retrieve notification messages sent to the window + BOOL SetCallbackMessage(UINT uCallbackMessage); + UINT GetCallbackMessage() const; + + HWND GetSafeHwnd() const { return (this)? m_hWnd : NULL; } + UINT_PTR GetTimerID() const { return m_nTimerID; } + + // Static functions +public: + static void MinimiseToTray(HWND hWnd); + static void MaximiseFromTray(HWND hWnd); + +public: + // Default handler for tray notification message + virtual LRESULT OnTrayNotification(WPARAM uID, LPARAM lEvent); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSystemTray) + //}}AFX_VIRTUAL + +// Static callback functions and data +public: + static LRESULT PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + static CSystemTray* m_pThis; + +// Implementation +protected: + void Initialise(); + void InstallIconPending(); + ATOM RegisterClass(HINSTANCE hInstance); + + virtual void CustomizeMenu(HMENU) {} + +// Implementation +protected: + NOTIFYICONDATA m_tnd; + HINSTANCE m_hInstance; + HWND m_hWnd; + HWND m_hTargetWnd; // Window that menu commands are sent + + BOOL m_bEnabled; // does O/S support tray icon? + BOOL m_bHidden; // Has the icon been hidden? + BOOL m_bRemoved; // Has the icon been removed? + BOOL m_bShowIconPending; // Show the icon once tha taskbar has been created + BOOL m_bWin2K; // Use new W2K features? + + ICONVECTOR m_IconList; + UINT_PTR m_uIDTimer; + int m_nCurrentIcon; + time_t m_StartTime; + int m_nAnimationPeriod; + HICON m_hSavedIcon; + UINT m_DefaultMenuItemID; + BOOL m_DefaultMenuItemByPos; + UINT m_uCreationFlags; + +// Static data +protected: + static BOOL RemoveTaskbarIcon(HWND hWnd); + + static const UINT_PTR m_nTimerID; + static UINT m_nMaxTooltipLength; + static const UINT m_nTaskbarCreatedMsg; + static HWND m_hWndInvisible; + + static BOOL GetW2K(); +#ifndef _WIN32_WCE + static void GetTrayWndRect(LPRECT lprect); + static BOOL GetDoWndAnimation(); +#endif + +// message map functions +public: + LRESULT OnTimer(UINT nIDEvent); + LRESULT OnTaskbarCreated(WPARAM wParam, LPARAM lParam); +#ifndef _WIN32_WCE + LRESULT OnSettingChange(UINT uFlags, LPCTSTR lpszSection); +#endif +}; + + +#endif // !defined(AFX_TRAYICON_H__43104212_F2C1_11D2_A9E9_8EA47C000000__INCLUDED_) diff --git a/WeaselServer/WeaselServer.vcxproj b/WeaselServer/WeaselServer.vcxproj index b01c1ecc0..9782b0216 100644 --- a/WeaselServer/WeaselServer.vcxproj +++ b/WeaselServer/WeaselServer.vcxproj @@ -459,15 +459,19 @@ Create Create + + + + diff --git a/WeaselServer/WeaselServer.vcxproj.filters b/WeaselServer/WeaselServer.vcxproj.filters index 40d9f414b..e5c8cbe23 100644 --- a/WeaselServer/WeaselServer.vcxproj.filters +++ b/WeaselServer/WeaselServer.vcxproj.filters @@ -27,6 +27,12 @@ Source Files + + Source Files + + + Source Files + @@ -41,6 +47,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/WeaselServer/WeaselServerApp.cpp b/WeaselServer/WeaselServerApp.cpp index 859ac4094..af865a0bf 100644 --- a/WeaselServer/WeaselServerApp.cpp +++ b/WeaselServer/WeaselServerApp.cpp @@ -3,6 +3,7 @@ WeaselServerApp::WeaselServerApp() : m_handler(std::make_unique(&m_ui)) + , tray_icon(m_ui) { //m_handler.reset(new RimeWithWeaselHandler(&m_ui)); m_server.SetRequestHandler(m_handler.get()); @@ -22,12 +23,20 @@ int WeaselServerApp::Run() win_sparkle_set_registry_path("Software\\Rime\\Weasel\\Updates"); win_sparkle_init(); m_ui.Create(m_server.GetHWnd()); + + tray_icon.Create(m_server.GetHWnd()); + tray_icon.Refresh(); + m_handler->Initialize(); + m_handler->OnUpdateUI([this]() { + tray_icon.Refresh(); + }); int ret = m_server.Run(); m_handler->Finalize(); m_ui.Destroy(); + tray_icon.RemoveIcon(); win_sparkle_cleanup(); return ret; diff --git a/WeaselServer/WeaselServerApp.h b/WeaselServer/WeaselServerApp.h index 29477dfc9..324562c65 100644 --- a/WeaselServer/WeaselServerApp.h +++ b/WeaselServer/WeaselServerApp.h @@ -9,6 +9,8 @@ #include #include +#include "WeaselTrayIcon.h" + class WeaselServerApp { public: static bool execute(const std::wstring &cmd, const std::wstring &args) @@ -58,5 +60,6 @@ class WeaselServerApp { weasel::Server m_server; weasel::UI m_ui; + WeaselTrayIcon tray_icon; std::unique_ptr m_handler; }; diff --git a/WeaselUI/WeaselTrayIcon.cpp b/WeaselServer/WeaselTrayIcon.cpp similarity index 95% rename from WeaselUI/WeaselTrayIcon.cpp rename to WeaselServer/WeaselTrayIcon.cpp index 288dd8c04..30d176964 100644 --- a/WeaselUI/WeaselTrayIcon.cpp +++ b/WeaselServer/WeaselTrayIcon.cpp @@ -1,64 +1,64 @@ -#include "stdafx.h" -#include "WeaselTrayIcon.h" - -// nasty -#include "../WeaselServer/resource.h" - -static UINT mode_icon[] = { IDI_ZH, IDI_ZH, IDI_EN, IDI_RELOAD }; -static const WCHAR *mode_label[] = { NULL, /*L"中文"*/ NULL, /*L"西文"*/ NULL, L"維護中" }; - -WeaselTrayIcon::WeaselTrayIcon(weasel::UI &ui) - : m_style(ui.style()), m_status(ui.status()), m_mode(INITIAL) -{ -} - -void WeaselTrayIcon::CustomizeMenu(HMENU hMenu) -{ -} - -BOOL WeaselTrayIcon::Create(HWND hTargetWnd) -{ - HMODULE hModule = GetModuleHandle(NULL); - CIcon icon; - icon.LoadIconW(IDI_ZH); - BOOL bRet = CSystemTray::Create(hModule, NULL, WM_WEASEL_TRAY_NOTIFY, - WEASEL_IME_NAME, icon, IDR_MENU_POPUP); - if (hTargetWnd) - { - SetTargetWnd(hTargetWnd); - } - if (!m_style.display_tray_icon) - { - RemoveIcon(); - } - return bRet; -} - -void WeaselTrayIcon::Refresh() -{ - if (!m_style.display_tray_icon) - { - if (m_mode != INITIAL) - { - RemoveIcon(); - m_mode = INITIAL; - } - return; - } - WeaselTrayMode mode = m_status.disabled ? DISABLED : - m_status.ascii_mode ? ASCII : ZHUNG; - if (mode != m_mode) - { - m_mode = mode; - ShowIcon(); - SetIcon(mode_icon[mode]); - if (mode_label[mode]) - { - ShowBalloon(mode_label[mode], WEASEL_IME_NAME); - } - } - else if (!Visible()) - { - ShowIcon(); - } -} +#include "stdafx.h" +#include "WeaselTrayIcon.h" + +// nasty +#include "../WeaselServer/resource.h" + +static UINT mode_icon[] = { IDI_ZH, IDI_ZH, IDI_EN, IDI_RELOAD }; +static const WCHAR *mode_label[] = { NULL, /*L"中文"*/ NULL, /*L"西文"*/ NULL, L"維護中" }; + +WeaselTrayIcon::WeaselTrayIcon(weasel::UI &ui) + : m_style(ui.style()), m_status(ui.status()), m_mode(INITIAL) +{ +} + +void WeaselTrayIcon::CustomizeMenu(HMENU hMenu) +{ +} + +BOOL WeaselTrayIcon::Create(HWND hTargetWnd) +{ + HMODULE hModule = GetModuleHandle(NULL); + CIcon icon; + icon.LoadIconW(IDI_ZH); + BOOL bRet = CSystemTray::Create(hModule, NULL, WM_WEASEL_TRAY_NOTIFY, + WEASEL_IME_NAME, icon, IDR_MENU_POPUP); + if (hTargetWnd) + { + SetTargetWnd(hTargetWnd); + } + if (!m_style.display_tray_icon) + { + RemoveIcon(); + } + return bRet; +} + +void WeaselTrayIcon::Refresh() +{ + if (!m_style.display_tray_icon) + { + if (m_mode != INITIAL) + { + RemoveIcon(); + m_mode = INITIAL; + } + return; + } + WeaselTrayMode mode = m_status.disabled ? DISABLED : + m_status.ascii_mode ? ASCII : ZHUNG; + if (mode != m_mode) + { + m_mode = mode; + ShowIcon(); + SetIcon(mode_icon[mode]); + if (mode_label[mode]) + { + ShowBalloon(mode_label[mode], WEASEL_IME_NAME); + } + } + else if (!Visible()) + { + ShowIcon(); + } +} diff --git a/WeaselUI/WeaselTrayIcon.h b/WeaselServer/WeaselTrayIcon.h similarity index 94% rename from WeaselUI/WeaselTrayIcon.h rename to WeaselServer/WeaselTrayIcon.h index f477a7597..a51d5212a 100644 --- a/WeaselUI/WeaselTrayIcon.h +++ b/WeaselServer/WeaselTrayIcon.h @@ -1,28 +1,28 @@ -#pragma once -#include -#include -#include "SystemTraySDK.h" - -#define WM_WEASEL_TRAY_NOTIFY (WEASEL_IPC_LAST_COMMAND + 100) - - -class WeaselTrayIcon : public CSystemTray -{ -public: - enum WeaselTrayMode { - INITIAL, ZHUNG, ASCII, DISABLED, - }; - - WeaselTrayIcon(weasel::UI &ui); - - BOOL Create(HWND hTargetWnd); - void Refresh(); - -protected: - virtual void CustomizeMenu(HMENU hMenu); - - weasel::UIStyle &m_style; - weasel::Status &m_status; - WeaselTrayMode m_mode; -}; - +#pragma once +#include +#include +#include "SystemTraySDK.h" + +#define WM_WEASEL_TRAY_NOTIFY (WEASEL_IPC_LAST_COMMAND + 100) + + +class WeaselTrayIcon : public CSystemTray +{ +public: + enum WeaselTrayMode { + INITIAL, ZHUNG, ASCII, DISABLED, + }; + + WeaselTrayIcon(weasel::UI &ui); + + BOOL Create(HWND hTargetWnd); + void Refresh(); + +protected: + virtual void CustomizeMenu(HMENU hMenu); + + weasel::UIStyle &m_style; + weasel::Status &m_status; + WeaselTrayMode m_mode; +}; + diff --git a/WeaselTSF/CandidateList.cpp b/WeaselTSF/CandidateList.cpp new file mode 100644 index 000000000..08bc7217a --- /dev/null +++ b/WeaselTSF/CandidateList.cpp @@ -0,0 +1,306 @@ +#include "stdafx.h" + +#include "WeaselTSF.h" +#include "CandidateList.h" + +using namespace std; +using namespace weasel; + +CandidateList::CandidateList(WeaselTSF * pTextService) + : _ui(make_unique()) +{ + //_ui->Create(NULL); + _cRef = 1; + _tsf = pTextService; + _tsf->AddRef(); +} + +CandidateList::~CandidateList() +{ + _tsf->Release(); +} + +STDMETHODIMP CandidateList::QueryInterface(REFIID riid, void ** ppvObj) +{ + if (ppvObj == nullptr) + { + return E_INVALIDARG; + } + + *ppvObj = nullptr; + + if (IsEqualIID(riid, IID_ITfUIElement) || + IsEqualIID(riid, IID_ITfCandidateListUIElement)) + { + *ppvObj = (ITfCandidateListUIElement*)this; + } + else if (IsEqualIID(riid, IID_IUnknown) || + IsEqualIID(riid, IID_ITfCandidateListUIElementBehavior)) + { + *ppvObj = (ITfCandidateListUIElementBehavior*)this; + } + + if (*ppvObj) + { + AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) CandidateList::AddRef(void) +{ + return ++_cRef; +} + +STDMETHODIMP_(ULONG) CandidateList::Release(void) +{ + LONG cr = --_cRef; + + assert(_cRef >= 0); + + if (_cRef == 0) + { + delete this; + } + + return cr; +} + +STDMETHODIMP CandidateList::GetDescription(BSTR * pbstr) +{ + static auto str = SysAllocString(L"Candidate List"); + if (pbstr) + { + *pbstr = str; + } + return S_OK; +} + +STDMETHODIMP CandidateList::GetGUID(GUID * pguid) +{ + /// 36c3c795-7159-45aa-ab12-30229a51dbd3 + *pguid = { 0x36c3c795, 0x7159, 0x45aa, { 0xab, 0x12, 0x30, 0x22, 0x9a, 0x51, 0xdb, 0xd3 } }; + return S_OK; +} + +STDMETHODIMP CandidateList::Show(BOOL showCandidateWindow) +{ + BOOL pbShow = true; + ITfUIElementMgr *emgr = nullptr; + + if (FAILED(_tsf->_pThreadMgr->QueryInterface(IID_ITfUIElementMgr, (void **)&emgr)) || emgr == nullptr) { + return E_FAIL; + } + + emgr->BeginUIElement(this, &pbShow, &uiid); + if (!pbShow) { + emgr->UpdateUIElement(uiid); + } + + if (pbShow && showCandidateWindow) + _ui->Show(); + else + _ui->Hide(); + + if (!showCandidateWindow) { + emgr->EndUIElement(uiid); + } + + emgr->Release(); + + return S_OK; +} + +STDMETHODIMP CandidateList::IsShown(BOOL * pIsShow) +{ + *pIsShow = _ui->IsShown(); + return S_OK; +} + +STDMETHODIMP CandidateList::GetUpdatedFlags(DWORD * pdwFlags) +{ + if (!pdwFlags) + return E_INVALIDARG; + + *pdwFlags = TF_CLUIE_DOCUMENTMGR | TF_CLUIE_COUNT | TF_CLUIE_SELECTION | TF_CLUIE_STRING | TF_CLUIE_CURRENTPAGE; + return S_OK; +} + +STDMETHODIMP CandidateList::GetDocumentMgr(ITfDocumentMgr ** ppdim) +{ + *ppdim = nullptr; + if ((_tsf->_pThreadMgr->GetFocus(ppdim) == S_OK) && (*ppdim != nullptr)) + { + return S_OK; + } + + return E_FAIL; +} + +STDMETHODIMP CandidateList::GetCount(UINT * pCandidateCount) +{ + *pCandidateCount = _ui->ctx().cinfo.candies.size(); + return S_OK; +} + +STDMETHODIMP CandidateList::GetSelection(UINT * pSelectedCandidateIndex) +{ + *pSelectedCandidateIndex = _ui->ctx().cinfo.highlighted; + return S_OK; +} + +STDMETHODIMP CandidateList::GetString(UINT uIndex, BSTR * pbstr) +{ + *pbstr = nullptr; + if (!_ui->ctx().cinfo.empty()) { + auto &str = _ui->ctx().cinfo.candies[_ui->ctx().cinfo.highlighted].str; + *pbstr = SysAllocStringLen(str.c_str(), str.size() + 1); + } + + return S_OK; +} + +STDMETHODIMP CandidateList::GetPageIndex(UINT * pIndex, UINT uSize, UINT * puPageCnt) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CandidateList::SetPageIndex(UINT * pIndex, UINT uPageCnt) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CandidateList::GetCurrentPage(UINT * puPage) +{ + *puPage = _ui->ctx().cinfo.currentPage; + return S_OK; +} + +STDMETHODIMP CandidateList::SetSelection(UINT nIndex) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CandidateList::Finalize(void) +{ + Destroy(); + return S_OK; +} + +STDMETHODIMP CandidateList::Abort(void) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CandidateList::SetIntegrationStyle(GUID guidIntegrationStyle) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CandidateList::GetSelectionStyle(TfIntegratableCandidateListSelectionStyle * ptfSelectionStyle) +{ + *ptfSelectionStyle = _selectionStyle; + return S_OK; +} + +STDMETHODIMP CandidateList::OnKeyDown(WPARAM wParam, LPARAM lParam, BOOL * pIsEaten) +{ + *pIsEaten = TRUE; + return S_OK; +} + +STDMETHODIMP CandidateList::ShowCandidateNumbers(BOOL * pIsShow) +{ + *pIsShow = TRUE; + return S_OK; +} + +STDMETHODIMP CandidateList::FinalizeExactCompositionString() +{ + _tsf->_AbortComposition(false); + return E_NOTIMPL; +} + +void CandidateList::UpdateUI(const Context & ctx, const Status & status) +{ + if (_ui->style().inline_preedit) { + _ui->style().client_caps |= weasel::INLINE_PREEDIT_CAPABLE; + } + else { + _ui->style().client_caps &= ~weasel::INLINE_PREEDIT_CAPABLE; + } + + /// In UWP, candidate window will only be shown + /// if it is owned by active view window + HWND actw = _GetActiveWnd(); + if (actw != _curp) { + UIStyle sty = _ui->style(); + _ui->Destroy(); + _ui->Create(actw); + _curp = actw; + _ui->style() = sty; + } + _ui->Update(ctx, status); + + Show(status.composing); +} + +void CandidateList::UpdateStyle(const UIStyle & sty) +{ + _ui->style() = sty; +} + +void CandidateList::UpdateInputPosition(RECT const & rc) +{ + _ui->UpdateInputPosition(rc); +} + +void CandidateList::Destroy() +{ + Show(false); + _ui->Destroy(); + _curp = NULL; +} + +UIStyle & CandidateList::style() +{ + return _ui->style(); +} + +HWND CandidateList::_GetActiveWnd() +{ + ITfDocumentMgr *dmgr = nullptr; + ITfContext *ctx = nullptr; + ITfContextView *view = nullptr; + HWND w = NULL; + + if (FAILED(_tsf->_pThreadMgr->GetFocus(&dmgr))) { + goto Exit; + } + if (FAILED(dmgr->GetTop(&ctx))) { + goto Exit; + } + if (FAILED(ctx->GetActiveView(&view))) { + goto Exit; + } + + view->GetWnd(&w); + +Exit: + if (dmgr) + dmgr->Release(); + if (ctx) + ctx->Release(); + if (view) + view->Release(); + + if (w == NULL) w = ::GetFocus(); + return w; +} + +void WeaselTSF::_UpdateUI(const Context & ctx, const Status & status) +{ + _cand->UpdateUI(ctx, status); +} diff --git a/WeaselTSF/CandidateList.h b/WeaselTSF/CandidateList.h new file mode 100644 index 000000000..8ab415440 --- /dev/null +++ b/WeaselTSF/CandidateList.h @@ -0,0 +1,68 @@ +#pragma once +#include +#include "ctffunc.h" + +class WeaselTSF; + +namespace weasel { + class CandidateList : + public ITfIntegratableCandidateListUIElement, + public ITfCandidateListUIElementBehavior + { + public: + CandidateList(WeaselTSF *pTextService); + ~CandidateList(); + + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + + // ITfUIElement + STDMETHODIMP GetDescription(BSTR *pbstr); + STDMETHODIMP GetGUID(GUID *pguid); + STDMETHODIMP Show(BOOL showCandidateWindow); + STDMETHODIMP IsShown(BOOL *pIsShow); + + // ITfCandidateListUIElement + STDMETHODIMP GetUpdatedFlags(DWORD *pdwFlags); + STDMETHODIMP GetDocumentMgr(ITfDocumentMgr **ppdim); + STDMETHODIMP GetCount(UINT *pCandidateCount); + STDMETHODIMP GetSelection(UINT *pSelectedCandidateIndex); + STDMETHODIMP GetString(UINT uIndex, BSTR *pbstr); + STDMETHODIMP GetPageIndex(UINT *pIndex, UINT uSize, UINT *puPageCnt); + STDMETHODIMP SetPageIndex(UINT *pIndex, UINT uPageCnt); + STDMETHODIMP GetCurrentPage(UINT *puPage); + + // ITfCandidateListUIElementBehavior methods + STDMETHODIMP SetSelection(UINT nIndex); + STDMETHODIMP Finalize(void); + STDMETHODIMP Abort(void); + + // ITfIntegratableCandidateListUIElement methods + STDMETHODIMP SetIntegrationStyle(GUID guidIntegrationStyle); + STDMETHODIMP GetSelectionStyle(_Out_ TfIntegratableCandidateListSelectionStyle *ptfSelectionStyle); + STDMETHODIMP OnKeyDown(_In_ WPARAM wParam, _In_ LPARAM lParam, _Out_ BOOL *pIsEaten); + STDMETHODIMP ShowCandidateNumbers(_Out_ BOOL *pIsShow); + STDMETHODIMP FinalizeExactCompositionString(); + + /* Update */ + void UpdateUI(const Context &ctx, const Status &status); + void UpdateStyle(const UIStyle &sty); + void UpdateInputPosition(RECT const& rc); + void Destroy(); + UIStyle &style(); + + private: + HWND _GetActiveWnd(); + + std::unique_ptr _ui; + DWORD _cRef; + WeaselTSF *_tsf; + DWORD uiid; + TfIntegratableCandidateListSelectionStyle _selectionStyle = STYLE_ACTIVE_SELECTION; + + /* The parent of current candidate window */ + HWND _curp; + }; +} diff --git a/WeaselTSF/Composition.cpp b/WeaselTSF/Composition.cpp index 10463809d..8d0f0d3a0 100644 --- a/WeaselTSF/Composition.cpp +++ b/WeaselTSF/Composition.cpp @@ -2,6 +2,7 @@ #include "WeaselTSF.h" #include "EditSession.h" #include "ResponseParser.h" +#include "CandidateList.h" /* Start Composition */ class CStartCompositionEditSession: public CEditSession @@ -44,11 +45,17 @@ STDAPI CStartCompositionEditSession::DoEditSession(TfEditCookie ec) * So we insert a dummy space character here. * This is the same workaround used by Microsoft Pinyin IME (New Experience). */ - if (_fCUASWorkaroundEnabled) - { - pRangeComposition->SetText(ec, TF_ST_CORRECTION, L" ", 1); - pRangeComposition->Collapse(ec, TF_ANCHOR_START); - } + //if (_fCUASWorkaroundEnabled) + //{ + // pRangeComposition->SetText(ec, TF_ST_CORRECTION, L" ", 1); + // pRangeComposition->Collapse(ec, TF_ANCHOR_START); + //} + + // NOTE: Seems that `OnCompositionTerminated` will be triggered even when + // normally end a composition if not put any string in it. + // So just insert a blank here. + pRangeComposition->SetText(ec, TF_ST_CORRECTION, L" ", 1); + pRangeComposition->Collapse(ec, TF_ANCHOR_START); TF_SELECTION tfSelection; tfSelection.range = pRangeComposition; tfSelection.style.ase = TF_AE_NONE; @@ -69,21 +76,11 @@ STDAPI CStartCompositionEditSession::DoEditSession(TfEditCookie ec) void WeaselTSF::_StartComposition(ITfContext *pContext, BOOL fCUASWorkaroundEnabled) { - if (!_fCUASWorkaroundTested) - { - /* Test if we need to apply the workaround */ - _UpdateCompositionWindow(_pEditSessionContext); - } - else if (!fCUASWorkaroundEnabled) - { - /* Workaround not applied, update candidate window position at this point. */ - _UpdateCompositionWindow(_pEditSessionContext); - } CStartCompositionEditSession *pStartCompositionEditSession; if ((pStartCompositionEditSession = new CStartCompositionEditSession(this, pContext, fCUASWorkaroundEnabled)) != NULL) { HRESULT hr; - pContext->RequestEditSession(_tfClientId, pStartCompositionEditSession, TF_ES_ASYNCDONTCARE | TF_ES_READWRITE, &hr); + pContext->RequestEditSession(_tfClientId, pStartCompositionEditSession, TF_ES_SYNC | TF_ES_READWRITE, &hr); pStartCompositionEditSession->Release(); } } @@ -92,7 +89,7 @@ void WeaselTSF::_StartComposition(ITfContext *pContext, BOOL fCUASWorkaroundEnab class CEndCompositionEditSession: public CEditSession { public: - CEndCompositionEditSession(WeaselTSF *pTextService, ITfContext *pContext, ITfComposition *pComposition, bool clear = true) + CEndCompositionEditSession(WeaselTSF *pTextService, ITfContext *pContext, ITfComposition *pComposition, BOOL clear = TRUE) : CEditSession(pTextService, pContext), _clear(clear) { _pComposition = pComposition; @@ -103,18 +100,19 @@ class CEndCompositionEditSession: public CEditSession private: ITfComposition *_pComposition; - bool _clear; + BOOL _clear; }; STDAPI CEndCompositionEditSession::DoEditSession(TfEditCookie ec) { /* Clear the dummy text we set before, if any. */ + if (_pComposition == nullptr) return S_OK; ITfRange *pCompositionRange; if (_clear && _pComposition->GetRange(&pCompositionRange) == S_OK) pCompositionRange->SetText(ec, 0, L"", 0); _pComposition->EndComposition(ec); - _pTextService->OnCompositionTerminated(ec, _pComposition); + _pTextService->_FinalizeComposition(); return S_OK; } @@ -125,7 +123,7 @@ void WeaselTSF::_EndComposition(ITfContext *pContext, BOOL clear) if ((pEditSession = new CEndCompositionEditSession(this, pContext, _pComposition, clear)) != NULL) { - pContext->RequestEditSession(_tfClientId, pEditSession, TF_ES_ASYNCDONTCARE | TF_ES_READWRITE, &hr); + pContext->RequestEditSession(_tfClientId, pEditSession, TF_ES_SYNC | TF_ES_READWRITE, &hr); pEditSession->Release(); } } @@ -160,7 +158,7 @@ STDAPI CGetTextExtentEditSession::DoEditSession(TfEditCookie ec) if ((pInsertAtSelection->InsertTextAtSelection(ec, TF_IAS_QUERYONLY, NULL, 0, &pRangeComposition)) != S_OK) goto Exit; - if ((_pContextView->GetTextExt(ec, pRangeComposition, &rc, &fClipped)) == S_OK) + if ((_pContextView->GetTextExt(ec, pRangeComposition, &rc, &fClipped)) == S_OK && (rc.left != 0 || rc.top != 0)) _pTextService->_SetCompositionPosition(rc); Exit: @@ -181,7 +179,7 @@ BOOL WeaselTSF::_UpdateCompositionWindow(ITfContext *pContext) if ((pEditSession = new CGetTextExtentEditSession(this, pContext, pContextView, _pComposition)) != NULL) { HRESULT hr; - pContext->RequestEditSession(_tfClientId, pEditSession, TF_ES_ASYNCDONTCARE | TF_ES_READ, &hr); + pContext->RequestEditSession(_tfClientId, pEditSession, TF_ES_SYNC | TF_ES_READ, &hr); pEditSession->Release(); pContextView->Release(); return TRUE; @@ -207,6 +205,7 @@ void WeaselTSF::_SetCompositionPosition(const RECT &rc) _rc.left = _rc.right = rc.left; _rc.top = _rc.bottom = rc.bottom; m_client.UpdateInputPosition(rc); + _cand->UpdateInputPosition(rc); } /* Inline Preedit */ @@ -318,7 +317,6 @@ STDMETHODIMP CInsertTextEditSession::DoEditSession(TfEditCookie ec) pRange->Release(); return hRet; - } BOOL WeaselTSF::_InsertText(ITfContext *pContext, const std::wstring& text) @@ -347,13 +345,32 @@ void WeaselTSF::_UpdateComposition(ITfContext *pContext) /* Composition State */ STDAPI WeaselTSF::OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition) +{ + // NOTE: + // This will be called when an edit session ended up with an empty composition string, + // Even if it is closed normally. + // Silly M$. + + _AbortComposition(); + return S_OK; +} + +void WeaselTSF::_AbortComposition(bool clear) +{ + m_client.ClearComposition(); + if (_IsComposing()) { + _EndComposition(_pEditSessionContext, clear); + } + _cand->Show(false); +} + +void WeaselTSF::_FinalizeComposition() { if (_pComposition != NULL) { _pComposition->Release(); _pComposition = NULL; } - return S_OK; } void WeaselTSF::_SetComposition(ITfComposition *pComposition) diff --git a/WeaselTSF/EditSession.cpp b/WeaselTSF/EditSession.cpp index c481414df..cf7f86088 100644 --- a/WeaselTSF/EditSession.cpp +++ b/WeaselTSF/EditSession.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "WeaselTSF.h" +#include "CandidateList.h" #include "ResponseParser.h" STDAPI WeaselTSF::DoEditSession(TfEditCookie ec) @@ -8,13 +9,19 @@ STDAPI WeaselTSF::DoEditSession(TfEditCookie ec) std::wstring commit; weasel::Status status; weasel::Config config; - auto context = std::make_shared(); - weasel::ResponseParser parser(&commit, context.get(), &status, &config); + auto _NewComposition = [this, &config]() { + _UpdateCompositionWindow(_pEditSessionContext); + _StartComposition(_pEditSessionContext, _fCUASWorkaroundEnabled && !config.inline_preedit); + }; + + weasel::ResponseParser parser(&commit, context.get(), &status, &config, &_cand->style()); bool ok = m_client.GetResponseData(std::ref(parser)); + _UpdateUI(*context, status); + if (ok) { if (!commit.empty()) @@ -22,24 +29,29 @@ STDAPI WeaselTSF::DoEditSession(TfEditCookie ec) // For auto-selecting, commit and preedit can both exist. // Commit and close the original composition first. if (!_IsComposing()) { - _StartComposition(_pEditSessionContext, _fCUASWorkaroundEnabled && !config.inline_preedit); + _NewComposition(); } _InsertText(_pEditSessionContext, commit); _EndComposition(_pEditSessionContext, false); } if (status.composing && !_IsComposing()) { - _StartComposition(_pEditSessionContext, _fCUASWorkaroundEnabled && !config.inline_preedit); + _NewComposition(); } else if (!status.composing && _IsComposing()) { _EndComposition(_pEditSessionContext, true); } + if (status.composing) { + _UpdateCompositionWindow(_pEditSessionContext); + } if (_IsComposing() && config.inline_preedit) { _ShowInlinePreedit(_pEditSessionContext, context); } } + + return TRUE; } diff --git a/WeaselTSF/KeyEventSink.cpp b/WeaselTSF/KeyEventSink.cpp index 63a89c1e9..a97a4add0 100644 --- a/WeaselTSF/KeyEventSink.cpp +++ b/WeaselTSF/KeyEventSink.cpp @@ -26,8 +26,11 @@ STDAPI WeaselTSF::OnSetFocus(BOOL fForeground) { if (fForeground) m_client.FocusIn(); - else + else { m_client.FocusOut(); + _AbortComposition(); + } + return S_OK; } diff --git a/WeaselTSF/ThreadMgrEventSink.cpp b/WeaselTSF/ThreadMgrEventSink.cpp index 6f2960a47..d0023c0a3 100644 --- a/WeaselTSF/ThreadMgrEventSink.cpp +++ b/WeaselTSF/ThreadMgrEventSink.cpp @@ -13,6 +13,7 @@ STDAPI WeaselTSF::OnUninitDocumentMgr(ITfDocumentMgr *pDocMgr) STDAPI WeaselTSF::OnSetFocus(ITfDocumentMgr *pDocMgrFocus, ITfDocumentMgr *pDocMgrPrevFocus) { + _AbortComposition(); _InitTextEditSink(pDocMgrFocus); return S_OK; diff --git a/WeaselTSF/WeaselTSF.cpp b/WeaselTSF/WeaselTSF.cpp index b679ab403..93e50c80d 100644 --- a/WeaselTSF/WeaselTSF.cpp +++ b/WeaselTSF/WeaselTSF.cpp @@ -2,6 +2,7 @@ #include "WeaselTSF.h" #include "WeaselCommon.h" +#include "CandidateList.h" static void error_message(const WCHAR *msg) { @@ -14,67 +15,6 @@ static void error_message(const WCHAR *msg) } } -//static bool launch_server() -//{ -// // 從註冊表取得server位置 -// HKEY hKey; -// LSTATUS ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); -// if (ret != ERROR_SUCCESS) -// { -// error_message(L"註冊表信息無影了"); -// return false; -// } -// -// WCHAR value[MAX_PATH]; -// DWORD len = sizeof(value); -// DWORD type = 0; -// ret = RegQueryValueEx(hKey, L"WeaselRoot", NULL, &type, (LPBYTE)value, &len); -// if (ret != ERROR_SUCCESS) -// { -// error_message(L"未設置 WeaselRoot"); -// RegCloseKey(hKey); -// return false; -// } -// wpath weaselRoot(value); -// -// len = sizeof(value); -// type = 0; -// ret = RegQueryValueEx(hKey, L"ServerExecutable", NULL, &type, (LPBYTE)value, &len); -// if (ret != ERROR_SUCCESS) -// { -// error_message(L"未設置 ServerExecutable"); -// RegCloseKey(hKey); -// return false; -// } -// wpath serverPath(weaselRoot / value); -// -// RegCloseKey(hKey); -// -// // 啓動服務進程 -// std::wstring exe = serverPath.wstring(); -// std::wstring dir = weaselRoot.wstring(); -// -// STARTUPINFO startup_info = {0}; -// PROCESS_INFORMATION process_info = {0}; -// startup_info.cb = sizeof(startup_info); -// -// if (!CreateProcess(exe.c_str(), NULL, NULL, NULL, FALSE, 0, NULL, dir.c_str(), &startup_info, &process_info)) -// { -// // EZDBGONLYLOGGERPRINT("ERROR: failed to launch weasel server."); -// error_message(L"服務進程啓動不起來 :("); -// return false; -// } -// -// if (!WaitForInputIdle(process_info.hProcess, 1500)) -// { -//// EZDBGONLYLOGGERPRINT("WARNING: WaitForInputIdle() timed out; succeeding IPC messages might not be delivered."); -// } -// if (process_info.hProcess) CloseHandle(process_info.hProcess); -// if (process_info.hThread) CloseHandle(process_info.hThread); -// -// return true; -//} - WeaselTSF::WeaselTSF() { _cRef = 1; @@ -93,6 +33,8 @@ WeaselTSF::WeaselTSF() _fCUASWorkaroundTested = _fCUASWorkaroundEnabled = FALSE; + _cand = std::make_unique(this); + DllAddRef(); } @@ -109,19 +51,23 @@ STDAPI WeaselTSF::QueryInterface(REFIID riid, void **ppvObject) *ppvObject = NULL; if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfTextInputProcessor)) - *ppvObject = (ITfTextInputProcessor *) this; + *ppvObject = (ITfTextInputProcessor *)this; + else if (IsEqualIID(riid, IID_ITfTextInputProcessorEx)) + *ppvObject = (ITfTextInputProcessorEx *)this; else if (IsEqualIID(riid, IID_ITfThreadMgrEventSink)) - *ppvObject = (ITfThreadMgrEventSink *) this; + *ppvObject = (ITfThreadMgrEventSink *)this; else if (IsEqualIID(riid, IID_ITfTextEditSink)) - *ppvObject = (ITfTextEditSink *) this; + *ppvObject = (ITfTextEditSink *)this; else if (IsEqualIID(riid, IID_ITfTextLayoutSink)) - *ppvObject = (ITfTextLayoutSink *) this; + *ppvObject = (ITfTextLayoutSink *)this; else if (IsEqualIID(riid, IID_ITfKeyEventSink)) - *ppvObject = (ITfKeyEventSink *) this; + *ppvObject = (ITfKeyEventSink *)this; else if (IsEqualIID(riid, IID_ITfCompositionSink)) - *ppvObject = (ITfCompositionSink *) this; + *ppvObject = (ITfCompositionSink *)this; else if (IsEqualIID(riid, IID_ITfEditSession)) - *ppvObject = (ITfEditSession *) this; + *ppvObject = (ITfEditSession *)this; + else if (IsEqualIID(riid, IID_ITfThreadFocusSink)) + *ppvObject = (ITfThreadFocusSink *)this; if (*ppvObject) { @@ -150,7 +96,36 @@ STDAPI_(ULONG) WeaselTSF::Release() STDAPI WeaselTSF::Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClientId) { - //((ITfThreadMgr2 *)pThreadMgr)->GetActiveFlags(&_activateFlags); + return ActivateEx(pThreadMgr, tfClientId, 0U); +} + +STDAPI WeaselTSF::Deactivate() +{ + m_client.EndSession(); + + _InitTextEditSink(NULL); + + _UninitThreadMgrEventSink(); + + _UninitKeyEventSink(); + _UninitPreservedKey(); + + _UninitLanguageBar(); + + if (_pThreadMgr != NULL) + { + _pThreadMgr->Release(); + _pThreadMgr = NULL; + } + + _tfClientId = TF_CLIENTID_NULL; + + return S_OK; +} + +STDAPI WeaselTSF::ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, DWORD dwFlags) +{ + _activateFlags = dwFlags; _EnsureServerConnected(); _pThreadMgr = pThreadMgr; @@ -188,29 +163,16 @@ STDAPI WeaselTSF::Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClientId) return E_FAIL; } -STDAPI WeaselTSF::Deactivate() +STDMETHODIMP WeaselTSF::OnSetThreadFocus() { - m_client.EndSession(); - - _InitTextEditSink(NULL); - - _UninitThreadMgrEventSink(); - - _UninitKeyEventSink(); - _UninitPreservedKey(); - - _UninitLanguageBar(); - - if (_pThreadMgr != NULL) - { - _pThreadMgr->Release(); - _pThreadMgr = NULL; - } - - _tfClientId = TF_CLIENTID_NULL; - return S_OK; } +STDMETHODIMP WeaselTSF::OnKillThreadFocus() +{ + _AbortComposition(); + return S_OK; +} + void WeaselTSF::_EnsureServerConnected() { diff --git a/WeaselTSF/WeaselTSF.h b/WeaselTSF/WeaselTSF.h index 19698a23f..ba53616d0 100644 --- a/WeaselTSF/WeaselTSF.h +++ b/WeaselTSF/WeaselTSF.h @@ -1,15 +1,21 @@ #pragma once +#include #include "Globals.h" #include "WeaselIPC.h" +namespace weasel { + class CandidateList; +} + class WeaselTSF: - public ITfTextInputProcessor, + public ITfTextInputProcessorEx, public ITfThreadMgrEventSink, public ITfTextEditSink, public ITfTextLayoutSink, public ITfKeyEventSink, public ITfCompositionSink, + public ITfThreadFocusSink, public ITfEditSession { public: @@ -25,6 +31,9 @@ class WeaselTSF: STDMETHODIMP Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClientId); STDMETHODIMP Deactivate(); + /* ITfTextInputProcessorEx */ + STDMETHODIMP ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, DWORD dwFlags); + /* ITfThreadMgrEventSink */ STDMETHODIMP OnInitDocumentMgr(ITfDocumentMgr *pDocMgr); STDMETHODIMP OnUninitDocumentMgr(ITfDocumentMgr *pDocMgr); @@ -43,9 +52,13 @@ class WeaselTSF: STDMETHODIMP OnTestKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten); STDMETHODIMP OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten); STDMETHODIMP OnTestKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten); - STDMETHODIMP OnKeyUp(ITfContext *pContext, WPARAM wParm, LPARAM lParam, BOOL *pfEaten); + STDMETHODIMP OnKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten); STDMETHODIMP OnPreservedKey(ITfContext *pContext, REFGUID rguid, BOOL *pfEaten); + // ITfThreadFocusSink + STDMETHODIMP OnSetThreadFocus(); + STDMETHODIMP OnKillThreadFocus(); + /* ITfCompositionSink */ STDMETHODIMP OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition); @@ -66,6 +79,7 @@ class WeaselTSF: void _SetComposition(ITfComposition *pComposition); void _SetCompositionPosition(const RECT &rc); BOOL _UpdateCompositionWindow(ITfContext *pContext); + void _FinalizeComposition(); /* Language bar */ HWND _GetFocusedContextWindow(); @@ -74,7 +88,12 @@ class WeaselTSF: /* IPC */ void _EnsureServerConnected(); + /* UI */ + void _UpdateUI(const weasel::Context & ctx, const weasel::Status & status); + private: + friend class weasel::CandidateList; + /* TSF Related */ BOOL _InitThreadMgrEventSink(); void _UninitThreadMgrEventSink(); @@ -92,6 +111,7 @@ class WeaselTSF: void _UninitLanguageBar(); BOOL _InsertText(ITfContext *pContext, const std::wstring& ext); + void _AbortComposition(bool clear = true); bool isImmersive() const { return (_activateFlags & TF_TMF_IMMERSIVEMODE) != 0; @@ -113,6 +133,8 @@ class WeaselTSF: ITfLangBarItemButton *_pLangBarButton; + std::unique_ptr _cand; + LONG _cRef; // COM ref count /* CUAS Candidate Window Position Workaround */ diff --git a/WeaselTSF/WeaselTSF.vcxproj b/WeaselTSF/WeaselTSF.vcxproj index 4793c95df..e329c7672 100644 --- a/WeaselTSF/WeaselTSF.vcxproj +++ b/WeaselTSF/WeaselTSF.vcxproj @@ -120,12 +120,12 @@ false - $(SolutionDir)output\ + $(SolutionDir)output\ weasel false - $(SolutionDir)output\ + $(SolutionDir)output\ weaselt @@ -136,12 +136,12 @@ false - $(SolutionDir)output\ + $(SolutionDir)output\ weasel$(Platform) false - $(SolutionDir)output\ + $(SolutionDir)output\ weaselt$(Platform) @@ -154,7 +154,7 @@ WIN32;_DEBUG;_WINDOWS;_USRDLL;WEASELTSF_EXPORTS;%(PreprocessorDefinitions) true EnableFastChecks - MultiThreadedDebugDLL + MultiThreadedDebug Use Level3 EditAndContinue @@ -167,6 +167,7 @@ Windows MachineX86 WeaselTSF.def + Usp10.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(SolutionDir)\include @@ -194,7 +195,7 @@ true MachineX86 WeaselTSF.def - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + Usp10.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(SolutionDir)\include @@ -222,6 +223,7 @@ true MachineX86 WeaselTSF.def + Usp10.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) WEASEL_HANT;%(PreprocessorDefinitions) @@ -250,6 +252,7 @@ true MachineX86 WeaselTSF.def + Usp10.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(SolutionDir)\include @@ -265,7 +268,7 @@ WIN32;_DEBUG;_WINDOWS;_USRDLL;WEASELTSF_EXPORTS;%(PreprocessorDefinitions) true EnableFastChecks - MultiThreadedDebugDLL + MultiThreadedDebug Use Level3 ProgramDatabase @@ -279,6 +282,7 @@ MachineX64 WeaselTSF.def $(OutDir)weaselx64.pdb + Usp10.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(SolutionDir)\include @@ -309,6 +313,7 @@ true MachineX64 WeaselTSF.def + Usp10.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(SolutionDir)\include @@ -339,6 +344,7 @@ true MachineX64 WeaselTSF.def + Usp10.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) WEASEL_HANT;%(PreprocessorDefinitions) @@ -370,12 +376,14 @@ true MachineX64 WeaselTSF.def + Usp10.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(SolutionDir)\include + @@ -426,6 +434,8 @@ + + @@ -448,6 +458,9 @@ {ce11a2df-8d20-4b07-a935-4b0d03f0303d} false + + {10b3b8bf-7294-4661-9a8a-2ffc920fa2f4} + diff --git a/WeaselTSF/WeaselTSF.vcxproj.filters b/WeaselTSF/WeaselTSF.vcxproj.filters index f1723801c..8f9634bb9 100644 --- a/WeaselTSF/WeaselTSF.vcxproj.filters +++ b/WeaselTSF/WeaselTSF.vcxproj.filters @@ -57,6 +57,9 @@ Source Files + + Source Files + @@ -83,6 +86,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/WeaselTSF/ctffunc.h b/WeaselTSF/ctffunc.h new file mode 100644 index 000000000..661f9b270 --- /dev/null +++ b/WeaselTSF/ctffunc.h @@ -0,0 +1,3225 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 8.01.0622 */ +/* @@MIDL_FILE_HEADING( ) */ + + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __ctffunc_h__ +#define __ctffunc_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ITfCandidateString_FWD_DEFINED__ +#define __ITfCandidateString_FWD_DEFINED__ +typedef interface ITfCandidateString ITfCandidateString; + +#endif /* __ITfCandidateString_FWD_DEFINED__ */ + + +#ifndef __IEnumTfCandidates_FWD_DEFINED__ +#define __IEnumTfCandidates_FWD_DEFINED__ +typedef interface IEnumTfCandidates IEnumTfCandidates; + +#endif /* __IEnumTfCandidates_FWD_DEFINED__ */ + + +#ifndef __ITfCandidateList_FWD_DEFINED__ +#define __ITfCandidateList_FWD_DEFINED__ +typedef interface ITfCandidateList ITfCandidateList; + +#endif /* __ITfCandidateList_FWD_DEFINED__ */ + + +#ifndef __ITfFnReconversion_FWD_DEFINED__ +#define __ITfFnReconversion_FWD_DEFINED__ +typedef interface ITfFnReconversion ITfFnReconversion; + +#endif /* __ITfFnReconversion_FWD_DEFINED__ */ + + +#ifndef __ITfFnPlayBack_FWD_DEFINED__ +#define __ITfFnPlayBack_FWD_DEFINED__ +typedef interface ITfFnPlayBack ITfFnPlayBack; + +#endif /* __ITfFnPlayBack_FWD_DEFINED__ */ + + +#ifndef __ITfFnLangProfileUtil_FWD_DEFINED__ +#define __ITfFnLangProfileUtil_FWD_DEFINED__ +typedef interface ITfFnLangProfileUtil ITfFnLangProfileUtil; + +#endif /* __ITfFnLangProfileUtil_FWD_DEFINED__ */ + + +#ifndef __ITfFnConfigure_FWD_DEFINED__ +#define __ITfFnConfigure_FWD_DEFINED__ +typedef interface ITfFnConfigure ITfFnConfigure; + +#endif /* __ITfFnConfigure_FWD_DEFINED__ */ + + +#ifndef __ITfFnConfigureRegisterWord_FWD_DEFINED__ +#define __ITfFnConfigureRegisterWord_FWD_DEFINED__ +typedef interface ITfFnConfigureRegisterWord ITfFnConfigureRegisterWord; + +#endif /* __ITfFnConfigureRegisterWord_FWD_DEFINED__ */ + + +#ifndef __ITfFnConfigureRegisterEudc_FWD_DEFINED__ +#define __ITfFnConfigureRegisterEudc_FWD_DEFINED__ +typedef interface ITfFnConfigureRegisterEudc ITfFnConfigureRegisterEudc; + +#endif /* __ITfFnConfigureRegisterEudc_FWD_DEFINED__ */ + + +#ifndef __ITfFnShowHelp_FWD_DEFINED__ +#define __ITfFnShowHelp_FWD_DEFINED__ +typedef interface ITfFnShowHelp ITfFnShowHelp; + +#endif /* __ITfFnShowHelp_FWD_DEFINED__ */ + + +#ifndef __ITfFnBalloon_FWD_DEFINED__ +#define __ITfFnBalloon_FWD_DEFINED__ +typedef interface ITfFnBalloon ITfFnBalloon; + +#endif /* __ITfFnBalloon_FWD_DEFINED__ */ + + +#ifndef __ITfFnGetSAPIObject_FWD_DEFINED__ +#define __ITfFnGetSAPIObject_FWD_DEFINED__ +typedef interface ITfFnGetSAPIObject ITfFnGetSAPIObject; + +#endif /* __ITfFnGetSAPIObject_FWD_DEFINED__ */ + + +#ifndef __ITfFnPropertyUIStatus_FWD_DEFINED__ +#define __ITfFnPropertyUIStatus_FWD_DEFINED__ +typedef interface ITfFnPropertyUIStatus ITfFnPropertyUIStatus; + +#endif /* __ITfFnPropertyUIStatus_FWD_DEFINED__ */ + + +#ifndef __IEnumSpeechCommands_FWD_DEFINED__ +#define __IEnumSpeechCommands_FWD_DEFINED__ +typedef interface IEnumSpeechCommands IEnumSpeechCommands; + +#endif /* __IEnumSpeechCommands_FWD_DEFINED__ */ + + +#ifndef __ISpeechCommandProvider_FWD_DEFINED__ +#define __ISpeechCommandProvider_FWD_DEFINED__ +typedef interface ISpeechCommandProvider ISpeechCommandProvider; + +#endif /* __ISpeechCommandProvider_FWD_DEFINED__ */ + + +#ifndef __ITfFnCustomSpeechCommand_FWD_DEFINED__ +#define __ITfFnCustomSpeechCommand_FWD_DEFINED__ +typedef interface ITfFnCustomSpeechCommand ITfFnCustomSpeechCommand; + +#endif /* __ITfFnCustomSpeechCommand_FWD_DEFINED__ */ + + +#ifndef __ITfFnLMProcessor_FWD_DEFINED__ +#define __ITfFnLMProcessor_FWD_DEFINED__ +typedef interface ITfFnLMProcessor ITfFnLMProcessor; + +#endif /* __ITfFnLMProcessor_FWD_DEFINED__ */ + + +#ifndef __ITfFnLMInternal_FWD_DEFINED__ +#define __ITfFnLMInternal_FWD_DEFINED__ +typedef interface ITfFnLMInternal ITfFnLMInternal; + +#endif /* __ITfFnLMInternal_FWD_DEFINED__ */ + + +#ifndef __IEnumTfLatticeElements_FWD_DEFINED__ +#define __IEnumTfLatticeElements_FWD_DEFINED__ +typedef interface IEnumTfLatticeElements IEnumTfLatticeElements; + +#endif /* __IEnumTfLatticeElements_FWD_DEFINED__ */ + + +#ifndef __ITfLMLattice_FWD_DEFINED__ +#define __ITfLMLattice_FWD_DEFINED__ +typedef interface ITfLMLattice ITfLMLattice; + +#endif /* __ITfLMLattice_FWD_DEFINED__ */ + + +#ifndef __ITfFnAdviseText_FWD_DEFINED__ +#define __ITfFnAdviseText_FWD_DEFINED__ +typedef interface ITfFnAdviseText ITfFnAdviseText; + +#endif /* __ITfFnAdviseText_FWD_DEFINED__ */ + + +#ifndef __ITfFnSearchCandidateProvider_FWD_DEFINED__ +#define __ITfFnSearchCandidateProvider_FWD_DEFINED__ +typedef interface ITfFnSearchCandidateProvider ITfFnSearchCandidateProvider; + +#endif /* __ITfFnSearchCandidateProvider_FWD_DEFINED__ */ + + +#ifndef __ITfIntegratableCandidateListUIElement_FWD_DEFINED__ +#define __ITfIntegratableCandidateListUIElement_FWD_DEFINED__ +typedef interface ITfIntegratableCandidateListUIElement ITfIntegratableCandidateListUIElement; + +#endif /* __ITfIntegratableCandidateListUIElement_FWD_DEFINED__ */ + + +#ifndef __ITfFnGetPreferredTouchKeyboardLayout_FWD_DEFINED__ +#define __ITfFnGetPreferredTouchKeyboardLayout_FWD_DEFINED__ +typedef interface ITfFnGetPreferredTouchKeyboardLayout ITfFnGetPreferredTouchKeyboardLayout; + +#endif /* __ITfFnGetPreferredTouchKeyboardLayout_FWD_DEFINED__ */ + + +#ifndef __ITfFnGetLinguisticAlternates_FWD_DEFINED__ +#define __ITfFnGetLinguisticAlternates_FWD_DEFINED__ +typedef interface ITfFnGetLinguisticAlternates ITfFnGetLinguisticAlternates; + +#endif /* __ITfFnGetLinguisticAlternates_FWD_DEFINED__ */ + + +#ifndef __IUIManagerEventSink_FWD_DEFINED__ +#define __IUIManagerEventSink_FWD_DEFINED__ +typedef interface IUIManagerEventSink IUIManagerEventSink; + +#endif /* __IUIManagerEventSink_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "msctf.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_ctffunc_0000_0000 */ +/* [local] */ + +#include +//=--------------------------------------------------------------------------= +// ctffunc.h + + +// Text Framework function interfaces. + +//=--------------------------------------------------------------------------= +// (C) Copyright 1995-2001 Microsoft Corporation. All Rights Reserved. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +//=--------------------------------------------------------------------------= + +#ifndef CTFFUNC_DEFINED +#define CTFFUNC_DEFINED + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#pragma region Application Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define TF_E_NOCONVERSION MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0600) +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */ +#pragma endregion +#pragma region Desktop Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +EXTERN_C const CLSID CLSID_SapiLayr; +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ +#pragma endregion +#pragma region Application Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + + +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0000_v0_0_s_ifspec; + +#ifndef __ITfCandidateString_INTERFACE_DEFINED__ +#define __ITfCandidateString_INTERFACE_DEFINED__ + +/* interface ITfCandidateString */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfCandidateString; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("581f317e-fd9d-443f-b972-ed00467c5d40") + ITfCandidateString : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetString( + /* [out] */ __RPC__deref_out_opt BSTR *pbstr) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetIndex( + /* [out] */ __RPC__out ULONG *pnIndex) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfCandidateStringVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfCandidateString * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfCandidateString * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfCandidateString * This); + + HRESULT ( STDMETHODCALLTYPE *GetString )( + __RPC__in ITfCandidateString * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstr); + + HRESULT ( STDMETHODCALLTYPE *GetIndex )( + __RPC__in ITfCandidateString * This, + /* [out] */ __RPC__out ULONG *pnIndex); + + END_INTERFACE + } ITfCandidateStringVtbl; + + interface ITfCandidateString + { + CONST_VTBL struct ITfCandidateStringVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCandidateString_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCandidateString_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCandidateString_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCandidateString_GetString(This,pbstr) \ + ( (This)->lpVtbl -> GetString(This,pbstr) ) + +#define ITfCandidateString_GetIndex(This,pnIndex) \ + ( (This)->lpVtbl -> GetIndex(This,pnIndex) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCandidateString_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfCandidates_INTERFACE_DEFINED__ +#define __IEnumTfCandidates_INTERFACE_DEFINED__ + +/* interface IEnumTfCandidates */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfCandidates; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("defb1926-6c80-4ce8-87d4-d6b72b812bde") + IEnumTfCandidates : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ __RPC__deref_out_opt IEnumTfCandidates **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ __RPC__out_ecount_part(ulCount, *pcFetched) ITfCandidateString **ppCand, + /* [out] */ __RPC__out ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IEnumTfCandidatesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in IEnumTfCandidates * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in IEnumTfCandidates * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in IEnumTfCandidates * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + __RPC__in IEnumTfCandidates * This, + /* [out] */ __RPC__deref_out_opt IEnumTfCandidates **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + __RPC__in IEnumTfCandidates * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ __RPC__out_ecount_part(ulCount, *pcFetched) ITfCandidateString **ppCand, + /* [out] */ __RPC__out ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + __RPC__in IEnumTfCandidates * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + __RPC__in IEnumTfCandidates * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfCandidatesVtbl; + + interface IEnumTfCandidates + { + CONST_VTBL struct IEnumTfCandidatesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfCandidates_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfCandidates_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfCandidates_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfCandidates_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfCandidates_Next(This,ulCount,ppCand,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,ppCand,pcFetched) ) + +#define IEnumTfCandidates_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfCandidates_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfCandidates_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCandidateList_INTERFACE_DEFINED__ +#define __ITfCandidateList_INTERFACE_DEFINED__ + +/* interface ITfCandidateList */ +/* [unique][uuid][object] */ + +typedef /* [public][public][uuid] */ DECLSPEC_UUID("baa898f2-0207-4643-92ca-f3f7b0cf6f80") +enum __MIDL_ITfCandidateList_0001 + { + CAND_FINALIZED = 0, + CAND_SELECTED = 0x1, + CAND_CANCELED = 0x2 + } TfCandidateResult; + + +EXTERN_C const IID IID_ITfCandidateList; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("a3ad50fb-9bdb-49e3-a843-6c76520fbf5d") + ITfCandidateList : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE EnumCandidates( + /* [out] */ __RPC__deref_out_opt IEnumTfCandidates **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidate( + /* [in] */ ULONG nIndex, + /* [out] */ __RPC__deref_out_opt ITfCandidateString **ppCand) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateNum( + /* [out] */ __RPC__out ULONG *pnCnt) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetResult( + /* [in] */ ULONG nIndex, + /* [in] */ TfCandidateResult imcr) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfCandidateListVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfCandidateList * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfCandidateList * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfCandidateList * This); + + HRESULT ( STDMETHODCALLTYPE *EnumCandidates )( + __RPC__in ITfCandidateList * This, + /* [out] */ __RPC__deref_out_opt IEnumTfCandidates **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetCandidate )( + __RPC__in ITfCandidateList * This, + /* [in] */ ULONG nIndex, + /* [out] */ __RPC__deref_out_opt ITfCandidateString **ppCand); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateNum )( + __RPC__in ITfCandidateList * This, + /* [out] */ __RPC__out ULONG *pnCnt); + + HRESULT ( STDMETHODCALLTYPE *SetResult )( + __RPC__in ITfCandidateList * This, + /* [in] */ ULONG nIndex, + /* [in] */ TfCandidateResult imcr); + + END_INTERFACE + } ITfCandidateListVtbl; + + interface ITfCandidateList + { + CONST_VTBL struct ITfCandidateListVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCandidateList_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCandidateList_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCandidateList_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCandidateList_EnumCandidates(This,ppEnum) \ + ( (This)->lpVtbl -> EnumCandidates(This,ppEnum) ) + +#define ITfCandidateList_GetCandidate(This,nIndex,ppCand) \ + ( (This)->lpVtbl -> GetCandidate(This,nIndex,ppCand) ) + +#define ITfCandidateList_GetCandidateNum(This,pnCnt) \ + ( (This)->lpVtbl -> GetCandidateNum(This,pnCnt) ) + +#define ITfCandidateList_SetResult(This,nIndex,imcr) \ + ( (This)->lpVtbl -> SetResult(This,nIndex,imcr) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCandidateList_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnReconversion_INTERFACE_DEFINED__ +#define __ITfFnReconversion_INTERFACE_DEFINED__ + +/* interface ITfFnReconversion */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnReconversion; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4cea93c0-0a58-11d3-8df0-00105a2799b5") + ITfFnReconversion : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE QueryRange( + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [unique][out][in] */ __RPC__deref_opt_inout_opt ITfRange **ppNewRange, + /* [out] */ __RPC__out BOOL *pfConvertable) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetReconversion( + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [out] */ __RPC__deref_out_opt ITfCandidateList **ppCandList) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reconvert( + /* [in] */ __RPC__in_opt ITfRange *pRange) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnReconversionVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnReconversion * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnReconversion * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnReconversion * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnReconversion * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *QueryRange )( + __RPC__in ITfFnReconversion * This, + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [unique][out][in] */ __RPC__deref_opt_inout_opt ITfRange **ppNewRange, + /* [out] */ __RPC__out BOOL *pfConvertable); + + HRESULT ( STDMETHODCALLTYPE *GetReconversion )( + __RPC__in ITfFnReconversion * This, + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [out] */ __RPC__deref_out_opt ITfCandidateList **ppCandList); + + HRESULT ( STDMETHODCALLTYPE *Reconvert )( + __RPC__in ITfFnReconversion * This, + /* [in] */ __RPC__in_opt ITfRange *pRange); + + END_INTERFACE + } ITfFnReconversionVtbl; + + interface ITfFnReconversion + { + CONST_VTBL struct ITfFnReconversionVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnReconversion_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnReconversion_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnReconversion_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnReconversion_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnReconversion_QueryRange(This,pRange,ppNewRange,pfConvertable) \ + ( (This)->lpVtbl -> QueryRange(This,pRange,ppNewRange,pfConvertable) ) + +#define ITfFnReconversion_GetReconversion(This,pRange,ppCandList) \ + ( (This)->lpVtbl -> GetReconversion(This,pRange,ppCandList) ) + +#define ITfFnReconversion_Reconvert(This,pRange) \ + ( (This)->lpVtbl -> Reconvert(This,pRange) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnReconversion_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_ctffunc_0000_0004 */ +/* [local] */ + +EXTERN_C const GUID GUID_COMPARTMENT_SAPI_AUDIO; +EXTERN_C const GUID GUID_COMPARTMENT_SPEECH_DICTATIONSTAT; +#define TF_DICTATION_ON 0x00000001 +#define TF_DICTATION_ENABLED 0x00000002 +#define TF_COMMANDING_ENABLED 0x00000004 +#define TF_COMMANDING_ON 0x00000008 +#define TF_SPEECHUI_SHOWN 0x00000010 + +EXTERN_C const GUID GUID_COMPARTMENT_SPEECH_UI_STATUS; +#define TF_SHOW_BALLOON 0x00000001 +#define TF_DISABLE_BALLOON 0x00000002 +EXTERN_C const GUID GUID_COMPARTMENT_SPEECH_CFGMENU; +#define TF_MENUREADY 0x00000001 +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */ +#pragma endregion +#pragma region Desktop Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +EXTERN_C const GUID GUID_LBI_SAPILAYR_CFGMENUBUTTON; +EXTERN_C const GUID GUID_LBI_INPUTMODE; + + + +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0004_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0004_v0_0_s_ifspec; + +#ifndef __ITfFnPlayBack_INTERFACE_DEFINED__ +#define __ITfFnPlayBack_INTERFACE_DEFINED__ + +/* interface ITfFnPlayBack */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnPlayBack; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("a3a416a4-0f64-11d3-b5b7-00c04fc324a1") + ITfFnPlayBack : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE QueryRange( + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [out] */ __RPC__deref_out_opt ITfRange **ppNewRange, + /* [out] */ __RPC__out BOOL *pfPlayable) = 0; + + virtual HRESULT STDMETHODCALLTYPE Play( + /* [in] */ __RPC__in_opt ITfRange *pRange) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnPlayBackVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnPlayBack * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnPlayBack * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnPlayBack * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnPlayBack * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *QueryRange )( + __RPC__in ITfFnPlayBack * This, + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [out] */ __RPC__deref_out_opt ITfRange **ppNewRange, + /* [out] */ __RPC__out BOOL *pfPlayable); + + HRESULT ( STDMETHODCALLTYPE *Play )( + __RPC__in ITfFnPlayBack * This, + /* [in] */ __RPC__in_opt ITfRange *pRange); + + END_INTERFACE + } ITfFnPlayBackVtbl; + + interface ITfFnPlayBack + { + CONST_VTBL struct ITfFnPlayBackVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnPlayBack_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnPlayBack_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnPlayBack_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnPlayBack_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnPlayBack_QueryRange(This,pRange,ppNewRange,pfPlayable) \ + ( (This)->lpVtbl -> QueryRange(This,pRange,ppNewRange,pfPlayable) ) + +#define ITfFnPlayBack_Play(This,pRange) \ + ( (This)->lpVtbl -> Play(This,pRange) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnPlayBack_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnLangProfileUtil_INTERFACE_DEFINED__ +#define __ITfFnLangProfileUtil_INTERFACE_DEFINED__ + +/* interface ITfFnLangProfileUtil */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnLangProfileUtil; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("A87A8574-A6C1-4E15-99F0-3D3965F548EB") + ITfFnLangProfileUtil : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE RegisterActiveProfiles( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsProfileAvailableForLang( + /* [in] */ LANGID langid, + /* [out] */ __RPC__out BOOL *pfAvailable) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnLangProfileUtilVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnLangProfileUtil * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnLangProfileUtil * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnLangProfileUtil * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnLangProfileUtil * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *RegisterActiveProfiles )( + __RPC__in ITfFnLangProfileUtil * This); + + HRESULT ( STDMETHODCALLTYPE *IsProfileAvailableForLang )( + __RPC__in ITfFnLangProfileUtil * This, + /* [in] */ LANGID langid, + /* [out] */ __RPC__out BOOL *pfAvailable); + + END_INTERFACE + } ITfFnLangProfileUtilVtbl; + + interface ITfFnLangProfileUtil + { + CONST_VTBL struct ITfFnLangProfileUtilVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnLangProfileUtil_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnLangProfileUtil_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnLangProfileUtil_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnLangProfileUtil_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnLangProfileUtil_RegisterActiveProfiles(This) \ + ( (This)->lpVtbl -> RegisterActiveProfiles(This) ) + +#define ITfFnLangProfileUtil_IsProfileAvailableForLang(This,langid,pfAvailable) \ + ( (This)->lpVtbl -> IsProfileAvailableForLang(This,langid,pfAvailable) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnLangProfileUtil_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnConfigure_INTERFACE_DEFINED__ +#define __ITfFnConfigure_INTERFACE_DEFINED__ + +/* interface ITfFnConfigure */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnConfigure; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("88f567c6-1757-49f8-a1b2-89234c1eeff9") + ITfFnConfigure : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE Show( + /* [in] */ __RPC__in HWND hwndParent, + /* [in] */ LANGID langid, + /* [in] */ __RPC__in REFGUID rguidProfile) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnConfigureVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnConfigure * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnConfigure * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnConfigure * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnConfigure * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *Show )( + __RPC__in ITfFnConfigure * This, + /* [in] */ __RPC__in HWND hwndParent, + /* [in] */ LANGID langid, + /* [in] */ __RPC__in REFGUID rguidProfile); + + END_INTERFACE + } ITfFnConfigureVtbl; + + interface ITfFnConfigure + { + CONST_VTBL struct ITfFnConfigureVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnConfigure_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnConfigure_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnConfigure_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnConfigure_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnConfigure_Show(This,hwndParent,langid,rguidProfile) \ + ( (This)->lpVtbl -> Show(This,hwndParent,langid,rguidProfile) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnConfigure_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnConfigureRegisterWord_INTERFACE_DEFINED__ +#define __ITfFnConfigureRegisterWord_INTERFACE_DEFINED__ + +/* interface ITfFnConfigureRegisterWord */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnConfigureRegisterWord; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("bb95808a-6d8f-4bca-8400-5390b586aedf") + ITfFnConfigureRegisterWord : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE Show( + /* [in] */ __RPC__in HWND hwndParent, + /* [in] */ LANGID langid, + /* [in] */ __RPC__in REFGUID rguidProfile, + /* [unique][in] */ __RPC__in_opt BSTR bstrRegistered) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnConfigureRegisterWordVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnConfigureRegisterWord * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnConfigureRegisterWord * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnConfigureRegisterWord * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnConfigureRegisterWord * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *Show )( + __RPC__in ITfFnConfigureRegisterWord * This, + /* [in] */ __RPC__in HWND hwndParent, + /* [in] */ LANGID langid, + /* [in] */ __RPC__in REFGUID rguidProfile, + /* [unique][in] */ __RPC__in_opt BSTR bstrRegistered); + + END_INTERFACE + } ITfFnConfigureRegisterWordVtbl; + + interface ITfFnConfigureRegisterWord + { + CONST_VTBL struct ITfFnConfigureRegisterWordVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnConfigureRegisterWord_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnConfigureRegisterWord_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnConfigureRegisterWord_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnConfigureRegisterWord_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnConfigureRegisterWord_Show(This,hwndParent,langid,rguidProfile,bstrRegistered) \ + ( (This)->lpVtbl -> Show(This,hwndParent,langid,rguidProfile,bstrRegistered) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnConfigureRegisterWord_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnConfigureRegisterEudc_INTERFACE_DEFINED__ +#define __ITfFnConfigureRegisterEudc_INTERFACE_DEFINED__ + +/* interface ITfFnConfigureRegisterEudc */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnConfigureRegisterEudc; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("b5e26ff5-d7ad-4304-913f-21a2ed95a1b0") + ITfFnConfigureRegisterEudc : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE Show( + /* [in] */ __RPC__in HWND hwndParent, + /* [in] */ LANGID langid, + /* [in] */ __RPC__in REFGUID rguidProfile, + /* [unique][in] */ __RPC__in_opt BSTR bstrRegistered) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnConfigureRegisterEudcVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnConfigureRegisterEudc * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnConfigureRegisterEudc * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnConfigureRegisterEudc * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnConfigureRegisterEudc * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *Show )( + __RPC__in ITfFnConfigureRegisterEudc * This, + /* [in] */ __RPC__in HWND hwndParent, + /* [in] */ LANGID langid, + /* [in] */ __RPC__in REFGUID rguidProfile, + /* [unique][in] */ __RPC__in_opt BSTR bstrRegistered); + + END_INTERFACE + } ITfFnConfigureRegisterEudcVtbl; + + interface ITfFnConfigureRegisterEudc + { + CONST_VTBL struct ITfFnConfigureRegisterEudcVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnConfigureRegisterEudc_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnConfigureRegisterEudc_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnConfigureRegisterEudc_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnConfigureRegisterEudc_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnConfigureRegisterEudc_Show(This,hwndParent,langid,rguidProfile,bstrRegistered) \ + ( (This)->lpVtbl -> Show(This,hwndParent,langid,rguidProfile,bstrRegistered) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnConfigureRegisterEudc_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnShowHelp_INTERFACE_DEFINED__ +#define __ITfFnShowHelp_INTERFACE_DEFINED__ + +/* interface ITfFnShowHelp */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnShowHelp; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("5AB1D30C-094D-4C29-8EA5-0BF59BE87BF3") + ITfFnShowHelp : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE Show( + /* [in] */ __RPC__in HWND hwndParent) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnShowHelpVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnShowHelp * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnShowHelp * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnShowHelp * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnShowHelp * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *Show )( + __RPC__in ITfFnShowHelp * This, + /* [in] */ __RPC__in HWND hwndParent); + + END_INTERFACE + } ITfFnShowHelpVtbl; + + interface ITfFnShowHelp + { + CONST_VTBL struct ITfFnShowHelpVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnShowHelp_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnShowHelp_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnShowHelp_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnShowHelp_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnShowHelp_Show(This,hwndParent) \ + ( (This)->lpVtbl -> Show(This,hwndParent) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnShowHelp_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnBalloon_INTERFACE_DEFINED__ +#define __ITfFnBalloon_INTERFACE_DEFINED__ + +/* interface ITfFnBalloon */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnBalloon; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3BAB89E4-5FBE-45F4-A5BC-DCA36AD225A8") + ITfFnBalloon : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE UpdateBalloon( + /* [in] */ TfLBBalloonStyle style, + /* [size_is][in] */ __RPC__in_ecount_full(cch) const WCHAR *pch, + /* [in] */ ULONG cch) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnBalloonVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnBalloon * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnBalloon * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnBalloon * This); + + HRESULT ( STDMETHODCALLTYPE *UpdateBalloon )( + __RPC__in ITfFnBalloon * This, + /* [in] */ TfLBBalloonStyle style, + /* [size_is][in] */ __RPC__in_ecount_full(cch) const WCHAR *pch, + /* [in] */ ULONG cch); + + END_INTERFACE + } ITfFnBalloonVtbl; + + interface ITfFnBalloon + { + CONST_VTBL struct ITfFnBalloonVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnBalloon_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnBalloon_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnBalloon_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnBalloon_UpdateBalloon(This,style,pch,cch) \ + ( (This)->lpVtbl -> UpdateBalloon(This,style,pch,cch) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnBalloon_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_ctffunc_0000_0011 */ +/* [local] */ + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ +#pragma endregion +#pragma region Application Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +typedef /* [public][public][uuid] */ DECLSPEC_UUID("36adb6d9-da1f-45d8-a499-86167e0f936b") +enum __MIDL___MIDL_itf_ctffunc_0000_0011_0001 + { + GETIF_RESMGR = 0, + GETIF_RECOCONTEXT = 0x1, + GETIF_RECOGNIZER = 0x2, + GETIF_VOICE = 0x3, + GETIF_DICTGRAM = 0x4, + GETIF_RECOGNIZERNOINIT = 0x5 + } TfSapiObject; + + + +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0011_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0011_v0_0_s_ifspec; + +#ifndef __ITfFnGetSAPIObject_INTERFACE_DEFINED__ +#define __ITfFnGetSAPIObject_INTERFACE_DEFINED__ + +/* interface ITfFnGetSAPIObject */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnGetSAPIObject; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("5c0ab7ea-167d-4f59-bfb5-4693755e90ca") + ITfFnGetSAPIObject : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE Get( + /* [in] */ TfSapiObject sObj, + /* [out] */ __RPC__deref_out_opt IUnknown **ppunk) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnGetSAPIObjectVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnGetSAPIObject * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnGetSAPIObject * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnGetSAPIObject * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnGetSAPIObject * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *Get )( + __RPC__in ITfFnGetSAPIObject * This, + /* [in] */ TfSapiObject sObj, + /* [out] */ __RPC__deref_out_opt IUnknown **ppunk); + + END_INTERFACE + } ITfFnGetSAPIObjectVtbl; + + interface ITfFnGetSAPIObject + { + CONST_VTBL struct ITfFnGetSAPIObjectVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnGetSAPIObject_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnGetSAPIObject_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnGetSAPIObject_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnGetSAPIObject_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnGetSAPIObject_Get(This,sObj,ppunk) \ + ( (This)->lpVtbl -> Get(This,sObj,ppunk) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnGetSAPIObject_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_ctffunc_0000_0012 */ +/* [local] */ + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */ +#pragma endregion +#pragma region Desktop Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + + +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0012_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0012_v0_0_s_ifspec; + +#ifndef __ITfFnPropertyUIStatus_INTERFACE_DEFINED__ +#define __ITfFnPropertyUIStatus_INTERFACE_DEFINED__ + +/* interface ITfFnPropertyUIStatus */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnPropertyUIStatus; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2338AC6E-2B9D-44C0-A75E-EE64F256B3BD") + ITfFnPropertyUIStatus : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE GetStatus( + /* [in] */ __RPC__in REFGUID refguidProp, + /* [out] */ __RPC__out DWORD *pdw) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetStatus( + /* [in] */ __RPC__in REFGUID refguidProp, + /* [in] */ DWORD dw) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnPropertyUIStatusVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnPropertyUIStatus * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnPropertyUIStatus * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnPropertyUIStatus * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnPropertyUIStatus * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *GetStatus )( + __RPC__in ITfFnPropertyUIStatus * This, + /* [in] */ __RPC__in REFGUID refguidProp, + /* [out] */ __RPC__out DWORD *pdw); + + HRESULT ( STDMETHODCALLTYPE *SetStatus )( + __RPC__in ITfFnPropertyUIStatus * This, + /* [in] */ __RPC__in REFGUID refguidProp, + /* [in] */ DWORD dw); + + END_INTERFACE + } ITfFnPropertyUIStatusVtbl; + + interface ITfFnPropertyUIStatus + { + CONST_VTBL struct ITfFnPropertyUIStatusVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnPropertyUIStatus_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnPropertyUIStatus_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnPropertyUIStatus_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnPropertyUIStatus_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnPropertyUIStatus_GetStatus(This,refguidProp,pdw) \ + ( (This)->lpVtbl -> GetStatus(This,refguidProp,pdw) ) + +#define ITfFnPropertyUIStatus_SetStatus(This,refguidProp,dw) \ + ( (This)->lpVtbl -> SetStatus(This,refguidProp,dw) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnPropertyUIStatus_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_ctffunc_0000_0013 */ +/* [local] */ + + +#define TF_PROPUI_STATUS_SAVETOFILE 0x00000001 + + + +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0013_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0013_v0_0_s_ifspec; + +#ifndef __IEnumSpeechCommands_INTERFACE_DEFINED__ +#define __IEnumSpeechCommands_INTERFACE_DEFINED__ + +/* interface IEnumSpeechCommands */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumSpeechCommands; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8c5dac4f-083c-4b85-a4c9-71746048adca") + IEnumSpeechCommands : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ __RPC__deref_out_opt IEnumSpeechCommands **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ __RPC__out_ecount_part(ulCount, *pcFetched) WCHAR **pSpCmds, + /* [out] */ __RPC__out ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IEnumSpeechCommandsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in IEnumSpeechCommands * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in IEnumSpeechCommands * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in IEnumSpeechCommands * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + __RPC__in IEnumSpeechCommands * This, + /* [out] */ __RPC__deref_out_opt IEnumSpeechCommands **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + __RPC__in IEnumSpeechCommands * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ __RPC__out_ecount_part(ulCount, *pcFetched) WCHAR **pSpCmds, + /* [out] */ __RPC__out ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + __RPC__in IEnumSpeechCommands * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + __RPC__in IEnumSpeechCommands * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumSpeechCommandsVtbl; + + interface IEnumSpeechCommands + { + CONST_VTBL struct IEnumSpeechCommandsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumSpeechCommands_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumSpeechCommands_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumSpeechCommands_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumSpeechCommands_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumSpeechCommands_Next(This,ulCount,pSpCmds,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,pSpCmds,pcFetched) ) + +#define IEnumSpeechCommands_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumSpeechCommands_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumSpeechCommands_INTERFACE_DEFINED__ */ + + +#ifndef __ISpeechCommandProvider_INTERFACE_DEFINED__ +#define __ISpeechCommandProvider_INTERFACE_DEFINED__ + +/* interface ISpeechCommandProvider */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ISpeechCommandProvider; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("38e09d4c-586d-435a-b592-c8a86691dec6") + ISpeechCommandProvider : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE EnumSpeechCommands( + /* [in] */ LANGID langid, + /* [out] */ __RPC__deref_out_opt IEnumSpeechCommands **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE ProcessCommand( + /* [size_is][in] */ __RPC__in_ecount_full(cch) const WCHAR *pszCommand, + /* [in] */ ULONG cch, + /* [in] */ LANGID langid) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ISpeechCommandProviderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ISpeechCommandProvider * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ISpeechCommandProvider * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ISpeechCommandProvider * This); + + HRESULT ( STDMETHODCALLTYPE *EnumSpeechCommands )( + __RPC__in ISpeechCommandProvider * This, + /* [in] */ LANGID langid, + /* [out] */ __RPC__deref_out_opt IEnumSpeechCommands **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *ProcessCommand )( + __RPC__in ISpeechCommandProvider * This, + /* [size_is][in] */ __RPC__in_ecount_full(cch) const WCHAR *pszCommand, + /* [in] */ ULONG cch, + /* [in] */ LANGID langid); + + END_INTERFACE + } ISpeechCommandProviderVtbl; + + interface ISpeechCommandProvider + { + CONST_VTBL struct ISpeechCommandProviderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ISpeechCommandProvider_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ISpeechCommandProvider_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ISpeechCommandProvider_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ISpeechCommandProvider_EnumSpeechCommands(This,langid,ppEnum) \ + ( (This)->lpVtbl -> EnumSpeechCommands(This,langid,ppEnum) ) + +#define ISpeechCommandProvider_ProcessCommand(This,pszCommand,cch,langid) \ + ( (This)->lpVtbl -> ProcessCommand(This,pszCommand,cch,langid) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ISpeechCommandProvider_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnCustomSpeechCommand_INTERFACE_DEFINED__ +#define __ITfFnCustomSpeechCommand_INTERFACE_DEFINED__ + +/* interface ITfFnCustomSpeechCommand */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnCustomSpeechCommand; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("fca6c349-a12f-43a3-8dd6-5a5a4282577b") + ITfFnCustomSpeechCommand : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE SetSpeechCommandProvider( + /* [in] */ __RPC__in_opt IUnknown *pspcmdProvider) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnCustomSpeechCommandVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnCustomSpeechCommand * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnCustomSpeechCommand * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnCustomSpeechCommand * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnCustomSpeechCommand * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *SetSpeechCommandProvider )( + __RPC__in ITfFnCustomSpeechCommand * This, + /* [in] */ __RPC__in_opt IUnknown *pspcmdProvider); + + END_INTERFACE + } ITfFnCustomSpeechCommandVtbl; + + interface ITfFnCustomSpeechCommand + { + CONST_VTBL struct ITfFnCustomSpeechCommandVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnCustomSpeechCommand_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnCustomSpeechCommand_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnCustomSpeechCommand_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnCustomSpeechCommand_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnCustomSpeechCommand_SetSpeechCommandProvider(This,pspcmdProvider) \ + ( (This)->lpVtbl -> SetSpeechCommandProvider(This,pspcmdProvider) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnCustomSpeechCommand_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_ctffunc_0000_0016 */ +/* [local] */ + +EXTERN_C const GUID GUID_TFCAT_TIP_MASTERLM; +EXTERN_C const GUID GUID_MASTERLM_FUNCTIONPROVIDER; +EXTERN_C const GUID GUID_LMLATTICE_VER1_0; +EXTERN_C const GUID GUID_PROP_LMLATTICE; + + +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0016_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0016_v0_0_s_ifspec; + +#ifndef __ITfFnLMProcessor_INTERFACE_DEFINED__ +#define __ITfFnLMProcessor_INTERFACE_DEFINED__ + +/* interface ITfFnLMProcessor */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnLMProcessor; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7AFBF8E7-AC4B-4082-B058-890899D3A010") + ITfFnLMProcessor : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE QueryRange( + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [out] */ __RPC__deref_out_opt ITfRange **ppNewRange, + /* [out] */ __RPC__out BOOL *pfAccepted) = 0; + + virtual HRESULT STDMETHODCALLTYPE QueryLangID( + /* [in] */ LANGID langid, + /* [out] */ __RPC__out BOOL *pfAccepted) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetReconversion( + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [out] */ __RPC__deref_out_opt ITfCandidateList **ppCandList) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reconvert( + /* [in] */ __RPC__in_opt ITfRange *pRange) = 0; + + virtual HRESULT STDMETHODCALLTYPE QueryKey( + /* [in] */ BOOL fUp, + /* [in] */ WPARAM vKey, + /* [in] */ LPARAM lparamKeydata, + /* [out] */ __RPC__out BOOL *pfInterested) = 0; + + virtual HRESULT STDMETHODCALLTYPE InvokeKey( + /* [in] */ BOOL fUp, + /* [in] */ WPARAM vKey, + /* [in] */ LPARAM lparamKeyData) = 0; + + virtual HRESULT STDMETHODCALLTYPE InvokeFunc( + /* [in] */ __RPC__in_opt ITfContext *pic, + /* [in] */ __RPC__in REFGUID refguidFunc) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnLMProcessorVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnLMProcessor * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnLMProcessor * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnLMProcessor * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnLMProcessor * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *QueryRange )( + __RPC__in ITfFnLMProcessor * This, + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [out] */ __RPC__deref_out_opt ITfRange **ppNewRange, + /* [out] */ __RPC__out BOOL *pfAccepted); + + HRESULT ( STDMETHODCALLTYPE *QueryLangID )( + __RPC__in ITfFnLMProcessor * This, + /* [in] */ LANGID langid, + /* [out] */ __RPC__out BOOL *pfAccepted); + + HRESULT ( STDMETHODCALLTYPE *GetReconversion )( + __RPC__in ITfFnLMProcessor * This, + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [out] */ __RPC__deref_out_opt ITfCandidateList **ppCandList); + + HRESULT ( STDMETHODCALLTYPE *Reconvert )( + __RPC__in ITfFnLMProcessor * This, + /* [in] */ __RPC__in_opt ITfRange *pRange); + + HRESULT ( STDMETHODCALLTYPE *QueryKey )( + __RPC__in ITfFnLMProcessor * This, + /* [in] */ BOOL fUp, + /* [in] */ WPARAM vKey, + /* [in] */ LPARAM lparamKeydata, + /* [out] */ __RPC__out BOOL *pfInterested); + + HRESULT ( STDMETHODCALLTYPE *InvokeKey )( + __RPC__in ITfFnLMProcessor * This, + /* [in] */ BOOL fUp, + /* [in] */ WPARAM vKey, + /* [in] */ LPARAM lparamKeyData); + + HRESULT ( STDMETHODCALLTYPE *InvokeFunc )( + __RPC__in ITfFnLMProcessor * This, + /* [in] */ __RPC__in_opt ITfContext *pic, + /* [in] */ __RPC__in REFGUID refguidFunc); + + END_INTERFACE + } ITfFnLMProcessorVtbl; + + interface ITfFnLMProcessor + { + CONST_VTBL struct ITfFnLMProcessorVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnLMProcessor_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnLMProcessor_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnLMProcessor_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnLMProcessor_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnLMProcessor_QueryRange(This,pRange,ppNewRange,pfAccepted) \ + ( (This)->lpVtbl -> QueryRange(This,pRange,ppNewRange,pfAccepted) ) + +#define ITfFnLMProcessor_QueryLangID(This,langid,pfAccepted) \ + ( (This)->lpVtbl -> QueryLangID(This,langid,pfAccepted) ) + +#define ITfFnLMProcessor_GetReconversion(This,pRange,ppCandList) \ + ( (This)->lpVtbl -> GetReconversion(This,pRange,ppCandList) ) + +#define ITfFnLMProcessor_Reconvert(This,pRange) \ + ( (This)->lpVtbl -> Reconvert(This,pRange) ) + +#define ITfFnLMProcessor_QueryKey(This,fUp,vKey,lparamKeydata,pfInterested) \ + ( (This)->lpVtbl -> QueryKey(This,fUp,vKey,lparamKeydata,pfInterested) ) + +#define ITfFnLMProcessor_InvokeKey(This,fUp,vKey,lparamKeyData) \ + ( (This)->lpVtbl -> InvokeKey(This,fUp,vKey,lparamKeyData) ) + +#define ITfFnLMProcessor_InvokeFunc(This,pic,refguidFunc) \ + ( (This)->lpVtbl -> InvokeFunc(This,pic,refguidFunc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnLMProcessor_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnLMInternal_INTERFACE_DEFINED__ +#define __ITfFnLMInternal_INTERFACE_DEFINED__ + +/* interface ITfFnLMInternal */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnLMInternal; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("04B825B1-AC9A-4F7B-B5AD-C7168F1EE445") + ITfFnLMInternal : public ITfFnLMProcessor + { + public: + virtual HRESULT STDMETHODCALLTYPE ProcessLattice( + /* [in] */ __RPC__in_opt ITfRange *pRange) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnLMInternalVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnLMInternal * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnLMInternal * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnLMInternal * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnLMInternal * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *QueryRange )( + __RPC__in ITfFnLMInternal * This, + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [out] */ __RPC__deref_out_opt ITfRange **ppNewRange, + /* [out] */ __RPC__out BOOL *pfAccepted); + + HRESULT ( STDMETHODCALLTYPE *QueryLangID )( + __RPC__in ITfFnLMInternal * This, + /* [in] */ LANGID langid, + /* [out] */ __RPC__out BOOL *pfAccepted); + + HRESULT ( STDMETHODCALLTYPE *GetReconversion )( + __RPC__in ITfFnLMInternal * This, + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [out] */ __RPC__deref_out_opt ITfCandidateList **ppCandList); + + HRESULT ( STDMETHODCALLTYPE *Reconvert )( + __RPC__in ITfFnLMInternal * This, + /* [in] */ __RPC__in_opt ITfRange *pRange); + + HRESULT ( STDMETHODCALLTYPE *QueryKey )( + __RPC__in ITfFnLMInternal * This, + /* [in] */ BOOL fUp, + /* [in] */ WPARAM vKey, + /* [in] */ LPARAM lparamKeydata, + /* [out] */ __RPC__out BOOL *pfInterested); + + HRESULT ( STDMETHODCALLTYPE *InvokeKey )( + __RPC__in ITfFnLMInternal * This, + /* [in] */ BOOL fUp, + /* [in] */ WPARAM vKey, + /* [in] */ LPARAM lparamKeyData); + + HRESULT ( STDMETHODCALLTYPE *InvokeFunc )( + __RPC__in ITfFnLMInternal * This, + /* [in] */ __RPC__in_opt ITfContext *pic, + /* [in] */ __RPC__in REFGUID refguidFunc); + + HRESULT ( STDMETHODCALLTYPE *ProcessLattice )( + __RPC__in ITfFnLMInternal * This, + /* [in] */ __RPC__in_opt ITfRange *pRange); + + END_INTERFACE + } ITfFnLMInternalVtbl; + + interface ITfFnLMInternal + { + CONST_VTBL struct ITfFnLMInternalVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnLMInternal_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnLMInternal_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnLMInternal_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnLMInternal_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnLMInternal_QueryRange(This,pRange,ppNewRange,pfAccepted) \ + ( (This)->lpVtbl -> QueryRange(This,pRange,ppNewRange,pfAccepted) ) + +#define ITfFnLMInternal_QueryLangID(This,langid,pfAccepted) \ + ( (This)->lpVtbl -> QueryLangID(This,langid,pfAccepted) ) + +#define ITfFnLMInternal_GetReconversion(This,pRange,ppCandList) \ + ( (This)->lpVtbl -> GetReconversion(This,pRange,ppCandList) ) + +#define ITfFnLMInternal_Reconvert(This,pRange) \ + ( (This)->lpVtbl -> Reconvert(This,pRange) ) + +#define ITfFnLMInternal_QueryKey(This,fUp,vKey,lparamKeydata,pfInterested) \ + ( (This)->lpVtbl -> QueryKey(This,fUp,vKey,lparamKeydata,pfInterested) ) + +#define ITfFnLMInternal_InvokeKey(This,fUp,vKey,lparamKeyData) \ + ( (This)->lpVtbl -> InvokeKey(This,fUp,vKey,lparamKeyData) ) + +#define ITfFnLMInternal_InvokeFunc(This,pic,refguidFunc) \ + ( (This)->lpVtbl -> InvokeFunc(This,pic,refguidFunc) ) + + +#define ITfFnLMInternal_ProcessLattice(This,pRange) \ + ( (This)->lpVtbl -> ProcessLattice(This,pRange) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnLMInternal_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_ctffunc_0000_0018 */ +/* [local] */ + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ +#pragma endregion +#pragma region Application Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +typedef /* [uuid] */ DECLSPEC_UUID("1b646efe-3ce3-4ce2-b41f-35b93fe5552f") struct TF_LMLATTELEMENT + { + DWORD dwFrameStart; + DWORD dwFrameLen; + DWORD dwFlags; + /* [switch_is][switch_type] */ union + { + /* [case()] */ INT iCost; + } ; + BSTR bstrText; + } TF_LMLATTELEMENT; + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */ +#pragma endregion +#pragma region Desktop Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + + +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0018_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0018_v0_0_s_ifspec; + +#ifndef __IEnumTfLatticeElements_INTERFACE_DEFINED__ +#define __IEnumTfLatticeElements_INTERFACE_DEFINED__ + +/* interface IEnumTfLatticeElements */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfLatticeElements; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("56988052-47DA-4A05-911A-E3D941F17145") + IEnumTfLatticeElements : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ __RPC__deref_out_opt IEnumTfLatticeElements **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ __RPC__out_ecount_part(ulCount, *pcFetched) TF_LMLATTELEMENT *rgsElements, + /* [out] */ __RPC__out ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IEnumTfLatticeElementsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in IEnumTfLatticeElements * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in IEnumTfLatticeElements * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in IEnumTfLatticeElements * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + __RPC__in IEnumTfLatticeElements * This, + /* [out] */ __RPC__deref_out_opt IEnumTfLatticeElements **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + __RPC__in IEnumTfLatticeElements * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ __RPC__out_ecount_part(ulCount, *pcFetched) TF_LMLATTELEMENT *rgsElements, + /* [out] */ __RPC__out ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + __RPC__in IEnumTfLatticeElements * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + __RPC__in IEnumTfLatticeElements * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfLatticeElementsVtbl; + + interface IEnumTfLatticeElements + { + CONST_VTBL struct IEnumTfLatticeElementsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfLatticeElements_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfLatticeElements_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfLatticeElements_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfLatticeElements_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfLatticeElements_Next(This,ulCount,rgsElements,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,rgsElements,pcFetched) ) + +#define IEnumTfLatticeElements_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfLatticeElements_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfLatticeElements_INTERFACE_DEFINED__ */ + + +#ifndef __ITfLMLattice_INTERFACE_DEFINED__ +#define __ITfLMLattice_INTERFACE_DEFINED__ + +/* interface ITfLMLattice */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfLMLattice; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("D4236675-A5BF-4570-9D42-5D6D7B02D59B") + ITfLMLattice : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE QueryType( + /* [in] */ __RPC__in REFGUID rguidType, + /* [out] */ __RPC__out BOOL *pfSupported) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumLatticeElements( + /* [in] */ DWORD dwFrameStart, + /* [in] */ __RPC__in REFGUID rguidType, + /* [out] */ __RPC__deref_out_opt IEnumTfLatticeElements **ppEnum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfLMLatticeVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfLMLattice * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfLMLattice * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfLMLattice * This); + + HRESULT ( STDMETHODCALLTYPE *QueryType )( + __RPC__in ITfLMLattice * This, + /* [in] */ __RPC__in REFGUID rguidType, + /* [out] */ __RPC__out BOOL *pfSupported); + + HRESULT ( STDMETHODCALLTYPE *EnumLatticeElements )( + __RPC__in ITfLMLattice * This, + /* [in] */ DWORD dwFrameStart, + /* [in] */ __RPC__in REFGUID rguidType, + /* [out] */ __RPC__deref_out_opt IEnumTfLatticeElements **ppEnum); + + END_INTERFACE + } ITfLMLatticeVtbl; + + interface ITfLMLattice + { + CONST_VTBL struct ITfLMLatticeVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfLMLattice_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfLMLattice_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfLMLattice_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfLMLattice_QueryType(This,rguidType,pfSupported) \ + ( (This)->lpVtbl -> QueryType(This,rguidType,pfSupported) ) + +#define ITfLMLattice_EnumLatticeElements(This,dwFrameStart,rguidType,ppEnum) \ + ( (This)->lpVtbl -> EnumLatticeElements(This,dwFrameStart,rguidType,ppEnum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfLMLattice_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnAdviseText_INTERFACE_DEFINED__ +#define __ITfFnAdviseText_INTERFACE_DEFINED__ + +/* interface ITfFnAdviseText */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnAdviseText; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3527268B-7D53-4DD9-92B7-7296AE461249") + ITfFnAdviseText : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE OnTextUpdate( + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [size_is][in] */ __RPC__in_ecount_full(cch) const WCHAR *pchText, + /* [in] */ LONG cch) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnLatticeUpdate( + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [in] */ __RPC__in_opt ITfLMLattice *pLattice) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnAdviseTextVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnAdviseText * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnAdviseText * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnAdviseText * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnAdviseText * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *OnTextUpdate )( + __RPC__in ITfFnAdviseText * This, + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [size_is][in] */ __RPC__in_ecount_full(cch) const WCHAR *pchText, + /* [in] */ LONG cch); + + HRESULT ( STDMETHODCALLTYPE *OnLatticeUpdate )( + __RPC__in ITfFnAdviseText * This, + /* [in] */ __RPC__in_opt ITfRange *pRange, + /* [in] */ __RPC__in_opt ITfLMLattice *pLattice); + + END_INTERFACE + } ITfFnAdviseTextVtbl; + + interface ITfFnAdviseText + { + CONST_VTBL struct ITfFnAdviseTextVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnAdviseText_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnAdviseText_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnAdviseText_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnAdviseText_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnAdviseText_OnTextUpdate(This,pRange,pchText,cch) \ + ( (This)->lpVtbl -> OnTextUpdate(This,pRange,pchText,cch) ) + +#define ITfFnAdviseText_OnLatticeUpdate(This,pRange,pLattice) \ + ( (This)->lpVtbl -> OnLatticeUpdate(This,pRange,pLattice) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnAdviseText_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnSearchCandidateProvider_INTERFACE_DEFINED__ +#define __ITfFnSearchCandidateProvider_INTERFACE_DEFINED__ + +/* interface ITfFnSearchCandidateProvider */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFnSearchCandidateProvider; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("87a2ad8f-f27b-4920-8501-67602280175d") + ITfFnSearchCandidateProvider : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE GetSearchCandidates( + /* [in] */ __RPC__in BSTR bstrQuery, + /* [in] */ __RPC__in BSTR bstrApplicationId, + /* [out] */ __RPC__deref_out_opt ITfCandidateList **pplist) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetResult( + /* [in] */ __RPC__in BSTR bstrQuery, + /* [in] */ __RPC__in BSTR bstrApplicationID, + /* [in] */ __RPC__in BSTR bstrResult) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnSearchCandidateProviderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnSearchCandidateProvider * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnSearchCandidateProvider * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnSearchCandidateProvider * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnSearchCandidateProvider * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *GetSearchCandidates )( + __RPC__in ITfFnSearchCandidateProvider * This, + /* [in] */ __RPC__in BSTR bstrQuery, + /* [in] */ __RPC__in BSTR bstrApplicationId, + /* [out] */ __RPC__deref_out_opt ITfCandidateList **pplist); + + HRESULT ( STDMETHODCALLTYPE *SetResult )( + __RPC__in ITfFnSearchCandidateProvider * This, + /* [in] */ __RPC__in BSTR bstrQuery, + /* [in] */ __RPC__in BSTR bstrApplicationID, + /* [in] */ __RPC__in BSTR bstrResult); + + END_INTERFACE + } ITfFnSearchCandidateProviderVtbl; + + interface ITfFnSearchCandidateProvider + { + CONST_VTBL struct ITfFnSearchCandidateProviderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnSearchCandidateProvider_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnSearchCandidateProvider_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnSearchCandidateProvider_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnSearchCandidateProvider_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnSearchCandidateProvider_GetSearchCandidates(This,bstrQuery,bstrApplicationId,pplist) \ + ( (This)->lpVtbl -> GetSearchCandidates(This,bstrQuery,bstrApplicationId,pplist) ) + +#define ITfFnSearchCandidateProvider_SetResult(This,bstrQuery,bstrApplicationID,bstrResult) \ + ( (This)->lpVtbl -> SetResult(This,bstrQuery,bstrApplicationID,bstrResult) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnSearchCandidateProvider_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_ctffunc_0000_0022 */ +/* [local] */ + +// The applications has a search box with a horizontal candidate list below that and may have search suggestions below the candidate list +DEFINE_GUID(GUID_INTEGRATIONSTYLE_SEARCHBOX, 0xe6d1bd11, 0x82f7, 0x4903, 0xae, 0x21, 0x1a, 0x63, 0x97, 0xcd, 0xe2, 0xeb); +typedef /* [public][public][uuid] */ DECLSPEC_UUID("AF8F5D86-0615-4af3-90FA-5DCBB407A5D4") +enum __MIDL___MIDL_itf_ctffunc_0000_0022_0001 + { + STYLE_ACTIVE_SELECTION = 0, + STYLE_IMPLIED_SELECTION = 0x1 + } TfIntegratableCandidateListSelectionStyle; + + + +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0022_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0022_v0_0_s_ifspec; + +#ifndef __ITfIntegratableCandidateListUIElement_INTERFACE_DEFINED__ +#define __ITfIntegratableCandidateListUIElement_INTERFACE_DEFINED__ + +/* interface ITfIntegratableCandidateListUIElement */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfIntegratableCandidateListUIElement; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C7A6F54F-B180-416F-B2BF-7BF2E4683D7B") + ITfIntegratableCandidateListUIElement : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetIntegrationStyle( + /* [in] */ GUID guidIntegrationStyle) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetSelectionStyle( + /* [out] */ __RPC__out TfIntegratableCandidateListSelectionStyle *ptfSelectionStyle) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnKeyDown( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ __RPC__out BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShowCandidateNumbers( + /* [out] */ __RPC__out BOOL *pfShow) = 0; + + virtual HRESULT STDMETHODCALLTYPE FinalizeExactCompositionString( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfIntegratableCandidateListUIElementVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfIntegratableCandidateListUIElement * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfIntegratableCandidateListUIElement * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfIntegratableCandidateListUIElement * This); + + HRESULT ( STDMETHODCALLTYPE *SetIntegrationStyle )( + __RPC__in ITfIntegratableCandidateListUIElement * This, + /* [in] */ GUID guidIntegrationStyle); + + HRESULT ( STDMETHODCALLTYPE *GetSelectionStyle )( + __RPC__in ITfIntegratableCandidateListUIElement * This, + /* [out] */ __RPC__out TfIntegratableCandidateListSelectionStyle *ptfSelectionStyle); + + HRESULT ( STDMETHODCALLTYPE *OnKeyDown )( + __RPC__in ITfIntegratableCandidateListUIElement * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ __RPC__out BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *ShowCandidateNumbers )( + __RPC__in ITfIntegratableCandidateListUIElement * This, + /* [out] */ __RPC__out BOOL *pfShow); + + HRESULT ( STDMETHODCALLTYPE *FinalizeExactCompositionString )( + __RPC__in ITfIntegratableCandidateListUIElement * This); + + END_INTERFACE + } ITfIntegratableCandidateListUIElementVtbl; + + interface ITfIntegratableCandidateListUIElement + { + CONST_VTBL struct ITfIntegratableCandidateListUIElementVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfIntegratableCandidateListUIElement_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfIntegratableCandidateListUIElement_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfIntegratableCandidateListUIElement_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfIntegratableCandidateListUIElement_SetIntegrationStyle(This,guidIntegrationStyle) \ + ( (This)->lpVtbl -> SetIntegrationStyle(This,guidIntegrationStyle) ) + +#define ITfIntegratableCandidateListUIElement_GetSelectionStyle(This,ptfSelectionStyle) \ + ( (This)->lpVtbl -> GetSelectionStyle(This,ptfSelectionStyle) ) + +#define ITfIntegratableCandidateListUIElement_OnKeyDown(This,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> OnKeyDown(This,wParam,lParam,pfEaten) ) + +#define ITfIntegratableCandidateListUIElement_ShowCandidateNumbers(This,pfShow) \ + ( (This)->lpVtbl -> ShowCandidateNumbers(This,pfShow) ) + +#define ITfIntegratableCandidateListUIElement_FinalizeExactCompositionString(This) \ + ( (This)->lpVtbl -> FinalizeExactCompositionString(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfIntegratableCandidateListUIElement_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnGetPreferredTouchKeyboardLayout_INTERFACE_DEFINED__ +#define __ITfFnGetPreferredTouchKeyboardLayout_INTERFACE_DEFINED__ + +/* interface ITfFnGetPreferredTouchKeyboardLayout */ +/* [unique][uuid][object] */ + +typedef /* [public][public][uuid] */ DECLSPEC_UUID("E9967127-FB3C-4978-9008-FB3060D92730") +enum __MIDL_ITfFnGetPreferredTouchKeyboardLayout_0001 + { + TKBLT_UNDEFINED = 0, + TKBLT_CLASSIC = 1, + TKBLT_OPTIMIZED = 2 + } TKBLayoutType; + + +EXTERN_C const IID IID_ITfFnGetPreferredTouchKeyboardLayout; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("5F309A41-590A-4ACC-A97F-D8EFFF13FDFC") + ITfFnGetPreferredTouchKeyboardLayout : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE GetLayout( + /* [out] */ __RPC__out TKBLayoutType *pTKBLayoutType, + __RPC__in WORD *pwPreferredLayoutId) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnGetPreferredTouchKeyboardLayoutVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + __RPC__in ITfFnGetPreferredTouchKeyboardLayout * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in ITfFnGetPreferredTouchKeyboardLayout * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in ITfFnGetPreferredTouchKeyboardLayout * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + __RPC__in ITfFnGetPreferredTouchKeyboardLayout * This, + /* [out] */ __RPC__deref_out_opt BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *GetLayout )( + __RPC__in ITfFnGetPreferredTouchKeyboardLayout * This, + /* [out] */ __RPC__out TKBLayoutType *pTKBLayoutType, + __RPC__in WORD *pwPreferredLayoutId); + + END_INTERFACE + } ITfFnGetPreferredTouchKeyboardLayoutVtbl; + + interface ITfFnGetPreferredTouchKeyboardLayout + { + CONST_VTBL struct ITfFnGetPreferredTouchKeyboardLayoutVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnGetPreferredTouchKeyboardLayout_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnGetPreferredTouchKeyboardLayout_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnGetPreferredTouchKeyboardLayout_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnGetPreferredTouchKeyboardLayout_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnGetPreferredTouchKeyboardLayout_GetLayout(This,pTKBLayoutType,pwPreferredLayoutId) \ + ( (This)->lpVtbl -> GetLayout(This,pTKBLayoutType,pwPreferredLayoutId) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnGetPreferredTouchKeyboardLayout_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFnGetLinguisticAlternates_INTERFACE_DEFINED__ +#define __ITfFnGetLinguisticAlternates_INTERFACE_DEFINED__ + +/* interface ITfFnGetLinguisticAlternates */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfFnGetLinguisticAlternates; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ea163ce2-7a65-4506-82a3-c528215da64e") + ITfFnGetLinguisticAlternates : public ITfFunction + { + public: + virtual HRESULT STDMETHODCALLTYPE GetAlternates( + /* [annotation][in] */ + _In_ ITfRange *pRange, + /* [annotation][out] */ + _COM_Outptr_ ITfCandidateList **ppCandidateList) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ITfFnGetLinguisticAlternatesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfFnGetLinguisticAlternates * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfFnGetLinguisticAlternates * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfFnGetLinguisticAlternates * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + ITfFnGetLinguisticAlternates * This, + /* [out] */ BSTR *pbstrName); + + HRESULT ( STDMETHODCALLTYPE *GetAlternates )( + ITfFnGetLinguisticAlternates * This, + /* [annotation][in] */ + _In_ ITfRange *pRange, + /* [annotation][out] */ + _COM_Outptr_ ITfCandidateList **ppCandidateList); + + END_INTERFACE + } ITfFnGetLinguisticAlternatesVtbl; + + interface ITfFnGetLinguisticAlternates + { + CONST_VTBL struct ITfFnGetLinguisticAlternatesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFnGetLinguisticAlternates_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFnGetLinguisticAlternates_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFnGetLinguisticAlternates_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFnGetLinguisticAlternates_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + + +#define ITfFnGetLinguisticAlternates_GetAlternates(This,pRange,ppCandidateList) \ + ( (This)->lpVtbl -> GetAlternates(This,pRange,ppCandidateList) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFnGetLinguisticAlternates_INTERFACE_DEFINED__ */ + + +#ifndef __IUIManagerEventSink_INTERFACE_DEFINED__ +#define __IUIManagerEventSink_INTERFACE_DEFINED__ + +/* interface IUIManagerEventSink */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_IUIManagerEventSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("cd91d690-a7e8-4265-9b38-8bb3bbaba7de") + IUIManagerEventSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnWindowOpening( + /* [annotation][in] */ + _In_ RECT *prcBounds) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnWindowOpened( + /* [annotation][in] */ + _In_ RECT *prcBounds) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnWindowUpdating( + /* [annotation][in] */ + _In_ RECT *prcUpdatedBounds) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnWindowUpdated( + /* [annotation][in] */ + _In_ RECT *prcUpdatedBounds) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnWindowClosing( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnWindowClosed( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IUIManagerEventSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IUIManagerEventSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IUIManagerEventSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IUIManagerEventSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnWindowOpening )( + IUIManagerEventSink * This, + /* [annotation][in] */ + _In_ RECT *prcBounds); + + HRESULT ( STDMETHODCALLTYPE *OnWindowOpened )( + IUIManagerEventSink * This, + /* [annotation][in] */ + _In_ RECT *prcBounds); + + HRESULT ( STDMETHODCALLTYPE *OnWindowUpdating )( + IUIManagerEventSink * This, + /* [annotation][in] */ + _In_ RECT *prcUpdatedBounds); + + HRESULT ( STDMETHODCALLTYPE *OnWindowUpdated )( + IUIManagerEventSink * This, + /* [annotation][in] */ + _In_ RECT *prcUpdatedBounds); + + HRESULT ( STDMETHODCALLTYPE *OnWindowClosing )( + IUIManagerEventSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnWindowClosed )( + IUIManagerEventSink * This); + + END_INTERFACE + } IUIManagerEventSinkVtbl; + + interface IUIManagerEventSink + { + CONST_VTBL struct IUIManagerEventSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IUIManagerEventSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IUIManagerEventSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IUIManagerEventSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IUIManagerEventSink_OnWindowOpening(This,prcBounds) \ + ( (This)->lpVtbl -> OnWindowOpening(This,prcBounds) ) + +#define IUIManagerEventSink_OnWindowOpened(This,prcBounds) \ + ( (This)->lpVtbl -> OnWindowOpened(This,prcBounds) ) + +#define IUIManagerEventSink_OnWindowUpdating(This,prcUpdatedBounds) \ + ( (This)->lpVtbl -> OnWindowUpdating(This,prcUpdatedBounds) ) + +#define IUIManagerEventSink_OnWindowUpdated(This,prcUpdatedBounds) \ + ( (This)->lpVtbl -> OnWindowUpdated(This,prcUpdatedBounds) ) + +#define IUIManagerEventSink_OnWindowClosing(This) \ + ( (This)->lpVtbl -> OnWindowClosing(This) ) + +#define IUIManagerEventSink_OnWindowClosed(This) \ + ( (This)->lpVtbl -> OnWindowClosed(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IUIManagerEventSink_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_ctffunc_0000_0026 */ +/* [local] */ + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ +#pragma endregion +#pragma region Application Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define TKBL_UNDEFINED 0 +#define TKBL_CLASSIC_TRADITIONAL_CHINESE_PHONETIC 0x0404 +#define TKBL_CLASSIC_TRADITIONAL_CHINESE_CHANGJIE 0xF042 +#define TKBL_CLASSIC_TRADITIONAL_CHINESE_DAYI 0xF043 +#define TKBL_OPT_JAPANESE_ABC 0x0411 +#define TKBL_OPT_KOREAN_HANGUL_2_BULSIK 0x0412 +#define TKBL_OPT_SIMPLIFIED_CHINESE_PINYIN 0x0804 +#define TKBL_OPT_TRADITIONAL_CHINESE_PHONETIC 0x0404 +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */ +#pragma endregion +#endif // CTFFUNC_DEFINED + + +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0026_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_ctffunc_0000_0026_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +unsigned long __RPC_USER BSTR_UserSize( __RPC__in unsigned long *, unsigned long , __RPC__in BSTR * ); +unsigned char * __RPC_USER BSTR_UserMarshal( __RPC__in unsigned long *, __RPC__inout_xcount(0) unsigned char *, __RPC__in BSTR * ); +unsigned char * __RPC_USER BSTR_UserUnmarshal(__RPC__in unsigned long *, __RPC__in_xcount(0) unsigned char *, __RPC__out BSTR * ); +void __RPC_USER BSTR_UserFree( __RPC__in unsigned long *, __RPC__in BSTR * ); + +unsigned long __RPC_USER HWND_UserSize( __RPC__in unsigned long *, unsigned long , __RPC__in HWND * ); +unsigned char * __RPC_USER HWND_UserMarshal( __RPC__in unsigned long *, __RPC__inout_xcount(0) unsigned char *, __RPC__in HWND * ); +unsigned char * __RPC_USER HWND_UserUnmarshal(__RPC__in unsigned long *, __RPC__in_xcount(0) unsigned char *, __RPC__out HWND * ); +void __RPC_USER HWND_UserFree( __RPC__in unsigned long *, __RPC__in HWND * ); + +unsigned long __RPC_USER BSTR_UserSize64( __RPC__in unsigned long *, unsigned long , __RPC__in BSTR * ); +unsigned char * __RPC_USER BSTR_UserMarshal64( __RPC__in unsigned long *, __RPC__inout_xcount(0) unsigned char *, __RPC__in BSTR * ); +unsigned char * __RPC_USER BSTR_UserUnmarshal64(__RPC__in unsigned long *, __RPC__in_xcount(0) unsigned char *, __RPC__out BSTR * ); +void __RPC_USER BSTR_UserFree64( __RPC__in unsigned long *, __RPC__in BSTR * ); + +unsigned long __RPC_USER HWND_UserSize64( __RPC__in unsigned long *, unsigned long , __RPC__in HWND * ); +unsigned char * __RPC_USER HWND_UserMarshal64( __RPC__in unsigned long *, __RPC__inout_xcount(0) unsigned char *, __RPC__in HWND * ); +unsigned char * __RPC_USER HWND_UserUnmarshal64(__RPC__in unsigned long *, __RPC__in_xcount(0) unsigned char *, __RPC__out HWND * ); +void __RPC_USER HWND_UserFree64( __RPC__in unsigned long *, __RPC__in HWND * ); + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/WeaselUI/StandardLayout.cpp b/WeaselUI/StandardLayout.cpp index 5e90215cf..209cbd173 100644 --- a/WeaselUI/StandardLayout.cpp +++ b/WeaselUI/StandardLayout.cpp @@ -87,7 +87,7 @@ void StandardLayout::UpdateStatusIconLayout(int* width, int* height) bool StandardLayout::IsInlinePreedit() const { return _style.inline_preedit && (_style.client_caps & weasel::INLINE_PREEDIT_CAPABLE) != 0 && - _style.layout_type != LAYOUT_VERTICAL_FULLSCREEN && _style.layout_type != LAYOUT_HORIZONTAL_FULLSCREEN; + _style.layout_type != UIStyle::LAYOUT_VERTICAL_FULLSCREEN && _style.layout_type != UIStyle::LAYOUT_HORIZONTAL_FULLSCREEN; } bool StandardLayout::ShouldDisplayStatusIcon() const diff --git a/WeaselUI/WeaselPanel.cpp b/WeaselUI/WeaselPanel.cpp index 3b0434d29..037090480 100644 --- a/WeaselUI/WeaselPanel.cpp +++ b/WeaselUI/WeaselPanel.cpp @@ -15,7 +15,7 @@ using namespace weasel; static LPCWSTR DEFAULT_FONT_FACE = L""; static const int DEFAULT_FONT_POINT = 16; -static const LayoutType LAYOUT_TYPE = LAYOUT_VERTICAL; +static const UIStyle::LayoutType LAYOUT_TYPE = UIStyle::LAYOUT_VERTICAL; static const int MIN_WIDTH = 160; static const int MIN_HEIGHT = 0; static const int BORDER = 3; @@ -100,18 +100,18 @@ void WeaselPanel::_CreateLayout() delete m_layout; Layout* layout = NULL; - if (m_style.layout_type == LAYOUT_VERTICAL || - m_style.layout_type == LAYOUT_VERTICAL_FULLSCREEN) + if (m_style.layout_type == UIStyle::LAYOUT_VERTICAL || + m_style.layout_type == UIStyle::LAYOUT_VERTICAL_FULLSCREEN) { layout = new VerticalLayout(m_style, m_ctx, m_status); } - else if (m_style.layout_type == LAYOUT_HORIZONTAL || - m_style.layout_type == LAYOUT_HORIZONTAL_FULLSCREEN) + else if (m_style.layout_type == UIStyle::LAYOUT_HORIZONTAL || + m_style.layout_type == UIStyle::LAYOUT_HORIZONTAL_FULLSCREEN) { layout = new HorizontalLayout(m_style, m_ctx, m_status); } - if (m_style.layout_type == LAYOUT_VERTICAL_FULLSCREEN || - m_style.layout_type == LAYOUT_HORIZONTAL_FULLSCREEN) + if (m_style.layout_type == UIStyle::LAYOUT_VERTICAL_FULLSCREEN || + m_style.layout_type == UIStyle::LAYOUT_HORIZONTAL_FULLSCREEN) { layout = new FullScreenLayout(m_style, m_ctx, m_status, m_inputPos, layout); } diff --git a/WeaselUI/WeaselUI.cpp b/WeaselUI/WeaselUI.cpp index c3bce8144..3f733d008 100644 --- a/WeaselUI/WeaselUI.cpp +++ b/WeaselUI/WeaselUI.cpp @@ -1,25 +1,24 @@ #include "stdafx.h" #include #include "WeaselPanel.h" -#include "WeaselTrayIcon.h" using namespace weasel; class weasel::UIImpl { public: WeaselPanel panel; - WeaselTrayIcon tray_icon; UIImpl(weasel::UI &ui) - : panel(ui), tray_icon(ui) {} + : panel(ui), shown(false) {} void Refresh() { + if (!panel.IsWindow()) return; panel.Refresh(); - tray_icon.Refresh(); } void Show(); void Hide(); void ShowWithTimeout(DWORD millisec); + bool IsShown() const { return shown; } static VOID CALLBACK OnTimer( _In_ HWND hwnd, @@ -29,6 +28,7 @@ class weasel::UIImpl { ); static const int AUTOHIDE_TIMER = 20121220; static UINT_PTR timer; + bool shown; }; bool UI::Create(HWND parent) @@ -40,16 +40,15 @@ bool UI::Create(HWND parent) if (!pimpl_) return false; - pimpl_->panel.Create(NULL); - pimpl_->tray_icon.Create(parent); + pimpl_->panel.Create(parent, 0, 0, WS_POPUP | WS_CLIPCHILDREN, WS_EX_TOOLWINDOW | WS_EX_TOPMOST, 0U, 0); + //pimpl_->tray_icon.Create(parent); return true; } void UI::Destroy() { - if (pimpl_) + if (pimpl_ && pimpl_->panel.IsWindow()) { - pimpl_->tray_icon.RemoveIcon(); pimpl_->panel.DestroyWindow(); delete pimpl_; pimpl_ = 0; @@ -85,6 +84,11 @@ bool UI::IsCountingDown() const return pimpl_ && pimpl_->timer != 0; } +bool UI::IsShown() const +{ + return pimpl_ && pimpl_->IsShown(); +} + void UI::Refresh() { if (pimpl_) @@ -112,7 +116,9 @@ UINT_PTR UIImpl::timer = 0; void UIImpl::Show() { + if (!panel.IsWindow()) return; panel.ShowWindow(SW_SHOWNA); + shown = true; if (timer) { KillTimer(panel.m_hWnd, AUTOHIDE_TIMER); @@ -122,7 +128,9 @@ void UIImpl::Show() void UIImpl::Hide() { + if (!panel.IsWindow()) return; panel.ShowWindow(SW_HIDE); + shown = false; if (timer) { KillTimer(panel.m_hWnd, AUTOHIDE_TIMER); @@ -132,6 +140,7 @@ void UIImpl::Hide() void UIImpl::ShowWithTimeout(DWORD millisec) { + if (!panel.IsWindow()) return; DLOG(INFO) << "ShowWithTimeout: " << millisec; panel.ShowWindow(SW_SHOWNA); SetTimer(panel.m_hWnd, AUTOHIDE_TIMER, millisec, &UIImpl::OnTimer); diff --git a/WeaselUI/WeaselUI.vcxproj b/WeaselUI/WeaselUI.vcxproj index 5ef370f1b..a7c566f3f 100644 --- a/WeaselUI/WeaselUI.vcxproj +++ b/WeaselUI/WeaselUI.vcxproj @@ -256,10 +256,8 @@ Create Create - - @@ -268,13 +266,11 @@ - - diff --git a/WeaselUI/WeaselUI.vcxproj.filters b/WeaselUI/WeaselUI.vcxproj.filters index a14d3e3a8..cdedf6e2b 100644 --- a/WeaselUI/WeaselUI.vcxproj.filters +++ b/WeaselUI/WeaselUI.vcxproj.filters @@ -30,12 +30,6 @@ Source Files - - Source Files - - - Source Files - Source Files @@ -68,12 +62,6 @@ Header Files - - Header Files - - - Header Files - Header Files diff --git a/appveyor.install.bat b/appveyor.install.bat index 300e09a84..fd4577fb5 100644 --- a/appveyor.install.bat +++ b/appveyor.install.bat @@ -19,10 +19,10 @@ if %nocache% == 1 ( 7z x boost_1_61_0.7z | find "ing archive" cd boost_1_61_0 call .\bootstrap.bat - call .\b2.exe --prefix=%BOOST_ROOT% toolset=msvc-14.0 variant=release link=static threading=multi runtime-link=static define=BOOST_USE_WINAPI_VERSION=0x0501 cxxflags="/Zc:threadSafeInit- " --with-date_time --with-filesystem --with-locale --with-regex --with-signals --with-system --with-thread -q -d0 install + call .\b2.exe --prefix=%BOOST_ROOT% toolset=msvc-14.0 variant=release link=static threading=multi runtime-link=static define=BOOST_USE_WINAPI_VERSION=0x0501 cxxflags="/Zc:threadSafeInit- " --with-date_time --with-filesystem --with-locale --with-regex --with-signals --with-system --with-thread --with-serialization -q -d0 install xcopy /e /i /y /q %BOOST_ROOT%\include\boost-1_61\boost %BOOST_ROOT%\boost xcopy /e /i /y /q %BOOST_ROOT%\lib %BOOST_ROOT%\stage\lib - call .\b2.exe --prefix=%BOOST_ROOT%_x64 toolset=msvc-14.0 variant=release link=static threading=multi runtime-link=static address-model=64 define=BOOST_USE_WINAPI_VERSION=0x0501 cxxflags="/Zc:threadSafeInit- " --with-date_time --with-filesystem --with-locale --with-regex --with-signals --with-system --with-thread -q -d0 install + call .\b2.exe --prefix=%BOOST_ROOT%_x64 toolset=msvc-14.0 variant=release link=static threading=multi runtime-link=static address-model=64 define=BOOST_USE_WINAPI_VERSION=0x0501 cxxflags="/Zc:threadSafeInit- " --with-date_time --with-filesystem --with-locale --with-regex --with-signals --with-system --with-thread --with-serialization -q -d0 install xcopy /e /i /y /q %BOOST_ROOT%_x64\lib %BOOST_ROOT%\stage_x64\lib popd if %ERRORLEVEL% NEQ 0 goto ERROR diff --git a/build.bat b/build.bat index 9163410dc..a2c13a6f1 100644 --- a/build.bat +++ b/build.bat @@ -118,7 +118,8 @@ set BOOST_COMPILED_LIBS=--with-date_time^ --with-regex^ --with-signals^ --with-system^ - --with-thread + --with-thread^ + --with-serialization set BJAM_OPTIONS_COMMON=toolset=%BJAM_TOOLSET%^ variant=release^ diff --git a/include/ComPtr.h b/include/ComPtr.h new file mode 100644 index 000000000..960fb0055 --- /dev/null +++ b/include/ComPtr.h @@ -0,0 +1,194 @@ +#ifndef __COMPTR_H__ +#define __COMPTR_H__ + +#ifndef ASSERT +#include +#define ASSERT assert +#endif // ASSERT + +template +class ComPtr +{ + template + class RemoveAddRefRelease : public Interface + { + ULONG __stdcall AddRef(); + ULONG __stdcall Release(); + }; + template + friend class ComPtr; + +public: + ComPtr() noexcept = default; + ComPtr(ComPtr const & other) noexcept + : m_ptr(other.m_ptr) + { + InternalAddRef(); + } + + template + ComPtr(ComPtr const & other) noexcept + : m_ptr(other.m_ptr) + { + InternalAddRef(); + } + + ComPtr(ComPtr && other) noexcept + : m_ptr(other.m_ptr) + { + other.m_ptr = nullptr; + } + + template + ComPtr(ComPtr && other) noexcept + : m_ptr(other.m_ptr) + { + other.m_ptr = nullptr; + } + + ~ComPtr() noexcept + { + InternalRelease(); + } + + explicit operator bool() const noexcept + { + return nullptr != m_ptr; + } + + RemoveAddRefRelease * operator->() const noexcept + { + return static_cast *>(m_ptr); + } + + ComPtr & operator=(ComPtr const & other) noexcept + { + InternalCopy(other.m_ptr); + return *this; + } + + bool operator==(std::nullptr_t null) noexcept + { + return m_ptr == null; + } + + template + ComPtr & operator=(ComPtr const & other) noexcept + { + InternalCopy(other.m_ptr); + return *this; + } + + template + ComPtr & operator=(ComPtr && other) noexcept + { + InternalMove(other); + return *this; + } + + void Swap(ComPtr & other) noexcept + { + Interface * temp = m_ptr; + m_ptr = other.m_ptr; + other.m_ptr = temp; + } + + void Reset() noexcept + { + InternalRelease(); + } + + Interface * Get() const noexcept + { + return m_ptr; + } + + Interface * Detach() noexcept + { + Interface * temp = m_ptr; + m_ptr = nullptr; + return temp; + } + + void Copy(Interface * other) noexcept + { + InternalCopy(other); + } + + void Attach(Interface * other) noexcept + { + InternalRelease(); + m_ptr = other; + } + + Interface ** GetAddressOf() noexcept + { + ASSERT(m_ptr == nullptr); + return &m_ptr; + } + + void CopyTo(Interface ** other) const noexcept + { + InternalAddRef(); + *other = m_ptr; + } + + template + ComPtr As() const noexcept + { + ComPtr temp; + m_ptr->QueryInterface(temp.GetAddressOf()); + return temp; + } + +private: + void InternalAddRef() const noexcept + { + if (m_ptr) + { + m_ptr->AddRef(); + } + } + + void InternalRelease() noexcept + { + Interface * temp = m_ptr; + if (temp) + { + m_ptr = nullptr; + temp->Release(); + } + } + + void InternalCopy(Interface * other) noexcept + { + if (m_ptr != other) + { + InternalRelease(); + m_ptr = other; + InternalAddRef(); + } + } + + template + void InternalMove(ComPtr & other) noexcept + { + if (m_ptr != other.m_ptr) + { + InternalRelease(); + m_ptr = other.m_ptr; + other.m_ptr = nullptr; + } + } + + Interface * m_ptr = nullptr; +}; + +template +void swap(ComPtr & left, + ComPtr & right) noexcept +{ + left.Swap(right); +} + +#endif // __COMPTR_H__ \ No newline at end of file diff --git a/include/ResponseParser.h b/include/ResponseParser.h index e9ef38d9f..a8a934616 100644 --- a/include/ResponseParser.h +++ b/include/ResponseParser.h @@ -19,8 +19,9 @@ namespace weasel Context* p_context; Status* p_status; Config* p_config; + UIStyle* p_style; - ResponseParser(std::wstring* commit, Context* context = 0, Status* status = 0, Config* config = 0); + ResponseParser(std::wstring* commit, Context* context = 0, Status* status = 0, Config* config = 0, UIStyle* style = 0); // 重載函數調用運算符, 以扮做ResponseHandler bool operator() (LPWSTR buffer, UINT length); diff --git a/include/RimeWithWeasel.h b/include/RimeWithWeasel.h index 32ba1d897..cbf9adc56 100644 --- a/include/RimeWithWeasel.h +++ b/include/RimeWithWeasel.h @@ -4,6 +4,8 @@ #include #include +#include + typedef std::map AppOptions; typedef std::map AppOptionsByAppName; @@ -27,6 +29,8 @@ class RimeWithWeaselHandler : virtual void StartMaintenance(); virtual void EndMaintenance(); + void OnUpdateUI(std::function const &cb); + private: void _Setup(); bool _IsDeployerRunning(); @@ -35,6 +39,11 @@ class RimeWithWeaselHandler : bool _ShowMessage(weasel::Context& ctx, weasel::Status& status); bool _Respond(UINT session_id, EatLine eat); void _ReadClientInfo(UINT session_id, LPWSTR buffer); + void _GetCandidateInfo(weasel::CandidateInfo &cinfo, RimeContext &ctx); + void _GetStatus(weasel::Status &stat, UINT session_id); + void _GetContext(weasel::Context &ctx, UINT session_id); + + bool _IsSessionTSF(UINT session_id); AppOptionsByAppName m_app_options; weasel::UI* m_ui; // reference @@ -43,6 +52,8 @@ class RimeWithWeaselHandler : std::string m_last_schema_id; weasel::UIStyle m_base_style; + std::function _UpdateUICallback; + static void OnNotify(void* context_object, uintptr_t session_id, const char* message_type, diff --git a/include/WeaselCommon.h b/include/WeaselCommon.h index 870d6b9b5..4c9b93902 100644 --- a/include/WeaselCommon.h +++ b/include/WeaselCommon.h @@ -1,7 +1,9 @@ #pragma once -#include -#include +//#include +//#include +#include +#include #define WEASEL_IME_NAME L"小狼毫" #define WEASEL_REG_KEY L"Software\\Rime\\Weasel" @@ -127,4 +129,156 @@ namespace weasel } bool inline_preedit; }; + + struct UIStyle + { + enum PreeditType + { + COMPOSITION, + PREVIEW + }; + enum LayoutType + { + LAYOUT_VERTICAL = 0, + LAYOUT_HORIZONTAL, + LAYOUT_VERTICAL_FULLSCREEN, + LAYOUT_HORIZONTAL_FULLSCREEN, + LAYOUT_TYPE_LAST + }; + + PreeditType preedit_type; + LayoutType layout_type; + std::wstring font_face; + int font_point; + bool inline_preedit; + bool display_tray_icon; + std::wstring label_text_format; + // layout + int min_width; + int min_height; + int border; + int margin_x; + int margin_y; + int spacing; + int candidate_spacing; + int hilite_spacing; + int hilite_padding; + int round_corner; + // color scheme + int text_color; + int candidate_text_color; + int label_text_color; + int comment_text_color; + int back_color; + int border_color; + int hilited_text_color; + int hilited_back_color; + int hilited_candidate_text_color; + int hilited_candidate_back_color; + int hilited_label_text_color; + int hilited_comment_text_color; + // per client + int client_caps; + + UIStyle() : font_face(), + font_point(0), + inline_preedit(false), + preedit_type(COMPOSITION), + display_tray_icon(false), + label_text_format(L"%s."), + layout_type(LAYOUT_VERTICAL), + min_width(0), + min_height(0), + border(0), + margin_x(0), + margin_y(0), + spacing(0), + candidate_spacing(0), + hilite_spacing(0), + hilite_padding(0), + round_corner(0), + text_color(0), + candidate_text_color(0), + label_text_color(0), + comment_text_color(0), + back_color(0), + border_color(0), + hilited_text_color(0), + hilited_back_color(0), + hilited_candidate_text_color(0), + hilited_candidate_back_color(0), + hilited_label_text_color(0), + hilited_comment_text_color(0), + client_caps(0) {} + }; } +namespace boost { + namespace serialization { + template + void serialize(Archive &ar, weasel::UIStyle &s, const unsigned int version) + { + ar & s.font_face; + ar & s.font_point; + ar & s.inline_preedit; + ar & s.preedit_type; + ar & s.display_tray_icon; + ar & s.label_text_format; + // layout + ar & s.layout_type; + ar & s.min_width; + ar & s.min_height; + ar & s.border; + ar & s.margin_x; + ar & s.margin_y; + ar & s.spacing; + ar & s.candidate_spacing; + ar & s.hilite_spacing; + ar & s.hilite_padding; + ar & s.round_corner; + // color scheme + ar & s.text_color; + ar & s.candidate_text_color; + ar & s.label_text_color; + ar & s.comment_text_color; + ar & s.back_color; + ar & s.border_color; + ar & s.hilited_text_color; + ar & s.hilited_back_color; + ar & s.hilited_candidate_text_color; + ar & s.hilited_candidate_back_color; + ar & s.hilited_label_text_color; + ar & s.hilited_comment_text_color; + // per client + ar & s.client_caps; + } + + template + void serialize(Archive &ar, weasel::CandidateInfo &s, const unsigned int version) + { + ar & s.currentPage; + ar & s.totalPages; + ar & s.highlighted; + ar & s.candies; + ar & s.comments; + ar & s.labels; + } + template + void serialize(Archive &ar, weasel::Text &s, const unsigned int version) + { + ar & s.str; + ar & s.attributes; + } + template + void serialize(Archive &ar, weasel::TextAttribute &s, const unsigned int version) + { + ar & s.range; + ar & s.type; + } + template + void serialize(Archive &ar, weasel::TextRange &s, const unsigned int version) + { + ar & s.start; + ar & s.end; + } + } // namespace serialization +} // namespace boost \ No newline at end of file diff --git a/include/WeaselUI.h b/include/WeaselUI.h index 326919bc7..f5bd6712b 100644 --- a/include/WeaselUI.h +++ b/include/WeaselUI.h @@ -4,94 +4,12 @@ namespace weasel { - enum LayoutType - { - LAYOUT_VERTICAL = 0, - LAYOUT_HORIZONTAL, - LAYOUT_VERTICAL_FULLSCREEN, - LAYOUT_HORIZONTAL_FULLSCREEN, - LAYOUT_TYPE_LAST - }; enum ClientCapabilities { INLINE_PREEDIT_CAPABLE = 1, }; - enum PreeditType - { - COMPOSITION, - PREVIEW - }; - - struct UIStyle - { - std::wstring font_face; - int font_point; - bool inline_preedit; - PreeditType preedit_type; - bool display_tray_icon; - std::wstring label_text_format; - // layout - LayoutType layout_type; - int min_width; - int min_height; - int border; - int margin_x; - int margin_y; - int spacing; - int candidate_spacing; - int hilite_spacing; - int hilite_padding; - int round_corner; - // color scheme - int text_color; - int candidate_text_color; - int label_text_color; - int comment_text_color; - int back_color; - int border_color; - int hilited_text_color; - int hilited_back_color; - int hilited_candidate_text_color; - int hilited_candidate_back_color; - int hilited_label_text_color; - int hilited_comment_text_color; - // per client - int client_caps; - - UIStyle() : font_face(), - font_point(0), - inline_preedit(false), - preedit_type(COMPOSITION), - display_tray_icon(false), - label_text_format(L"%s."), - layout_type(LAYOUT_VERTICAL), - min_width(0), - min_height(0), - border(0), - margin_x(0), - margin_y(0), - spacing(0), - candidate_spacing(0), - hilite_spacing(0), - hilite_padding(0), - round_corner(0), - text_color(0), - candidate_text_color(0), - label_text_color(0), - comment_text_color(0), - back_color(0), - border_color(0), - hilited_text_color(0), - hilited_back_color(0), - hilited_candidate_text_color(0), - hilited_candidate_back_color(0), - hilited_label_text_color(0), - hilited_comment_text_color(0), - client_caps(0) {} - }; - class UIImpl; // @@ -121,6 +39,7 @@ namespace weasel void Hide(); void ShowWithTimeout(DWORD millisec); bool IsCountingDown() const; + bool IsShown() const; // 重绘界面 void Refresh(); diff --git a/include/WeaselUtility.h b/include/WeaselUtility.h index de97d1f0a..8c2b64abd 100644 --- a/include/WeaselUtility.h +++ b/include/WeaselUtility.h @@ -2,9 +2,28 @@ #include // UTF-8 conversion -const char* wcstoutf8(const WCHAR* wstr); -const WCHAR* utf8towcs(const char* utf8_str); -int utf8towcslen(const char* utf8_str, int utf8_len); +inline const char* wcstoutf8(const WCHAR* wstr) +{ + const int buffer_len = 1024; + static char buffer[buffer_len]; + memset(buffer, 0, sizeof(buffer)); + WideCharToMultiByte(CP_UTF8, 0, wstr, -1, buffer, buffer_len - 1, NULL, NULL); + return buffer; +} + +inline const WCHAR* utf8towcs(const char* utf8_str) +{ + const int buffer_len = 4096; + static WCHAR buffer[buffer_len]; + memset(buffer, 0, sizeof(buffer)); + MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1, buffer, buffer_len - 1); + return buffer; +} + +inline int utf8towcslen(const char* utf8_str, int utf8_len) +{ + return MultiByteToWideChar(CP_UTF8, 0, utf8_str, utf8_len, NULL, 0); +} // data directories std::wstring WeaselUserDataPath(); diff --git a/include/winapifamily.h b/include/winapifamily.h new file mode 100644 index 000000000..1fac1d4ee --- /dev/null +++ b/include/winapifamily.h @@ -0,0 +1,240 @@ +/* + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + winapifamily.h + +Abstract: + + Master include file for API family partitioning. + +*/ + +#ifndef _INC_WINAPIFAMILY +#define _INC_WINAPIFAMILY + +#if defined(_MSC_VER) && !defined(MOFCOMP_PASS) +#if _MSC_VER >= 1200 +#pragma warning(push) +#pragma warning(disable:4001) /* nonstandard extension 'single line comment' was used */ +#endif +#pragma once +#endif // defined(_MSC_VER) && !defined(MOFCOMP_PASS) + +#include + +/* + * When compiling C and C++ code using SDK header files, the development + * environment can specify a target platform by #define-ing the + * pre-processor symbol WINAPI_FAMILY to one of the following values. + * Each FAMILY value denotes an application family for which a different + * subset of the total set of header-file-defined APIs are available. + * Setting the WINAPI_FAMILY value will effectively hide from the + * editing and compilation environments the existence of APIs that + * are not applicable to the family of applications targeting a + * specific platform. + */ + +/* In Windows 10, WINAPI_PARTITIONs will be used to add additional + * device specific APIs to a particular WINAPI_FAMILY. + * For example, when writing Windows Universal apps, specifying + * WINAPI_FAMILY_APP will hide phone APIs from compilation. + * However, specifying WINAPI_PARTITION_PHONE_APP=1 additionally, will + * unhide any API hidden behind the partition, to the compiler. + + * The following partitions are currently defined: + * WINAPI_PARTITION_DESKTOP // usable for Desktop Win32 apps (but not store apps) + * WINAPI_PARTITION_APP // usable for Windows Universal store apps + * WINAPI_PARTITION_PC_APP // specific to Desktop-only store apps + * WINAPI_PARTITION_PHONE_APP // specific to Phone-only store apps + * WINAPI_PARTITION_SYSTEM // specific to System applications + + * The following partitions are indirect partitions and defined in + * winpackagefamily.h. These partitions are related to package based + * partitions. For example, specifying WINAPI_PARTITION_SERVER=1 will light up + * any API hidden behind the package based partitions that are bound to + * WINAPI_PARTITION_SERVER, to the compiler. + * WINAPI_PARTITION_SERVER // specific to Server applications +*/ + +/* + * The WINAPI_FAMILY values of 0 and 1 are reserved to ensure that + * an error will occur if WINAPI_FAMILY is set to any + * WINAPI_PARTITION value (which must be 0 or 1, see below). + */ +#define WINAPI_FAMILY_PC_APP 2 /* Windows Store Applications */ +#define WINAPI_FAMILY_PHONE_APP 3 /* Windows Phone Applications */ +#define WINAPI_FAMILY_SYSTEM 4 /* Windows Drivers and Tools */ +#define WINAPI_FAMILY_SERVER 5 /* Windows Server Applications */ +#define WINAPI_FAMILY_DESKTOP_APP 100 /* Windows Desktop Applications */ +/* The value of WINAPI_FAMILY_DESKTOP_APP may change in future SDKs. */ +/* Additional WINAPI_FAMILY values may be defined in future SDKs. */ + +/* + * For compatibility with Windows 8 header files, the following + * synonym for WINAPI_FAMILY_PC_APP is temporarily #define'd. + * Use of this symbol should be considered deprecated. + */ +#define WINAPI_FAMILY_APP WINAPI_FAMILY_PC_APP + +/* + * If no WINAPI_FAMILY value is specified, then all APIs available to + * Windows desktop applications are exposed. + */ +#ifndef WINAPI_FAMILY +#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP +#endif + +/* + * API PARTITONs are part of an indirection mechanism for mapping between + * individual APIs and the FAMILYs to which they apply. + * Each PARTITION is a category or subset of named APIs. PARTITIONs + * are permitted to have overlapping membership -- some single API + * might be part of more than one PARTITION. PARTITIONS are each #define-ed + * to be either 1 or 0 or depending on the platform at which the app is targeted. + */ + +/* + * The mapping between families and partitions is summarized here. + * An X indicates that the given partition is active for the given + * platform/family. + * + * +-------------------+---+ + * | *Partition* | | + * +---+---+---+---+---+---+ + * | | | | | | | + * | | | | | | | + * | | | | P | | | + * | | | | H | | | + * | D | | | O | | | + * | E | | P | N | S | S | + * | S | | C | E | Y | E | + * | K | | _ | _ | S | R | + * | T | A | A | A | T | V | + * +-------------------------+----+ O | P | P | P | E | E | + * | *Platform/Family* \| P | P | P | P | M | R | + * +------------------------------+---+---+---+---+---+---+ + * | WINAPI_FAMILY_DESKTOP_APP | X | X | X | | | | + * +------------------------------+---+---+---+---+---+---+ + * | WINAPI_FAMILY_PC_APP | | X | X | | | | + * +------------------------------+---+---+---+---+---+---+ + * | WINAPI_FAMILY_PHONE_APP | | X | | X | | | + * +----------------------------- +---+---+---+---+---+---+ + * | WINAPI_FAMILY_SYSTEM | | | | | X | | + * +----------------------------- +---+---+---+---+---+---+ + * | WINAPI_FAMILY_SERVER | | | | | X | X | + * +------------------------------+---+---+---+---+---+---+ + * + * The table above is encoded in the following expressions, + * each of which evaluates to 1 or 0. + * + * Whenever a new family is added, all of these expressions + * need to be reconsidered. + */ +#if WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP && \ + WINAPI_FAMILY != WINAPI_FAMILY_PC_APP && \ + WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP && \ + WINAPI_FAMILY != WINAPI_FAMILY_SYSTEM && \ + WINAPI_FAMILY != WINAPI_FAMILY_SERVER +#error Unknown WINAPI_FAMILY value. Was it defined in terms of a WINAPI_PARTITION_* value? +#endif + +#ifndef WINAPI_PARTITION_DESKTOP +#define WINAPI_PARTITION_DESKTOP (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) +#endif + +#ifndef WINAPI_PARTITION_APP +#define WINAPI_PARTITION_APP \ + (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP || \ + WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || \ + WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +#endif + +#ifndef WINAPI_PARTITION_PC_APP +#define WINAPI_PARTITION_PC_APP \ + (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP || \ + WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) +#endif + +#ifndef WINAPI_PARTITION_PHONE_APP +#define WINAPI_PARTITION_PHONE_APP (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +#endif + +/* + * SYSTEM is the only partition defined here. + * All other System based editions are defined as packages + * on top of the System partition. + * See winpackagefamily.h for packages level partitions + */ +#ifndef WINAPI_PARTITION_SYSTEM +#define WINAPI_PARTITION_SYSTEM \ + (WINAPI_FAMILY == WINAPI_FAMILY_SYSTEM || \ + WINAPI_FAMILY == WINAPI_FAMILY_SERVER) +#endif + +/* + * For compatibility with Windows Phone 8 header files, the following + * synonym for WINAPI_PARTITION_PHONE_APP is temporarily #define'd. + * Use of this symbol should be regarded as deprecated. + */ +#define WINAPI_PARTITION_PHONE WINAPI_PARTITION_PHONE_APP + +/* + * Header files use the WINAPI_FAMILY_PARTITION macro to assign one or + * more declarations to some group of partitions. The macro chooses + * whether the preprocessor will emit or omit a sequence of declarations + * bracketed by an #if/#endif pair. All header file references to the + * WINAPI_PARTITION_* values should be in the form of occurrences of + * WINAPI_FAMILY_PARTITION(...). + * + * For example, the following usage of WINAPI_FAMILY_PARTITION identifies + * a sequence of declarations that are part of both the Windows Desktop + * Partition and the Windows-Phone-Specific Store Partition: + * + * #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP) + * ... + * #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP) + * + * The comment on the closing #endif allow tools as well as people to find the + * matching #ifdef properly. + * + * Usages of WINAPI_FAMILY_PARTITION may be combined, when the partitition definitions are + * related. In particular one might use declarations like + * + * #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + * + * or + * + * #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + * + * Direct references to WINAPI_PARTITION_ values (eg #if !WINAPI_FAMILY_PARTITION_...) + * should not be used. + */ +#define WINAPI_FAMILY_PARTITION(Partitions) (Partitions) + +/* + * Macro used to #define or typedef a symbol used for selective deprecation + * of individual methods of a COM interfaces that are otherwise available + * for a given set of partitions. + */ +#define _WINAPI_DEPRECATED_DECLARATION __declspec(deprecated("This API cannot be used in the context of the caller's application type.")) + +/* + * For compatibility with Windows 8 header files, the following + * symbol is temporarily conditionally #define'd. Additional symbols + * like this should be not defined in winapifamily.h, but rather should be + * introduced locally to the header files of the component that needs them. + */ +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define APP_DEPRECATED_HRESULT HRESULT _WINAPI_DEPRECATED_DECLARATION +#endif // WINAPIFAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + +#if defined(_MSC_VER) && !defined(MOFCOMP_PASS) +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif +#endif + +#endif /* !_INC_WINAPIFAMILY */ diff --git a/include/winpackagefamily.h b/include/winpackagefamily.h new file mode 100644 index 000000000..ee691f9c2 --- /dev/null +++ b/include/winpackagefamily.h @@ -0,0 +1,91 @@ +/* + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + winpackagefamily.h + +Abstract: + + API family partitioning based on packages. + +*/ + +#ifndef _INC_WINPACKAGEFAMILY +#define _INC_WINPACKAGEFAMILY + +#if defined(_MSC_VER) && !defined(MOFCOMP_PASS) +#if _MSC_VER >= 1200 +#pragma warning(push) +#pragma warning(disable:4001) /* nonstandard extension 'single line comment' was used */ +#endif +#pragma once +#endif // defined(_MSC_VER) && !defined(MOFCOMP_PASS) + +#ifndef WINAPI_PARTITION_SERVER +#define WINAPI_PARTITION_SERVER (WINAPI_FAMILY == WINAPI_FAMILY_SERVER) +#endif + +/* + * PARTITIONS based on packages are each #undef'ed below, and then will be #define-ed + * to be either 1 or 0 or depending on the active WINAPI_FAMILY. + */ +#undef WINAPI_PARTITION_PKG_WINTRUST +#undef WINAPI_PARTITION_PKG_WEBSERVICES +#undef WINAPI_PARTITION_PKG_EVENTLOGSERVICE +#undef WINAPI_PARTITION_PKG_VHD +#undef WINAPI_PARTITION_PKG_PERFCOUNTER +#undef WINAPI_PARTITION_PKG_SECURESTARTUP +#undef WINAPI_PARTITION_PKG_REMOTEFS +#undef WINAPI_PARTITION_PKG_BOOTABLESKU +#undef WINAPI_PARTITION_PKG_CMDTOOLS +#undef WINAPI_PARTITION_PKG_DISM +#undef WINAPI_PARTITION_PKG_CORESETUP +#undef WINAPI_PARTITION_PKG_APPRUNTIME +#undef WINAPI_PARTITION_PKG_ESENT +#undef WINAPI_PARTITION_PKG_WINMGMT +#undef WINAPI_PARTITION_PKG_WNV +#undef WINAPI_PARTITION_PKG_CLUSTER +#undef WINAPI_PARTITION_PKG_VSS +#undef WINAPI_PARTITION_PKG_TRAFFIC +#undef WINAPI_PARTITION_PKG_ISCSI +#undef WINAPI_PARTITION_PKG_STORAGE +#undef WINAPI_PARTITION_PKG_MPSSVC +#undef WINAPI_PARTITION_PKG_APPXDEPLOYMENT +#undef WINAPI_PARTITION_PKG_WER + +/* + * PARTITIONS for feature packages. Each package might be active for one or more editions + */ +#define WINAPI_PARTITION_PKG_WINTRUST (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_WEBSERVICES (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_EVENTLOGSERVICE (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_VHD (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_PERFCOUNTER (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_SECURESTARTUP (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_REMOTEFS (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_BOOTABLESKU (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_CMDTOOLS (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_DISM (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_CORESETUP (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_APPRUNTIME (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_ESENT (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_WINMGMT (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_WNV (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_CLUSTER (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_VSS (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_TRAFFIC (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_ISCSI (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_STORAGE (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_MPSSVC (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_APPXDEPLOYMENT (WINAPI_PARTITION_SERVER == 1) +#define WINAPI_PARTITION_PKG_WER (WINAPI_PARTITION_SERVER == 1) + +#if defined(_MSC_VER) && !defined(MOFCOMP_PASS) +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif +#endif + +#endif /* !_INC_WINPACKAGEFAMILY */ diff --git a/weasel.sln b/weasel.sln index eaf11ac29..e00441c0d 100644 --- a/weasel.sln +++ b/weasel.sln @@ -5,6 +5,7 @@ VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{53F79A24-5390-4640-84B5-19984EB3353B}" ProjectSection(SolutionItems) = preProject + include\ComPtr.h = include\ComPtr.h include\PipeChannel.h = include\PipeChannel.h include\PyWeasel.h = include\PyWeasel.h include\ResponseParser.h = include\ResponseParser.h @@ -16,6 +17,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution include\WeaselUI.h = include\WeaselUI.h include\WeaselUtility.h = include\WeaselUtility.h include\WeaselVersion.h = include\WeaselVersion.h + include\winapifamily.h = include\winapifamily.h + include\winpackagefamily.h = include\winpackagefamily.h EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WeaselTSF", "WeaselTSF\WeaselTSF.vcxproj", "{FF9B3625-BBD6-4972-8F23-7BA57F3127E8}" @@ -69,11 +72,15 @@ Global {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.Debug|Win32.ActiveCfg = Debug|Win32 {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.Debug|Win32.Build.0 = Debug|Win32 {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.Debug|x64.ActiveCfg = Debug|x64 + {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.Debug|x64.Build.0 = Debug|x64 {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.Release|Win32.ActiveCfg = Release|Win32 {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.Release|Win32.Build.0 = Release|Win32 {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.Release|x64.ActiveCfg = Release|x64 + {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.Release|x64.Build.0 = Release|x64 {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.ReleaseHant|Win32.ActiveCfg = ReleaseHant|Win32 + {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.ReleaseHant|Win32.Build.0 = ReleaseHant|Win32 {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.ReleaseHant|x64.ActiveCfg = ReleaseHant|x64 + {10B3B8BF-7294-4661-9A8A-2FFC920FA2F4}.ReleaseHant|x64.Build.0 = ReleaseHant|x64 {CE11A2DF-8D20-4B07-A935-4B0D03F0303D}.Debug|Win32.ActiveCfg = Debug|Win32 {CE11A2DF-8D20-4B07-A935-4B0D03F0303D}.Debug|Win32.Build.0 = Debug|Win32 {CE11A2DF-8D20-4B07-A935-4B0D03F0303D}.Debug|x64.ActiveCfg = Debug|x64