?? start.cpp
字號:
// Start.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "start.h"
#include "resource.h"
HINSTANCE g_hInstance;
BOOL g_bInstalled = FALSE;
HBITMAP g_hbmStart = NULL;
BOOL g_bSubclassed = FALSE;
WNDPROC g_pfnStartProc = NULL;
HWND g_hwndTip = NULL;
TOOLINFO g_ti;
BOOL g_bAlreadyDrawn = FALSE;
BOOL g_bFirstTime = TRUE;
BOOL APIENTRY DllMain( HINSTANCE hInstance,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
g_hInstance = hInstance;
return TRUE;
}
/*---------------------------------------------------------------------------*/
// DllGetClassObject
// Main function for a COM in-proc object like this
/*---------------------------------------------------------------------------*/
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
InstallHandler();
return CLASS_E_CLASSNOTAVAILABLE;
}
/*---------------------------------------------------------------------------*/
// DllCanUnloadNow
// Confirm the unload for a COM library
/*---------------------------------------------------------------------------*/
STDAPI DllCanUnloadNow()
{
return (g_bInstalled ? S_FALSE : S_OK);
}
STDAPI DllRegisterServer()
{
TCHAR szSubKey[MAX_PATH] = {0};
TCHAR szCLSID[MAX_PATH] = {0};
TCHAR szModule[MAX_PATH] = {0};
HKEY hKey;
DWORD dwDisp;
// Set the CLSID
lstrcpy(szCLSID, __TEXT("{20051998-0019-0005-1998-000000000000}"));
// Get the module name
GetModuleFileName(g_hInstance, szModule, MAX_PATH);
// HKCR: CLSID\{...}
wsprintf(szSubKey, __TEXT("CLSID\\%s"), szCLSID);
LRESULT lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, szSubKey, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
if(lResult == NOERROR)
{
TCHAR szData[MAX_PATH] = {0};
wsprintf(szData, __TEXT("Start Button"), szModule);
lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ,
reinterpret_cast<LPBYTE>(szData), lstrlen(szData) + 1);
RegCloseKey(hKey);
}
// HKCR: CLSID\{...}\InProcServer32
wsprintf(szSubKey, __TEXT("CLSID\\%s\\InProcServer32"), szCLSID);
lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, szSubKey, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
if(lResult == NOERROR)
{
lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ,
reinterpret_cast<LPBYTE>(szModule), lstrlen(szModule) + 1);
TCHAR szData[MAX_PATH] = {0};
lstrcpy(szData, __TEXT("Apartment"));
lResult = RegSetValueEx(hKey, __TEXT("ThreadingModel"), 0, REG_SZ,
reinterpret_cast<LPBYTE>(szData), lstrlen(szData) + 1);
RegCloseKey(hKey);
}
return S_OK;
}
STDAPI DllUnregisterServer()
{
TCHAR szSubKey[MAX_PATH] = {0};
TCHAR szCLSID[MAX_PATH] = {0};
TCHAR szModule[MAX_PATH] = {0};
HKEY hKey;
DWORD dwDisp;
// Set the CLSID
lstrcpy(szCLSID, __TEXT("{20051998-0019-0005-1998-000000000000}"));
// Open HKCR
LRESULT lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, "", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
if(lResult == NOERROR)
{
wsprintf(szSubKey, __TEXT("CLSID\\%s\\InProcServer32"), szCLSID);
RegDeleteKey(hKey, szSubKey);
wsprintf(szSubKey, __TEXT("CLSID\\%s"), szCLSID);
RegDeleteKey(hKey, szSubKey);
RegCloseKey(hKey);
}
return S_OK;
}
/*-------------------------------------------------------*/
// InstallHandler
// Replace the Start button and install the hooks
/*-------------------------------------------------------*/
void InstallHandler()
{
if(g_bInstalled)
{
int irc = MessageBox(HWND_DESKTOP,
__TEXT("The extension is installed. Would you like to uninstall?"),
__TEXT("Start"), MB_ICONQUESTION | MB_YESNO | MB_SETFOREGROUND);
if(irc == IDYES)
UninstallHandler();
return;
}
// Remember whether the handler is installed
g_bInstalled = TRUE;
// Set a new Start button
SetNewStartButton(TRUE);
}
void UninstallHandler()
{
// Restore the Start settings
SetNewStartButton(FALSE);
// The handler is now uninstalled
g_bInstalled = FALSE;
// Restore the old tooltip text
g_ti.lpszText = __TEXT("Click here to begin");
SendMessage(g_hwndTip, TTM_UPDATETIPTEXT, 0, reinterpret_cast<LPARAM>(&g_ti));
}
HBITMAP NewStartBitmap(HWND hwndStart, BOOL fNew)
{
if(!fNew)
{
if(g_hbmStart)
SendMessage(hwndStart, BM_SETIMAGE, IMAGE_BITMAP, reinterpret_cast<LPARAM>(g_hbmStart));
// Refresh the button to reflect the change
SetWindowPos(hwndStart, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_DRAWFRAME);
return NULL;
}
// Save the current bitmap
g_hbmStart = reinterpret_cast<HBITMAP>(SendMessage(hwndStart, BM_GETIMAGE, IMAGE_BITMAP, 0));
// Load and set the new bitmap
HBITMAP hbm = reinterpret_cast<HBITMAP>(LoadImage(g_hInstance, MAKEINTRESOURCE(IDB_NEWSTART), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE));
SendMessage(hwndStart, BM_SETIMAGE, IMAGE_BITMAP, reinterpret_cast<LPARAM>(hbm));
// Refresh the button to reflect the change
SetWindowPos(hwndStart, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_DRAWFRAME);
return g_hbmStart;
}
/*-------------------------------------------------------*/
// SetNewStartButton
// Replace/Restore the bitmap for the Start button
/*-------------------------------------------------------*/
void SetNewStartButton(BOOL fNew)
{
// Get the handle to the Start button
HWND hwndTray = FindWindowEx(NULL, NULL, "Shell_TrayWnd", NULL);
HWND hwndStart = FindWindowEx(hwndTray, NULL, "Button", NULL);
// Change the bitmap
g_hbmStart = NewStartBitmap(hwndStart, fNew);
// Replace the tooltip text
RemoveTooltip(hwndStart);
// Subclass the button
if(fNew)
{
if(!g_bSubclassed)
{
g_pfnStartProc = SubclassWindow(hwndStart, NewStartProc);
g_bSubclassed = TRUE;
}
}
else
{
if(g_pfnStartProc != NULL)
SubclassWindow(hwndStart, g_pfnStartProc);
g_bSubclassed = FALSE;
}
}
LRESULT CALLBACK NewStartProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_SETCURSOR:
SetCursor(LoadCursor(g_hInstance, MAKEINTRESOURCE(IDC_HANDY)));
return 0;
case WM_MEASUREITEM:
MeasureItem(HWND_DESKTOP, reinterpret_cast<LPMEASUREITEMSTRUCT>(lParam));
break;
case WM_DRAWITEM:
DrawItem(reinterpret_cast<LPDRAWITEMSTRUCT>(lParam));
break;
case WM_CONTEXTMENU:
return 0;
case BM_SETSTATE:
case WM_LBUTTONDOWN:
{
WNDCLASS wc;
GetClassInfo(NULL, "Button", &wc);
CallWindowProc(wc.lpfnWndProc, hwnd, BM_SETSTATE, TRUE, 0);
STARTMENUPOS smp;
GetStartMenuPosition(&smp);
HMENU hmnuPopup = GetMenuHandle("c:\\myStartMenu");
int iCmd = TrackPopupMenu(hmnuPopup,
smp.uFlags | TPM_RETURNCMD | TPM_NONOTIFY,
smp.ix, smp.iy, 0, hwnd, NULL);
// Handle the user's mouse clicks
HandleResults(hmnuPopup, iCmd);
// Free memory
DestroyMenu(hmnuPopup);
CallWindowProc(wc.lpfnWndProc, hwnd, BM_SETSTATE, FALSE, 0);
return 0;
}
}
return CallWindowProc(g_pfnStartProc, hwnd, uMsg, wParam, lParam);
}
void RemoveTooltip(HWND hwndStart)
{
EnumThreadWindows(GetCurrentThreadId(), EnumThreadWndProc, reinterpret_cast<LPARAM>(hwndStart));
}
// This thread created just one tooltip window. All the windows that belong
// to the thread are enumerated in order to find the tooltip. This
// callback receives the handle of all the windows the thread created. The
// lParam is the handle (hwndStart) of the Start button.
BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM lParam)
{
TCHAR szClass[MAX_PATH] = {0};
GetClassName(hwnd, szClass, MAX_PATH);
if(0 == lstrcmpi(szClass, TOOLTIPS_CLASS))
{
// Tooltip window found, so try to locate the tool
int iNumOfTools = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
for(int i = 0 ; i < iNumOfTools ; i++)
{
// Get information about the ith tool
TOOLINFO ti;
g_hwndTip = hwnd;
ti.cbSize = sizeof(TOOLINFO);
SendMessage(hwnd, TTM_ENUMTOOLS, i, reinterpret_cast<LPARAM>(&ti));
if(ti.uId == static_cast<UINT>(lParam))
{
// Tool for the Start button found.
CopyMemory(&g_ti, &ti, sizeof(TOOLINFO));
ti.lpszText = __TEXT("Buy this book!");
SendMessage(hwnd, TTM_UPDATETIPTEXT, 0, reinterpret_cast<LPARAM>(&ti));
}
}
return FALSE;
}
return TRUE;
}
void GetStartMenuPosition(LPSTARTMENUPOS lpsmp)
{
// Get the taskbar's edge and position
APPBARDATA abd;
abd.cbSize = sizeof(APPBARDATA);
SHAppBarMessage(ABM_GETTASKBARPOS, &abd);
switch(abd.uEdge)
{
case ABE_BOTTOM:
lpsmp->ix = 0;
lpsmp->iy = abd.rc.top;
lpsmp->uFlags = TPM_LEFTALIGN | TPM_BOTTOMALIGN;
break;
case ABE_TOP:
lpsmp->ix = 0;
lpsmp->iy = abd.rc.bottom;
lpsmp->uFlags = TPM_LEFTALIGN | TPM_TOPALIGN;
break;
case ABE_LEFT:
lpsmp->ix = abd.rc.right;
lpsmp->iy = 0;
lpsmp->uFlags = TPM_LEFTALIGN | TPM_TOPALIGN;
break;
case ABE_RIGHT:
lpsmp->ix = abd.rc.left;
lpsmp->iy = 0;
lpsmp->uFlags = TPM_RIGHTALIGN | TPM_TOPALIGN;
break;
}
}
HMENU GetMenuHandle(LPTSTR szPath)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -