📄 imcommon.cpp
字号:
#include <windows.h> // For all that Windows stuff
#include <commctrl.h> // Command bar includes
#define INITGUID
#include <initguid.h>
#include <coguid.h>
#include <sip.h> // 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -