Codejock Forums Homepage
Forum Home Forum Home > General > XAML Snippets > Samples and Demo Applications
  New Posts New Posts RSS Feed - MFC - C++ - CWnd derived control in markup
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

MFC - C++ - CWnd derived control in markup

 Post Reply Post Reply
Author
Message
gorski View Drop Down
Newbie
Newbie
Avatar

Joined: 06 July 2006
Location: Poland
Status: Offline
Points: 6
Post Options Post Options   Thanks (0) Thanks(0)   Quote gorski Quote  Post ReplyReply Direct Link To This Post Topic: MFC - C++ - CWnd derived control in markup
    Posted: 29 May 2009 at 5:39am
I would like to present the way you can create your own XAML tag and put CWnd derived control inside markup. In my exaple I create edit box markup.

All you have to do is to create a class derived from CXTPMarkupFrameworkElement, register a new markup type and register some events, so you can interact with the control.

MarkupEdit.h

#pragma once
class MarkupEdit : public CXTPMarkupFrameworkElement
{
    DECLARE_MARKUPCLASS(MarkupEdit)

public:
    virtual CSize MeasureOverride(CXTPMarkupDrawingContext* pDC, CSize constraint);
    virtual void OnRender(CXTPMarkupDrawingContext* pDC);

    HWND GetEdit();  //returns HWND of the edit box control

protected:
    MarkupEdit() {}
    virtual ~MarkupEdit() {}
   
    void CreateControl(CRect rc);

protected:
    CXTPEdit mEdit; //the control we want to put into markup

public:
    static CXTPMarkupRoutedEvent* m_pCreateEvent; //an event we want to fire after the control is created

};


MarkupEdit.cpp

#include "stdafx.h"
#include "MarkupEdit.h"

CXTPMarkupRoutedEvent* MarkupEdit::m_pCreateEvent = NULL;

//This line bindes the markup control with its tag
IMPLEMENT_MARKUPCLASS(L"EditBox", MarkupEdit, CXTPMarkupFrameworkElement)

void MarkupEdit::RegisterMarkupClass()
{
    //register 'Create' event
    m_pCreateEvent = CXTPMarkupRoutedEvent::RegisterRoutedEvent(L"Create", CXTPMarkupRoutedEvent::routingBubble, MARKUP_TYPE(MarkupEdit));
}

CSize MarkupEdit::MeasureOverride(CXTPMarkupDrawingContext* /*pDC*/, CSize constraint)
{
    return constraint;
}

void MarkupEdit::OnRender(CXTPMarkupDrawingContext* pDC)
{
    if (!mEdit.GetSafeHwnd())
    {
        CRect rc = m_pMarkupContext->GetClientBoundingRect(this);
        CreateControl(rc);
    }
}

void MarkupEdit::CreateControl(CRect rc)
{
    if (m_pMarkupContext)
    {
        CWnd* wnd = CWnd::FromHandle(m_pMarkupContext->m_hContextWnd);
        if (wnd)
        {
            if (!mEdit.GetSafeHwnd())
            {
                mEdit.Create(ES_LEFT | ES_AUTOHSCROLL | WS_VISIBLE | WS_CHILD | WS_BORDER,
                    rc, wnd, 0);
                mEdit.SetFont(&XTAuxData().font);

                //fire 'Create' event
                CXTPMarkupRoutedEventArgs e(m_pCreateEvent, this);
                RaiseEvent(&e);
            }
        }
    }
}

HWND MarkupEdit::GetEdit()
{
    return mEdit.GetSafeHwnd();
}



Register new markup control:

    MarkupEdit::RegisterType();

You can do it for example in the constructor of CMarkupStatic class from Codejock sample.

Define method to handle control events:

    AddHandler(MarkupEdit::m_pCreateEvent, CreateMarkupClassDelegate(this, &CMarkupStatic::OnEditCreate));


Now you can put into XAML your tag:

...
<EditBox Tag='Edit1' Width='100' Height='26'/>
...



When the edit control is created inside markup, 'Create' event is fired and you can get the pointer or HWND of the control. If you put more edit boxes into markup, you can distighuish them by 'Tag' property.

void Avatar::OnEditCreate(CXTPMarkupObject* pSender, CXTPMarkupRoutedEventArgs* pArgs)
{
    if (pSender->IsKindOf(MARKUP_TYPE(MarkupEdit)))
    {
        pArgs->SetHandled();

        CXTPMarkupString* pTag = MARKUP_DYNAMICCAST(CXTPMarkupString, ((MarkupEdit*)pSender)->GetTag());
        if (pTag)
        {
            CString tag = (LPCTSTR)*pTag;
            if (tag == _T("Edit1"))
            {
                mEditHwnd = ((MarkupEdit*)pSender)->GetEdit();
            }
        }
    }
}



As long as markup exists, you can read whatever user entered into edit box.

    if (mEditHwnd)
    {
        CString text;
        ::GetWindowText(mEditHwnd, text.GetBufferSetLength(128), 128);
    }




Voila

Comments, questions and improvements are welcome.
Back to Top
Alina View Drop Down
Newbie
Newbie
Avatar

Joined: 26 September 2008
Location: Romania
Status: Offline
Points: 4
Post Options Post Options   Thanks (0) Thanks(0)   Quote Alina Quote  Post ReplyReply Direct Link To This Post Posted: 04 June 2009 at 6:57am
How can I create edit box markup in Visual Basic?
Please help!
Thank you!

Back to Top
Krog View Drop Down
Groupie
Groupie


Joined: 06 February 2008
Status: Offline
Points: 94
Post Options Post Options   Thanks (0) Thanks(0)   Quote Krog Quote  Post ReplyReply Direct Link To This Post Posted: 27 June 2009 at 6:32am
Hi Alina!

In VB it is not possible :(
Product: Xtreme SuitePro (ActiveX) version 15.2.1
Platform: Windows XP SP2
Language: Visual Basic 6 SP6
Back to Top
nemmartins View Drop Down
Newbie
Newbie


Joined: 24 November 2009
Status: Offline
Points: 1
Post Options Post Options   Thanks (0) Thanks(0)   Quote nemmartins Quote  Post ReplyReply Direct Link To This Post Posted: 02 May 2010 at 6:07pm
Hi! and how to make the edit control to have the same behavior as other controls, i.e., automatic resize, etc?


Back to Top
pdhammond View Drop Down
Newbie
Newbie


Joined: 01 February 2012
Status: Offline
Points: 1
Post Options Post Options   Thanks (0) Thanks(0)   Quote pdhammond Quote  Post ReplyReply Direct Link To This Post Posted: 01 February 2012 at 5:54am
Hi, I tried this and could not get it to work. I expect this is my not understanding Code Jock idioms, and it's been a long time since I used MFC too.

Using this XAML:
<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<EditBox>Enter something...</EditBox>
</Page>

I get this error:
Cannot convert the string 'Enter something...' into a 'MarkupEdit' object. Line 5, position 38

One thing I was particulalry confused about was where the AddHandler call is supposed to go. Can someone point me to some good intrudcutory documentation on this idiom?

Thanks,
Pete.
Back to Top
adrien View Drop Down
Senior Member
Senior Member


Joined: 30 April 2007
Location: New Zealand
Status: Offline
Points: 344
Post Options Post Options   Thanks (0) Thanks(0)   Quote adrien Quote  Post ReplyReply Direct Link To This Post Posted: 24 April 2013 at 11:54pm
Pete - your markup is wrong.  In the example it was

...
<EditBox Tag='Edit1' Width='100' Height='26'/>
...

not <EditBox>... </EditBox>

If you want some default text settable from the markup, you'd need to set it as a named attribute and extract that from the markup context when it's being created I guess.
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down



This page was generated in 0.078 seconds.