All pastes #905003 Raw Edit

NSIS Link common code

public cpp v1 · immutable
·published 2008-02-15 14:07 UTC
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;}