Listing 5



// *** border.h
using namespace win32::gui::draw;
// [1]
struct border : surface_<border> {
  // [6]
  border();
  static defs::string surface_type();

  void draw(HDC dc, int width_px, int height_px);

  // [3]
  // border color
  trivial_property<reflectable_color> color_;
  // the width of the border, in pixels
  trivial_property<int> width;
  // distance from the edges
  trivial_property<length> inside;
};

// *** border.cpp
// [6]
border::border() {
  width(1);
}

// [2]
defs::string border::surface_type() { return "border"; }



// [5]
void border::draw(HDC dc, int width_px, int height_px) {
  using namespace win32::gui;
  pen<owned> p( PS_SOLID, 1, (COLORREF)color_() );
  HGDIOBJ old_pen = ::SelectObject(dc, p);
  int inside_px = (int)as_unit(inside(), length::px, dc).val();
  for ( int idx = 0; idx < width(); ++idx) {
    win32::gui::rectangle r( 
      idx + inside_px, idx + inside_px, 
      width_px - idx - inside_px, height_px - idx - inside_px);
    draw_rect(dc, r);
  }
  ::SelectObject(dc, old_pen);
}

// *** register_props.cpp
using namespace win32::gui::draw::surface;
namespace {
  // [4]
  WIN32GUI_REGISTER_REFLECT("color", &border::color_);
  WIN32GUI_REGISTER_REFLECT("width", &border::width);
  WIN32GUI_REGISTER_REFLECT("inside", &border::inside);
}