www.pudn.com > NumPanel.rar > IMCommon.cpp
#include// For all that Windows stuff #include // Command bar includes #define INITGUID #include #include #include // SIP includes #include "IMCommon.h" // My IM common includes #include "NumPanel.h" // IM window specific includes long g_DllCnt = 0; // Global DLL reference count extern "C" { HINSTANCE hInst; // DLL instance handle } // // GUID defines for my input method. Create a new one with GUIDGEN. // const GUID CLSID_NumPanel2 = { 0xc8311f61, 0x12df,0x4107,{0xb5,0xea,0xb0,0xb0,0xd5,0x5c,0xec,0x50}}; const TCHAR szCLSIDNumPanel2[] = TEXT ("{C8311F61-12DF-4107-B5EA-B0B0D55CEC50}"); const TCHAR szFriendlyName[] = TEXT ("Numeric Keypad"); //====================================================================== // DllMain - DLL initialization entry point // BOOL WINAPI DllMain (HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved) { hInst = (HINSTANCE)hinstDLL; return TRUE; } //====================================================================== // DllGetClassObject - Exported function called to get pointer to // Class factory object. // STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID *ppv) { MyClassFactory *pcf; HRESULT hr; // See if caller wants us. if (IsEqualCLSID (rclsid, CLSID_NumPanel2)) { // Create IClassFactory object. pcf = new MyClassFactory(); if (pcf == NULL) return E_OUTOFMEMORY; // Call class factory's query interface method. hr = pcf->QueryInterface (riid, ppv); // This will cause an obj delete unless interface found. pcf->Release(); return hr; } return CLASS_E_CLASSNOTAVAILABLE; } //====================================================================== // DllCanUnloadNow - Exported function called when DLL can unload // STDAPI DllCanUnloadNow () { if (g_DllCnt) return S_FALSE; return S_OK; } //====================================================================== // DllRegisterServer - Exported function called to register the server // STDAPI DllRegisterServer () { TCHAR szName[MAX_PATH+2]; TCHAR szTmp[128]; DWORD dwDisp; HKEY hKey, hSubKey; INT rc; GetModuleFileName (hInst, szName, sizeof (szName)); // Open the key. wsprintf (szTmp, TEXT ("CLSID\\%s"), szCLSIDNumPanel2); rc = RegCreateKeyEx (HKEY_CLASSES_ROOT, szTmp, 0, TEXT(""), 0, 0, NULL, &hKey, &dwDisp); if (rc != ERROR_SUCCESS) return E_FAIL; // Set the friendly name of the SIP. RegSetValueEx (hKey, TEXT (""), 0, REG_SZ, (PBYTE)szFriendlyName, (lstrlen (szFriendlyName)+1) * sizeof (TCHAR)); // Create subkeys. // Set the module name of the SIP. rc = RegCreateKeyEx (hKey, TEXT ("InProcServer32"), 0, TEXT(""), 0, 0, NULL, &hSubKey, &dwDisp); rc = RegSetValueEx (hSubKey, TEXT (""), 0, REG_SZ, (PBYTE)szName, (lstrlen (szName)+1) * sizeof (TCHAR)); RegCloseKey (hSubKey); // Set the default icon of the server. RegCreateKeyEx (hKey, TEXT ("DefaultIcon"), 0, TEXT(""), 0, 0, NULL, &hSubKey, &dwDisp); lstrcat (szName, TEXT (",0")); RegSetValueEx (hSubKey, TEXT (""), 0, REG_SZ, (PBYTE)szName, (lstrlen (szName)+1) * sizeof (TCHAR)); RegCloseKey (hSubKey); // Set the flag indicating this is a SIP. RegCreateKeyEx (hKey, TEXT ("IsSIPInputMethod"), 0, TEXT(""), 0, 0, NULL, &hSubKey, &dwDisp); lstrcpy (szTmp, TEXT ("1")); RegSetValueEx (hSubKey, TEXT (""), 0, REG_SZ, (PBYTE)szTmp, 4); RegCloseKey (hSubKey); RegCloseKey (hKey); return S_OK; } //====================================================================== // DllUnregisterServer - Exported function called to remove the server // information from the registry // STDAPI DllUnregisterServer() { INT rc; TCHAR szTmp[128]; wsprintf (szTmp, TEXT ("CLSID\\%s"), szCLSIDNumPanel2); rc = RegDeleteKey (HKEY_CLASSES_ROOT, szTmp); if (rc == ERROR_SUCCESS) return S_OK; return E_FAIL; } //********************************************************************** // MyClassFactory Object implementation //---------------------------------------------------------------------- // Object constructor MyClassFactory::MyClassFactory () { m_lRef = 1; // Set ref count to 1 on create. return; } //---------------------------------------------------------------------- // Object destructor MyClassFactory::~MyClassFactory () { return; } //---------------------------------------------------------------------- // QueryInterface - Called to see what interfaces this object supports STDMETHODIMP MyClassFactory::QueryInterface (THIS_ REFIID riid, LPVOID *ppv) { // If caller wants our IUnknown or IClassFactory object, // return a pointer to the object. if (IsEqualIID (riid, IID_IUnknown) || IsEqualIID (riid, IID_IClassFactory)) { *ppv = (LPVOID)this; // Return pointer to object. AddRef(); // Increment ref to prevent delete on return. return NOERROR; } *ppv = NULL; return (E_NOINTERFACE); } //---------------------------------------------------------------------- // AddRef - Increment object ref count. STDMETHODIMP_(ULONG) MyClassFactory::AddRef (THIS) { ULONG cnt; cnt = (ULONG)InterlockedIncrement (&m_lRef); return cnt; } //---------------------------------------------------------------------- // Release - Decrement object ref count. STDMETHODIMP_(ULONG) MyClassFactory::Release (THIS) { ULONG cnt; cnt = (ULONG)InterlockedDecrement (&m_lRef); if (cnt == 0) delete this; return cnt; } //---------------------------------------------------------------------- // LockServer - Called to tell the DLL not to unload even if use count is 0 STDMETHODIMP MyClassFactory::LockServer (BOOL fLock) { if (fLock) InterlockedIncrement (&g_DllCnt); else InterlockedDecrement (&g_DllCnt); return NOERROR; } //---------------------------------------------------------------------- // CreateInstance - Called to have class factory object create other // objects STDMETHODIMP MyClassFactory::CreateInstance (LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppv) { MyIInputMethod *pMyIM; HRESULT hr; if (pUnkOuter) return (CLASS_E_NOAGGREGATION); if (IsEqualIID (riid, IID_IUnknown) || IsEqualIID (riid, IID_IInputMethod) || IsEqualIID (riid, IID_IInputMethod2)) { // Create Input method object. pMyIM = new MyIInputMethod(); if (!pMyIM) return E_OUTOFMEMORY; // See if object exports the proper interface. hr = pMyIM->QueryInterface (riid, ppv); // This will cause an obj delete unless interface found. pMyIM->Release (); return hr; } return E_NOINTERFACE; } //********************************************************************** // MyIInputMethod Object implementation //---------------------------------------------------------------------- // Object constructor MyIInputMethod::MyIInputMethod () { m_lRef = 1; // Set ref count to 1 on create. g_DllCnt++; return; } //---------------------------------------------------------------------- // Object destructor MyIInputMethod::~MyIInputMethod () { g_DllCnt--; return; } //---------------------------------------------------------------------- // QueryInterface - Called to see what interfaces this object supports STDMETHODIMP MyIInputMethod::QueryInterface (THIS_ REFIID riid, LPVOID *ppv) { // If caller wants our IUnknown or IID_IInputMethod2 object, // return a pointer to the object. if (IsEqualIID (riid, IID_IUnknown) || IsEqualIID (riid, IID_IInputMethod) || IsEqualIID (riid, IID_IInputMethod2)){ // Return ptr to object. *ppv = (IInputMethod *)this; AddRef(); // Increment ref to prevent delete on return. return NOERROR; } *ppv = NULL; return (E_NOINTERFACE); } //---------------------------------------------------------------------- // AddRef - Increment object ref count. STDMETHODIMP_(ULONG) MyIInputMethod::AddRef (THIS) { ULONG cnt; cnt = (ULONG)InterlockedIncrement (&m_lRef); return cnt; } //---------------------------------------------------------------------- // Release - Decrement object ref count. STDMETHODIMP_(ULONG) MyIInputMethod::Release (THIS) { ULONG cnt; cnt = (ULONG)InterlockedDecrement (&m_lRef); if (cnt == 0) { delete this; return 0; } return cnt; } //---------------------------------------------------------------------- // Select - The IM has just been loaded into memory. // HRESULT STDMETHODCALLTYPE MyIInputMethod::Select (HWND hwndSip) { HBITMAP hBmp, hbmpMask; m_hwndParent = hwndSip; // Create image list for narrow (16x16) image. m_himlNarrow = ImageList_Create (16, 16, ILC_COLOR | ILC_MASK, 1, 0); hBmp = LoadBitmap (hInst, TEXT ("NarrowBmp")); hbmpMask = LoadBitmap (hInst, TEXT ("NarrowMask")); ImageList_Add (m_himlNarrow, hBmp, hbmpMask); DeleteObject (hBmp); DeleteObject (hbmpMask); // Create image list for wide (32x16) image. m_himlWide = ImageList_Create (32, 16, ILC_COLOR | ILC_MASK, 1, 0); hBmp = LoadBitmap (hInst, TEXT ("WideBmp")); hbmpMask = LoadBitmap (hInst, TEXT ("WideMask")); ImageList_Add (m_himlWide, hBmp, hbmpMask); DeleteObject (hBmp); DeleteObject (hbmpMask); // Create SIP window. m_hwndMyWnd = CreateIMWindow (hwndSip); if (!IsWindow (m_hwndMyWnd)) return E_FAIL; return S_OK; } //---------------------------------------------------------------------- // Deselect - The IM is about to be unloaded. // HRESULT STDMETHODCALLTYPE MyIInputMethod::Deselect (void) { DestroyIMWindow (m_hwndMyWnd); ImageList_Destroy (m_himlNarrow); ImageList_Destroy (m_himlWide); return S_OK; } //---------------------------------------------------------------------- // Showing - The IM is about to be made visible. // HRESULT STDMETHODCALLTYPE MyIInputMethod::Showing (void) { return S_OK; } //---------------------------------------------------------------------- // Hiding - The IM is about to be hidden. // HRESULT STDMETHODCALLTYPE MyIInputMethod::Hiding (void) { return S_OK; } //---------------------------------------------------------------------- // GetInfo - The SIP wants info from the IM. // HRESULT STDMETHODCALLTYPE MyIInputMethod::GetInfo ( IMINFO __RPC_FAR *pimi) { pimi->cbSize = sizeof (IMINFO); pimi->hImageNarrow = m_himlNarrow; pimi->hImageWide = m_himlWide; pimi->iNarrow = 0; pimi->iWide = 0; pimi->fdwFlags = SIPF_DOCKED; pimi->rcSipRect.left = 0; pimi->rcSipRect.top = 0; pimi->rcSipRect.right = FLOATWIDTH; pimi->rcSipRect.bottom = FLOATHEIGHT; SendMessage (m_hwndMyWnd, MYMSG_METHCALL, MSGCODE_GETINFO, (LPARAM) pimi); return S_OK; } //---------------------------------------------------------------------- // ReceiveSipInfo - The SIP is passing info to the IM. // HRESULT STDMETHODCALLTYPE MyIInputMethod::ReceiveSipInfo ( SIPINFO __RPC_FAR *psi) { // Pass the sip info data to the window. SendMessage (m_hwndMyWnd, MYMSG_METHCALL, MSGCODE_SETINFO, (LPARAM) psi); return S_OK; } //---------------------------------------------------------------------- // RegisterCallback - The SIP is providing the IM with the pointer to // the IIMCallback interface. // HRESULT STDMETHODCALLTYPE MyIInputMethod::RegisterCallback ( IIMCallback __RPC_FAR *lpIMCallback) { m_pIMCallback = lpIMCallback; PostMessage (m_hwndMyWnd, MYMSG_METHCALL, MSGCODE_REGCALLBACK, (LPARAM)m_pIMCallback); return S_OK; } //---------------------------------------------------------------------- // GetImData - An application is passing IM-specific data to the IM. // HRESULT STDMETHODCALLTYPE MyIInputMethod::GetImData (DWORD dwSize, LPVOID pvImData) { return E_FAIL; } //---------------------------------------------------------------------- // SetImData - An application is querying IM-specific data from the IM. // HRESULT STDMETHODCALLTYPE MyIInputMethod::SetImData (DWORD dwSize, LPVOID pvImData) { return S_OK; } //---------------------------------------------------------------------- // UserOptionsDlg - The SIP Control Panel applet is asking for a // configuration dialog box to be displayed. // HRESULT STDMETHODCALLTYPE MyIInputMethod::UserOptionsDlg ( HWND hwndParent) { MessageBox (hwndParent, TEXT ("UserOptionsDlg called."), TEXT ("NumPanel"), MB_OK); return S_OK; } //---------------------------------------------------------------------- // SetIMMActiveContext - Provides information about the IME // HRESULT STDMETHODCALLTYPE MyIInputMethod::SetIMMActiveContext(HWND hwnd, BOOL bOpen, DWORD dwConversion, DWORD dwSentence, DWORD hkl) { return S_OK; } //---------------------------------------------------------------------- // RegisterCallback2 - The SIP is providing the IM with the pointer to // the IIMCallback interface. // HRESULT STDMETHODCALLTYPE MyIInputMethod::RegisterCallback2 ( IIMCallback2 __RPC_FAR *lpIMCallback) { m_pIMCallback = lpIMCallback; PostMessage (m_hwndMyWnd, MYMSG_METHCALL, MSGCODE_REGCALLBACK2, (LPARAM)m_pIMCallback); return S_OK; }