locked
[MFC] [DirectWrite] Properly using IDWriteTextLayout::HitTestPoint so the Caret can be positioned properly RRS feed

  • Question

  • I'm working with Direct Write (and 2D) in an MFC-based solution and I was wondering how to know where exactly to place the caret in a given piece of text produced in Direct Write using the IDWriteTextLayout interface. I read that there was a method called HitTestPoint, which is why I added the Layout interface as opposed to simply using the Format interface.

    So far, I can edit what the text says. The program properly responds to keyboard input (mostly as 'o' becomes '/' and there may be other similar anomalies) but I'm not sure how to ensure the Caret positions itself properly.

    afx_msg void TTextField::OnLButtonDown(UINT nFlags, CPoint point, messageOutput* mOut)
    {
    
    	BOOL trailing = false, isInside = false;
    	DWRITE_HIT_TEST_METRICS metrics;
            // text1 is an object that controls text and Direct Write related resources
            // text1->fontLayout is the IDWriteTextLayout 
    
    	text1->fontLayout->HitTestPoint(point.x, point.y, &trailing, &isInside, &metrics);
    
    	if (isInside)
    	{
    		if (trailing)
    			caretLoc = metrics.textPosition;
    		else
    			caretLoc = metrics.textPosition + 1;
    
    		CreateCaret(windowHandle, NULL, 1, 12); // windowHandle is a HWND presupplied by the application
    		SetCaretPos(metrics.left + caretLoc * metrics.width / metrics.length, metrics.top);
    		ShowCaret(windowHandle);
    
    		onFocus = true;
    		TTextField* feild;
                    // This loop is in case there are other TTextFeilds out there, TextList is a global CArray
    		for (int c = 0; c < TextList.GetCount(); c++)
    		{
    			feild = TextList.ElementAt(c);
    			if (feild)
    				feild->onFocus = false;
    		}
    
    	}
    	else
    	{
    		if(onFocus) 
    		DestroyCaret();
    		onFocus = false;
    	}
    }

    The code above is actually in a DLL that the application has access to.

    Sometimes, the caret appears where I want it to, but often will appear off to the side (while still in the same box). How can I better use this method to get the caret where it needs to be (or is there a better technique entirely)?

    Thanks 

    Disclaimer: This thread is the predecessor to the thread "[MFC] [DirectWrite] determining a character's width so the Caret can be moved properly when 'VK_LEFT' or 'VK_RIGHT' is pressed" at

    https://social.msdn.microsoft.com/Forums/en-US/9dbc0c2b-7b3f-43e8-9bd1-c5997cf609ac/mfc-directwrite-determining-a-characters-width-so-the-caret-can-be-moved-properly-when?forum=windowsgeneraldevelopmentissues


    • Edited by Trec Apps Monday, August 15, 2016 9:15 PM Adding link to related successor
    Monday, August 15, 2016 9:01 PM

Answers

  • Hi Trec,

    >>"Sometimes, the caret appears where I want it to, but often will appear off to the side "

    text1->fontLayout->HitTestPoint(point.x, point.y, &trailing, &isInside, &metrics);

    When the specified pixel location is outside the text string, the function sets the output value *isInside to FALSE.  Please make sure the location which you provided is right.

    Best Regards,
    Li Wang


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, August 17, 2016 3:27 AM