rendered paste body/*To use this code, you should define LnkCtrl_MemAlloc and LnkCtrl_MemFree before you include this header if your plugin uses a memory function other than GlobalXXX//////////////////////////////////////////////////////////////////////////nsDialogs:----------#define LnkCtrl_MemAlloc(cb) (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb))#define LnkCtrl_MemFree(mem) (HeapFree(GetProcessHeap(), 0, mem))#define NSISLNKCTRL_UNDERLINED#define NSISLNKCTRL_CURSORHAND#include "../?Shared?/NSISDlg_LinkCtrl.h".....case WM_DRAWITEM: if ( !lParam || !GetControl( ((DRAWITEMSTRUCT*)lParam)->hwndItem ) )break; return LnkCtrl_HandleDraw( (DRAWITEMSTRUCT*)lParam , g_dialog.rtl );//////////////////////////////////////////////////////////////////////////InstallOptions:---------------#define LnkCtrl_MemAlloc MALLOC#define LnkCtrl_MemFree FREE#define NSISLNKCTRL_DEFBTN#define NSISLNKCTRL_UNDERLINED#define NSISLNKCTRL_CURSORHAND#include "../?Shared?/NSISDlg_LinkCtrl.h"....case WM_DRAWITEM: if (FindControlIdx( !lParam || ((DRAWITEMSTRUCT*)lParam)->CtlID) < 0 )break; return LnkCtrl_HandleDraw( (DRAWITEMSTRUCT*)lParam , bRTL );....//pField->nParentIdx = SetWindowLong(hwCtrl, GWL_WNDPROC, (long)StaticLINKWindowProc);//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////And remember kids, if you change any code in this file, always test with XPStyle on AND off*/#pragma once #include <windowsx.h>#if 0# define LnkCtrl_DBGTRACE TRACE# else# define LnkCtrl_DBGTRACE(x)# endif#ifndef ODS_NOACCEL#define ODS_NOACCEL 0x0100#define ODS_NOFOCUSRECT 0x0200#endif#ifndef DT_HIDEPREFIX#define DT_HIDEPREFIX 0x00100000#endif#ifndef NSISLNKCTRL_FINLINE#ifdef _MSC_VER#define NSISLNKCTRL_FINLINE __forceinline#else#define NSISLNKCTRL_FINLINE inline#endif#endif#if defined(NSISLNKCTRL_UNDERLINED) || defined(NSISLNKCTRL_CURSORHAND) || defined(NSISLNKCTRL_DEFBTN)#define NSISLNKCTRL_SUBCLASStypedef struct {// BOOL HasFocusRect; WNDPROC OrgWndProc;#ifdef NSISLNKCTRL_CURSORHAND RECT rcHitTest;#endif#ifdef NSISLNKCTRL_DEFBTN BOOL IsDefBtn;#endif} LNKCTRLDATA;#define LnkCtrl_GetData(hLnk) ((LNKCTRLDATA*)GetProp(hLnk,"NSIS:LnkCtrl"))#define LnkCtrl_SetData(hLnk,pLNKCTRLDATA) (SetProp(hLnk,"NSIS:LnkCtrl",(HANDLE)(LNKCTRLDATA*)pLNKCTRLDATA))#define LnkCtrl_FreeDataPtr(hLnk) (RemoveProp(hLnk,"NSIS:LnkCtrl"))//"owner" can choose mem functions#ifndef LnkCtrl_MemAlloc //must return 0 on fail!#define LnkCtrl_MemAlloc(cb) (GlobalAlloc(GPTR,cb))#define LnkCtrl_MemFree(mem) (GlobalFree((HGLOBAL)mem))#endif#endif /* defined(NSISLNKCTRL_UNDERLINED) || defined(NSISLNKCTRL_CURSORHAND) */#define LnkCtrl_EraseBkgnd(hwnd,hdc,pRect) (SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)hdc,0))/*#ifndef NSISLNKCTRL_SUBCLASS#define LnkCtrl_GetFocusState(hwnd) ((BOOL)GetProp(hwnd,"NSIS:LnkCtrl"))#define LnkCtrl_SetFocusState(hwnd,s) (SetProp(hwnd,"NSIS:LnkCtrl",(HANDLE)s)) //other nsD code does not seem to care about RemoveProp, so I'm "leaking" aswell#endif*/#ifdef NSISLNKCTRL_SUBCLASS/*void NSISLNKCTRL_FINLINE LnkCtrl_SetFocusState(HWND hLnk,BOOL HasFocusRect) { LNKCTRLDATA* pLCD=LnkCtrl_GetData(hLnk); if (pLCD)pLCD->HasFocusRect=HasFocusRect;}BOOL NSISLNKCTRL_FINLINE LnkCtrl_GetFocusState(HWND hLnk) { LNKCTRLDATA* pLCD=LnkCtrl_GetData(hLnk); return (pLCD) ? pLCD->HasFocusRect : FALSE;}*/LRESULT CALLBACK LnkCtrl_SubProc(HWND hwnd,UINT uMsg,WPARAM wp,LPARAM lp) { LNKCTRLDATA* pLCD=LnkCtrl_GetData(hwnd); if (!pLCD) return DefWindowProc(hwnd,uMsg,wp,lp); switch(uMsg) {#ifdef NSISLNKCTRL_CURSORHAND case WM_NCHITTEST: if (pLCD) { POINT pt = {GET_X_LPARAM(lp), GET_Y_LPARAM(lp)}; MapWindowPoints(0, hwnd, &pt, 1); return (PtInRect(&pLCD->rcHitTest, pt)) ? HTCLIENT : HTNOWHERE ; } break; case WM_SETCURSOR: if ((HWND)wp == hwnd && LOWORD(lp) == HTCLIENT) { HCURSOR hCur = LoadCursor(NULL, IDC_HAND); if (hCur) { SetCursor(hCur); return 1; // halt further processing } } break;#endif /* NSISLNKCTRL_CURSORHAND */#ifdef NSISLNKCTRL_DEFBTN case WM_GETDLGCODE: return DLGC_BUTTON | ((pLCD->IsDefBtn) ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON); case BM_SETSTYLE: pLCD->IsDefBtn= ((wp & BS_TYPEMASK) == BS_DEFPUSHBUTTON); //remember DEFBTN state wp = (wp & ~BS_TYPEMASK) | BS_OWNERDRAW; //turn owner-draw back on lp &= ~(TRUE); //No redraw! break;#endif /* NSISLNKCTRL_DEFBTN */ case WM_NCDESTROY: { const WNDPROC OrgWndProc=pLCD->OrgWndProc; LnkCtrl_MemFree(pLCD); LnkCtrl_FreeDataPtr(hwnd); return CallWindowProc(OrgWndProc,hwnd,uMsg,wp,lp); } } return CallWindowProc(pLCD->OrgWndProc,hwnd,uMsg,wp,lp);} DWORD NSISLNKCTRL_FINLINE LnkCtrl_SubclassInit(HWND hLnk) { LNKCTRLDATA* pLCD=(LNKCTRLDATA*)LnkCtrl_MemAlloc(sizeof(LNKCTRLDATA)); if (!pLCD) return ERROR_OUTOFMEMORY; pLCD->OrgWndProc=(WNDPROC)SetWindowLongPtr(hLnk,GWLP_WNDPROC,(LONG_PTR)LnkCtrl_SubProc); if (pLCD->OrgWndProc) { LnkCtrl_SetData(hLnk,pLCD); return NO_ERROR; } return GetLastError();}#endif /* NSISLNKCTRL_SUBCLASS */LRESULT NSISLNKCTRL_FINLINE LnkCtrl_HandleDraw(DRAWITEMSTRUCT*pDIS,const BOOL RTL) { const baseDrawFlags= DT_VCENTER | DT_WORDBREAK; const BOOL hideFocus = !!(pDIS->itemState & ODS_NOFOCUSRECT); const BOOL hideAccel = !!(pDIS->itemState & ODS_NOACCEL);// BOOL hasFocusRect = LnkCtrl_GetFocusState(pDIS->hwndItem); RECT rc; char text[1024];#ifdef NSISLNKCTRL_UNDERLINED HFONT OldFont; LOGFONT lf;#endif#ifdef NSISLNKCTRL_SUBCLASS LNKCTRLDATA* pLCD=LnkCtrl_GetData(pDIS->hwndItem); if ( !pLCD ) { if ( NO_ERROR==LnkCtrl_SubclassInit(pDIS->hwndItem) ) { //First time HandleDraw was called, force redraw InvalidateRect(pDIS->hwndItem,0,TRUE); } }#endif /* NSISLNKCTRL_SUBCLASS */#if 0 {BOOL ActionFocus=(pDIS->itemAction & ODA_FOCUS); BOOL StateFocus=(pDIS->itemState & ODS_FOCUS) ; BOOL DrawEntire=(pDIS->itemAction & ODA_DRAWENTIRE); LnkCtrl_DBGTRACE("ActionFcs=%d StateFcs=%d DrawEntire=%d hadFocus=%d HWND=%X:\n",ActionFocus,StateFocus,DrawEntire,hasFocusRect,pDIS->hwndItem);}#endif#ifdef NSISLNKCTRL_UNDERLINED GetObject(GetCurrentObject(pDIS->hDC, OBJ_FONT), sizeof(lf), &lf); lf.lfUnderline = TRUE; OldFont = (HFONT)SelectObject(pDIS->hDC, CreateFontIndirect(&lf));#endif rc = pDIS->rcItem; // Get button's text text[0] = '\0'; GetWindowText(pDIS->hwndItem, text, 1024); // Calculate needed size of the control DrawText(pDIS->hDC, text, -1, &rc, baseDrawFlags | DT_CALCRECT); // Make some more room so the focus rect won't cut letters off rc.right = min(rc.right + 2, pDIS->rcItem.right);#ifdef NSISLNKCTRL_UNDERLINED //Make more room rc.bottom= min(rc.bottom + 1, pDIS->rcItem.bottom);#endif // Move rect to right if in RTL mode if (RTL) { rc.left += pDIS->rcItem.right - rc.right; rc.right += pDIS->rcItem.right - rc.right; } //Remove old focus rect?/* if ( ( (pDIS->itemAction & ODA_DRAWENTIRE) || !(pDIS->itemState & ODS_FOCUS) ) && hasFocusRect ) { DrawFocusRect(pDIS->hDC, &rc); hasFocusRect=FALSE; LnkCtrl_SetFocusState(pDIS->hwndItem,(FALSE)); LnkCtrl_DBGTRACE("killing focus rect\n"); }*/ if ( (pDIS->itemAction & ODA_DRAWENTIRE) ) { COLORREF oldTxtClr=(COLORREF)-1; DWORD xtraDrawStyle = (RTL ? DT_RTLREADING : 0); if (hideAccel) xtraDrawStyle |= DT_HIDEPREFIX; LnkCtrl_EraseBkgnd(pDIS->hwndItem,pDIS->hDC,&rc); if (!GetWindowLong(pDIS->hwndItem, GWL_USERDATA)) oldTxtClr=SetTextColor(pDIS->hDC, RGB(0,0,255)); // Draw the text /*Should we call? */SetBkMode(pDIS->hDC,TRANSPARENT); DrawText(pDIS->hDC, text, -1, &rc, baseDrawFlags | xtraDrawStyle | DT_CENTER ); LnkCtrl_DBGTRACE("ODA_DRAWENTIRE\n"); //BUGFIX: Must restore so we don't corrupt the focus rect if (oldTxtClr!=-1) SetTextColor(pDIS->hDC,oldTxtClr); } if ( ((pDIS->itemState & ODS_FOCUS)&&(pDIS->itemAction & ODA_DRAWENTIRE)) || (pDIS->itemAction & ODA_FOCUS) ) // if ((pDIS->itemState & ODS_FOCUS) && !hasFocusRect) { if (!hideFocus) { DrawFocusRect(pDIS->hDC, &rc);// LnkCtrl_SetFocusState(pDIS->hwndItem,TRUE); LnkCtrl_DBGTRACE("DrawFocusRect\n"); } }#ifdef NSISLNKCTRL_UNDERLINED DeleteObject(SelectObject(pDIS->hDC, OldFont));#endif#ifdef NSISLNKCTRL_CURSORHAND //update hit-test rect if(pLCD)pLCD->rcHitTest=rc;#endif return TRUE;}