ZMatrix是一个桌面增强软件,可以在桌面上显示字符流动态背景,它模拟的字符动画与黑客帝国电影中的效果极为相似。而更神奇的是,ZMatrix还可以将字符与桌面背景融合,类似于使用字符组合成图像:
工程如图:
MsgHook中主要是负责对鼠标钩子以及桌面操作钩子的实现。如下:
/****************************************************************************
* SetMouseMessageHook
* Inputs:
* HWND hWnd: Window to notify
* Result: bool
* true if successful
* false if error
* Effect:
* Sets the hook
****************************************************************************/
bool SetMouseMessageHook(HWND hWnd)
{
if(hMouseMessageHookProcTargetWindow != NULL)
return FALSE; // already hooked!
MouseMessageHook = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)MouseMessageHookProc,hInst,0);
if(MouseMessageHook != NULL)
{ /* success */
hMouseMessageHookProcTargetWindow = hWnd;
return true;
}
return false; // failed to set hook
}
/****************************************************************************
* ClearMouseMessageHook
* Inputs:
* HWND hWnd: Window hook
* Result: bool
* true if successful
* false if error
* Effect:
* Removes the hook that has been set
****************************************************************************/
bool ClearMouseMessageHook(HWND hWnd)
{
if(hWnd != hMouseMessageHookProcTargetWindow || hWnd == NULL)
return FALSE;
bool unhooked = (0 != UnhookWindowsHookEx(MouseMessageHook));
if(unhooked)
hMouseMessageHookProcTargetWindow = NULL;
return unhooked;
}
/****************************************************************************
* MouseMessageHookProc
* Inputs:
* int nCode: Code value
* WPARAM wParam:
* LPARAM lParam:
* Result: LRESULT
* Either 0 or the result of CallNextHookEx
* Effect:
* Hook processing function. If the message is a mouse-move message,
* posts the coordinates to the parent window
****************************************************************************/
static LRESULT CALLBACK MouseMessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode != HC_ACTION)
{ /* pass it on */
return CallNextHookEx(MouseMessageHook, nCode, wParam, lParam);
}
LPMSG msg = (LPMSG)lParam;
if((msg != NULL) && (msg->hwnd != hMouseMessageHookProcTargetWindow))
{
if((msg->message == WM_MOUSEMOVE) || (msg->message == WM_NCMOUSEMOVE))
{
POINT MousePoint;
MousePoint.x = GET_X_LPARAM(lParam);
MousePoint.y = GET_Y_LPARAM(lParam);
ClientToScreen(msg->hwnd,&MousePoint);
ClientToScreen(hMouseMessageHookProcTargetWindow,&MousePoint);
LPARAM NewLParam = MAKELPARAM(MousePoint.x,MousePoint.y);
PostMessage(hMouseMessageHookProcTargetWindow, WM_MOUSEMOVE, 0, NewLParam);
}
else if((msg->message == WM_LBUTTONDOWN) || (msg->message == WM_NCLBUTTONDOWN))
{
PostMessage(hMouseMessageHookProcTargetWindow, WM_LBUTTONDOWN, 0, 0);
}
else if((msg->message == WM_RBUTTONDOWN) || (msg->message == WM_NCRBUTTONDOWN))
{
PostMessage(hMouseMessageHookProcTargetWindow, WM_RBUTTONDOWN, 0, 0);
}
else if((msg->message == WM_MBUTTONDOWN) || (msg->message == WM_NCMBUTTONDOWN))
{
PostMessage(hMouseMessageHookProcTargetWindow, WM_MBUTTONDOWN, 0, 0);
}
else if(msg->message == WM_KEYDOWN)
{
PostMessage(hMouseMessageHookProcTargetWindow, WM_KEYDOWN, 0, 0);
}
else if(msg->message == WM_SYSKEYDOWN)
{
PostMessage(hMouseMessageHookProcTargetWindow, WM_SYSKEYDOWN, 0, 0);
}
else if(msg->message == WM_SYSCOMMAND)
{
PostMessage(hMouseMessageHookProcTargetWindow, WM_SYSCOMMAND, 0, 0);
}
}
return CallNextHookEx(MouseMessageHook, nCode, wParam, lParam);
}
/****************************************************************************
* SetDesktopMonitorHook
* Inputs:
* HWND hWnd: Window to notify
* Result: bool
* true if successful
* false if error
* Effect:
* Sets the hook
****************************************************************************/
bool SetDesktopMonitorHook(HWND hWnd)
{
if(hDesktopMonitorHookProcTargetWindow != NULL)
return FALSE; // already hooked!
DesktopMonitorHook = SetWindowsHookEx(WH_CALLWNDPROCRET,(HOOKPROC)DesktopMonitorHookProc,hInst,0);
if(DesktopMonitorHook != NULL)
{ /* success */
hDesktopMonitorHookProcTargetWindow = hWnd;
return true;
}
return false; // failed to set hook
}
/****************************************************************************
* ClearDesktopMonitorHook
* Inputs:
* HWND hWnd: Window hook
* Result: bool
* true if successful
* false if error
* Effect:
* Removes the hook that has been set
****************************************************************************/
bool ClearDesktopMonitorHook(HWND hWnd)
{
if(hWnd != hDesktopMonitorHookProcTargetWindow || hWnd == NULL)
return FALSE;
bool unhooked = (0 != UnhookWindowsHookEx(DesktopMonitorHook));
if(unhooked)
hDesktopMonitorHookProcTargetWindow = NULL;
return unhooked;
}
/****************************************************************************
* DesktopMonitorHookProc
* Inputs:
* int nCode: Code value
* WPARAM wParam:
* LPARAM lParam:
* Result: LRESULT
* Either 0 or the result of CallNextHookEx
* Effect:
* Hook processing function.
****************************************************************************/
static LRESULT CALLBACK DesktopMonitorHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
static bool ChangesOccurredToDesktopIcons = false;
if(nCode != HC_ACTION)
{ /* pass it on */
return CallNextHookEx(DesktopMonitorHook, nCode, wParam, lParam);
}
CWPRETSTRUCT *msg = (CWPRETSTRUCT *)lParam;
if(msg != NULL)
{
if(msg->hwnd == hSysListView)
{
switch(msg->message)
{
case(WM_PAINT):
{
if(ChangesOccurredToDesktopIcons)
{
PostMessage(hDesktopMonitorHookProcTargetWindow,UWM_DESKTOPITEMCHANGED,0,0);
ChangesOccurredToDesktopIcons = false;
}
}
break;
case(WM_NCPAINT):
{
if(ChangesOccurredToDesktopIcons)
{
PostMessage(hDesktopMonitorHookProcTargetWindow,UWM_DESKTOPITEMCHANGED,0,0);
ChangesOccurredToDesktopIcons = false;
}
if(msg->wParam == 1)
{
PostMessage(hDesktopMonitorHookProcTargetWindow, UWM_DESKTOPREDRAW, 0, 0);
}
}
break;
case(LVM_SETITEM):
case(LVM_SETITEMTEXT):
case(LVM_DELETEITEM):
case(LVM_ARRANGE):
case(LVM_SETITEMPOSITION32):
case(LVM_SETITEMSTATE):
{
ChangesOccurredToDesktopIcons = true;
}
break;
default:
{
}
break;
}
}
else if(msg->hwnd == hShellDll)
{
switch(msg->message)
{
case(WM_PARENTNOTIFY):
{
if(WM_CREATE == LOWORD(msg->wParam))
{
PostMessage(hDesktopMonitorHookProcTargetWindow,UWM_DESKTOPCHILDATTACHED,msg->wParam,msg->lParam);
}
}
break;
default:
{
}
break;
}
}
}
return CallNextHookEx(DesktopMonitorHook, nCode, wParam, lParam);
}
zsMatrix是一个控件,主要是产生绘画对象进行桌旁背景的绘画,如下:
HRESULT zsMatrixFactory::CreatezsMatrix(IzsMatrix **ppNewMatrix,HWND TargetWindow,HBITMAP BGBitmap)
{
*ppNewMatrix=(IzsMatrix*) new zsMatrix(TargetWindow,BGBitmap);
return NO_ERROR;
}
//===========================================================================
//===========================================================================
HRESULT zsMatrixFactory::CreatezsMatrix(IzsMatrix **ppNewMatrix,const IzsMatrix &OtherMatrix)
{
*ppNewMatrix=(IzsMatrix*) new zsMatrix(OtherMatrix);
return NO_ERROR;
}
//===========================================================================
//===========================================================================
HRESULT zsMatrixFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppObject)
{
if (pUnkOuter!=NULL)
{
return CLASS_E_NOAGGREGATION;
}
zsMatrix *pMatrix = new zsMatrix();
if (FAILED(pMatrix->QueryInterface(riid, ppObject)))
{
delete pMatrix;
*ppObject=NULL;
return E_NOINTERFACE;
}
return NO_ERROR;
}
matrix是主程序,关键引用控件源码源码如下:
HRESULT Result = NO_ERROR;
MULTI_QI Qi;
Qi.pIID = &IID_IZSMATRIX;
Qi.pItf = NULL;
Qi.hr = 0;
if(FAILED(Result = CoCreateInstanceEx(CLSID_ZSMATRIX,NULL,CLSCTX_ALL,NULL,1,&Qi) ) )
{
MB("Failed to create MatrixObject");
StopRegistryListenerThread();
DestroyTopLevelListener();
RestoreOrigDesktop();
Shell_NotifyIcon(NIM_DELETE,&IconData);
MatrixObject->Release();
DeleteObject(ValidRGN);
DestroyMenu(gSysTrayMenu);
DestroyIcon(IconData.hIcon);
if(!DestroyWindow(ghWnd))
MB("Failed to delete ZMatrix rendering window");
if(!UnregisterClass(szWinName,ghInstance))
MB("Failed to unregister ZMatrix rendering class");
CoUninitialize();
return 0;
};
MatrixObject = (IzsMatrix *)Qi.pItf;
SetDesktopMonitorHook(ghWnd);
//MatrixObject->SethWnd(ghWnd);
//MatrixObject->SetBGBitmap(Refresh());
HBITMAP NewBGBitmap = Refresh();
MatrixObject->UpdateTarget(ghWnd,NewBGBitmap);
if(!DeleteObject(NewBGBitmap))
{
MB("Failed to delete new BG bitmap during startup");
}
LoadConfig(MatrixObject,RefreshTime);
ProcessMiscConfiguration();
ReadyToScreenSave = true;
if(OutstandingScreenSaveRequest)
{
vector<OutstandingScreenSaveRequestPair>::iterator Iter = OutstandingScreenSaveRequestParams.begin();
for(;Iter != OutstandingScreenSaveRequestParams.end(); ++Iter)
{
PostMessage(ghWnd,WM_START_SCREENSAVE,Iter->first,Iter->second);
}
OutstandingScreenSaveRequestParams.clear();
}
学习的目的是成熟!~