Beispiel #1
0
void MakeButtonSkinned(HWND hWnd)
{
	SendMessage(hWnd, BUTTONSETCUSTOMPAINT, sizeof(TBBUTTONDATA), (LPARAM)PaintWorker);
	mir_subclassWindow(hWnd, ToolbarButtonProc);

	TBBUTTONDATA* p = (TBBUTTONDATA*)GetWindowLongPtr(hWnd, 0);
	p->nFontID = -1;
	p->hThemeButton = xpt_AddThemeHandle(p->hwnd, L"BUTTON");
	p->hThemeToolbar = xpt_AddThemeHandle(p->hwnd, L"TOOLBAR");
	WindowList_Add(hButtonWindowList, hWnd, NULL);
}
Beispiel #2
0
void CustomizeToolbar(HWND hwnd)
{
	mir_subclassWindow(hwnd, toolbarWndProc);
	SendMessage(hwnd, TTB_SETCUSTOMDATASIZE, 0, sizeof(ModernToolbarCtrl));

	ModernToolbarCtrl* pMTBInfo = (ModernToolbarCtrl*)GetWindowLongPtr(hwnd, 0);

	CLISTFrame Frame = { sizeof(Frame) };
	Frame.tname = _T("Toolbar");
	Frame.hWnd = hwnd;
	Frame.align = alTop;
	Frame.Flags = F_VISIBLE | F_NOBORDER | F_LOCKED | F_TCHAR | F_NO_SUBCONTAINER;
	Frame.height = 18;
	Frame.hIcon = LoadSkinnedIcon(SKINICON_OTHER_FRAME);
	pMTBInfo->hFrame = (HANDLE)CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&Frame, 0);

	CallService(MS_SKINENG_REGISTERPAINTSUB, (WPARAM)hwnd, (LPARAM)ToolBar_LayeredPaintProc);

	pMTBInfo->mtbXPTheme = xpt_AddThemeHandle(hwnd, L"TOOLBAR");
	pMTBInfo->bHardUpdate = TRUE;

	Modern_InitButtons();
}
static LRESULT CALLBACK ToolBar_WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	static BOOL supressRepos=FALSE;
	MTBINFO * pMTBInfo=(MTBINFO *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
	switch (msg) 
	{	
	case WM_CREATE:
		{
			HANDLE hFrame=NULL;
			CLISTFrame Frame={0};
			CREATESTRUCT * lpcs = (CREATESTRUCT *) lParam;
			//create internal info
			MTBINFO * pMTBInfo = (MTBINFO *) mir_calloc( sizeof(MTBINFO) );
			pMTBInfo->cbSize = sizeof(MTBINFO);
			SetWindowLongPtr( hwnd, GWLP_USERDATA, (LONG_PTR) pMTBInfo );

			pMTBInfo->nButtonWidth = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnWidth",  SETTINGS_BARBTNWIDTH_DEFAULT);
			pMTBInfo->nButtonHeight= ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnHeight", SETTINGS_BARBTNHEIGHT_DEFAULT);
			pMTBInfo->nButtonSpace = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnSpace",  SETTINGS_BARBTNSPACE_DEFAULT);
			pMTBInfo->fAutoSize    = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_Autosize",  SETTINGS_BARAUTOSIZE_DEFAULT);
			pMTBInfo->fSingleLine  = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_Multiline", SETTINGS_BARMULTILINE_DEFAULT)==0;

			//register self frame
			Frame.cbSize=sizeof(CLISTFrame);
			Frame.hWnd=hwnd;
			Frame.align=alTop;
			Frame.hIcon=LoadSkinnedIcon (SKINICON_OTHER_MIRANDA);
			Frame.Flags=(ModernGetSettingByte(NULL,"CLUI","ShowButtonBar",SETTINGS_SHOWBUTTONBAR_DEFAULT)?F_VISIBLE:0)|F_LOCKED|F_NOBORDER|F_NO_SUBCONTAINER;
	
			Frame.height=ModernGetSettingDword(NULL, "ModernToolBar", "option_Bar0_OldHeight", pMTBInfo->nButtonHeight);
			pMTBInfo->wLastHeight=Frame.height;
		  
			pMTBInfo->nLineCount   = 1;
			pMTBInfo->pButtonList=li.List_Create(0,1);

			Frame.name=(char*) lpcs->lpCreateParams;
			hFrame=(HANDLE)CallService(MS_CLIST_FRAMES_ADDFRAME,(WPARAM)&Frame,(LPARAM)0);
			CallService(MS_SKINENG_REGISTERPAINTSUB,(WPARAM)Frame.hWnd,(LPARAM)ToolBar_LayeredPaintProc); //$$$$$ register sub for frame		
			pMTBInfo->hFrame = hFrame;
			pMTBInfo->hWnd = hwnd;



			//add self to window list
			WindowList_Add(tbdat.hToolBarWindowList, hwnd, NULL);
			pMTBInfo->mtbXPTheme=xpt_AddThemeHandle(hwnd,L"TOOLBAR");
			ToolBar_DefaultButtonRegistration();
			//SetTimer(hwnd,123,1000,NULL);
			return 0;
		}
	case WM_TIMER:
		{
			
			//KillTimer(hwnd,123);
			//ToolBar_DefaultButtonRegistration();
			return 0;
		}
	case WM_SHOWWINDOW:
		{
			{
				int res;
				int ID;
				ID= Sync( FindFrameID, hwnd );
				if (ID)
				{
					res=CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS,ID),0);
					if (res>=0) ModernWriteSettingByte(0,"CLUI","ShowButtonBar",(BYTE)(wParam/*(res&F_VISIBLE)*/?1:0));
					if (wParam) SendMessage(hwnd, MTBM_REPOSBUTTONS, 0, 0);
				}
			}
			break;
		}
	case MTBM_UPDATEFRAMEVISIBILITY:
		{
			BOOL vis=(BOOL)wParam;
			INT_PTR frameopt; 
			BOOL curvis=IsWindowVisible(hwnd);
			BOOL bResize=FALSE;
			int frameID=Sync( FindFrameID, hwnd );
			int Height;
		
			pMTBInfo->nButtonWidth = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnWidth",  SETTINGS_BARBTNWIDTH_DEFAULT);
			pMTBInfo->nButtonHeight= ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnHeight", SETTINGS_BARBTNHEIGHT_DEFAULT);
			pMTBInfo->nButtonSpace = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnSpace",  SETTINGS_BARBTNSPACE_DEFAULT);
			pMTBInfo->fAutoSize    = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_Autosize",  SETTINGS_BARAUTOSIZE_DEFAULT);
			pMTBInfo->fSingleLine  = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_Multiline", SETTINGS_BARMULTILINE_DEFAULT)==0;

			Height=sttReposButtons( pMTBInfo );

			if (pMTBInfo->fAutoSize)
			{
				frameopt=CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT,frameID),0);			
				if (Height!=frameopt)
				{
					frameopt=Height;
					CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_HEIGHT,frameID),frameopt);
					bResize=TRUE;
				}
			}		

			if ((curvis!=vis || bResize) && vis !=-1)
			{				
				frameopt=CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS,frameID),0);
				frameopt&=~F_VISIBLE;
				frameopt|=vis ? F_VISIBLE : 0;
				CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_FLAGS,frameID),frameopt);
			}
			break;
		}
	case WM_DESTROY:
		{
			xpt_FreeThemeForWindow(hwnd);
			WindowList_Remove( tbdat.hToolBarWindowList, hwnd );
			SendMessage(hwnd, MTBM_REMOVE_ALL_BUTTONS, 0, 0 );
			li.List_Destroy( pMTBInfo->pButtonList );
			mir_free( pMTBInfo->pButtonList );
			SetWindowLongPtr( hwnd, GWLP_USERDATA, 0 );
			mir_free( pMTBInfo );
			return 0;
		}
	case WM_COMMAND:
		{
			if (HIWORD(wParam)==BN_CLICKED && lParam!=0 )
				  sttButtonPressed(pMTBInfo, (HWND) lParam );
			return TRUE;
		}
	case MTBM_ADDBUTTON:
		{
			//Adding button
			MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO * )wParam;
			HWND hwndButton = NULL;
			if (!(mtbi->bSeparator))
				hwndButton= CreateWindow(SKINBUTTONCLASS /*MIRANDABUTTONCLASS*/, _T(""), BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP , 0, 0, pMTBInfo->nButtonWidth, pMTBInfo->nButtonHeight, 
											hwnd, (HMENU) NULL, g_hInst, NULL);
			mtbi->hWindow=hwndButton;
			mtbi->hwndToolBar=hwnd;

			li.List_Insert(pMTBInfo->pButtonList, mtbi, pMTBInfo->pButtonList->realCount);  //just insert pointer. such object are managed in global tbbutton list
			if (hwndButton) 
			{	
				char * buttonId=(char *)_malloca(sizeof("ToolBar.")+strlen(mtbi->szButtonID)+2);
				strcpy(buttonId,"ToolBar.");
				strcat(buttonId,mtbi->szButtonID);					
				SendMessage(hwndButton, BUTTONSETID, 0 ,(LPARAM) buttonId );
				if (pMTBInfo->bFlatButtons)			
					SendMessage(hwndButton, BUTTONSETASFLATBTN, 0, 1 );
				SetWindowLongPtr(hwndButton,GWLP_USERDATA,(LONG_PTR)mtbi);
				SendMessage(hwndButton, MBM_UPDATETRANSPARENTFLAG, 0, 2);
			}
			return (LRESULT)hwndButton;			
		}

	case MTBM_REMOVE_ALL_BUTTONS:
		{
			int i;
			for (i=0; i<pMTBInfo->pButtonList->realCount; i++ )
			{
				MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO *)pMTBInfo->pButtonList->items[i];
				if (mtbi->hWindow && mtbi->hwndToolBar==hwnd)
				{
					DestroyWindow(mtbi->hWindow);
					mtbi->hWindow = NULL;
					mtbi->hwndToolBar = NULL;
				}
			}
			li.List_Destroy( pMTBInfo->pButtonList );
			mir_free( pMTBInfo->pButtonList );
			pMTBInfo->pButtonList=li.List_Create(0,1);
			break;
		}
	case WM_SIZE: 
		if (pMTBInfo->wLastHeight!=HIWORD(lParam))
		{
			ModernWriteSettingDword(NULL, "ModernToolBar", "option_Bar0_OldHeight", HIWORD(lParam));
			pMTBInfo->wLastHeight=HIWORD(lParam);
		}
		if (supressRepos)
		{
			supressRepos=FALSE;
			break;
		}
		//fall through
	case MTBM_REPOSBUTTONS:
		{
			if (pMTBInfo && pMTBInfo->hWnd == hwnd)
			{
				int Height=sttReposButtons(pMTBInfo);			
				if ( pMTBInfo->fAutoSize) 
				{
					RECT rcClient;
					GetClientRect(pMTBInfo->hWnd, &rcClient);
					if (rcClient.bottom-rcClient.top != Height && Height)
					{
						supressRepos=TRUE;
						PostMessage(pMTBInfo->hWnd,MTBM_UPDATEFRAMEVISIBILITY, -1, 0);
					}
				}

				return 0;
			}			
			break;
		}
	case WM_ERASEBKGND:
		if (g_CluiData.fDisableSkinEngine)
			return sttDrawToolBarBackground(hwnd, (HDC)wParam, NULL, pMTBInfo);
		else
			return 0;
	
	case WM_NCPAINT:				
	case WM_PAINT:
		{
			BOOL ret=FALSE;
			PAINTSTRUCT ps;
			BOOL bFloat = (GetParent(hwnd)!=pcli->hwndContactList);
			if (g_CluiData.fDisableSkinEngine|| !g_CluiData.fLayered || bFloat )
			{
				BeginPaint(hwnd,&ps);
				if ((!g_CluiData.fLayered || bFloat) && !g_CluiData.fDisableSkinEngine)
				{
					sttDrawNonLayeredSkinedBar(hwnd, ps.hdc);
				}
				else
					ret=sttDrawToolBarBackground(hwnd, ps.hdc, &ps.rcPaint, pMTBInfo);	
				EndPaint(hwnd,&ps);
			}
			
			return DefWindowProc(hwnd, msg, wParam, lParam);
		}
	case WM_NOTIFY:
		{
			if (((LPNMHDR) lParam)->code==BUTTONNEEDREDRAW) 
				pcli->pfnInvalidateRect(hwnd, NULL, FALSE);
			return 0;
		}
	case MTBM_LAYEREDPAINT:
		{
			int i;
			RECT MyRect={0};
			HDC hDC=(HDC)wParam;
			GetWindowRect(hwnd,&MyRect);
			{
				RECT rcClient;
				GetClientRect(hwnd, &rcClient);
				SkinDrawGlyph(hDC,&rcClient,&rcClient,"Bar,ID=ToolBar,Part=Background");
			}
			for (i=0; i<pMTBInfo->pButtonList->realCount; i++)
			{
				RECT childRect;
				POINT Offset;
				MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO *)pMTBInfo->pButtonList->items[i];
				GetWindowRect(mtbi->hWindow,&childRect);
				Offset.x=childRect.left-MyRect.left;;
				Offset.y=childRect.top-MyRect.top;
				SendMessage(mtbi->hWindow, BUTTONDRAWINPARENT, (WPARAM)hDC,(LPARAM)&Offset);
			}	
			return 0;
		}
	case MTBM_SETBUTTONSTATEBYID:
	case MTBM_SETBUTTONSTATE:
		{	
			char * hButtonId=(msg==MTBM_SETBUTTONSTATEBYID) ? (char *) wParam : NULL;
			void * hButton=(msg==MTBM_SETBUTTONSTATE) ? (void *)wParam : NULL;
			MTB_BUTTONINFO *mtbi=NULL;
			int i;
			for (i=0; i<pMTBInfo->pButtonList->realCount; i++)
			{
				mtbi=(MTB_BUTTONINFO*)pMTBInfo->pButtonList->items[i];
				if ((hButtonId && !strcmp(mtbi->szButtonID, hButtonId)) || (hButton == mtbi))
				{
					mtbi->bPushButton=(BOOL)lParam;
					sttUpdateButtonState(mtbi);
					pcli->pfnInvalidateRect(hwnd, NULL, FALSE);
					break;
				}
			}
			break;
		}
	case MTBM_GETBUTTONSTATEBYID:
	case MTBM_GETBUTTONSTATE:
		{		
			int * res= (int*)lParam;
			if (res==NULL) break;
			char * hButtonId=(msg==MTBM_GETBUTTONSTATEBYID) ? (char *) wParam : NULL;
			void * hButton=(msg==MTBM_GETBUTTONSTATE) ? (void *)wParam : NULL;
			MTB_BUTTONINFO *mtbi=NULL;
			int i;
			for (i=0; i<pMTBInfo->pButtonList->realCount; i++)
			{
				mtbi=(MTB_BUTTONINFO*)pMTBInfo->pButtonList->items[i];
				if ((hButtonId && !strcmp(mtbi->szButtonID, hButtonId)) || (hButton == mtbi))
				{
					*res=0;
					*res |= mtbi->bPushButton ? TBST_PUSHED : TBST_RELEASED;
					break;
				}
			}	
			break;
		}

	case MTBM_REMOVEBUTTON:
		{
			MTB_BUTTONINFO *mtbi=NULL;
			for (int i=0; i<pMTBInfo->pButtonList->realCount; i++)
			{
				mtbi=(MTB_BUTTONINFO*)pMTBInfo->pButtonList->items[i];
				if (mtbi==(MTB_BUTTONINFO*)wParam)
				{
					li.List_Remove(pMTBInfo->pButtonList,i);
					for (int j=0; j<tbdat.listOfButtons->realCount; j++)
						if (mtbi==(MTB_BUTTONINFO*)tbdat.listOfButtons->items[j])
						{
							li.List_Remove(tbdat.listOfButtons,j);
							break;
						}
					li.List_RemovePtr(tbdat.listOfButtons,mtbi);
					delete_MTB_BUTTONINFO((void*)mtbi);
					mtbi=NULL;
					pcli->pfnInvalidateRect(hwnd, NULL, FALSE);
					break;	
				}
			}
			break;
		}
	default :
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}		
	return TRUE;
}
static LRESULT CALLBACK TollbarButtonProc(HWND hwndDlg, UINT  msg, WPARAM wParam, LPARAM lParam)
{
	TBBUTTONDATA *lpSBData = (TBBUTTONDATA *) GetWindowLongPtr(hwndDlg, 0);
	switch (msg) 
	{
	case WM_NCCREATE:
		{
			SetWindowLong(hwndDlg, GWL_STYLE, GetWindowLong(hwndDlg, GWL_STYLE) | BS_OWNERDRAW);
			lpSBData = (TBBUTTONDATA *)malloc(sizeof(TBBUTTONDATA));
			if (lpSBData == NULL)
				return FALSE;
			memset(lpSBData,0,sizeof(TBBUTTONDATA)); //I prefer memset to guarantee zeros
			lpSBData->hWnd = hwndDlg;
			lpSBData->nStateId = PBS_NORMAL;
			lpSBData->fFocused = FALSE;
			lpSBData->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
			lpSBData->hIconPrivate = NULL;
			lpSBData->cHot = '\0';
			lpSBData->szText[0] = '\0';
			lpSBData->szButtonID[0] = '?';
			lpSBData->szButtonID[1] = '\0';
			lpSBData->pushBtn = FALSE;
			lpSBData->pbState = 0;
			lpSBData->fSendOnDown = FALSE;
			lpSBData->fHotMark = FALSE;
			lpSBData->nFontID = -1;
			SetWindowLongPtr(hwndDlg, 0, (LONG_PTR) lpSBData);
			if (((CREATESTRUCTA *) lParam)->lpszName)
				SetWindowText(hwndDlg, ((CREATESTRUCT *) lParam)->lpszName);
			lpSBData->hThemeButton = xpt_AddThemeHandle(lpSBData->hWnd, L"BUTTON");
			lpSBData->hThemeToolbar = xpt_AddThemeHandle(lpSBData->hWnd, L"TOOLBAR");
			WindowList_Add(hButtonWindowList, hwndDlg, NULL);				
			return TRUE;
		}
	case WM_DESTROY:
		{
			/* #ifdef _DEBUG
			if (GetWindowLong(hwndButton, GWL_USERDATA))
			DebugBreak();
			#endif */

			xpt_FreeThemeForWindow(hwndDlg);
			WindowList_Remove(hButtonWindowList, hwndDlg);
			if (lpSBData) 
			{
				if (hwndToolTips) 
				{
					TOOLINFO ti;

					ZeroMemory(&ti, sizeof(ti));
					ti.cbSize = sizeof(ti);
					ti.uFlags = TTF_IDISHWND;
					ti.hwnd = lpSBData->hWnd;
					ti.uId = (UINT_PTR) lpSBData->hWnd;
					if (SendMessage(hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM) &ti)) 
					{
						SendMessage(hwndToolTips, TTM_DELTOOL, 0, (LPARAM) &ti);
					}
					if (SendMessage(hwndToolTips, TTM_GETTOOLCOUNT, 0, (LPARAM) &ti) == 0) 
					{
						DestroyWindow(hwndToolTips);
						hwndToolTips = NULL;
					}
				}
				if (lpSBData->hIconPrivate)
					DestroyIcon(lpSBData->hIconPrivate);
				free(lpSBData);  // lpSBData was malloced by native malloc
			}
			SetWindowLong(hwndDlg, 0, (LONG) NULL);
			break;  // DONT! fall thru
		}
	case WM_SETTEXT:
		{
			lpSBData->cHot = 0;
			if ((TCHAR*) lParam) 
			{
				TCHAR *tmp = (TCHAR *) lParam;
				while (*tmp) 
				{
					if (*tmp == '&' && *(tmp + 1)) 
					{
						lpSBData->cHot = (char)tolower(*(tmp + 1));
						break;
					}
					tmp++;
				}
				InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
				lstrcpyn(lpSBData->szText, (TCHAR *)lParam, SIZEOF(lpSBData->szText)-1);
				lpSBData->szText[SIZEOF(lpSBData->szText)-1] = '\0';
			}
			break;
		}
	case WM_SYSKEYUP:
		if (lpSBData->nStateId != PBS_DISABLED && lpSBData->cHot && lpSBData->cHot == tolower((int) wParam)) 
		{
			if (lpSBData->pushBtn) 
			{
				if (lpSBData->pbState)
					lpSBData->pbState = 0;
				else
					lpSBData->pbState = 1;
				InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
			}
			if(!lpSBData->fSendOnDown)
				SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg);
			return 0;
		}
		break;

	case WM_SETFONT:			
		{	
			// remember the font so we can use it later
			lpSBData->hFont = (HFONT) wParam; // maybe we should redraw?
			lpSBData->nFontID = (int) lParam - 1;
			break;
		}
	case BUTTONSETSENDONDOWN:
		{
			lpSBData->fSendOnDown = (BOOL) lParam;
			break;
		}
	case BUTTONSETMARGINS:
		{
			if (lParam)	lpSBData->rcMargins=*(RECT*)lParam;
			else 
			{
				RECT nillRect={0};
				lpSBData->rcMargins=nillRect;
			}
			return 0;
		}
	case BUTTONSETID:
		{
			lstrcpynA(lpSBData->szButtonID, (char *)lParam, SIZEOF(lpSBData->szButtonID)-1);
			lpSBData->szButtonID[SIZEOF(lpSBData->szButtonID)-1] = '\0';
			return 0;
		}
	case BUTTONDRAWINPARENT:
		{
			if (IsWindowVisible(hwndDlg))
				PaintWorker(lpSBData, (HDC) wParam, (POINT*) lParam);
			return 0;
		}
	case WM_NCPAINT:
	case WM_PAINT:
		{

			PAINTSTRUCT ps;
			HDC hdcPaint;
			if (g_CluiData.fDisableSkinEngine)
			{
				hdcPaint = BeginPaint(hwndDlg, &ps);
				if (hdcPaint) 
				{
					PaintWorker(lpSBData, hdcPaint, NULL);
					EndPaint(hwndDlg, &ps);
				}
			}
			ValidateRect(hwndDlg,NULL);
			return 0;
		}
	case BUTTONADDTOOLTIP:
		{
			TOOLINFO ti;

			if (!(char*) wParam)
				break;
			if (!hwndToolTips) 
			{
				hwndToolTips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), WS_POPUP, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
				SetWindowPos(hwndToolTips, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
			}
			ZeroMemory(&ti, sizeof(ti));
			ti.cbSize = sizeof(ti);
			ti.uFlags = TTF_IDISHWND;
			ti.hwnd = lpSBData->hWnd;
			ti.uId = (UINT_PTR) lpSBData->hWnd;
			if (SendMessage(hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM) &ti)) {
				SendMessage(hwndToolTips, TTM_DELTOOL, 0, (LPARAM) &ti);
			}
			ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
			ti.uId = (UINT_PTR) lpSBData->hWnd;
			ti.lpszText = (TCHAR *) wParam;
			SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) &ti);
			break;
		}
	case BUTTONSETASPUSHBTN:
		{

			if (lParam==0)
				lpSBData->pushBtn=1;
			else
			{
				lpSBData->pushBtn=wParam;
				lpSBData->pbState = (lParam&2) ? TRUE : FALSE;
			}
			return 0;
		}
	case WM_SETFOCUS:
		{
			// set keyboard focus and redraw
			lpSBData->fFocused = TRUE;
			InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
			break;
		}
	case WM_KILLFOCUS:
		{
			// kill focus and redraw
			lpSBData->fFocused = FALSE;
			InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
			break;
		}
	case WM_WINDOWPOSCHANGED:
		InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
		break;
	case WM_ENABLE:
		// windows tells us to enable/disable
		{
			lpSBData->nStateId = wParam ? PBS_NORMAL : PBS_DISABLED;
			InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
			break;
		}
	/*case WM_MOUSELEAVE:			
		{
			// faked by the WM_TIMER
			if (lpSBData->nStateId != PBS_DISABLED) 
			{
				// don't change states if disabled
				lpSBData->nStateId = PBS_NORMAL;
				InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
			}
			break;
		}
		*/
	case WM_CAPTURECHANGED:
		{                
			if ( (HWND)lParam != lpSBData->hWnd && lpSBData->nStateId != PBS_DISABLED) 
			{
				// don't change states if disabled
				lpSBData->nStateId = PBS_NORMAL;
				InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
			}
			break;
		}
	case WM_LBUTTONDOWN:
		{
			int xPos=( ( int )( short ) LOWORD( lParam ) );
			int yPos=( ( int )( short ) HIWORD( lParam ) );
			POINT ptMouse = { xPos, yPos };

			RECT rcClient;
			GetClientRect( lpSBData->hWnd, &rcClient );

			if ( !PtInRect( &rcClient, ptMouse ) )
			{
				lpSBData->fHotMark = FALSE;
				ReleaseCapture();
				break;
			}

			if (lpSBData->nStateId != PBS_DISABLED && lpSBData->nStateId != PBS_PRESSED) 
			{
				lpSBData->nStateId = PBS_PRESSED;
				lpSBData->fHotMark = TRUE;
				InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
				if(lpSBData->fSendOnDown) 
				{
					SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg);
					lpSBData->nStateId = PBS_NORMAL;
					InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
				}
			}
			SetCapture( lpSBData->hWnd );
			break;
		}
	case WM_LBUTTONUP:
		if ( GetCapture() == lpSBData->hWnd )
		{

			int xPos=( ( int )( short ) LOWORD( lParam ) );
			int yPos=( ( int )( short ) HIWORD( lParam ) );
			POINT ptMouse = { xPos, yPos };

			RECT rcClient;
			GetClientRect( lpSBData->hWnd, &rcClient );
			
			if ( !PtInRect( &rcClient, ptMouse ) )
			{
				lpSBData->fHotMark = FALSE;
				ReleaseCapture();
				break;
			}

			if (lpSBData->pushBtn) 
			{
				if (lpSBData->pbState)
					lpSBData->pbState = FALSE;
				else
					lpSBData->pbState = TRUE;
			}

			if (lpSBData->nStateId != PBS_DISABLED)
			{
				// don't change states if disabled
				if (msg == WM_LBUTTONUP)
					lpSBData->nStateId = PBS_HOT;
				else
					lpSBData->nStateId = PBS_NORMAL;
				InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
			}
			if(!lpSBData->fSendOnDown && lpSBData->fHotMark)
				SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg);
			lpSBData->fHotMark = FALSE;
			break;
		}
	case WM_MOUSEMOVE:
		{
			RECT rc;
			POINT pt;
			BOOL bPressed = (wParam & MK_LBUTTON) != 0;
			if ( bPressed && !lpSBData->fHotMark )
				break;
			GetWindowRect(hwndDlg, &rc);
			GetCursorPos(&pt);
			BOOL inClient = PtInRect(&rc, pt);
			if ( inClient )
			{
				SetCapture( lpSBData->hWnd );
				if ( lpSBData->nStateId == PBS_NORMAL ) 
				{
					lpSBData->nStateId = PBS_HOT;
					InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
				}
			}

			if ( !inClient && lpSBData->nStateId == PBS_PRESSED )
			{
				lpSBData->nStateId = PBS_HOT; 
				InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
			}
			else if ( inClient && lpSBData->nStateId == PBS_HOT && bPressed )
			{
				if( lpSBData->fHotMark )
				{
					lpSBData->nStateId = PBS_PRESSED;
					InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
				}
			}
			else if ( !inClient && !bPressed)
			{
				lpSBData->fHotMark = FALSE;
				ReleaseCapture();
			}
		}
	//	else
		{
			//KillTimer(hwndDlg, BUTTON_POLLID);
			//CLUI_SafeSetTimer(hwndDlg, BUTTON_POLLID, BUTTON_POLLDELAY, NULL);
		}
		// Call timer, used to start cheesy TrackMouseEvent faker
		

		break;

	case WM_NCHITTEST:
		{
			LRESULT lr = SendMessage(GetParent(hwndDlg), WM_NCHITTEST, wParam, lParam);
			if(lr == HTLEFT || lr == HTRIGHT || lr == HTBOTTOM || lr == HTTOP || lr == HTTOPLEFT || lr == HTTOPRIGHT
				|| lr == HTBOTTOMLEFT || lr == HTBOTTOMRIGHT)
				return HTTRANSPARENT;
			break;
		}
	/*case WM_TIMER: // use a timer to check if they have did a mouse out		
		{
			if (wParam == BUTTON_POLLID)
			{
				HWND hwnd=GetCapture();
				if ( hwnd == lpSBData->hWnd ) 
				{
					//KillTimer(hwndDlg, BUTTON_POLLID);
					break;
				}
				RECT rc;
				POINT pt;
				GetWindowRect(hwndDlg, &rc);
				GetCursorPos(&pt);
				BOOL bInside = ( PtInRect( &rc, pt ) && ( WindowFromPoint( pt ) == lpSBData->hWnd) );
				if ( !bInside ) 
				{
					// mouse must be gone, trigger mouse leave
					PostMessage(hwndDlg, WM_MOUSELEAVE, 0, 0L);
					KillTimer(hwndDlg, BUTTON_POLLID);
				}
			}
			break;
		}
		*/
	case WM_ERASEBKGND:
		{
			return 1;
		}
	case MBM_SETICOLIBHANDLE:
		{
			if (lpSBData->hIconPrivate) 
			{
				DestroyIcon(lpSBData->hIconPrivate);
				lpSBData->hIconPrivate = 0;
			}

			lpSBData->hIcolibHandle=(HANDLE)lParam;
			if (lpSBData->hIcolibHandle)
				lpSBData->hIcon=(HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0 , (LPARAM) lpSBData->hIcolibHandle);
			else
				lpSBData->hIcon=NULL;
			return 1;
		}
	case MBM_REFRESHICOLIBICON:
		{
			if (lpSBData->hIconPrivate) 
			{
				DestroyIcon(lpSBData->hIconPrivate);
				lpSBData->hIconPrivate = 0;
			}
			if (lpSBData->hIcolibHandle)
				lpSBData->hIcon=(HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0 , (LPARAM) lpSBData->hIcolibHandle);
			else		
				lpSBData->hIcon=NULL;
			InvalidateRect(hwndDlg,NULL,TRUE);
			pcli->pfnInvalidateRect(GetParent(GetParent(hwndDlg)),NULL,TRUE);
			return 1;
		}
	case MBM_UPDATETRANSPARENTFLAG:
		{
			LONG flag=GetWindowLong(hwndDlg,GWL_EXSTYLE);
			LONG oldFlag=flag;
			if (lParam==2) 
				lParam=(g_CluiData.fDisableSkinEngine)?0:1;
			flag&=~WS_EX_TRANSPARENT;
			if (lParam) flag|=WS_EX_TRANSPARENT;
			if (flag!=oldFlag)
			{
				SetWindowLong(hwndDlg,GWL_EXSTYLE,flag);
				RedrawWindow(hwndDlg,NULL,NULL,RDW_INVALIDATE|RDW_UPDATENOW);
			}
			return 0;
		}
	case BM_GETIMAGE:
		{
			if(wParam == IMAGE_ICON)
				return (LRESULT)(lpSBData->hIconPrivate ? lpSBData->hIconPrivate : lpSBData->hIcon);
			break;
		}
	case BM_SETIMAGE:
		{
			if(!lParam)
				break;
			if (wParam == IMAGE_ICON) 
			{
				ICONINFO ii = {0};
				BITMAP bm = {0};

				if (lpSBData->hIconPrivate) 
				{
					DestroyIcon(lpSBData->hIconPrivate);
					lpSBData->hIconPrivate = 0;
				}

				GetIconInfo((HICON) lParam, &ii);
				GetObject(ii.hbmColor, sizeof(bm), &bm);
				if (bm.bmWidth > 16 || bm.bmHeight > 16) 
				{
					HIMAGELIST hImageList;
					hImageList = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR16 | ILC_MASK, 1, 0);
					ImageList_AddIcon(hImageList, (HICON) lParam);
					lpSBData->hIconPrivate = ImageList_GetIcon(hImageList, 0, ILD_NORMAL);
					ImageList_RemoveAll(hImageList);
					ImageList_Destroy(hImageList);
					lpSBData->hIcon = 0;
				} 
				else 
				{
					lpSBData->hIcon = (HICON) lParam;
					lpSBData->hIconPrivate = NULL;
				}

				DeleteObject(ii.hbmMask);
				DeleteObject(ii.hbmColor);
				InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
			}
			else if (wParam == IMAGE_BITMAP) 
			{
				if (lpSBData->hIconPrivate)
					DestroyIcon(lpSBData->hIconPrivate);
				lpSBData->hIcon = lpSBData->hIconPrivate = NULL;
				InvalidateParentRect(lpSBData->hWnd, NULL, TRUE);
				return 0; // not supported
			}
			break;
		}
	}
	return DefWindowProc(hwndDlg, msg, wParam, lParam);
}