/* * 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); }
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); }