Пример #1
0
/*
 * Function CHyperLink::_HyperlinkProc
 *
 * Note: Processed messages are not passed back to the static control
 *       procedure. It does work fine but be aware that it could cause
 *       some problems if the static control is already subclassed.
 *       Consider the example where the static control would be already
 *       subclassed with the ToolTip control that needs to process mouse
 *       messages. In that situation, the ToolTip control would not work
 *       as expected.
 */
LRESULT CALLBACK CHyperLink::_HyperlinkProc(HWND hwnd, UINT message,
		                                   WPARAM wParam, LPARAM lParam)
{
	CHyperLink *pHyperLink = (CHyperLink *)GetProp(hwnd, PROP_OBJECT_PTR);

	switch (message)
	{
	case WM_MOUSEMOVE:
		{
			if ( pHyperLink->m_bOverControl )
			{
				// This is the most common case for static branch prediction
				// optimization
				RECT rect;
				GetClientRect(hwnd,&rect);

				POINT pt = { LOWORD(lParam), HIWORD(lParam) };

				if (!PTINRECT(&rect,pt))
				{
					ReleaseCapture();
				}
			}
			else
			{
				pHyperLink->m_bOverControl = TRUE;
				SendMessage(hwnd, WM_SETFONT,
					        (WPARAM)CHyperLink::g_UnderlineFont, FALSE);
				InvalidateRect(hwnd, NULL, FALSE);
				pHyperLink->OnSelect();
				SetCapture(hwnd);
			}
			return 0;
		}
	case WM_SETCURSOR:
		{
			SetCursor(CHyperLink::g_hLinkCursor);
			return TRUE;
		}
	case WM_CAPTURECHANGED:
		{
			pHyperLink->m_bOverControl = FALSE;
			pHyperLink->OnDeselect();
			SendMessage(hwnd, WM_SETFONT,
				        (WPARAM)pHyperLink->m_StdFont, FALSE);
			InvalidateRect(hwnd, NULL, FALSE);
			return 0;
		}
	case WM_KEYUP:
		{
			if( wParam != VK_SPACE )
			{
				break;
			}
		}
						// Fall through
	case WM_LBUTTONUP:
		{
			pHyperLink->Navigate();
			return 0;
		}
	case WM_SETFOCUS:	// Fall through
	case WM_KILLFOCUS:
		{
			if( message == WM_SETFOCUS )
			{
				pHyperLink->OnSelect();
			}
			else		// WM_KILLFOCUS
			{
				pHyperLink->OnDeselect();
			}
			CHyperLink::DrawFocusRect(hwnd);
			return 0;
		}
	case WM_DESTROY:
		{
			SetWindowLongPtr(hwnd, GWLP_WNDPROC,
				          (LONG) pHyperLink->m_pfnOrigCtlProc);

			SendMessage(hwnd, WM_SETFONT, (WPARAM) pHyperLink->m_StdFont, 0);

			if( --CHyperLink::g_counter <= 0 )
			{
				destroyGlobalResources();
			}

			RemoveProp(hwnd, PROP_OBJECT_PTR);
			break;
		}
	}

	return CallWindowProc(pHyperLink->m_pfnOrigCtlProc, hwnd, message,
		                  wParam, lParam);
}
Пример #2
0
LRESULT CALLBACK CLinkControl::_HyperlinkProc(HWND hwnd, UINT message,
                                           WPARAM wParam, LPARAM lParam)
{
    CLinkControl *pHyperLink = (CLinkControl *)GetProp(hwnd, PROP_OBJECT_PTR);

    switch (message)
    {
    case WM_MOUSEMOVE:
        {
            if (pHyperLink->m_bOverControl)
            {
                RECT rect;
                GetClientRect(hwnd, &rect);

                POINT pt = { LOWORD(lParam), HIWORD(lParam) };

                if (!PtInRect(&rect, pt))
                    ReleaseCapture();
            }
            else
            {
                pHyperLink->m_bOverControl = TRUE;
                SendMessage(hwnd, WM_SETFONT, (WPARAM)CLinkControl::g_UnderlineFont, FALSE);
                InvalidateRect(hwnd, NULL, FALSE);
                SetCapture(hwnd);
            }
        }
        break;
    case WM_SETCURSOR:
        {
            SetCursor(CLinkControl::g_hLinkCursor);
            return TRUE;
        }
        break;
    case WM_CAPTURECHANGED:
        {
            pHyperLink->m_bOverControl = FALSE;
            SendMessage(hwnd, WM_SETFONT, (WPARAM)CLinkControl::g_NormalFont, FALSE);
            InvalidateRect(hwnd, NULL, FALSE);
        }
        break;
    case WM_KEYDOWN:
        {
            if ((wParam != VK_SPACE)&&(wParam != VK_RETURN))
                break;
            PostMessage(::GetParent(hwnd), LK_LINKITEMCLICKED, (WPARAM)hwnd, (LPARAM)0);
            return 0;
        }
        break;
    case BM_CLICK:
        PostMessage(::GetParent(hwnd), LK_LINKITEMCLICKED, (WPARAM)hwnd, (LPARAM)0);
        break;
    case WM_LBUTTONDOWN:
        pHyperLink->m_bMouseDownPressed = true;
        // fallthrough
    case WM_LBUTTONUP:
        {
            if (pHyperLink->m_bMouseDownPressed)
                PostMessage(::GetParent(hwnd), LK_LINKITEMCLICKED, (WPARAM)hwnd, (LPARAM)0);
            pHyperLink->m_bMouseDownPressed = false;
        }
        break;
    case WM_GETDLGCODE:
        {
            LRESULT lres = CallWindowProc(pHyperLink->m_pfnOrigCtlProc, hwnd, message, wParam, lParam);
            // we want all keys to get the return key
            lres |= DLGC_WANTALLKEYS;
            lres |= DLGC_BUTTON;
            // but we don't want the tab key since that should be used in dialogs
            // to switch the focus
            lres &= ~DLGC_WANTTAB;
            lres &= ~DLGC_STATIC;
            if (lParam &&
                ((MSG *)lParam)->message == WM_KEYDOWN &&
                ((MSG *)lParam)->wParam == VK_TAB)
            {
                lres &= ~DLGC_WANTMESSAGE;
            }
            return lres;
        }
        break;
    case WM_SETFOCUS:
        // Fall through
    case WM_KILLFOCUS:
        {
            CLinkControl::DrawFocusRect(hwnd);
        }
        break;
    case WM_DESTROY:
        {
            SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)pHyperLink->m_pfnOrigCtlProc);

            SendMessage(hwnd, WM_SETFONT, (WPARAM)pHyperLink->m_StdFont, 0);

            if (--CLinkControl::g_counter <= 0)
                destroyGlobalResources();

            RemoveProp(hwnd, PROP_OBJECT_PTR);
        }
        break;
    }

    return CallWindowProc(pHyperLink->m_pfnOrigCtlProc, hwnd, message,
                          wParam, lParam);
}