Example #1
0
static LRESULT CALLBACK ModernSkinButtonWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	ModernSkinButtonCtrl* bct = (msg != WM_NCCREATE) ? (ModernSkinButtonCtrl *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA) : nullptr;
	if (bct) {
		if (bct->HandleService && IsBadStringPtrA(bct->HandleService, 255))
			bct->HandleService = nullptr;
		else if (bct->HandleService && ServiceExists(bct->HandleService)) {
			HandleServiceParams MSG = {};
			MSG.hwnd = hwndDlg;
			MSG.msg = msg;
			MSG.wParam = wParam;
			MSG.lParam = lParam;
			int t = CallService(bct->HandleService, (WPARAM)&MSG, 0);
			if (MSG.handled) return t;
		}
	}

	switch (msg) {
	case WM_NCCREATE:
		SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE) | BS_OWNERDRAW);
		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
		if (((CREATESTRUCT *)lParam)->lpszName) SetWindowText(hwndDlg, ((CREATESTRUCT *)lParam)->lpszName);
		return TRUE;

	case WM_DESTROY:
		if (bct == nullptr)
			break;

		if (hwndToolTips) {
			mir_cslock lck(csTips);
			TOOLINFO ti = { 0 };
			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 = nullptr;
			}
		}
		mir_free(bct->ID);
		mir_free(bct->CommandService);
		mir_free(bct->StateService);
		mir_free(bct->HandleService);
		mir_free(bct->Hint);
		mir_free(bct->ValueDBSection);
		mir_free(bct->ValueTypeDef);
		mir_free(bct);
		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
		break;	// DONT! fall thru

	case WM_SETCURSOR:
		{
			HCURSOR hCurs1 = LoadCursor(nullptr, IDC_ARROW);
			if (hCurs1) SetCursor(hCurs1);
			if (bct) SetToolTip(hwndDlg, bct->Hint);
		}
		return 1;

	case WM_PRINT:
		if (IsWindowVisible(hwndDlg))
			ModernSkinButtonPaintWorker(hwndDlg, (HDC)wParam);
		break;

	case WM_PAINT:
		if (IsWindowVisible(hwndDlg) && !g_CluiData.fLayered) {
			PAINTSTRUCT ps = {};
			BeginPaint(hwndDlg, &ps);
			ModernSkinButtonPaintWorker(hwndDlg, (HDC)ps.hdc);
			EndPaint(hwndDlg, &ps);
		}
		return DefWindowProc(hwndDlg, msg, wParam, lParam);

	case WM_CAPTURECHANGED:
		if (bct) {
			bct->hover = 0;
			bct->down = 0;
			ModernSkinButtonPaintWorker(bct->hwnd, nullptr);
		}
		break;

	case WM_MOUSEMOVE:
		if (bct) {
			if (!bct->hover) {
				SetCapture(bct->hwnd);
				bct->hover = 1;
				ModernSkinButtonPaintWorker(bct->hwnd, nullptr);
			}
			else {
				POINT t = UNPACK_POINT(lParam);
				ClientToScreen(bct->hwnd, &t);
				if (WindowFromPoint(t) != bct->hwnd)
					ReleaseCapture();
			}
		}
		return 0;

	case WM_LBUTTONDOWN:
		if (bct) {
			bct->down = 1;
			SetForegroundWindow(GetParent(bct->hwnd));
			ModernSkinButtonPaintWorker(bct->hwnd, nullptr);
			if (bct->CommandService && IsBadStringPtrA(bct->CommandService, 255))
				bct->CommandService = nullptr;
			if (bct->fCallOnPress) {
				if (bct->CommandService) {
					if (!_CallServiceStrParams(bct->CommandService, nullptr) && (bct->ValueDBSection && bct->ValueTypeDef))
						ModernSkinButtonToggleDBValue(bct->ValueDBSection, bct->ValueTypeDef);
				}
				bct->down = 0;

				ModernSkinButtonPaintWorker(bct->hwnd, nullptr);
			}
		}
		return 0;

	case WM_LBUTTONUP:
		if (bct && bct->down) {
			ReleaseCapture();
			bct->hover = 0;
			bct->down = 0;
			ModernSkinButtonPaintWorker(bct->hwnd, nullptr);
			if (bct->CommandService && IsBadStringPtrA(bct->CommandService, 255))
				bct->CommandService = nullptr;
			if (bct->CommandService)
				if (_CallServiceStrParams(bct->CommandService, nullptr)) {
				}
				else if (bct->ValueDBSection && bct->ValueTypeDef)
					ModernSkinButtonToggleDBValue(bct->ValueDBSection, bct->ValueTypeDef);
		}
	}
	return DefWindowProc(hwndDlg, msg, wParam, lParam);
}
Example #2
0
static LRESULT CALLBACK ToolbarButtonProc(HWND hwndDlg, UINT  msg, WPARAM wParam, LPARAM lParam)
{
	TBBUTTONDATA *bct = (TBBUTTONDATA*)GetWindowLongPtr(hwndDlg, 0);

	switch (msg) {
	case WM_DESTROY:
		xpt_FreeThemeForWindow(hwndDlg);
		WindowList_Remove(hButtonWindowList, hwndDlg);
		break;

	case WM_SETTEXT:
		mir_tstrncpy(bct->szText, (TCHAR*)lParam, _countof(bct->szText));
		break;

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

	case BUTTONSETMARGINS:
		if (!lParam) {
			RECT nillRect = { 0 };
			bct->rcMargins = nillRect;
		}
		else bct->rcMargins = *(RECT*)lParam;
		break;

	case BUTTONSETID:
		bct->szButtonID = (char *)lParam;
		break;

	case BUTTONDRAWINPARENT:
		if (IsWindowVisible(hwndDlg)) {
			PaintWorker(bct, (HDC)wParam, (POINT*)lParam);
			return 0;
		}
		break;

	case WM_NCPAINT:
	case WM_PAINT:
		if (g_CluiData.fDisableSkinEngine) {
			PAINTSTRUCT ps;
			HDC hdcPaint = BeginPaint(hwndDlg, &ps);
			if (hdcPaint) {
				PaintWorker(bct, hdcPaint, NULL);
				EndPaint(hwndDlg, &ps);
			}
		}
		ValidateRect(hwndDlg, NULL);
		return 0;

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

	case WM_MOUSELEAVE:
	case BUTTONSETASPUSHBTN:
		return 0;

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

	case WM_LBUTTONDOWN:
		{
			POINT ptMouse = UNPACK_POINT(lParam);

			RECT rcClient;
			GetClientRect(bct->hwnd, &rcClient);
			if (!PtInRect(&rcClient, ptMouse)) {
				bct->bHotMark = false;
				ReleaseCapture();
			}
			else {
				if (bct->stateId != PBS_DISABLED && bct->stateId != PBS_PRESSED) {
					bct->stateId = PBS_PRESSED;
					bct->bHotMark = true;
					InvalidateParentRect(bct->hwnd, NULL, TRUE);
					if (bct->bSendOnDown) {
						SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
						bct->stateId = PBS_NORMAL;
						InvalidateParentRect(bct->hwnd, NULL, TRUE);
					}
				}
				SetCapture(bct->hwnd);
			}
		}
		return 0;

	case WM_LBUTTONUP:
		if (GetCapture() == bct->hwnd) {
			POINT ptMouse = UNPACK_POINT(lParam);

			RECT rcClient;
			GetClientRect(bct->hwnd, &rcClient);

			if (!PtInRect(&rcClient, ptMouse)) {
				bct->bHotMark = false;
				ReleaseCapture();
				return 0;
			}

			if (bct->bIsPushBtn)
				bct->bIsPushed = !bct->bIsPushed;

			if (bct->stateId != PBS_DISABLED) {
				// don't change states if disabled
				bct->stateId = PBS_HOT;
				InvalidateParentRect(bct->hwnd, NULL, TRUE);
			}
			if (!bct->bSendOnDown) {
				bct->bHotMark = false;
				SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
			}
		}
		else {
			bct->bHotMark = false;
			InvalidateParentRect(bct->hwnd, NULL, TRUE);
		}
		return 0;

	case WM_MOUSEMOVE:
		{
			BOOL bPressed = (wParam & MK_LBUTTON) != 0;
			if (bPressed && !bct->bHotMark)
				break;

			RECT rc;
			GetWindowRect(hwndDlg, &rc);

			POINT pt;
			GetCursorPos(&pt);

			BOOL inClient = PtInRect(&rc, pt);
			if (inClient) {
				SetCapture(bct->hwnd);
				if (bct->stateId == PBS_NORMAL) {
					bct->stateId = PBS_HOT;
					InvalidateParentRect(bct->hwnd, NULL, TRUE);
				}
			}

			if (!inClient && bct->stateId == PBS_PRESSED) {
				bct->stateId = PBS_HOT;
				InvalidateParentRect(bct->hwnd, NULL, TRUE);
			}
			else if (inClient && bct->stateId == PBS_HOT && bPressed) {
				if (bct->bHotMark) {
					bct->stateId = PBS_PRESSED;
					InvalidateParentRect(bct->hwnd, NULL, TRUE);
				}
			}
			else if (!inClient && !bPressed) {
				bct->bHotMark = false;
				ReleaseCapture();
			}
		}
		return 0;

	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 BM_SETCHECK:
		if (!bct->bIsPushBtn) break;
		if (wParam == BST_CHECKED)
			bct->bIsPushed = 1;
		else if (wParam == BST_UNCHECKED)
			bct->bIsPushed = 0;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		return 0;

	case WM_SETFOCUS: // set keyboard focus and redraw
		bct->bFocused = true;
		InvalidateParentRect(bct->hwnd, NULL, TRUE);
		break;

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

	case WM_ERASEBKGND:
		return 1;

	case MBM_SETICOLIBHANDLE:
		bct->hIcolibHandle = (HANDLE)lParam;
		bct->hIcon = (bct->hIcolibHandle) ? IcoLib_GetIconByHandle(bct->hIcolibHandle) : NULL;
		return 1;

	case MBM_REFRESHICOLIBICON:
		if (bct->hIcolibHandle)
			bct->hIcon = IcoLib_GetIconByHandle(bct->hIcolibHandle);
		else
			bct->hIcon = NULL;
		InvalidateRect(hwndDlg, NULL, TRUE);
		pcli->pfnInvalidateRect(GetParent(GetParent(hwndDlg)), NULL, TRUE);
		return 1;

	case MBM_UPDATETRANSPARENTFLAG:
		LONG_PTR flag = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE);
		LONG_PTR oldFlag = flag;
		if (lParam == 2)
			lParam = (g_CluiData.fDisableSkinEngine) ? 0 : 1;
		flag &= ~WS_EX_TRANSPARENT;
		if (lParam) flag |= WS_EX_TRANSPARENT;
		if (flag != oldFlag) {
			SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, flag);
			RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
		}
		return 1;
	}

	LRESULT res = mir_callNextSubclass(hwndDlg, ToolbarButtonProc, msg, wParam, lParam);
	if (msg == BM_SETIMAGE)
		InvalidateParentRect(hwndDlg, NULL, TRUE);
	return res;
}