Windows Ink开发使用COM组件开发
官方示例初始化
HRESULT Init(
HWND hWnd)
{// Initialize event sink. This consists of setting// up the free threaded marshaler.HRESULT hr = m_InkEvents.Init(hWnd);if (FAILED(hr))...// Create the ink collectorhr = CoCreateInstance(CLSID_InkCollector, NULL, CLSCTX_ALL, IID_IInkCollector, (void **) &m_pInkCollector);
/*
CLSID_InkCollector 创建时会自动加载InkObj.dll
但是如果动态库加载位置不对,很有可能会导致后面的put_hWnd或者put_Enabled出现crash的情况
我在项目中曾经就栽在这个坑上。它加载的位置是用户安装的老版office下面的目录下,导致程序崩溃。
在我windows10正常的加载模块目录应该是下面这个InkObj.dll C:\Program Files (x86)\Common Files\microsoft shared\Ink\InkObj.dll N/A N/A 未加载符号。 177 10.0.17763.806 (WinBuild.160101.0800) 2026/10/12 7:01 58AF0000-58C75000 [12296] TrainLine.exe: 本机
动态库加载后可以先通过如下代码获取并检查HMODULE dll_hInstance = ::GetModuleHandle(_T("inkobj.dll"));if(dll_hInstance == NULL)return FALSE;TCHAR path[MAX_PATH] = {0};GetModuleFileName(dll_hInstance, path, MAX_PATH);OS_INFO_TRACE_THIS("CInkCollector::Init dll path = "<<Encoding::ToUtf8(path));if(path[0] == 0)return FALSE;CString strTemp = path;strTemp.MakeUpper();int nPos = strTemp.Find(_T("OFFICE"));if(nPos > 0)return FALSE;
当然这种方法并不准确,我们可以使用查找注册表的方法来获取正确的加载路径,具体代码我就不贴了,大家可以自行摸索。
*/if (FAILED(hr))...// Set up connection between Ink Collector and our event sinkhr = m_InkEvents.AdviseInkCollector(m_pInkCollector);if (FAILED(hr))...// Attach Ink Collector to windowhr = m_pInkCollector->put_hWnd((long) hWnd);if (FAILED(hr))...// Allow Ink Collector to receive input.return m_pInkCollector->put_Enabled(VARIANT_TRUE);
}
最后放上我对官方demo改动后的代码,加入了Windows墨迹数据采集功能,并采用gdi+渲染采集到的数据。