A Dialog Units Conversion Class

(This was originally on the February 1998 issue of "Windows Developers' Journal", p 51. It appears below in it's original form (that is, as I submitted it; it was changed slightly on it's way to publication)

Frequently, when I create dialog boxes, I like giving the user the ability to resize them. This requires implementing the OnSize() function, and repositioning the various controls based on the new size. However, this gets a bit tricky, since the original locations of the controls (as reported in the dialog editor), is given in Dialog Units, while the new size is passed to OnSize in pixels, which is also what we need to passed to MoveWindow, to move the controls.

For example, you may know that a button wants to be 38 dialog units from the bottom, and 9 d.u. from the left. But, OnSize() only tells you how big the dialogs is, after the resize, in pixels. To get the position right, the values need to be scaled. The scaling factor themselves --- there are two different numbers for vertical and horizontal – come from Windows, but in a form which is cumbersome to use. The two values are stuffed into a single 32-bit DWORD, and they aren’t even the actual values, which would have required floating point to properly state, but multiples of them.

Putting all that together, the canonical way to scale the values would be:

DWORD	DlgUnits = GetDialogBaseUnits();
	int	top = cy - (38 * HIWORD(DlgUnits)) /8;
int	left 	= ( 9 * LOWORD(DlgUnits)) /4;

This seemed to me to be overly complicated and ugly, and whenever I am confronted with a programming problem that’s overly complicated and ugly, I immediately think – Hide it in a class. MSKDialogUnits is the result of that. (The prefix are the initials of my employer<, on whose time I wrote this) To use, just declare an object of than type, and use it’s member functions X() and Y() to do the actually scaling:

MSKDialogUnits du;
    int top = cy - du.Y(38);
    int left = du.X( 9);

	

The Code

    /////////////////////////////////////////////////////////////////////////
    DlgUnits.h: interface for the MSKDialogUnits class.
    /////////////////////////////////////////////////////////////////////////
    // Copyright (C) 1997 Memorial Sloan-Kettering Cancer Center.
    // All rights reserved. 
    // 
    ///////////////////////////////////////////////////////////////////////
    #if !defined(DLGUNITS_H_INCLUDED_)
    #define DLGUNITS_H_INCLUDED_
    class MSKDialogUnits 
    {
      private:
		WORD m_duXx4; // Dialog Units, on the X axis, times 4
		WORD m_duYx8; // Dialog Units, on the Y axis, times 8
      public:
		MSKDialogUnits() 
		{
            DWORD dw = GetDialogBaseUnits();
            m_duXx4 = LOWORD(dw);
            m_duYx8 = HIWORD(dw);
		}
        ~MSKDialogUnits() {};
        int X(int x) {return ((x * m_duXx4) /4);}
        int Y(int y) {return ((y * m_duYx8) /8);}

} #endif // !defined(DLGUNITS_H_INCLUDED__)

Copyright © 1997 James M. Curran.
All rights reserved.