Exemple #1
0
static void LoadTheme(MButtonCtrl *ctl)
{
	if (openThemeData) {
		DestroyTheme(ctl);
		ctl->hThemeButton = openThemeData(ctl->hwnd, L"BUTTON");
		ctl->hThemeToolbar = openThemeData(ctl->hwnd, L"TOOLBAR");
	}
}
Exemple #2
0
static void LoadTheme(MButtonCtrl *ctl)
{
	DestroyTheme(ctl);
	if(IS_THEMED) {
		ctl->hThemeButton = Api::pfnOpenThemeData(ctl->hwnd, L"BUTTON");
		ctl->hThemeToolbar = Api::pfnOpenThemeData(ctl->hwnd, L"TOOLBAR");
		ctl->bThemed = TRUE;
	}
}
Exemple #3
0
static void TSAPI LoadTheme(MButtonCtrl *ctl)
{
	if (M->isVSAPIState()) {
		DestroyTheme(ctl);
		ctl->hThemeButton = CMimAPI::m_pfnOpenThemeData(ctl->hwnd, L"BUTTON");
		ctl->hThemeToolbar = (M->isAero() || IsWinVerVistaPlus()) ? CMimAPI::m_pfnOpenThemeData(ctl->hwnd, L"MENU") : CMimAPI::m_pfnOpenThemeData(ctl->hwnd, L"TOOLBAR");
		ctl->bThemed = TRUE;
	}
}
static void LoadTheme(MButtonCtrl *ctl)
{
    if (ThemeSupport()) {
        DestroyTheme(ctl);
        ctl->hThemeButton = MyOpenThemeData(ctl->hwnd, L"BUTTON");
        ctl->hThemeToolbar = MyOpenThemeData(ctl->hwnd, L"TOOLBAR");
        ctl->bThemed = TRUE;
    }
}
Exemple #5
0
/**
 * name:	LoadTheme
 * desc:	load theme data for buttons if supported by os
 * param:	ctl - BTNCTRL structure with the information about the theme to load
 * return:	nothing
 **/
static void __fastcall LoadTheme(BTNCTRL *ctl)
{
    DestroyTheme(ctl);
    ctl->hThemeButton = OpenThemeData(ctl->hwnd, L"BUTTON");
    ctl->hThemeToolbar = OpenThemeData(ctl->hwnd, L"TOOLBAR");
}
Exemple #6
0
/**
 * name:	Button_WndProc
 * desc:	window procedure for the button class
 * param:	hwndBtn		- window handle to the button
 *			uMsg		- message to handle
 *			wParam		- message specific parameter
 *			lParam		- message specific parameter
 * return:	message specific
 **/
static LRESULT CALLBACK Button_WndProc(HWND hwndBtn, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    LPBTNCTRL bct = (LPBTNCTRL)GetWindowLongPtr(hwndBtn, 0);

    switch (uMsg) {
    case WM_NCCREATE:
    {
        LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam;

        cs->style |= BS_OWNERDRAW;
        if (!(bct = (LPBTNCTRL)mir_alloc(sizeof(BTNCTRL))))
            return FALSE;
        memset(bct, 0, sizeof(BTNCTRL));
        bct->hwnd = hwndBtn;
        bct->stateId = PBS_NORMAL;
        bct->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
        bct->dwStyle = cs->style;
        if (cs->style & MBS_DOWNARROW)
            bct->arrow = GetIconBtn(ICO_BTN_DOWNARROW);
        LoadTheme(bct);
        SetWindowLongPtr(hwndBtn, 0, (LONG_PTR)bct);
        if (cs->lpszName)
            SetWindowText(hwndBtn, cs->lpszName);
    }
    return TRUE;

    case WM_DESTROY:
        if (bct) {
            mir_cslock lck(csTips);
            if (hwndToolTips) {
                TOOLINFO ti;

                memset(&ti, 0, sizeof(ti));
                ti.cbSize = sizeof(ti);
                ti.uFlags = TTF_IDISHWND;
                ti.hwnd = bct->hwnd;
                ti.uId = (UINT_PTR)bct->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;
                }
            }
            DestroyTheme(bct);
            mir_free(bct);
        }
        SetWindowLongPtr(hwndBtn, 0, 0);
        break;

    case WM_SETTEXT:
        bct->cHot = 0;
        if ((LPTSTR)lParam) {
            LPTSTR tmp = (LPTSTR)lParam;

            while (*tmp) {
                if (*tmp == '&' && *(tmp + 1)) {
                    bct->cHot = _totlower(*(tmp + 1));
                    break;
                }
                tmp++;
            }
            InvalidateRect(bct->hwnd, NULL, TRUE);
        }
        break;

    case WM_SYSKEYUP:
        if (bct->stateId != PBS_DISABLED && bct->cHot && bct->cHot == _totlower((TCHAR)wParam)) {
            if (bct->dwStyle & MBS_PUSHBUTTON) {
                if (bct->pbState) bct->pbState = 0;
                else bct->pbState = 1;
                InvalidateRect(bct->hwnd, NULL, TRUE);
            }
            else
                SetFocus(hwndBtn);
            SendMessage(GetParent(hwndBtn), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndBtn), BN_CLICKED), (LPARAM)hwndBtn);
            return 0;
        }
        break;

    case WM_THEMECHANGED:
        // themed changed, reload theme object
        LoadTheme(bct);
        InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it
        break;

    case WM_SETFONT: // remember the font so we can use it later
        bct->hFont = (HFONT)wParam; // maybe we should redraw?
        break;

    case WM_NCPAINT:
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdcPaint;
        HDC hdcMem;
        HBITMAP hbmMem;
        HDC hOld;
        RECT rcClient;

        if (hdcPaint = BeginPaint(hwndBtn, &ps)) {
            GetClientRect(bct->hwnd, &rcClient);
            hdcMem = CreateCompatibleDC(hdcPaint);
            hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
            hOld = (HDC)SelectObject(hdcMem, hbmMem);

            // If its a push button, check to see if it should stay pressed
            if ((bct->dwStyle & MBS_PUSHBUTTON) && bct->pbState) bct->stateId = PBS_PRESSED;

            if ((bct->dwStyle & MBS_FLAT) && bct->hThemeToolbar || bct->hThemeButton)
                PaintThemeButton(bct, hdcMem, &rcClient);
            else
                PaintButton(bct, hdcMem, &rcClient);

            BitBlt(hdcPaint, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, hdcMem, 0, 0, SRCCOPY);
            SelectObject(hdcMem, hOld);
            DeleteObject(hbmMem);
            DeleteDC(hdcMem);
            EndPaint(hwndBtn, &ps);
        }
    }
    return 0;

    case BM_SETIMAGE:
        if (wParam == IMAGE_ICON) {
            bct->hIcon = (HICON)lParam;
            bct->hBitmap = NULL;
            InvalidateRect(bct->hwnd, NULL, TRUE);
        }
        else if (wParam == IMAGE_BITMAP) {
            bct->hIcon = NULL;
            bct->hBitmap = (HBITMAP)lParam;
            InvalidateRect(bct->hwnd, NULL, TRUE);
        }
        else if (wParam == NULL && lParam == NULL) {
            bct->hIcon = NULL;
            bct->hBitmap = NULL;
            InvalidateRect(bct->hwnd, NULL, TRUE);
        }
        break;

    case BM_SETCHECK:
        if (!(bct->dwStyle & MBS_PUSHBUTTON)) break;
        if (wParam == BST_CHECKED) {
            bct->pbState = 1;
            bct->stateId = PBS_PRESSED;
        }
        else if (wParam == BST_UNCHECKED) {
            bct->pbState = 0;
            bct->stateId = PBS_NORMAL;
        }
        InvalidateRect(bct->hwnd, NULL, TRUE);
        break;

    case BM_GETCHECK:
        if (bct->dwStyle & MBS_PUSHBUTTON) return bct->pbState ? BST_CHECKED : BST_UNCHECKED;
        return 0;

    case BUTTONSETDEFAULT:
        bct->defbutton = (wParam != 0);
        InvalidateRect(bct->hwnd, NULL, TRUE);
        break;

    case BUTTONADDTOOLTIP:
        if (wParam) {
            mir_cslock lck(csTips);
            if (!hwndToolTips)
                hwndToolTips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);

            if (lParam == MBBF_UNICODE) {
                TOOLINFOW ti;

                memset(&ti, 0, sizeof(TOOLINFOW));
                ti.cbSize = sizeof(TOOLINFOW);
                ti.uFlags = TTF_IDISHWND;
                ti.hwnd = bct->hwnd;
                ti.uId = (UINT_PTR)bct->hwnd;
                if (SendMessage(hwndToolTips, TTM_GETTOOLINFOW, 0, (LPARAM)&ti)) {
                    SendMessage(hwndToolTips, TTM_DELTOOLW, 0, (LPARAM)&ti);
                }
                ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
                ti.uId = (UINT_PTR)bct->hwnd;
                ti.lpszText = (LPWSTR)wParam;
                SendMessage(hwndToolTips, TTM_ADDTOOLW, 0, (LPARAM)&ti);
            }
            else {
                TOOLINFOA ti;

                memset(&ti, 0, sizeof(TOOLINFOA));
                ti.cbSize = sizeof(TOOLINFOA);
                ti.uFlags = TTF_IDISHWND;
                ti.hwnd = bct->hwnd;
                ti.uId = (UINT_PTR)bct->hwnd;
                if (SendMessage(hwndToolTips, TTM_GETTOOLINFOA, 0, (LPARAM)&ti)) {
                    SendMessage(hwndToolTips, TTM_DELTOOLA, 0, (LPARAM)&ti);
                }
                ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
                ti.uId = (UINT_PTR)bct->hwnd;
                ti.lpszText = (LPSTR)wParam;
                SendMessage(hwndToolTips, TTM_ADDTOOLA, 0, (LPARAM)&ti);
            }
        }
        break;

    case BUTTONTRANSLATE:
        TCHAR szButton[MAX_PATH];
        GetWindowText(bct->hwnd, szButton, _countof(szButton));
        SetWindowText(bct->hwnd, TranslateTS(szButton));
        break;

    case WM_SETFOCUS: // set keybord bFocus and redraw
        bct->bFocus = 1;
        InvalidateRect(bct->hwnd, NULL, TRUE);
        break;

    case WM_KILLFOCUS: // kill bFocus and redraw
        bct->bFocus = 0;
        InvalidateRect(bct->hwnd, NULL, TRUE);
        break;

    case WM_WINDOWPOSCHANGED:
        InvalidateRect(bct->hwnd, NULL, TRUE);
        break;

    case WM_ENABLE: // windows tells us to enable/disable
        bct->stateId = wParam ? PBS_NORMAL : PBS_DISABLED;
        InvalidateRect(bct->hwnd, NULL, TRUE);
        break;

    case WM_MOUSELEAVE: // faked by the WM_TIMER
        if (bct->stateId != PBS_DISABLED) { // don't change states if disabled
            bct->stateId = PBS_NORMAL;
            InvalidateRect(bct->hwnd, NULL, TRUE);
        }
        break;

    case WM_LBUTTONDOWN:
        if (bct->stateId != PBS_DISABLED) { // don't change states if disabled
            bct->stateId = PBS_PRESSED;
            InvalidateRect(bct->hwnd, NULL, TRUE);
        }
        break;

    case WM_LBUTTONUP:
        if (bct->stateId != PBS_DISABLED) { // don't change states if disabled
            BYTE bPressed = bct->stateId == PBS_PRESSED;

            if (bct->dwStyle & MBS_PUSHBUTTON) {
                if (bct->pbState) bct->pbState = 0;
                else bct->pbState = 1;
            }
            bct->stateId = PBS_HOT;

            // Tell your daddy you got clicked, if mouse is still over the button.
            if ((bct->dwStyle & MBS_PUSHBUTTON) || bPressed)
                SendMessage(GetParent(hwndBtn), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndBtn), BN_CLICKED), (LPARAM)hwndBtn);
            InvalidateRect(bct->hwnd, NULL, TRUE);
        }
        break;

    case WM_MOUSEMOVE:
        if (bct->stateId == PBS_NORMAL) {
            bct->stateId = PBS_HOT;
            InvalidateRect(bct->hwnd, NULL, TRUE);
        }
        // Call timer, used to start cheesy TrackMouseEvent faker
        SetTimer(hwndBtn, BUTTON_POLLID, BUTTON_POLLDELAY, NULL);
        break;

    case WM_TIMER: // use a timer to check if they have did a mouseout
        if (wParam == BUTTON_POLLID) {
            RECT rc;
            POINT pt;

            GetWindowRect(hwndBtn, &rc);
            GetCursorPos(&pt);
            if (!PtInRect(&rc, pt)) { // mouse must be gone, trigger mouse leave
                PostMessage(hwndBtn, WM_MOUSELEAVE, 0, 0L);
                KillTimer(hwndBtn, BUTTON_POLLID);
            }
        }
        break;
    case WM_ERASEBKGND:
        return 1;
    }
    return DefWindowProc(hwndBtn, uMsg, wParam, lParam);
}
Exemple #7
0
static LRESULT CALLBACK TSButtonWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	MButtonCtrl *bct = (MButtonCtrl *) GetWindowLongPtr(hwndDlg, 0);
	switch(msg) {
		case WM_NCCREATE: {
			SetWindowLong(hwndDlg, GWL_STYLE, GetWindowLong(hwndDlg, GWL_STYLE) | BS_OWNERDRAW);
			bct = reinterpret_cast<MButtonCtrl *>(malloc(sizeof(MButtonCtrl)));
			if(bct == NULL)
				return FALSE;
			bct->hwnd = hwndDlg;
			bct->stateId = PBS_NORMAL;
			bct->focus = 0;
			bct->hFont = reinterpret_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT));
			bct->arrow = NULL;
			bct->defbutton = 0;
			bct->hIcon = bct->hIconPrivate = 0;
			bct->iIcon = 0;
			bct->hIml = 0;
			bct->hBitmap = NULL;
			bct->pushBtn = 0;
			bct->pbState = 0;
			bct->hThemeButton = NULL;
			bct->hThemeToolbar = NULL;
			bct->cHot = 0;
			bct->flatBtn = 0;
			bct->bThemed = FALSE;
			bct->bSkinned = bct->bSendOnDown = 0;
			bct->buttonItem = NULL;
			LoadTheme(bct);
			SetWindowLongPtr(hwndDlg, 0, (LONG_PTR) bct);
			if(((CREATESTRUCTA *) lParam)->lpszName)
				SetWindowText(hwndDlg, ((CREATESTRUCT *) lParam)->lpszName);
			return TRUE;
		}

		case WM_DESTROY: {
			if(bct) {
				if(hwndToolTips) {
					TOOLINFO ti;

					ZeroMemory(&ti, sizeof(ti));
					ti.cbSize = sizeof(ti);
					ti.uFlags = TTF_IDISHWND;
					ti.hwnd = bct->hwnd;
					ti.uId = (UINT_PTR) bct->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(bct->hIconPrivate)
					DestroyIcon(bct->hIconPrivate);
				DestroyTheme(bct);
				free(bct);
			}
			SetWindowLongPtr(hwndDlg, 0, 0);
			break;  // DONT! fall thru
		}

		case WM_SETTEXT: {
			bct->cHot = 0;
			if((char*) lParam) {
				char *tmp = (char *) lParam;
				while(*tmp) {
					if(*tmp == '&' && *(tmp + 1)) {
						bct->cHot = tolower(*(tmp + 1));
						break;
					}
					tmp++;
				}
				InvalidateRect(bct->hwnd, NULL, TRUE);
				lstrcpyn(bct->szText, (wchar_t *)lParam, 127);
				bct->szText[127] = 0;
			}
			break;
		}

		case WM_SYSKEYUP:
			if(bct->stateId != PBS_DISABLED && bct->cHot && bct->cHot == tolower((int) wParam)) {
				if(bct->pushBtn) {
					if(bct->pbState)
						bct->pbState = 0;
					else
						bct->pbState = 1;
					InvalidateRect(bct->hwnd, NULL, TRUE);
				}
				if(!bct->bSendOnDown)
					SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg);
				return 0;
			}
			break;

		case WM_THEMECHANGED: {
			if(bct->bThemed)
				LoadTheme(bct);
			InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it
			break;
		}

		case WM_SETFONT: {
			bct->hFont = (HFONT) wParam; // maybe we should redraw?
			break;
		}

		case WM_PAINT: {
			PAINTSTRUCT ps;
			HDC hdcPaint;

			hdcPaint = BeginPaint(hwndDlg, &ps);
			if(hdcPaint) {
				PaintWorker(bct, hdcPaint);
				EndPaint(hwndDlg, &ps);
			}
			break;
		}

		case BM_GETIMAGE:
			if(wParam == IMAGE_ICON)
				return (LRESULT)(bct->hIconPrivate ? bct->hIconPrivate : bct->hIcon);
			break;

		case BM_SETIMAGE:
			if(!lParam)
				break;
			bct->hIml = 0;
			bct->iIcon = 0;
			if(wParam == IMAGE_ICON) {
				ICONINFO ii = {0};
				BITMAP bm = {0};

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

				GetIconInfo((HICON) lParam, &ii);
				GetObject(ii.hbmColor, sizeof(bm), &bm);
				if(bm.bmWidth > CXSMICON || bm.bmHeight > CYSMICON) {
					HIMAGELIST hImageList;
					hImageList = ImageList_Create(CXSMICON, CYSMICON, ILC_COLOR32 | ILC_MASK, 1, 0);
					ImageList_AddIcon(hImageList, (HICON) lParam);
					bct->hIconPrivate = ImageList_GetIcon(hImageList, 0, ILD_NORMAL);
					ImageList_RemoveAll(hImageList);
					ImageList_Destroy(hImageList);
					bct->hIcon = 0;
				} else {
					bct->hIcon = (HICON) lParam;
					bct->hIconPrivate = 0;
				}

				DeleteObject(ii.hbmMask);
				DeleteObject(ii.hbmColor);
				bct->hBitmap = NULL;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			} else if(wParam == IMAGE_BITMAP) {
				bct->hBitmap = (HBITMAP) lParam;
				if(bct->hIconPrivate)
					DestroyIcon(bct->hIconPrivate);
				bct->hIcon = bct->hIconPrivate = NULL;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			break;

		case BM_SETPRIVATEICON:
			bct->hIml = 0;
			bct->iIcon = 0;
			{
				if(bct->hIconPrivate)
					DestroyIcon(bct->hIconPrivate);
				bct->hIconPrivate = DuplicateIcon(g_hInst, (HICON) lParam);
				bct->hIcon = 0;
				break;
			}

		case BM_SETIMLICON: {
			if(bct->hIconPrivate)
				DestroyIcon(bct->hIconPrivate);
			bct->hIml = (HIMAGELIST) wParam;
			bct->iIcon = (int) lParam;
			bct->hIcon = bct->hIconPrivate = 0;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;
		}

		case BM_SETSKINNED:
			bct->bSkinned = (DWORD)lParam;
			bct->bThemed = bct->bSkinned ? FALSE : bct->bThemed;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;

		case BM_SETBTNITEM:
			bct->buttonItem = (TButtonItem *)lParam;
			break;

		case BM_SETASMENUACTION:
			bct->bSendOnDown = wParam ? TRUE : FALSE;
			return 0;

		case BM_SETCHECK:
			if(!bct->pushBtn)
				break;
			if(wParam == BST_CHECKED) {
				bct->pbState = 1;
				bct->stateId = PBS_PRESSED;
			} else if(wParam == BST_UNCHECKED) {
				bct->pbState = 0;
				bct->stateId = PBS_NORMAL;
			}
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;

		case BM_GETCHECK:
			if(bct->pushBtn) {
				return bct->pbState ? BST_CHECKED : BST_UNCHECKED;
			}
			return 0;

		case BUTTONSETARROW:
			// turn arrow on/off
			if(wParam) {
				if(!bct->arrow)
					bct->arrow = (HICON) LoadImage(g_hInst, MAKEINTRESOURCE(IDI_MINIMIZE), IMAGE_ICON, CXSMICON, CYSMICON, 0);
			} else {
				if(bct->arrow) {
					DestroyIcon(bct->arrow);
					bct->arrow = NULL;
				}
			}
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;

		case BUTTONSETDEFAULT:
			bct->defbutton = wParam ? 1 : 0;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;

		case BUTTONSETASPUSHBTN:
			bct->pushBtn = 1;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;

		case BUTTONSETASFLATBTN:
			bct->flatBtn = lParam == 0 ? 1 : 0;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;

		case BUTTONSETASFLATBTN + 10:
			bct->bThemed = lParam ? TRUE : FALSE;
			bct->bSkinned = bct->bThemed ? 0 : bct->bSkinned;
			break;

		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 = bct->hwnd;
			ti.uId = (UINT_PTR) bct->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) bct->hwnd;
			ti.lpszText = (wchar_t *) wParam;
			SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) &ti);
			break;
		}
		case WM_SETFOCUS:
			// set keybord focus and redraw
			bct->focus = 1;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;

		case WM_KILLFOCUS:
			// kill focus and redraw
			bct->focus = 0;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;

		case WM_WINDOWPOSCHANGED:
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;

		case WM_ENABLE:	{
			bct->stateId = wParam ? PBS_NORMAL : PBS_DISABLED;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;
		}

		case WM_MOUSELEAVE: {
			if(bct->stateId != PBS_DISABLED) {
				// don't change states if disabled
				bct->stateId = PBS_NORMAL;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			break;
		}

		case WM_LBUTTONDOWN: {
			if(bct->stateId != PBS_DISABLED && bct->stateId != PBS_PRESSED) {
				bct->stateId = PBS_PRESSED;
				InvalidateRect(bct->hwnd, NULL, TRUE);
				if(bct->bSendOnDown) {
					SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg);
					bct->stateId = PBS_NORMAL;
					InvalidateRect(bct->hwnd, NULL, TRUE);
				}
			}
			break;
		}

		case WM_LBUTTONUP: {
			if(bct->pushBtn) {
				if(bct->pbState)
					bct->pbState = 0;
				else
					bct->pbState = 1;
			}
			if(bct->stateId != PBS_DISABLED) {
				// don't change states if disabled
				if(msg == WM_LBUTTONUP)
					bct->stateId = PBS_HOT;
				else
					bct->stateId = PBS_NORMAL;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			if(!bct->bSendOnDown)
				SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg);
			break;
		}

		case WM_MOUSEMOVE:
			if(bct->stateId == PBS_NORMAL) {
				bct->stateId = PBS_HOT;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			// Call timer, used to start cheesy TrackMouseEvent faker
			SetTimer(hwndDlg, BUTTON_POLLID, BUTTON_POLLDELAY, NULL);
			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: {
			if(wParam == BUTTON_POLLID) {
				RECT rc;
				POINT pt;
				GetWindowRect(hwndDlg, &rc);
				GetCursorPos(&pt);
				if(!PtInRect(&rc, pt)) {
					// mouse must be gone, trigger mouse leave
					PostMessage(hwndDlg, WM_MOUSELEAVE, 0, 0L);
					KillTimer(hwndDlg, BUTTON_POLLID);
				}
			}
			break;
		}

		case WM_ERASEBKGND:
			return 1;
	}
	return DefWindowProc(hwndDlg, msg, wParam, lParam);
}
Exemple #8
0
static LRESULT CALLBACK MButtonWndProc(HWND hwndDlg, UINT msg,  WPARAM wParam, LPARAM lParam)
{
	MButtonCtrl* bct =  (MButtonCtrl *)GetWindowLongPtr(hwndDlg, 0);
	switch(msg) {
	case WM_NCCREATE:
		SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE) | BS_OWNERDRAW);
		bct = ( MButtonCtrl* )mir_calloc(sizeof(MButtonCtrl));
		if (bct==NULL) return FALSE;
		bct->hwnd = hwndDlg;
		bct->stateId = PBS_NORMAL;
		bct->hFont = ( HFONT )GetStockObject(DEFAULT_GUI_FONT);
		LoadTheme(bct);
		if (SUCCEEDED(CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, 
			IID_IAccPropServices, (void**)&bct->pAccPropServices))) 
		{
			// Annotating the Role of this object to be PushButton
			SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_PUSHBUTTON);
		} 
		else 
			bct->pAccPropServices = NULL;
		SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)bct);
		if (((CREATESTRUCT *)lParam)->lpszName) SetWindowText(hwndDlg, ((CREATESTRUCT *)lParam)->lpszName);
		return TRUE;

	case WM_DESTROY:
		if (bct) {
			if (bct->pAccPropServices) {
				bct->pAccPropServices->Release();
				bct->pAccPropServices = NULL;
			}
			if (bct->hwndToolTips) {
				TOOLINFO ti = {0};
				ti.cbSize = sizeof(ti);
				ti.uFlags = TTF_IDISHWND;
				ti.hwnd = bct->hwnd;
				ti.uId = (UINT_PTR)bct->hwnd;
				if (SendMessage(bct->hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM)&ti)) {
					SendMessage(bct->hwndToolTips, TTM_DELTOOL, 0, (LPARAM)&ti);
				}
				if ( SendMessage(bct->hwndToolTips, TTM_GETTOOLCOUNT, 0, (LPARAM)&ti) == 0 ) {
					int idx;
					TTooltips tt;
					tt.ThreadId = GetCurrentThreadId();
			        
                    EnterCriticalSection(&csTips);
					if ( List_GetIndex( &lToolTips, &tt, &idx ) ) {
						mir_free( lToolTips.items[idx] );
						List_Remove( &lToolTips, idx );
						DestroyWindow( bct->hwndToolTips );
					}
			        LeaveCriticalSection(&csTips);
					
                    bct->hwndToolTips = NULL;
				}
			}
			if (bct->arrow) IconLib_ReleaseIcon(bct->arrow, 0);
			DestroyTheme(bct);
		}
		break;	// DONT! fall thru

    case WM_NCDESTROY:
		mir_free(bct);
        break;

	case WM_SETTEXT:
		bct->cHot = 0;
		if ( lParam != 0 ) {
			TCHAR *tmp = ( TCHAR* )lParam;
			while (*tmp) {
				if (*tmp=='&' && *(tmp+1)) {
					bct->cHot = _tolower(*(tmp+1));
					break;
				}
				tmp++;
			}
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		break;

	case WM_KEYUP:
		if (bct->stateId!=PBS_DISABLED && wParam == VK_SPACE) {
			if (bct->pushBtn) {
				if (bct->pbState) {
					bct->pbState = 0;
					bct->stateId = PBS_NORMAL;
				}
				else {
					bct->pbState = 1;
					bct->stateId = PBS_PRESSED;
				}
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
			return 0;
		}
		break;

	case WM_SYSKEYUP:
		if (bct->stateId!=PBS_DISABLED && bct->cHot && bct->cHot == tolower((int)wParam)) {
			if (bct->pushBtn) {
				if (bct->pbState) {
					bct->pbState = 0;
					bct->stateId = PBS_NORMAL;
				}
				else {
					bct->pbState = 1;
					bct->stateId = PBS_PRESSED;
				}
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
			return 0;
		}
		break;

	case WM_THEMECHANGED:
		// themed changed, reload theme object
		LoadTheme(bct);
		InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it
		break;

	case WM_SETFONT: // remember the font so we can use it later
		bct->hFont = (HFONT)wParam; // maybe we should redraw?
		break;

	case WM_NCPAINT:
	case WM_PAINT:
	{
		PAINTSTRUCT ps;
		HDC hdcPaint;

		hdcPaint = BeginPaint(hwndDlg, &ps);
		if (hdcPaint) {
			PaintWorker(bct, hdcPaint);
			EndPaint(hwndDlg, &ps);
		}
		break;
	}
	case BM_SETIMAGE:
	{
		HGDIOBJ hnd = NULL;
		if (bct->hIcon) hnd = bct->hIcon;
		else if (bct->hBitmap) hnd = bct->hBitmap;

		if (wParam == IMAGE_ICON) {
			bct->hIcon = (HICON)lParam;
			bct->hBitmap = NULL;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		else if (wParam == IMAGE_BITMAP) {
			bct->hBitmap = (HBITMAP)lParam;
			bct->hIcon = NULL;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		return (LRESULT)hnd;
	}
	case BM_GETIMAGE:
		if (bct->hIcon) return (LRESULT)bct->hIcon;
		else if (bct->hBitmap) return (LRESULT)bct->hBitmap;
		else return 0;
	case BM_SETCHECK:
		if (!bct->pushBtn) break;
		if (wParam == BST_CHECKED) {
			bct->pbState = 1;
               bct->stateId = PBS_PRESSED;
		}
		else if (wParam == BST_UNCHECKED) {
			bct->pbState = 0;
               bct->stateId = PBS_NORMAL;
		}
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;
	case BM_GETCHECK:
		if (bct->pushBtn) {
			return bct->pbState?BST_CHECKED:BST_UNCHECKED;
		}
		return 0;
	case BUTTONSETARROW: // turn arrow on/off
		if (wParam) {
			if (!bct->arrow) {
				bct->arrow = LoadSkinIcon(SKINICON_OTHER_DOWNARROW);
				SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_BUTTONDROPDOWN);
			}
		}
		else {
			if (bct->arrow) {
				IconLib_ReleaseIcon(bct->arrow, 0);
				bct->arrow = NULL;
				SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_PUSHBUTTON);
			}
		}
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;
	case BUTTONSETDEFAULT:
		bct->defbutton = wParam?1:0;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;
	case BUTTONSETASPUSHBTN:
		bct->pushBtn = 1;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;
	case BUTTONSETASFLATBTN:
		bct->flatBtn = 1;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;
	case BUTTONADDTOOLTIP:
		if ( wParam ) {
			TOOLINFO ti = {0};
			if ( !bct->hwndToolTips ) {
				int idx;
				TTooltips tt;
				tt.ThreadId = GetCurrentThreadId();
			    
                EnterCriticalSection(&csTips);
				if ( List_GetIndex( &lToolTips, &tt, &idx )) {
					bct->hwndToolTips = ((TTooltips*)lToolTips.items[idx])->hwnd;
				} else {
					TTooltips *ptt = ( TTooltips* )mir_alloc( sizeof(TTooltips) );
					ptt->ThreadId = tt.ThreadId;
					ptt->hwnd = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), TTS_ALWAYSTIP, 0, 0, 0, 0, NULL, NULL, hMirandaInst, NULL);
					List_Insert( &lToolTips, ptt, idx );
					bct->hwndToolTips = ptt->hwnd;
				}
    			LeaveCriticalSection(&csTips);
			}
			ti.cbSize = sizeof(ti);
			ti.uFlags = TTF_IDISHWND;
			ti.hwnd = bct->hwnd;
			ti.uId = (UINT_PTR)bct->hwnd;
			if (SendMessage(bct->hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM)&ti))
				SendMessage(bct->hwndToolTips, TTM_DELTOOL, 0, (LPARAM)&ti);
			ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS;
			ti.uId = (UINT_PTR)bct->hwnd;
			#if defined( _UNICODE )
				if ( lParam & BATF_UNICODE )
					ti.lpszText = mir_wstrdup( TranslateW(( WCHAR* )wParam ));
				else
					ti.lpszText = LangPackPcharToTchar(( char* )wParam );
			#else
				ti.lpszText = Translate(( char* )wParam );
			#endif
			if (bct->pAccPropServices) {
				wchar_t *tmpstr = mir_t2u(ti.lpszText);
				bct->pAccPropServices->SetHwndPropStr(bct->hwnd, OBJID_CLIENT, 
					CHILDID_SELF, PROPID_ACC_DESCRIPTION, tmpstr);
				mir_free(tmpstr);
			}
			SendMessage( bct->hwndToolTips, TTM_ADDTOOL, 0, (LPARAM)&ti);
			#if defined( _UNICODE )
				mir_free( ti.lpszText );
			#endif
		}
		break;
	case WM_SETFOCUS: // set keybord focus and redraw
		bct->focus = 1;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;

	case WM_KILLFOCUS: // kill focus and redraw
		bct->focus = 0;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;

	case WM_WINDOWPOSCHANGED:
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;

	case WM_ENABLE: // windows tells us to enable/disable
		bct->stateId = wParam?PBS_NORMAL:PBS_DISABLED;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;

	case WM_MOUSELEAVE: // faked by the WM_TIMER
		if (bct->stateId!=PBS_DISABLED) { // don't change states if disabled
			bct->stateId = PBS_NORMAL;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		break;

	case WM_LBUTTONDOWN:
		if (bct->stateId!=PBS_DISABLED) { // don't change states if disabled
			bct->stateId = PBS_PRESSED;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		break;

	case WM_LBUTTONUP:
    {
        int showClick = 0;
		if (bct->pushBtn) {
			if (bct->pbState) bct->pbState = 0;
			else bct->pbState = 1;
		}
		if (bct->stateId!=PBS_DISABLED) { // don't change states if disabled
            if (bct->stateId==PBS_PRESSED)
                showClick = 1;
			if (msg==WM_LBUTTONUP) bct->stateId = PBS_HOT;
			else bct->stateId = PBS_NORMAL;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
        if (showClick) // Tell your daddy you got clicked.
            SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
		break;
    }
	case WM_MOUSEMOVE:
		if (bct->stateId == PBS_NORMAL) {
			bct->stateId = PBS_HOT;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		// Call timer, used to start cheesy TrackMouseEvent faker
		SetTimer(hwndDlg,BUTTON_POLLID,BUTTON_POLLDELAY,NULL);
		break;
	case WM_TIMER: // use a timer to check if they have did a mouseout
		if (wParam == BUTTON_POLLID) {
			RECT rc;
			POINT pt;
			GetWindowRect(hwndDlg,&rc);
			GetCursorPos(&pt);
			if(!PtInRect(&rc,pt)) { // mouse must be gone, trigger mouse leave
				PostMessage(hwndDlg,WM_MOUSELEAVE,0,0L);
				KillTimer(hwndDlg,BUTTON_POLLID);
		}	}
		break;

	case WM_ERASEBKGND:
		return 1;
	}
	return DefWindowProc(hwndDlg, msg, wParam, lParam);
}
Exemple #9
0
static LRESULT CALLBACK TSButtonWndProc(HWND hwndDlg, UINT msg,  WPARAM wParam, LPARAM lParam)
{
	MButtonCtrl* bct = (MButtonCtrl *)GetWindowLongPtr(hwndDlg, 0);
	switch (msg) {
		case WM_NCCREATE: {
			SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE) | BS_OWNERDRAW);
			bct = (MButtonCtrl *)malloc(sizeof(MButtonCtrl));
			if (bct == NULL)
				return FALSE;
			ZeroMemory(bct, sizeof(MButtonCtrl));
			bct->hwnd = hwndDlg;
			bct->stateId = PBS_NORMAL;
			bct->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
			LoadTheme(bct);
			SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)bct);
			if (((CREATESTRUCT *)lParam)->lpszName)
				SetWindowText(hwndDlg, ((CREATESTRUCT *)lParam)->lpszName);
			return TRUE;
		}
		case WM_DESTROY: {
			if (bct) {
				EnterCriticalSection(&csTips);
				if (hwndToolTips) {
					TOOLINFO ti;

					ZeroMemory(&ti, sizeof(ti));
					ti.cbSize = sizeof(ti);
					ti.uFlags = TTF_IDISHWND;
					ti.hwnd = bct->hwnd;
					ti.uId = (UINT_PTR)bct->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 (bct->hIconPrivate)
					DestroyIcon(bct->hIconPrivate);
				LeaveCriticalSection(&csTips);
				DestroyTheme(bct);
			}
			break;	// DONT! fall thru
		}

		case WM_NCDESTROY:
			free(bct);
			SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)NULL);
			break;

		case WM_SETTEXT: {
			bct->cHot = 0;
			if ((TCHAR *)lParam) {
				TCHAR *tmp = (TCHAR *)lParam;
				while (*tmp) {
					if (*tmp == (TCHAR)'&' && *(tmp + 1)) {
						bct->cHot = _totlower(*(tmp + 1));
						break;
					}
					tmp++;
				}
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			break;
		}
		case WM_KEYUP:
			if (bct->stateId != PBS_DISABLED && wParam == VK_SPACE && !(GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_SHIFT) & 0x8000)) {
				if (bct->pushBtn) {
					if (bct->pbState) bct->pbState = 0;
					else bct->pbState = 1;
					InvalidateRect(bct->hwnd, NULL, TRUE);
				}
				SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
				return 0;
			}
			break;
		case WM_SYSKEYUP:
			if (bct->stateId != PBS_DISABLED && bct->cHot && bct->cHot == tolower((int)wParam)) {
				if (bct->pushBtn) {
					if (bct->pbState) bct->pbState = 0;
					else bct->pbState = 1;
					InvalidateRect(bct->hwnd, NULL, TRUE);
				}
				SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
				return 0;
			}
			break;
		case WM_THEMECHANGED: {
			// themed changed, reload theme object
			if (bct->bThemed)
				LoadTheme(bct);
			InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it
			break;
		}
		case WM_SETFONT: { // remember the font so we can use it later
			bct->hFont = (HFONT)wParam; // maybe we should redraw?
			break;
		}
		case WM_NCPAINT:
			return(0);

		case WM_PAINT: {
			PAINTSTRUCT ps;
			HDC hdcPaint;

			hdcPaint = BeginPaint(hwndDlg, &ps);
			if (hdcPaint) {
				if(bct->sitem)
					bct->sitem->RenderThis(hdcPaint);
				else
					PaintWorker(bct, hdcPaint);
				EndPaint(hwndDlg, &ps);
			}
			return(0);
		}
		case BM_SETIMAGE:
			if (wParam == IMAGE_ICON) {
				ICONINFO ii;
				BITMAP bm;

				if (bct->hIconPrivate)
					DestroyIcon(bct->hIconPrivate);

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

				DeleteObject(ii.hbmMask);
				DeleteObject(ii.hbmColor);
				bct->hBitmap = NULL;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			} else if (wParam == IMAGE_BITMAP) {
				bct->hBitmap = (HBITMAP)lParam;
				if (bct->hIconPrivate)
					DestroyIcon(bct->hIconPrivate);
				bct->hIcon = bct->hIconPrivate = NULL;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			break;
		case BM_SETCHECK:
			if (!bct->pushBtn) break;
			if (wParam == BST_CHECKED) {
				bct->pbState = 1;
				bct->stateId = PBS_PRESSED;
			} else if (wParam == BST_UNCHECKED) {
				bct->pbState = 0;
				bct->stateId = PBS_NORMAL;
			}
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;
		case BM_GETCHECK:
			if (bct->pushBtn) {
				return bct->pbState ? BST_CHECKED : BST_UNCHECKED;
			}
			return 0;
		case BUTTONSETARROW: // turn arrow on/off
			bct->arrow = (HICON)wParam;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;
		case BUTTONSETDEFAULT:
			bct->defbutton = wParam ? 1 : 0;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;
		case BUTTONSETASPUSHBTN:
			bct->pushBtn = 1;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;
		case BUTTONSETASFLATBTN:
			bct->flatBtn = lParam == 0 ? 1 : 0;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;
		case BUTTONSETASFLATBTN + 10:
			bct->bThemed = lParam ? TRUE : FALSE;
			break;
		case BUTTONSETASFLATBTN + 11:
			bct->dimmed = lParam ? TRUE : FALSE;
			break;
		case BUTTONSETASFLATBTN + 12:
			bct->pContainer = (struct TContainerData *)lParam;
			break;
		case BUTTONSETASFLATBTN + 13:
			bct->bTitleButton = TRUE;
			break;
		case BUTTONSETASFLATBTN + 14:
			bct->stateId = (wParam) ? PBS_NORMAL : PBS_DISABLED;
			InvalidateRect(bct->hwnd, NULL, FALSE);
			break;
		case BUTTONSETASFLATBTN + 15:
			return bct->stateId;
		case BUTTONSETASTOOLBARBUTTON:
			bct->bToolbarButton = lParam;
			break;
		case BUTTONSETASSIDEBARBUTTON:
			bct->sitem = reinterpret_cast<CSideBarButton *>(lParam);
			break;
		case BUTTONSETOVERLAYICON:
			bct->overlay = (HICON)lParam;
			break;
		case BUTTONADDTOOLTIP: {
			TOOLINFO ti;

			if (!(char*)wParam)
				break;
			EnterCriticalSection(&csTips);
			if (!hwndToolTips) {
				hwndToolTips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), WS_POPUP, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
			}
			ZeroMemory(&ti, sizeof(ti));
			ti.cbSize = sizeof(ti);
			ti.uFlags = TTF_IDISHWND;
			ti.hwnd = bct->hwnd;
			ti.uId = (UINT_PTR)bct->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)bct->hwnd;
			ti.lpszText = (TCHAR *)wParam;
			SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM)&ti);
			SendMessage(hwndToolTips, TTM_SETMAXTIPWIDTH, 0, 300);
			LeaveCriticalSection(&csTips);
			break;
		}
		case WM_SETFOCUS: // set keybord focus and redraw
			bct->focus = 1;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;
		case WM_KILLFOCUS: // kill focus and redraw
			bct->focus = 0;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;
		case WM_ENABLE: { // windows tells us to enable/disable
			bct->stateId = wParam ? PBS_NORMAL : PBS_DISABLED;
			InvalidateRect(bct->hwnd, NULL, TRUE);
			break;
		}
		case WM_MOUSELEAVE: { // faked by the WM_TIMER
			if (bct->stateId != PBS_DISABLED) { // don't change states if disabled
				bct->stateId = PBS_NORMAL;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			break;
		}

		case WM_CONTEXTMENU:
			if(bct->sitem)
				bct->sitem->invokeContextMenu();
			break;

		case WM_MBUTTONUP:
			if(bct->sitem) {
				if(bct->sitem->getDat())
					SendMessage(bct->sitem->getDat()->hwnd, WM_CLOSE, 1, 0);
			}
			break;

		case WM_LBUTTONDOWN: {
			RECT rc;

			if(bct->sitem) {
				if(bct->sitem->testCloseButton() != -1)
					return(TRUE);
				bct->stateId = PBS_PRESSED;
				InvalidateRect(bct->hwnd, NULL, TRUE);
				bct->sitem->activateSession();
			}

			if (bct->arrow) {
				GetClientRect(bct->hwnd, &rc);
				if (LOWORD(lParam) < rc.right - 12 && bct->stateId != PBS_DISABLED)
					bct->stateId = PBS_PRESSED;
				else if(LOWORD(lParam) > rc.right - 12) {
					if(GetDlgCtrlID(hwndDlg) == IDOK || bct->stateId != PBS_DISABLED) {
						WORD w = (WORD)((int)bct->arrow & 0x0000ffff);
						SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(w, BN_CLICKED), (LPARAM)hwndDlg);
					}
				}
				InvalidateRect(bct->hwnd, NULL, TRUE);
			} else if (bct->stateId != PBS_DISABLED) {
				bct->stateId = PBS_PRESSED;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			break;
		}
		case WM_LBUTTONUP: {
			int  showClick = 0;

			if (bct->sitem) {
				if(bct->sitem->testCloseButton() != -1) {
					SendMessage(bct->sitem->getDat()->hwnd, WM_CLOSE, 1, 0);
					return(TRUE);
				}
			}
			if (bct->pushBtn) {
				if (bct->pbState) bct->pbState = 0;
				else bct->pbState = 1;
			}
			if (bct->stateId != PBS_DISABLED) { // don't change states if disabled
				if(bct->stateId == PBS_PRESSED)
					showClick = 1;
				if (msg == WM_LBUTTONUP)
					bct->stateId = PBS_HOT;
				else
					bct->stateId = PBS_NORMAL;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			if(showClick)
		          SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
			break;
		}
		case WM_MOUSEMOVE:
			if (bct->stateId == PBS_NORMAL) {
				bct->stateId = PBS_HOT;
				InvalidateRect(bct->hwnd, NULL, TRUE);
			} else if (bct->arrow && bct->stateId == PBS_HOT) {
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			// Call timer, used to start cheesy TrackMouseEvent faker
			SetTimer(hwndDlg, BUTTON_POLLID, BUTTON_POLLDELAY, NULL);
			if(bct->sitem) {
				if(bct->sitem->testCloseButton() != -1) {
					if(bct->sitem->m_sideBar->getHoveredClose() != bct->sitem) {
						bct->sitem->m_sideBar->setHoveredClose(bct->sitem);
						InvalidateRect(hwndDlg, 0, FALSE);
					}
				}
				else {
					bct->sitem->m_sideBar->setHoveredClose(0);
					InvalidateRect(hwndDlg, 0, FALSE);
				}
			}
			break;
		case WM_TIMER: { // use a timer to check if they have did a mouseout
			if (wParam == BUTTON_POLLID) {
				RECT rc;
				POINT pt;
				GetWindowRect(hwndDlg, &rc);
				GetCursorPos(&pt);
				if (!PtInRect(&rc, pt)) { // mouse must be gone, trigger mouse leave
					PostMessage(hwndDlg, WM_MOUSELEAVE, 0, 0L);
					KillTimer(hwndDlg, BUTTON_POLLID);
					if(bct->sitem) {
						bct->sitem->m_sideBar->setHoveredClose(0);
						InvalidateRect(hwndDlg, 0, FALSE);
					}
				}
			}
			break;
		}
		case WM_ERASEBKGND:
			return(1);
	}
	return DefWindowProc(hwndDlg, msg, wParam, lParam);
}