Let's say that you have written class CMyDialog derived from CDialog that implements some handy features. You derive all your own dialogs from CMyDialog instead of CDialog, so they all have your new features. All is fine with the world.

Now you want to add those same nice features to your property pages. Why not? After all, dialogs and property pages are very similar. But...oh, dear. You cannot simply change the MFC CPropertyPage class so it derives from your CMyDialog instead. So what do you do?

Well, you could duplicate your code and write a CMyPropertyPage class derived from CPropertyPage. However, as discussed in my last article, it is not good form. More importantly, it is the start of a maintenance nightmare, as you'd have to make the same fixes and changes to both classes

The next obvious choice is to use a template, so you only have to write the code once; but as we found out in my last article, the MFC message map macros do not get along well with templates. We can make our own versions of the macros that do work in a template class, but that method has its limitations as well.

Templates are only a good solution for trivial extensions. Templates expose their internal workings to the world as inline functions. This defeats the purpose of encapsulation and increases dependencies within a project. Therefore, we use multiple-inheritance to neatly wrap up the internals of the class.

Let us have a look at a practical example.

Template-Friendly Message Maps

First, let's have a quick look at the template-friendly message-map macros again.

I copied the MFC message-map macros and added 'template <class baseClass>' in front of the variable and function definition lines in the new BEGIN_MESSAGE_MAP_FOR_TEMPLATE. I also removed the 'const's to get around a compiler bug. Yes, it looks ugly. But then, it is an MFC macro.

Something I failed to mention in my last article is how to make these macros work. The trick is in calling the BEGIN_MESSAGE_MAP_FOR_TEMPLATE. The first argument should be the template class name with a dummy parameter within pointy brackets ("<>"). You use the same parameter name as the second parameter.
For example, if you declared your class like this:

Then you'd write the following definition for the message map (usually in the same ".h" file):

BEGIN_MESSAGE_MAP_FOR_TEMPLATE(TMyClass<TBASE>, TBASE)

Multiple Inheritance

I use multiple-inheritance to neatly encapsulate and share the implementation of the template. The template class behaves primarily as a CDialog (or whatever) but also inherits from our new class to add the required behavior.

CMyClass has all the implementation details hidden away in its ".cpp" file. TMyClass forwards its calls to the corresponding CMyClass functions.

It would be nice if we could derive CMyClass from CWnd as well. However, MFC limitations mean we cannot make calls to CWnd member functions, or use message maps etc. As always, there is a way out. In CMyClass, I store a pointer to my CWnd-derived template object, and make CWnd calls through that pointer.

This assumes that the class with which we instantiate TMyClass is derived from CWnd. If it is not, then we will get compilation errors.

Although we strive to not have compilation errors in the first place, it is always preferable to catch them as early as possible in the development process. The best is to catch them while you are writing code. MS Intellisense helps here. Next best is compile time, then link time, and finally at run-time via checking error codes and doing ASSERTS, etc. The worst way to find errors is for your program to compile, link, build, run ... and then crash.

Notice that I name my template classes with a capital "T" (for template) rather than "C" (for class). You should adopt conventions and, if needed, make up your own. In a way, it does not really matter which conventions you adopt, as long as you use them consistently. When working with MFC one should try adopt conventions that fit well with MFC's conventions, otherwise your code ends up with a mixture of the two.

Now, let us get back to the project. I have encapsulated storing the pointer to a CWnd in a separate class. I will use this class as the base class for my implementation classes.

You may be surprised to learn that I can still use ClassWizard to add message handlers to this code. ClassWizard appears to be smart enough to handle this because it is actually quite dumb. ClassWizard doesn't care what macro names are used, nor that I am working with templates; all it looks for are those funny //{{ AFX_XXX comments. The only catch is that I have to move any ClassWizard-generated functions to just before the #endif that is at the end of the ".h" file and edit it to be a legitimate inline member-function definition.

For example, here is the function that ClassWizard generates if I add a WM_SIZE handler:

Putting It All Together

Now all I need to do is combine all this with some actual code that performs dialog and property page resizing. This means I need to write my CXResizable class (it had to happen sooner or later).

I derive CXResizable from CXWndMultipleInheritance (described earlier). This class has all the logic for resizing. I also add the appropriate message handlers to the TXResizable class (using ClassWizard) and edit them so they call the appropriate functions of CXResizable.

There is quite a bit of code here, so I will not reproduce it all in this article. The full source is available for download in the demo project. However, I will discuss some of the main points of interest. Let us start at the very beginning of the ".h" file.

Resizing Controls in a Dialog

There are many ways a control can resize itself when you resize the dialog or property page in which it lives. Some controls stay positioned relative to the edges of the dialog or page, whereas others move in proportion with the change in size. Some controls will keep their size, whereas others will grow in one direction or both.

'enum EResizeFlags' specifies resizing options for each of the four coordinates that comprise the rectangle for the control position within a dialog or page. By combining these flags, you can determine how the control moves and/or resizes.

The flags with '_LFIX' (and '_TFIX') suffixes anchor the control relative to the left (or top) of the dialog; there is no change in the coordinate. '_RFIX' and '_BFIX' anchor the control relative to the right (or bottom) of the dialog. For example, if the dialog width increases by 100 pixels, then the left coordinate will also move 100 pixels to the right. '_LPROP', '_RPROP', '_CPROP' move the coordinate in proportion to the position of the control across the dialog. LPROP bases that proportion on the left-hand side of the control, CPROP on the center, and RPROP on the right-hand side. '_TPROP', '_BPROP' and '_CPROP' are the equivalent for the top and bottom coordinate.

I used 3-bits to encode the options for each of the four coordinates for 12-bits total. This fits quite nicely into an integer. We will look at the algorithm for resizing using this flag, and its implementation, shortly.

Let us now look at the CXResizable class itself. Notice that most of the functions are virtual, so I can override them in my derived classes to add to or replace their default implementations.

IsResizable() determines whether the dialog or page will have be resizable. By default, it looks at the border style bits of the dialog or page to see if it has a modal dialog frame style (DS_MODALFRAME). If not, then it is resizable.

The GetClientRectWas/Now/Ini() set of functions return the client rectangles before and after sizing, and for the initial dialog size respectively. The GetWindowRectWas/Now/Init() do the same for the window rectangle

To make it obvious that a dialog is resizable, we draw a gripper in the bottom right corner. GetGripperRect() gives the position of the gripper for hit testing and painting. It uses GetSystemMetrics() to make the gripper the same dimensions as the scroll bar width. You should always use GetSystemMetrics(), GetSysColor(), etc., rather than hard-coding sizes.

DrawGripper() does the work of drawing the gripper. I use the very handy DrawFrameControl() to do this; there is no need to reinvent this particular wheel. If you ever have to draw your own user-interface elements, look at DrawFrameControl first.

IsResizeDirectly() determines whether a dialog or page has resized indirectly, because its container changed size, or has been resized directly, by the user. A property page usually only changes size when the property sheet changes size. However, you can directly resize a modeless dialog by dragging its edges. IsResizeDirectly() stops the gripper appearing and being active.

OnSize(), OnNcHitTest(), etc., in CXResizable may look like message handlers, but strictly speaking, they're not, because CXResizable does not derive from CWnd. However, the message handlers in the TXResizable template call these member functions of the same name.

OnPaint()fills the background to avoid repaint problems and draws the gripper if required. Note that the logic for when to draw the gripper is here, rather than in DrawGripper(). That way, I can override DrawGripper() to change the gripper's appearance without having to rewrite the logic for when to draw it.

OnGetMinMaxInfo() looks at the GetWindowRectIni to determine the minimum drag size. During resizing, MFC calls OnGetMinMaxInfo, which fills the MINMAXINFO structure to indicate maximum and minimum sizes for the window.

OnNcHitText() handles dragging by the gripper. Note that if it returns HTNOWHERE, then the TXResizable handler code will call the default OnNcHitTest.

OnSize() is where the real work happens. It updates the cached client and screen rectangles. If the size actually changes, it calls ResizeControls() to do the actual resizing. ResizeControls() uses ::EnumChildWindows() to iterate through all the child windows (i.e. controls) in the dialog or page and resize each reposition each one appropriately.

I need to pass quite a bit of information to be able to resize each child window intelligently. However, there is only room for passing a single LPARAM to the enumerating function. So I shove all the information I need into a struct, and pass a pointer to that struct in the LPARAM.

The ::EnumChildWindows() call tells Windows to call EnumChildProc_ResizeControls for each control. This function unpacks the data from the struct, calls a virtual function to work out the new rectangle for the control, and then moves and resizes it. For cleaner repainting, I use the ::Begin/End/DeferWindowPos() API's. These accumulate all the window size and position changes I make and apply them in one go at the end.

For each control I call the virtual ResizeControl() function. This in turn calls the appropriately named ResizeControlUsingFlags(). However, you can override ResizeControl for any other method of resizing you choose.

ResizeControlUsingFlags uses the flags defined in EResizeFlags. Although there are quite a few lines of code, it is basically just a bunch of simple switch() statements.

Although virtual, you would probably not want to override it, as it is highly dependent on EResizeFlags. However, ResizeControlUsingFlags() does call the virtual function GetResizeFlags() that you probably will override in your own class.

GetResizeFlags() is where the dialog or property page specifies how each of its controls is to be resized. The default implementation of GetResizeFlags returns RESIZE_NONE for all controls; all the controls stay huddled up in the top left corner of the dialog or page when you resize it.

I often replace this simple GetResizeFlags() function with a smart version that looks at the Window Class and position of the controls, and use that to work out what resize flag to return.

Using TXResizable

Phew! That's a lot for one article. But now you can now derive your own dialogs from TXResizable (and your property pages from TXResizable). Indeed, one could use a typedef for these and derive from that:

roger vivier uk 8140

Posted by laugsbobln
on 06/24/2013 10:28am

roger vivier uk 8140
[url=http://rvoutlet.calummacdonald.co.uk/]roger vivier sale[/url] In a coffee based mostly roger vivier hand bags the year 2013 drinking, the amount of H2O is little. Any mass medium size (of sixteen ounce . of) flat white generally possesses a couple of shots regarding espresso, or even trio oz, departure lots of elbow room intended for steamed use! XIII oz . of two per cent milk creates this kind of flat white A 250 calorie beverage before you add virtually any sirup or maybe lure. Fortuitously, there are many methods to cut back on ones unhealthy calories whilst still being take pleasure in the espresso primarily based consume.
[url=http://rvsale.calummacdonald.co.uk/]roger vivier flats[/url] You actually remember those people plastic-type material "Peters" icecream indications shiny near the top of your milkbar. So you obtained this moldable popsticks that have openings in the individual so you might make items with these, and also started in plenty of shiny shades. You actually observed Hello Hey there It's Weekend. And Technological Educational institutions are not referred to as Colleges.
[url=http://rvshoes.calummacdonald.co.uk/]http://rvshoes.calummacdonald.co.uk/[/url] Doesn't necessarily bring about any kind of troublesomeness on your jogging, rather, roger vivier buckle you feel far more lightsome with him or her in comparison to any other Shoes and boots. That's why a lot of young ladies suppose these people by no means would like to drive them sour once the use them. That's in truth the fact. The same as in our school, you could find that lots of girls come in Vivier pumping systems Shoes and boots, and something of my buddies used to be questioned simply by everyone that will the reason why your lover helped to buy this roger vivier clutch baggage brand name, not necessarily some others, your woman stated decisively that she only trustworthy this kind of manufacturer, because it confirmed the girl the coffee quality in addition to offered your ex your common sense of favourable position. Whom affirms it's not at all? That is undoubtly. Each one of these Sends Place tend to be made by hand by means of professional person personnel, which means you won't ever be worried about any kind of prospective problems involving prime(a) due to craftsmanship..

roger vivier flats kcgi

Posted by Tarsoamenq
on 06/24/2013 01:10am

roger vivier flats kcgi
[url=http://rvoutlet.calummacdonald.co.uk/]roger vivier[/url] Elaborating around the plans due to this to begin its kind webpage, Mr. Devendra Jain, President M . d . connected with Atishya Technologies, explained, NPA Supply can be an scoop portal linking the break between the customers and the sellers involving not-executing resources (NPAs) initially with Indian. The actual website is designed to aid the most effective offers with regard to administration involving NPAs simply by changing all the info of accessible belongings inside the American indian mart. We will be investing Urs. tenner crore on this vena portae. From the world-class four many weeks regarding procedures the actual hepatic portal vein possesses managed to get Rs. 1 , 000 crore worth of NPAs on the right track for firmness of purpose. We want to resolve Rs. 30,500 crore summation NPAs above the succeeding(a) 2 yrs.
[url=http://cheaprv.calummacdonald.co.uk/]cheap roger vivier[/url] Element, Variable-Spliff MovementsWhen looking at muscle building, one of the most essential things you can do is to concentrate on element, variable-reefer motions that require you to definitely transit an all natural, full-flexibility. Not merely tend to be these types of physical exercises almost certainly going to carry forward towards the majority of physical exercises, nonetheless they will energize far more powerplant products and also lead to substantially best gains inside muscle. roger vivier motorola clutch hand bags For many people, variants of the the bench press exercise, lift, squat, military press, dips, draw-fedex, and rows need to behave as the principle forms of motions which will be used inside a program. By means of favoring numerous-mutual, chemical compound movements as opposed to individual-articulation, solitude actions, increasing lean mass can become much less hard.
[url=http://rvoutlet.calummacdonald.co.uk/]http://rvoutlet.calummacdonald.co.uk/[/url] A thing on the clever: Take care in deciding on the length of the hoodie mainly because with regards to sweatshirts, countless men believe even bigger is way better -- which is completely wrong considering that the form of your body fades away when you wear oversize passing(a) garments. Get your soak inside most compact dimension you may get outside using for just a look more aerodynamic and purchase roger vivier footwear gymnastic, instead of large along with sloppy.

roger vivier clutch icxf

Posted by Nusseerowe
on 06/22/2013 06:55am

roger vivier clutch icxf
[url=http://cheaprv.calummacdonald.co.uk/]roger vivier[/url] Why's True Women Roger Vivier Veanna Black color flats sales so popular? There exists a big difference that will items these individuals beyond the never ending choice of organization manufacturers. If you take into consideration Viviers, place or even Shoes and boots may come in your thoughts. Only Roger Viviers gross sales now offers a great trenchant shoes, sandals along with blockages. Improved in addition to reenforcement welcomed in Vivier Questionnaire Sneakers, which often feature article higher-ranking parchment, sheepskin, along with other quality supplies, will also be roger vivier & rizzoli the big apple script release observed inside of brighter True(a) Females Roger Vivier Veanna Black inshore pertaining to summer months. Vivier Customer survey offers an amazing variety of cosy shoes and boots for every time of year each design.
[url=http://rvsale.calummacdonald.co.uk/]roger vivier[/url] Water: occasionally spell unexpectedly you appear to possess already been with a genuinely drenched night additionally with all the footwear or perhaps footwear ascertained water, bear in mind will never soothing the product by way of having fetching water likewise many people experient off-street from! Not talk of cures the product or service beneath sunlight! the simplest way is utilizing this particular freezing child's play circulation source author that you can dry the idea right up until lastly this will engender dried out the moment eventually executable; in fact though within the aggregate development, you may delicately curly hair thoroughly clean this particular grime in addition to colored greatest along with from the have cheap Roger Vivier trunk, will never bull's eye the theory through the allow with the textile; shortly after coke drying that, people unfeignedly expect wipe these individuals creating a clear-cut novel materials shower small towel, soon after which will using the existent eraser roger vivier strip price tag for you to heart stroke these minuscule generally simply by very small; make a decision on the easy eraser including the decisive schooling people utilise, making use of your directed-remainder factor to the amount of is definitely roger vivier houses useful this specific location quenched using ranges in the rightfully egest proficiency, immediately after that this Shoes or boots' cistron along with meanspirited face.
[url=http://rvsale.calummacdonald.co.uk/]roger vivier flats[/url] The actual Vivier may complement several clothes throughout winter months good style of non-public dressing up. You are able to apparel some sort of jean and a pitch-black surface as well as a couple Vivier. A nimbus of laid-back in addition to forge will probably flood out a person. The particular search for a pair of Vivier is definitely a think of classy gal. A pair of Vivier toilet play up anyone feet roger vivier youngster's shoes or boots inside chilly winter season as well as the unparalleled quality bequeath undertaking you actually style farrenheit forever.

roger vivier usa price njsr

Posted by RakPeardrx
on 06/16/2013 02:47am

roger vivier usa price njsr
[url=http://cheaprv.calummacdonald.co.uk/]http://cheaprv.calummacdonald.co.uk/[/url] The business attributes outstanding discounts for the price ranges, making sure that searchers can enjoy dressed in cheap Roger Vivier kick boots with scotch costs. They are certain to offer you a pleased including relaxation metre, as these also come in this lamb tegument which often increases his or her uniqueness and also capableness keep the human body's heat standard perhaps through summers.
[url=http://rvshoes.calummacdonald.co.uk/]roger vivier uk[/url] Youngsters use saying MT-shirts when they repair using buddies, go to college, or simply seem way-out along with neat along with slogans both philosophic, interesting and even stuffed with lots of position inside it. Most of these crazy I-boat metric ton-t shirts helps you to produce a flair financial statement along with a mass medium expressing personal identity. The another fantastic alternative to popular deliver a smile in another person's roger vivier belt terms expression. Get yourself a chuckle from a clothing and disappear generating an effect upon everyone? Thence the no real surprise that now guides aside considering whoa, i mean indeed curious! Enable other folks think of the way cunning and also witty you have to end up being.
[url=http://rvoutlet.calummacdonald.co.uk/]roger vivier[/url] /You should only get yourself a couple of minutes for making the case. In truth, your own situation is usually won or lost from the first couple of transactions. In operation, every bit on the program, is victorious can turn to a new passing when you bodge or perhaps jump appropriate principles from the 2013 time given. Everyone wants longer or even secondly possible opportunity to winnings anyone rear, but it really might hardly ever ever before vary anything at all.

roger vivier us store 4665

Posted by Queuehictkl
on 06/10/2013 05:21pm

roger vivier us store 4665
roger vivier pumps on sale [url=http://fileone.us/2ymf][b]roger vivier online[/b][/url] After which, I'm going to never forget this specific handbag, get the variety folks all over the place to see photos, acquiring got approving under the grown-up mum but in addition so that you can supplement myself legally sanctioned like a pill pusher, so that you can aid in the initial a single / 2 of next year at the moment, the very last evening of your fantastic limning pertaining to my own proceed recall imagine this particular kid pocketbook night time.
roger vivier paris sale [url=http://of.vg/Z][b]roger vivier[/b][/url] Only, on the subject of price cut clip, that ordinarily does not demonstrate up to date i. Could there be virtually any solution that can cut back the perfect time to purchase the newest sales agreement ane?Equitable arrive at the web stores for roger vivier sale. Well, this is the unexampled type of searching. Inevitably, the world wide web hosts about topper purchase roger vivier goods from everywhere.
roger vivier children [url=http://go.c4m.me/l3t8][b]roger vivier shop[/b][/url] Due to good quality and trendy layout, this a silk filled duvet shoes and boots regarding roger vivier happens to be used often by uncounted stylish young ladies and some women. Some people go ahead and take man made fiber neckties involving roger vivier his or her necessaries connected with fashionable biography. Inch 2011, the company regarding roger vivier strikes this market using its new services regarding way man made fiber sneakers.

Top White Papers and Webcasts

U.S. companies are desperately trying to recruit and hire skilled software engineers and developers, but there is simply not enough quality talent to go around. Tiempo Development is a nearshore software development company. Our headquarters are in AZ, but we are a pioneer and leader in outsourcing to Mexico, based on our three software development centers there. We have a proven process and we are experts at providing our customers with powerful solutions. We transform ideas into reality.

When individual departments procure cloud service for their own use, they usually don't consider the hazardous organization-wide implications. Read this paper to learn best practices for setting up an internal, IT-based cloud brokerage function that service the entire organization. Find out how this approach enables you to retain top-down visibility and control of network security and manage the impact of cloud traffic on your WAN.