[comp.windows.ms.programmer] Dialog Box Units to Device Coordinate Mapping

demillo@porter.geo.brown.edu (Rob DeMillo) (05/08/91)

A few days ago I responded to someone who wanted to 
know how to create a Microsoft-like toolbar. I told
them it was easy...since it was a modeless dialog box
with small push buttons.

The I made the mistake of offhandedly saying: "...to draw
on the buttons, you can just get the screen coordinates of
the button locations using a dialogbox coordinate system to
device coordinate system mapping function..."

The next day my mailbox was flooded with requests for this
mapping function...I guess not that many people have figured out
how to do it...(I work with coordinate transformations all the
time, so this just seemed like a simple thing to do.)

Anyway, as you may or may not be aware of, all of the locations
of objects within a dialog box is given in terms of a device-independent
coodinate space called a 'dialog box coordinate system.' This is so
that dialog boxes and dialog box items can be positioned with the
Resource Construction Set and still look the same on
CGA, EGA, VGA or whatever type of device you have. (Ever notice 
how much 'play' there is in a DBU (dialog box unit) within the
resource construction set? Its usually about a pixel or two...)

Anyhow, the following function will, given an (x,y) pair of
DB coordinates that you are interested in (say, the dialog box
coodinates for a button) and the dialog box handle, return
an (x,y) pair in the real "screen" coordinates. You can 
then pass those converted coordinates to a drawing routine and
then "draw" on the button, or put an icon there, or whatever. 

By using this function, you will be assured that (regardles of the
device you are on) you will draw on the correct spot on a dialog
box.

So, how do you get the coordinates of the object you wish to convert in
DB units? There are half a dozen ways to do this, from getting the
information in the Resource Construction Set to querying the
windows library for the position of a object. (I forget the call offhand,
but I can look it up tonight if you are interested...but, then again, 
so can you. ;) ) A good mdification for this function would
be to pass it tyour object's NAME rather than the
coordinates, and let the function do all the work.

Anyway, here you go...Have fun...


----------  cut here -----------------


/***********
 * Conversion functions
 ***********/
 
/*
 *    function:   DBU2Device
 *
 *    Description:
 *
 *    Converts Dialog Box x,y coordinates to real screen
 *    pixel values. Requires the dlg handle for input.
 */
DBU2Device(hDlg, x_dbu, y_dbu, x_device, y_device)
HWND  hDlg;
int   x_dbu,
      y_dbu;
int   *x_device,
      *y_device;
{
   RECT     passer;
      
   /* This does its work by getting the DB Base units, then
      loading up an imaginary 1 DBU large Rectangle to the
      MapDialogRect() function. The returned upper left
      corner *should* be the pixel value we want ---
      Let's watch the fun, shall we? */
      
   passer.left = x_dbu;
   passer.top = y_dbu;
   passer.right = x_dbu+1;
   passer.bottom = y_dbu+1;
   
   MapDialogRect(hDlg, &passer);
   
   /* Should have them. Send them back */
   *x_device = passer.left;
   *y_device = passer.top;
   
   return ;

}



 - Rob DeMillo			     | Internet: demillo@juliet.ll.mit.edu
   Mass Inst of Tech/Lincoln Lab     | Also:     demillo@porter.geo.brown.edu
   Weather Sensing Project-Group 43  | Reality:  401-273-0804 (home)
"I say you *are* the Messiah, Lord! And I ought to know, I've followed a few!"