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; 
}