Adding Behavior to Classes, Part II - Resizing Dialogs and Property Pages

However, it is not entirely good news.

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.

File "XMessageMapsForTemplates.h":

#ifndef _XMESSAGEMAPSFORTEMPLATES_
#define _XMESSAGEMAPSFORTEMPLATES_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifdef _AFXDLL
#define DECLARE_MESSAGE_MAP_FOR_TEMPLATE() \
private: \
 static /*const*/ AFX_MSGMAP_ENTRY _messageEntries[]; \
protected: \
 static AFX_DATA /*const*/ AFX_MSGMAP messageMap; \
 static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); \
 virtual const AFX_MSGMAP* GetMessageMap() const; \

#else
#define DECLARE_MESSAGE_MAP_FOR_TEMPLATE() \
private: \
 static /*const*/ AFX_MSGMAP_ENTRY _messageEntries[]; \
protected: \
 static AFX_DATA /*const*/ AFX_MSGMAP messageMap; \
 virtual const AFX_MSGMAP* GetMessageMap() const; \

#endif

#ifdef _AFXDLL
#define BEGIN_MESSAGE_MAP_FOR_TEMPLATE(theClass, baseClass) \
 template <class baseClass> \
  const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() \
  { return &baseClass::messageMap; } \
 template <class baseClass> \
  const AFX_MSGMAP* theClass::GetMessageMap() const \
  { return &theClass::messageMap; } \
 template <class baseClass> \
  AFX_COMDAT AFX_DATADEF /*const*/ AFX_MSGMAP \
  theClass::messageMap = \
  { &theClass::_GetBaseMessageMap, \
  &theClass::_messageEntries[0] }; \
 template <class baseClass> \ 
  AFX_COMDAT /*const*/ AFX_MSGMAP_ENTRY \
  theClass::_messageEntries[] = \
  { \
#else
#define BEGIN_MESSAGE_MAP_FOR_TEMPLATE(theClass, baseClass) \
 template <class baseClass> \
  const AFX_MSGMAP* theClass::GetMessageMap() const \
  { return &theClass::messageMap; } \
 template <class baseClass> \
  AFX_COMDAT AFX_DATADEF /*const*/ AFX_MSGMAP \
  theClass::messageMap = \
  { &baseClass::messageMap, &theClass::_messageEntries[0] }; \
 template <class baseClass> \
  AFX_COMDAT /*const*/ AFX_MSGMAP_ENTRY \
  theClass::_messageEntries[] = \
  { \
#endif
#define END_MESSAGE_MAP_FOR_TEMPLATE() END_MESSAGE_MAP()

#endif
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:
template <class TBASE> class TMyClass : public TBASE {
 ...
 DECLARE_MESSAGE_MAP_FOR_TEMPLATE()
};

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.

The corresponding C++ code looks like this:

template <class TWND> // TWND will be derived from CWND
class TMyClass : public TWND, public CMyClass {
...
};

class CMyClass {
...
private:
 CWnd* m_pWnd;
};

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.

File "XWndMultipleInheritance.h":

// XWndMultipleInheritance.h : header file
//

#ifndef _XWNDMULTIPLEINHERITANCE_
#define _XWNDMULTIPLEINHERITANCE_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CXWndMultipleInheritance {
 // Construction
public:
 CXWndMultipleInheritance(CWnd* pWnd) : m_pWnd(pWnd) {}
 // Casting operators etc
public:
 operator CWnd&() { return *m_pWnd; }
 operator const CWnd&() const { return *m_pWnd; }
 operator CWnd*() { return m_pWnd; }
 operator const CWnd*() const { return m_pWnd; }
 CWnd* operator->() { return m_pWnd; }
 const CWnd* operator->() const { return m_pWnd; }

// Encapsulate some common calls (add to this later if required)
public:
 LRESULT CWnd_SendMessage( UINT message, 
                           WPARAM wParam = 0, 
                           LPARAM lParam = 0 ) {
  return (*this)->SendMessage(message,wParam,lParam);
 }
 LRESULT CWnd_PostMessage( UINT message, 
                           WPARAM wParam = 0, 
                           LPARAM lParam = 0 ) {
  return (*this)->PostMessage(message,wParam,lParam);
 }
 HWND CWnd_GetSafeHwnd() const {
  return (*this)->GetSafeHwnd();
 }
 void CWnd_ScreenToClient(LPPOINT lpPoint) const {
  (*this)->ScreenToClient(lpPoint);
 }
 void CWnd_ScreenToClient(LPRECT lpRect) const {
  (*this)->ScreenToClient(lpRect);
 }
 void CWnd_ClientToScreen(LPPOINT lpPoint) const {
  (*this)->ClientToScreen(lpPoint);
 }
 void CWnd_ClientToScreen(LPRECT lpRect) const {
  (*this)->ClientToScreen(lpRect);
 }
 // the pointer to the actual window
private:
 CWnd* m_pWnd;
};

#endif

As you can see, the pointer is set up in the constructor. We gain access to it via the casting operators. I also added some shortcuts for some commonly used functions.

The Template Class

With that out of the way, let's start fleshing out the template class.

I find the easiest way to write a template like this is to use ClassWizard to generate a new MFC-derived class, and then hand-edit it into a proper template class afterwards. These are the steps:

  1. Use ClassWizard to create a new MFC class called "TXResizable" and to derive it from a generic CWnd.
  2. Change the class declaration to be a template (with multiple-inheritance as described above)
  3. Move the body of the generated ".cpp" file near the end of the ".h" file
  4. Make all the functions inline.
  5. Fix the default constructor so that it correctly initializes both base classes.
  6. Add a #pragma to prevent VC from giving warnings about using "this" in the base member initializer list.
  7. Add #include "XMessageMapsForTemplates.h" and change the message map declarations and definitions to use your template-friendly macros.
  8. Delete the ".clw" and the now-unused ".cpp" file.

I end up with a class that looks consistent with MFC and ClassWizard-generated code. And consistency is a wonderful thing. The result of all that tweaking is the following ".h" file:

File: "TXREsizable.h":

#ifndef _TXRESIZABLE_H_
#define _TXRESIZABLE_H_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// TXResizable.h : header file
//

#include "XMessageMapsForTemplates.h"

// ========================================
// TXResizable window

template <class TDIALOGORPAGE>
class TXResizable : public TDIALOGORPAGE, public CXResizable {
// Construction
public:
 TXResizable();
    
// Attributes
public:
    
// Operations
public:
    
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(TXResizable)
//}}AFX_VIRTUAL

// Implementation
public:
 virtual ~TXResizable();
    
// Generated message map functions
protected:
//{{AFX_MSG(TXResizable)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP_FOR_TEMPLATE()
};

//==============================================
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional 
// declarations immediately before the previous 
// line.

//==============================================
// TXResizable

// 'this' : used in base member initializer list
#pragma warning (disable: 4355) 
TXResizable::TXResizable()
: TDIALOGORPAGE()
, CXResizable(this)
{
}
// 'this' : used in base member initializer list
#pragma warning (default: 4355) 

TXResizable::~TXResizable()
{
}


BEGIN_MESSAGE_MAP_FOR_TEMPLATE(TXResizable<TDIALOGORPAGE>, 
                               TDIALOGORPAGE)
//{{AFX_MSG_MAP(TXResizable)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


//==============================================
// TXResizable message handlers

#endif

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:

void TXResizable::OnSize(UINT nType, int cx, int cy) 
{
 C???::OnSize(nType, cx, cy);
 // TODO: Add your message handler code here
}

Because ClassWizard cannot determine what the base class is, it just uses "C???". This is good because it forces me us to correct the code. Again, compilation errors are a good thing.

I then hand-edit the above code to look like this:

template <class TDIALOGORPAGE>
void TXResizable<TDIALOGORPAGE>::OnSize(UINT nType, int cx, int cy) 
{
 TDIALOGORPAGE::OnSize(nType, cx, cy);
 // TODO: Add your message handler code here
}

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.

enum EResizeFlags {
 RESIZE_LEFT_LFIX = 00000,

 RESIZE_LEFT_LPROP = 00001,

 RESIZE_LEFT_RPROP = 00002,

 RESIZE_LEFT_CPROP = RESIZE_LEFT_LPROP
                   | RESIZE_LEFT_RPROP,

 RESIZE_LEFT_RFIX = 00004,

 RESIZE_LEFT_FLAGS = RESIZE_LEFT_LPROP
                   | RESIZE_LEFT_RPROP
                   | RESIZE_LEFT_RFIX,
... etc for other coordinates and useful combinations 
};
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.

void CXResizable::ResizeControlUsingFlags(UINT id,CWnd* pControl,
                                          CRect& rcControl, 
                                          const CSize& szNow, 
                                          const CSize& szWas, 
                                          const CSize& szIni, 
                                          const CSize& szDelta) {
 UINT nFlags = GetResizeFlags(id,
                              pControl,
                              rcControl, 
                              szNow,
                              szWas,
                              szIni,
                              szDelta);
 if (nFlags != RESIZE_LFIX) {
  {
   int l = rcControl.left;
   int r = rcControl.right;
   int c = (l+r+1)/2;
   int dlprop = ::MulDiv3(l,szNow.cx,szWas.cx,szIni.cx)-l;
   int drprop = ::MulDiv3(r,szNow.cx,szWas.cx,szIni.cx)-r;
   int dcprop = ::MulDiv3(c,szNow.cx,szWas.cx,szIni.cx)-c;
   int dfull = szDelta.cx;
  
   switch (nFlags & RESIZE_LEFT_FLAGS) {
    case RESIZE_LEFT_LFIX:
    break;
  
    case RESIZE_LEFT_LPROP:
     rcControl.left += dlprop;
    break;
  
    case RESIZE_LEFT_RPROP:
     rcControl.left += drprop;
    break;
  
    case RESIZE_LEFT_CPROP:
     rcControl.left += dcprop;
    break;
  
    case RESIZE_LEFT_RFIX:
     rcControl.left += dfull;
    break;
   } 

   switch (nFlags & RESIZE_RIGHT_FLAGS) {
    case RESIZE_RIGHT_LFIX:
    break;
  
    case RESIZE_RIGHT_LPROP:
     rcControl.right += dlprop;
    break;
  
    case RESIZE_RIGHT_RPROP:
     rcControl.right += drprop;
    break;
  
    case RESIZE_RIGHT_CPROP:
     rcControl.right += dcprop;
    break;
 
    case RESIZE_RIGHT_RFIX:
     rcControl.right += dfull;
    break;
   }
  }
  {
   int t = rcControl.top;
   int b = rcControl.bottom;
   int c = (t+b+1)/2;
   int dtprop = ::MulDiv3(t,szNow.cy,szWas.cy,szIni.cy)-t;
   int dbprop = ::MulDiv3(b,szNow.cy,szWas.cy,szIni.cy)-b;
   int dcprop = ::MulDiv3(c,szNow.cy,szWas.cy,szIni.cy)-c;
   int dfull = szDelta.cy;

   switch (nFlags & RESIZE_TOP_FLAGS) {
    case RESIZE_TOP_TFIX:
    break;
   
    case RESIZE_TOP_TPROP:
     rcControl.top += dtprop;
    break;
   
    case RESIZE_TOP_BPROP:
     rcControl.top += dbprop;
    break;
   
    case RESIZE_TOP_CPROP:
     rcControl.top += dcprop;
    break;
   
    case RESIZE_TOP_BFIX:
     rcControl.top += dfull;
    break;
   }

   switch (nFlags & RESIZE_BOTTOM_FLAGS) {
    case RESIZE_BOTTOM_TFIX:
    break;
 
    case RESIZE_BOTTOM_TPROP:
     rcControl.bottom += dtprop;
    break;
 
    case RESIZE_BOTTOM_BPROP:
     rcControl.bottom += dbprop;
    break;
 
    case RESIZE_BOTTOM_CPROP:
     rcControl.bottom += dcprop;
    break;
 
    case RESIZE_BOTTOM_BFIX:
     rcControl.bottom += dfull;
    break;
   }
  }
 }
}

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:
typedef TXResizable<CDialog> CXResizableDialog;
typedef TXResizable<CPropertyPage> CXResizablePropertyPage;

To use these classes with your own application, you will need to change the dialog resources and select a border style of Resizing from the Style tab of the Dialog Properties.

To see any real resizing of controls, provide your own GetResizeFlags() function that says how to resize each control.

The sample application shows some simple resizing for both the main application and the about box.

Here is what the application looks like when you first start it...

But if you resize it, it looks like this...

Hmmm ... I wonder if TXResizable will work with a CFormView?



Downloads

Comments

  • Chaque ghd pink aura un code de suivi unique qui peut être vérifié en suivant les instructions de la boîte

    Posted by temafx822 on 07/16/2013 05:58am

    Il a toutes les fonctionnalités dont vous avez besoin et offre un bel éclat rempli et les cheveux doux et soyeux avec un finish.Tangen avoir nano-revêtement qui protège les cheveux contre les dommages de la chaleur et des manches longues et minces disques minces (120 x 24 mm), qui est également verrouillable . Il est équipé de la fonction ionique, une fonction qui émet des ions négatifs qui empêchent la formation d'électricité statique pendant que vous section. Fonction Ionic ferme la tige du cheveu et offre une lisse les cheveux avec plus d'éclat. ! Avec une température maximale de 230 degrés s'adapte à tous les types de cheveux et longueurs et réchauffe la température de travail en seulement 20 secondes D'autre part, il y aura un nombre égal de femmes qui ont blessé des anneaux et des produits de beauté ces GHD peut atteindre n'importe quel look; afin femme aux cheveux bouclés peut être heureux avec elle dirigée cheveux raides femme de cheveux raides peuvent prendre du plaisir dans ses cheveux bouclés. [url=http://ghdpascherfer.hpage.com/]ghd lisseur prix[/url] La meilleure chose à faire lorsque vous essayez de trouver défrisants bon marché est d'examiner la véritable valeur de n'importe quelle marque. Si vous allez à débourser plus de 100 £ pour quelqu'un, assurez-vous que vous obtenez votre argent vaut. Lire les commentaires des consommateurs, car ce sont les commentaires les plus honnêtes que vous obtiendrez dans l'industrie. Cela vous aidera à prendre la bonne décision lorsque vous êtes à la recherche pour les cheveux rettetang.Selvfølgelig pas cher est rose ghd n'est pas seulement une norme de tourbière styler ghd. C'est un ghd qui a été conçu pour recueillir des fonds pour des organisations caritatives du cancer du sein. En effet, un tel succès a été redresseurs rose que selon GHD il a abouti à 1 million de livres étant donné. Il ya aussi un grand succès auprès des célébrités comme Jennifer Aniston et Victoria Beckham. [url=http://ghdpascherfer.tripod.com/]lisseur ghd styler[/url] La chaleur est plus facile Gjennom peu cheveux épais enn. Par conséquent, le Satin Hair 7 Colour tige droite un réglage de chaleur intuitive qui laisse deg avancer sinn calme température banquets précise le type de cheveux (peu, les cheveux épais normal). Et même si vous Bruker bouton d'alimentation une jolie G. uregjerlige tresses, alors vous ne serez pas utsette ditt de cheveux à des températures supérieures à 200 ° C. Obtenez d'excellents résultats de coiffage danger uten des températures Hoye et nouvelle la belle hårfargen votre IMOT lenger.Tvert: ils empêchent fuktighetstap de style en y infligent ditt de cheveux satengioner unique! Ces ladde négatif ionène célébrations segment à la chevelure ladde positif ditt et reduserer sec, krusete cheveux et tiltrekker fuktighetspartikler de Lufta et leur envoyer votre le Trenger de cheveux le plus.

    Reply
  • tywhecept http://stateofbeing.org/mk.html

    Posted by Culseboubtelo on 07/15/2013 03:40am

    blossomsandaccents.com/mk.html www.americanconcern.com/cl.html ravenadventures.com/clsale.html

    Reply
  • mishapes zdbsh p

    Posted by BicchacheNogBaw on 07/11/2013 09:54pm

    raffle ticket template suspiciously similar substitute keypunch ability test louis vuitton black belt price Louis Vuitton Outlet none of them is purchased immediately and / or free of crash. Linyekula choreographed electronic evidence not to for a big recording studio, employing the living room area of your hired residential when devices also figure welcomed.

    Reply
  • 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..

    Reply
  • 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.

    Reply
  • 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.

    Reply
  • 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.

    Reply
  • 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.

    Reply
  • supporting characters

    Posted by spellura on 05/30/2013 10:28pm

    louis vuitton outlet cincinnatihttp://southnettradeaust.com#lv wallet for men price malaysia louis vuitton paris watch incredible hulk encourage yourself virgin mobile phones astray seventeenth century

    Reply
  • Give den bedste ghd glattejern, professionel personlig pleje i Danmark

    Posted by cheneason on 05/30/2013 08:13am

    [url=http://www.beatsbydrebaratos.webgarden.com/]beats by dr dre baratos[/url] Dette skyldes ofte, at din styling-værktøjer, og nu til Barber Shop er den værste valg, fordi nu er du nødt til at line op, hvis [url=http://www.beats-by-dre-2013.webs.com/]auriculares beats baratos[/url] Så længe krøllet hår hår glatning jern vil være typisk anvendes korrekt anvendelse af de specifikke instrukser dem faktisk er beskyttet at skabe brug af. Simpelthen fordi alles vidner der er en fremragende fuld at kunne for at kunne noget ud over den grund er det virkelig er ekstremt identisk med dit hår straightner alligevel passet korrekt og derefter en mere for en mere tidsramme tidsramme. Slip af med hurtigt lige efter hver og hver og beskæftiger også ofte være bevidst ikke rigtig definitivt inddrage fremdrift af el-ledninger rundt den nøjagtige hår straightner med hinanden har at sikre, at kost regime metode er faktisk skylles opnå en fuldbyrdende en individuel krøllet hår i form af metal meget forbedret ordentlig snart efter hver og også hver design tidsramme. [url=http://www.beatsbydrdrebaratos.weebly.com/]beats by dr dre baratos[/url] Den mest kendte er ghd IV Salon Styler som bliver brugt verden over på blandt andet modeshows og catwalk. Fordelen ved en IV Salon Styler er de brede plader. Det betyder at man kan glatte større områder af gangen og dermed bliver hurtigere færdige. Ulempen er at de brede plader f.eks. ikke er optimale til at style håret. Vi du både kunne glatte dit hår og samtidig bruge dit ghd glattejern til at lave f.eks. krøller, så er ghd IV styler et oplagt valg. Den kan det hele og glatter også dit hår perfekt. Men den er lidt langsommere end hvis man vælger den brede salon styler fra ghd. Endelig er der også den helt smalle ghd IV Mini Styler.

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Savvy enterprises are discovering that the cloud holds the power to transform IT processes and support business objectives. IT departments can use the cloud to redefine the continuum of development and operations—a process that is becoming known as DevOps. Download the Executive Brief DevOps: Why IT Operations Managers Should Care About the Cloud—prepared by Frost & Sullivan and sponsored by IBM—to learn how IBM SmartCloud Application services provide a robust platform that streamlines …

  • Live Event Date: August 14, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Data protection has long been considered "overhead" by many organizations in the past, many chalking it up to an insurance policy or an extended warranty you may never use. The realities of today make data protection a must-have, as we live in a data driven society. The digital assets we create, share, and collaborate with others on must be managed and protected for many purposes. Check out this upcoming eSeminar and join eVault Chief Technology …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds