<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>MFC, My own reflected from control</title>
		<link>http://www.allegro.cc/forums/view/519766</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Wed, 17 Aug 2005 06:33:44 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I have no idea what this is called, MFC was saying something about Reflected From Control or whatever...umm, well just let me explain:</p><p>Let&#39;s say you have a button on a dialog. You can then go to that dialog&#39;s class and setup a handler for the click event on that button, even when the button has its own class. So the click messages are getting to both the button and the dialog the button is in.</p><p>This is quite a useful feature because it often means you don&#39;t have to create a new class for every button, or any control for that matter.</p><p>But some events are not sent back to the parent. One such event that interests me is the WM_MOUSEMOVE event. This is only sent to the control, it is not sent to the dialog when the mouse is inside the control (a button for example).</p><p>So I was wondering if it is possible to hack MFC to send this info back to the dialog? This question is mainly aimed at those who know the inner workings of MFC.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Billybob)</author>
		<pubDate>Tue, 16 Aug 2005 03:01:27 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
This is only sent to the control
</p></div></div><p>

I don&#39;t even see mouse move event available for a button. It&#39;s available for the dialog though. If you can find it in the control, just call the dialogs mouse move event from within the controls mouse move (if that exists).</p><p>[EDIT]<br />God, I just remember how ugly MFC is. Why in the world would they even release something like that. What a monster.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Rick)</author>
		<pubDate>Tue, 16 Aug 2005 06:41:23 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>A little more context as to what you&#39;re trying to do would help, as I&#39;m not sure what exactly you&#39;re shooting for.  What are you trying to do that makes you want to redirect mouse moves from a button control to the parent dialog?</p><p>But yes, what you&#39;re asking for is possible - you can use SendMessage() to send any message you want to any control that&#39;s listening for it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Wil Renczes)</author>
		<pubDate>Tue, 16 Aug 2005 07:51:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>See, that solution requires having a non-default class assigned to the Button or whatever other control. I want to avoid that so I can just have a single function in the dialog the control exists in. I removes a lot of pain and agony that way. Even doing a single non-default class for all the controls is a pain in the butt. Something I could hack into the dialog&#39;s header or source would be much better.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Billybob)</author>
		<pubDate>Tue, 16 Aug 2005 09:26:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Reflected From Control?<br />I always thought MFC means Microsoft Foundation Classes...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ABC DEF)</author>
		<pubDate>Tue, 16 Aug 2005 12:09:41 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You&#39;re still losing me - not sure what you&#39;re trying to do exactly.  But in essence, you already probably have what you need.  Check out the definition of the BEGIN_MESSAGE_MAP macro (right-click - go to Definition, if you can) - my ATL version looks like this:
</p><div class="source-code snippet"><div class="inner"><pre><span class="p">#define BEGIN_MSG_MAP(theClass) \</span>
<span class="p">public: \ </span>
<span class="p">  BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT&amp; lResult, DWORD dwMsgMapID = 0) \ </span>
<span class="p">  { \ </span>
<span class="p">    BOOL bHandled = TRUE; \ </span>
<span class="p">    (hWnd); \ </span>
<span class="p">    (uMsg); \ </span>
<span class="p">    (wParam); \ </span>
<span class="p">    (lParam); \ </span>
<span class="p">    (lResult); \ </span>
<span class="p">    (bHandled); \ </span>
<span class="p">    switch(dwMsgMapID) \ </span>
<span class="p">    { \ </span>
<span class="p">    case 0: </span>
</pre></div></div><p>

In other words, you already have a function that is set up to handle every type of possible message that Windows will pump around.  The whole reflection thing is a red herring - that&#39;s usually for when a dialog&#39;s child control is trying to notify the parent that something&#39;s going on, and you as the parent want to redirect that message back to the child for whatever reason.  Generally, a child control will direct messages to the parent dialog - it has to, since the parent dialog decides what happens based on a click, a scroll, etc.</p><p>If you want the override for mouse move, you just need to add ON_WM_MOUSEMOVE to your message map...  <br />Check out &quot;Message Maps&quot; and &quot;Handlers for WM_Messages&quot; in the MFC library reference in MSDN - it has all the info in there on all the message types &amp; the name of the handler functions...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Wil Renczes)</author>
		<pubDate>Tue, 16 Aug 2005 13:40:53 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
If you want the override for mouse move, you just need to add ON_WM_MOUSEMOVE to your message map...
</p></div></div><p>
What he wants to do is allot like KeyPreview in VB. Basically when KeyPreview is set to True, the Form gets all key events, even if controls have focus. ie. you press enter in a textbox, and both the textbox and the form get the KeyDown &amp; KeyUp events fired. It seems he wants the controls to fire the Dialogs MouseMove event. At a quick glance I didn&#39;t see a button even having a MouseMove event in the ClassWizard, but when I subclassed CButton I noticed it&#39;s there, but like he said he doesn&#39;t want to do that for all controls that he uses.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Rick)</author>
		<pubDate>Tue, 16 Aug 2005 16:25:03 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Wil Renczes: Thanks, that&#39;s sorta what I needed to know.</p><p>So now I know what I wanted to do is impossible, because these classes don&#39;t shove mouse move events back to the parent. <img src="http://www.allegro.cc/forums/smileys/angry.gif" alt="&gt;:(" /></p><p>I can&#39;t do that find declare thing because it wants to build some weird stuff and I figure it&#39;s best not to what with MSVC being what it is.</p><p>And Rick, CButton derives from CWnd, so obviously it does have mousemove. <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Billybob)</author>
		<pubDate>Tue, 16 Aug 2005 22:54:00 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I just bounced this around in my head some more, and remembered something that might fit the bill:</p><p>CWnd::SubclassDlgItem().  When you use this, you reroute all messages that would normally go to the child control to go first through the parent&#39;s message map, so you can intercept them.</p><div class="source-code snippet"><div class="inner"><pre>BOOL CAboutDlg::OnInitDialog<span class="k2">(</span><span class="k2">)</span>
<span class="k2">{</span>
    CDialog::OnInitDialog<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    SubclassDlgItem<span class="k2">(</span>ID_SOMECONTROL, <span class="k1">this</span><span class="k2">)</span><span class="k2">;</span>

    <span class="k1">return</span> <span class="k1">true</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Wil Renczes)</author>
		<pubDate>Tue, 16 Aug 2005 23:49:19 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It&#39;s not at all impossible, William. Maybe I&#39;m not understanding something entirely, though. Is it impossible or impractical for you to simply create a custom button class derived from CButton? Then it would be fairly trivial to handle the message however you need, and pass it to the parent if you so desire.</p><p>Any window can receive and handle any message that is normally sent to windows. ClassWizard, however, in its infinite wisdom, applies a message filter to CWnd-derived classes, so that it will list certain messages only for certain types of windows. Of course, you can always add the message map entries yourself, but if you want ClassWizard to be able to do it, it&#39;s fairly easy. Just go to the &quot;Class Info&quot; tab, and set &quot;Message Filter&quot; to &quot;Window&quot;. Now the messages list in the &quot;Message Maps&quot; tab should have a lot more stuff in it.</p><p>Rick: come on, be fair. MFC can only be as ugly as the underlying Win32 API. ...Oh, wait. <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /></p><p>In all honesty, though, I&#39;ve been using Visual Studio 6 and MFC for Windows programming for nearly six years now, and I&#39;ve found it to be more than adequate. I wouldn&#39;t use MSVC for much else besides writing Windows apps, naturally, but it gets the job done, and I suppose I&#39;m used to it. MFC itself certainly has its quirks (a LOT of quirks), but I&#39;ve always managed to get it to do what I wanted to do with relatively little hassle.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mr. Accident)</author>
		<pubDate>Tue, 16 Aug 2005 23:49:21 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I know nothing about MFC, but could you make a template?</p><p>I.e.</p><p>Reflected&lt;CButton&gt; button;
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Wetimer)</author>
		<pubDate>Tue, 16 Aug 2005 23:51:06 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Wil Renczes said:</div><div class="quote"><p>

CWnd::SubclassDlgItem(). When you use this, you reroute all messages that would normally go to the child control to go first through the parent&#39;s message map, so you can intercept them.</p><pre>BOOL CAboutDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    SubclassDlgItem(ID_SOMECONTROL, this);

    return true;
}</pre><p>
</p></div></div><p>

That&#39;s not quite how SubclassDlgItem works. It doesn&#39;t route messages through the parent&#39;s message map, it gives them to the window procedure of the window for which SubclassDlgItem is called. In this case, you don&#39;t want to subclass your button to your dialog. This code will produce an assertion failure right away.</p><p>SubclassDlgItem simply gets the window associated with the control ID and calls SubclassWindow. CWnd::SubclassWindow tries to attach the control HWND to the CWnd object, and CWnd::Attach asserts because your dialog already has a window attached to it.</p><p>To properly use SubclassDlgItem, you should set up a class that will intercept your messages. I&#39;ve dressed up the basic example from MSDN to show you what I mean:</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="c">// In MyDialog.h</span></td></tr><tr><td class="number">2</td><td><span class="k1">class</span> CMyButton <span class="k2">:</span> <span class="k1">public</span> CButton</td></tr><tr><td class="number">3</td><td><span class="k2">{</span></td></tr><tr><td class="number">4</td><td>protected:</td></tr><tr><td class="number">5</td><td>   afx_msg <span class="k1">void</span> OnMouseMove<span class="k2">(</span>UINT nFlags, CPoint point<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">6</td><td>   DECLARE_MESSAGE_MAP<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">7</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">8</td><td>&#160;</td></tr><tr><td class="number">9</td><td><span class="k1">class</span> CMyDialog <span class="k2">:</span> <span class="k1">public</span> CDialog</td></tr><tr><td class="number">10</td><td><span class="k2">{</span></td></tr><tr><td class="number">11</td><td>   <span class="c">//...</span></td></tr><tr><td class="number">12</td><td>&#160;</td></tr><tr><td class="number">13</td><td>protected:</td></tr><tr><td class="number">14</td><td>   CMyButton m_myButton<span class="k2">;</span></td></tr><tr><td class="number">15</td><td>&#160;</td></tr><tr><td class="number">16</td><td>   <span class="c">//...</span></td></tr><tr><td class="number">17</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">18</td><td>&#160;</td></tr><tr><td class="number">19</td><td>&#160;</td></tr><tr><td class="number">20</td><td><span class="c">// In MyDialog.cpp</span></td></tr><tr><td class="number">21</td><td>&#160;</td></tr><tr><td class="number">22</td><td>BEGIN_MESSAGE_MAP<span class="k2">(</span>CMyButton, CButton<span class="k2">)</span></td></tr><tr><td class="number">23</td><td>   ON_WM_MOUSEMOVE<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">24</td><td>END_MESSAGE_MAP<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">25</td><td>&#160;</td></tr><tr><td class="number">26</td><td><span class="k1">void</span> CMyButton::OnMouseMove<span class="k2">(</span>UINT nFlags, CPoint point<span class="k2">)</span></td></tr><tr><td class="number">27</td><td><span class="k2">{</span></td></tr><tr><td class="number">28</td><td>   <span class="c">// Let's display the mouse coordinates on the button</span></td></tr><tr><td class="number">29</td><td>   CString str<span class="k2">;</span></td></tr><tr><td class="number">30</td><td>   str.Format<span class="k2">(</span><span class="s">"%d, %d"</span>, point.x, point.y<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">31</td><td>   SetWindowText<span class="k2">(</span>str<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">32</td><td><span class="k2">}</span></td></tr><tr><td class="number">33</td><td>&#160;</td></tr><tr><td class="number">34</td><td>&#160;</td></tr><tr><td class="number">35</td><td><span class="k1">void</span> CMyDialog::OnInitDialog<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">36</td><td><span class="k2">{</span></td></tr><tr><td class="number">37</td><td>   <span class="c">//...</span></td></tr><tr><td class="number">38</td><td>&#160;</td></tr><tr><td class="number">39</td><td>   <span class="c">// m_myButton is the CMyButton member of CMyDialog, and</span></td></tr><tr><td class="number">40</td><td>   <span class="c">// IDC_MYBUTTON is the ID of the dialog resource button</span></td></tr><tr><td class="number">41</td><td>   m_myButton.SubclassDlgItem<span class="k2">(</span>IDC_MYBUTTON, <span class="k1">this</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">42</td><td>&#160;</td></tr><tr><td class="number">43</td><td>   <span class="c">//...</span></td></tr><tr><td class="number">44</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>


This will dynamically subclass the button to the CMyButton object, which will then receive its messages. The CMyButton::OnMouseMove() handler will be called when the cursor moves across the button, and the coordinates (relative to the upper-left corner of the button) will be displayed as the button&#39;s caption.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mr. Accident)</author>
		<pubDate>Wed, 17 Aug 2005 00:21:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Can a single button be subclass&#39;d to multiple classes?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Billybob)</author>
		<pubDate>Wed, 17 Aug 2005 01:08:06 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>No, it can&#39;t; not dynamically, anyway. If I understand what you mean correctly, the closest thing would be creating a class using multiple inheritance, deriving from both CButton and some other class. I&#39;m not sure why you&#39;d want to do that, though. Multiple inheritance of any sort is usually best avoided, unless you have a really compelling reason to use it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mr. Accident)</author>
		<pubDate>Wed, 17 Aug 2005 01:35:27 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>To have VC handle this: </p><p>Goto class wizard<br />Click add class button-&gt;new<br />Enter name of class (MyButton)<br />Select CButton as Base class<br />Click OK</p><p>Now in your message maps you will see MyButton, and all available events. Find WM_MOUSEMOVE, add it, Edit code. </p><p>Now the only thing I want to know how to do is be able to add it via the dialog editor and not via code. But as stated above you can add it via code.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Rick)</author>
		<pubDate>Wed, 17 Aug 2005 01:39:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You can&#39;t make your button an instance of a custom class in the dialog editor. Probably the easiest way is to use ClassWizard to add a member variable for your button. If you&#39;ve added your custom button class using ClassWizard, you will be able to select your custom class as the type in the &quot;Add Member Variable&quot; dialog. Otherwise, you can just open your dialog&#39;s header file and change the variable to be an instance of your custom class instead of CButton.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mr. Accident)</author>
		<pubDate>Wed, 17 Aug 2005 01:50:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ah there ya go William. Do the subclass like I said. Then put a normal button on you dialog. Then add a member variable to you dialog of type your new button class. If you put in a mouse move event, it will fire for that button in your buttons class. That is half the battle.</p><p>Then you could use signal/slot to pass that up to your dialog, or there is probably another way.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Rick)</author>
		<pubDate>Wed, 17 Aug 2005 01:55:00 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Well, if you use SubclassDlgItem, there&#39;s no need to add a member variable with ClassWizard.  <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>Likewise, if you simply use ClassWizard / member variable approach, you don&#39;t need to actually call SubclassDlgItem - the subclassing of the button is handled by DDX.</p><p>EDIT: I should probably clarify myself a bit here. The two approaches are essentially the same thing. It&#39;s just that in the latter case, ClassWizard handles the work, and uses the DDX functions instead of just calling SubclassWindow directly. (Also, when I said there&#39;s no need to add a member variable, that&#39;s not really what I meant - you do need an instance of your custom class to subclass to, of course.) I&#39;m just not explaining myself well. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>EDIT2: 
</p><div class="quote_container"><div class="title">William Heatley said:</div><div class="quote"><p>
See, that solution requires having a non-default class assigned to the Button or whatever other control. I want to avoid that so I can just have a single function in the dialog the control exists in. I removes a lot of pain and agony that way. Even doing a single non-default class for all the controls is a pain in the butt. Something I could hack into the dialog&#39;s header or source would be much better.
</p></div></div><p>

Oop, I think I missed this somehow the first time I read this thread. May I ask why it is so difficult in this case to create a custom class for a button?</p><p>If you&#39;re really dead set against creating a new button class, one fairly easy hack would be to simply use the main dialog&#39;s OnMouseMove handler, and compare the cursor coordinates to the button rectangle. Honestly, though, it&#39;s better to just derive from CButton. MFC classes were meant to be used as base classes when you want to add functionality of your own! <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mr. Accident)</author>
		<pubDate>Wed, 17 Aug 2005 02:02:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
If you&#39;re really dead set against creating a new button class, one fairly easy hack would be to simply use the main dialog&#39;s OnMouseMove handler, and compare the cursor coordinates to the button rectangle.
</p></div></div><p>
You can&#39;t. The dialog doesn&#39;t get the mouse move event when the mouse is over the button.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Billybob)</author>
		<pubDate>Wed, 17 Aug 2005 05:03:40 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Whoops, duh. I forgot about that little detail for some reason. <img src="http://www.allegro.cc/forums/smileys/lipsrsealed.gif" alt=":-X" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mr. Accident)</author>
		<pubDate>Wed, 17 Aug 2005 06:33:44 +0000</pubDate>
	</item>
</rss>
