📄 newmenux.cpp
字号:
//======================================================================
// NewMenuX - A Pocket PC New menu extension
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <commctrl.h> // Command bar includes
#define INITGUID
#include <initguid.h>
#include <coguid.h>
#include <aygshell.h> // Pocket PC shell includes
#include <shlguid.h> // Shell GUIDs inc New menu ext
#include "NewMenuX.h" // My IM common includes
long g_DllCnt = 0; // Global DLL reference count
HINSTANCE hInst; // DLL instance handle
const TCHAR szFriendlyName[] = TEXT ("Prog Win CE New Menu Extension");
//======================================================================
// 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_NewMenuX)) {
// 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"), szCLSIDNewMenuX);
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 new menu item extension.
RegSetValueEx (hKey, TEXT (""), 0, REG_SZ, (PBYTE)szFriendlyName,
(lstrlen (szFriendlyName)+1) * sizeof (TCHAR));
// Create subkeys.
// Set the module name of the new menu item server
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);
RegCloseKey (hKey);
//
// Add entry to add new menu item
//
// Create string, use multuple lines due to book format limits
lstrcpy (szTmp, TEXT ("Software\\Microsoft\\Shell\\"));
lstrcat (szTmp, TEXT ("Extensions\\NewMenu\\"));
lstrcat (szTmp, szCLSIDNewMenuX);
rc = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szTmp, 0, TEXT(""),
0, 0, NULL, &hKey, &dwDisp);
if (rc != ERROR_SUCCESS)
return E_FAIL;
// Set the friendly name of the new menu item extension.
lstrcpy (szTmp, TEXT("Launch Calc"));
RegSetValueEx (hKey, TEXT (""), 0, REG_SZ, (PBYTE)szTmp,
(lstrlen (szTmp)+1) * sizeof (TCHAR));
dwDisp = 1;
RegSetValueEx (hKey, TEXT ("Enabled"), 0, REG_DWORD, (PBYTE)&dwDisp,
sizeof (DWORD));
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"), szCLSIDNewMenuX);
rc = RegDeleteKey (HKEY_CLASSES_ROOT, szTmp);
if (rc != ERROR_SUCCESS)
return E_FAIL;
// Create string, use multuple lines due to book format limits
lstrcpy (szTmp, TEXT ("Software\\Microsoft\\Shell\\"));
lstrcat (szTmp, TEXT ("Extensions\\NewMenu\\"));
lstrcat (szTmp, szCLSIDNewMenuX);
rc = RegDeleteKey (HKEY_CLASSES_ROOT, szTmp);
if (rc != ERROR_SUCCESS)
return E_FAIL;
return S_OK;
}
//**********************************************************************
// 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(); // Inc 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 cnt 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) {
MyNewMenuItemServer *pMyNMX;
HRESULT hr;
if (pUnkOuter)
return (CLASS_E_NOAGGREGATION);
if (IsEqualIID (riid, IID_IUnknown) ||
IsEqualIID (riid, IID_INewMenuItemServer)) {
// Create New menu item object.
pMyNMX = new MyNewMenuItemServer();
if (!pMyNMX)
return E_OUTOFMEMORY;
// See if object exports the proper interface.
hr = pMyNMX->QueryInterface (riid, ppv);
// This will cause an object delete unless interface found.
pMyNMX->Release ();
return hr;
}
return E_NOINTERFACE;
}
//**********************************************************************
// MyNewMenuItemServer Object implementation
//----------------------------------------------------------------------
// Object constructor
MyNewMenuItemServer::MyNewMenuItemServer () {
m_lRef = 1; //Set ref count to 1 on create.
g_DllCnt++;
return;
}
//----------------------------------------------------------------------
// Object destructor
MyNewMenuItemServer::~MyNewMenuItemServer () {
g_DllCnt--;
return;
}
//----------------------------------------------------------------------
// QueryInterface - Called to see what interfaces this object supports
STDMETHODIMP MyNewMenuItemServer::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_INewMenuItemServer)) {
// Return pointer to object.
*ppv = (INewMenuItemServer *)this;
AddRef(); // Inc ref to prevent delete on return.
return NOERROR;
}
*ppv = NULL;
return (E_NOINTERFACE);
}
//----------------------------------------------------------------------
// AddRef - Increment object ref count.
STDMETHODIMP_(ULONG) MyNewMenuItemServer::AddRef (THIS) {
ULONG cnt;
cnt = (ULONG)InterlockedIncrement (&m_lRef);
return cnt;
}
//----------------------------------------------------------------------
// Release - Decrement object ref count.
STDMETHODIMP_(ULONG) MyNewMenuItemServer::Release (THIS) {
ULONG cnt;
cnt = (ULONG)InterlockedDecrement (&m_lRef);
if (cnt == 0) {
delete this;
return 0;
}
return cnt;
}
//----------------------------------------------------------------------
// CreateNewItem - The new menu item has been selected.
//
STDMETHODIMP_(HRESULT) MyNewMenuItemServer::CreateNewItem
(HWND hwndParent) {
SHELLEXECUTEINFO se;
// Launch the calculator.
memset (&se, 0, sizeof (se));
se.cbSize = sizeof (se);
se.hwnd = hwndParent;
se.lpFile = TEXT ("calc.exe");
se.lpVerb = TEXT("open");
se.lpDirectory = TEXT ("\\windows");
ShellExecuteEx (&se); // Launch the control panel.
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -