опубликован 16-08-2001 18:14 MSK
Привожу пример:
(все в длл) - успешно заменяет wndproc у десктопного окна:#include "hooks.hpp"
HINSTANCE hInst;
HHOOK hCWPRHook;
HWND hExplWnd;
HWND hListWnd;
WNDPROC OldWndProc = NULL;
#define WM_HOOK_DONE WM_USER + 100
void DrawText(HWND hWnd)
{
HDC hDc = GetDC(hWnd);
TextOut(hDc,0,0,"Hello World",11);
ReleaseDC(hWnd,hDc);
}
void DrawItem(HWND hWnd,NMLVCUSTOMDRAW& lvcdr)
{
NMCUSTOMDRAW& cdr = (NMCUSTOMDRAW&)lvcdr;
RECT& Rect = cdr . rc;
HDC hDc = cdr . hdc;
int ItemIdx = cdr . dwItemSpec;
HIMAGELIST Images = ListView_GetImageList(hWnd,LVSIL_NORMAL);
LV_ITEM Item;
memset(&Item,0,sizeof(Item));
static char Buff[255];
Item . mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
Item . pszText = Buff;
Item . cchTextMax = 255;
Item . iItem = ItemIdx;
Item . stateMask = 255;
ListView_GetItem(hWnd,&Item);
ListView_GetItemRect(hWnd,ItemIdx,&Rect,LVIR_ICON);
int cx,cy;
ImageList_GetIconSize(Images,&cx,&cy);
int dx = (Rect . right - Rect . left - cx) / 2;
ImageList_Draw(Images,Item . iImage,hDc,Rect . left + dx,Rect . top + 2,
ILD_NORMAL | ILD_TRANSPARENT);
ListView_GetItemRect(hWnd,ItemIdx,&Rect,LVIR_LABEL);
RedrawWindow(NULL,&Rect,0,RDW_ERASE | RDW_INVALIDATE | RDW_NOINTERNALPAINT |
RDW_NOFRAME | RDW_ERASENOW | RDW_NOCHILDREN);
SetBkMode(hDc,TRANSPARENT);
Rect . left ++;
Rect . top ++;
SetTextColor(hDc,lvcdr . clrTextBk);
DrawText(hDc,Buff,-1,&Rect,DT_NOPREFIX | DT_WORDBREAK | DT_CENTER);
Rect . left --;
Rect . top --;
SetTextColor(hDc,lvcdr . clrText);
DrawText(hDc,Buff,-1,&Rect,DT_NOPREFIX | DT_WORDBREAK | DT_CENTER);
// SelectObject(hDc,hOldPen);
}
LRESULT DoCustomDraw(NMLVCUSTOMDRAW& lvcdr)
{
LRESULT Result = CDRF_DODEFAULT;
NMCUSTOMDRAW& cdr = (NMCUSTOMDRAW&)lvcdr;
switch(cdr . dwDrawStage)
{
case CDDS_PREPAINT:
Result = CDRF_NOTIFYITEMDRAW;
break;
// case CDDS_PREERASE:
// Result = CDRF_NOTIFYITEMERASE;
// break;
case CDDS_ITEMPREPAINT:
// SetBkMode(cdr . hdc,TRANSPARENT);
// lvcdr . clrTextBk = RGB(255,255,255);
// lvcdr . clrText = RGB(255,0,0);
if(!cdr . uItemState)
{
DrawItem(cdr . hdr . hwndFrom,lvcdr);
Result = CDRF_SKIPDEFAULT;//CDRF_NEWFONT;
}
break;
// case CDDS_ITEMPREERASE:
// Result = CDRF_SKIPDEFAULT;
// break;
}
return Result;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
LRESULT RetVal = 0;
PAINTSTRUCT ps;
switch(uMsg)
{
case WM_NOTIFY:
// BeginPaint(hWnd,&ps);
// EndPaint(hWnd,&ps);
// DrawText(hWnd);
{
NMHDR * Hdr = (NMHDR *)lParam;
if(Hdr -> code == NM_CUSTOMDRAW)
{
// RetVal = CallWindowProc(OldWndProc,hWnd,uMsg,wParam,lParam);
RetVal = DoCustomDraw(*((NMLVCUSTOMDRAW *)Hdr));
break;
}
else
RetVal = CallWindowProc(OldWndProc,hWnd,uMsg,wParam,lParam);
break;
}
case WM_HOOK_DONE:
SetWindowLong(hWnd,GWL_WNDPROC,(LONG)OldWndProc);
return 0;
default:
RetVal = CallWindowProc(OldWndProc,hWnd,uMsg,wParam,lParam);
}
// SetWindowLong(hWnd,GWL_WNDPROC,(LONG)WndProc);
return RetVal;
}
HWND FindDesktopWindow()
{
HWND hWnd = FindWindowEx(NULL,NULL,"Progman",NULL);
hWnd = FindWindowEx(hWnd,NULL,"SHELLDLL_DefView",NULL);
// hWnd = FindWindowEx(hWnd,NULL,"SysListView32",NULL);
return hWnd;
}
void InstallWndProc()
{
HWND hWnd = FindDesktopWindow();
OldWndProc = (WNDPROC)GetWindowLong(hWnd,GWL_WNDPROC);
SetWindowLong(hWnd,GWL_WNDPROC,(LONG)WndProc);
hExplWnd = hWnd;
}
LRESULT CALLBACK CWPRHookProc(int Code,WPARAM wParam,LPARAM lParam)
{
CWPRETSTRUCT * RetStruct = (CWPRETSTRUCT *)lParam;
// if(RetStruct -> message == WM_PAINT)// &&
// RetStruct -> hwnd == hExplWnd)
// DrawText(RetStruct -> hwnd);
if(!OldWndProc)
InstallWndProc();
CallNextHookEx(hCWPRHook,Code,wParam,lParam);
}
void InstallHook()
{
HWND hWnd = FindDesktopWindow();
OldWndProc = (WNDPROC)GetWindowLong(hWnd,GWL_WNDPROC);
hExplWnd = hWnd;
DWORD hThread = GetWindowThreadProcessId(hWnd,NULL);
hCWPRHook = SetWindowsHookEx(WH_CALLWNDPROCRET,CWPRHookProc,hInst,hThread);
}
void UnInstallHook()
{
// SetWindowLong(hExplWnd,GWL_WNDPROC,(LONG)OldWndProc);
SendMessage(hExplWnd,WM_HOOK_DONE,0,0);
UnhookWindowsHookEx(hCWPRHook);
}
int __export __stdcall DllEntryPoint(HINSTANCE _hInst,DWORD Reason,void *)
{
hInst = _hInst;
switch(Reason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return 1;
}