コード例 #1
0
ファイル: CLCButton.cpp プロジェクト: Seldom/miranda-ng
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);
}
コード例 #2
0
ファイル: modern_tbbutton.cpp プロジェクト: ybznek/miranda-ng
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;
}
コード例 #3
0
ファイル: TSButton.cpp プロジェクト: TonyAlloa/miranda-dev
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);
}
コード例 #4
0
ファイル: button.cpp プロジェクト: TonyAlloa/miranda-dev
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);
}
コード例 #5
0
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);
}