Custom Draw Toolbar

After WPF, spending time with NM_CUSTOMDRAW seemed like running somewhere, when one could catch a bus.  Someday, we may even do it’s like for pleasure.

My problem: I couldn’t get the separators to draw on my owner draw toolbar.  Apparently, the NM_CUSTOMDRAW doesn’t send a CDDS_ITEMPOSTPAINT for separators.  So, the way to do it is draw your separator over the top once drawing is complete.  Process the CDDS_POSTPAINT with something like this:

CDCHandle dc(__HDR.hdc);
CDC compatDC;
compatDC.CreateCompatibleDC(dc);
TBBUTTON button;
for (int i=0;i < ButtonCount();++i)
{
   Toolbar().GetButton(i,&button);
   if(button.fsStyle&BTNS_SEP)
   {
      CRect sepRc;
      Toolbar().GetRect(button.idCommand,&sepRc);
      extra::GDIBitmapObjectSelect leftBmpSel(compatDC,m_sep.Bmp());
      dc.BitBlt(sepRc.left,sepRc.top,m_sep.Size().cx,
         m_sep.Size().cy,compatDC,0,0,SRCCOPY);
   }
}
return CDRF_SKIPDEFAULT;

Don’t forget to return CDRF_NOTIFYPOSTPAINT in response to a CDDS_PREPAINT. (And NOTIFYITEMDRAW if you want to draw the items.)  Also, each separator must be added with a unique command Id otherwise GetRect will always just get the first.

Lazy Value

I wanted to replace a const int with a lazily evalueated int.  It had to be lazy evaluated as all that was needed to calculate it was not available when the class is instanciated but was available before the int was needed. I didn’t want to change the code that uses the int.  So, I made this class:

template <class T>
class CLazyValue
{
public:
   CLazyValue() : m_gotOffArse(false) {}
   operator T&() {return (m_gotOffArse ? m_value :
      (m_gotOffArse=true,GetOffArse(m_value),m_value));}
private:
   bool m_gotOffArse;
   T m_value;
   virtual void GetOffArse(T &val) = 0;
};

To use it, just derive and fill in GetOffArse.  Example:

class CTopOffset : public extra::CLazyValue
{
public:
   CTopOffset(CToolbarDrawerTabStyle &drawer) : m_drawer(drawer) {}
private:
   CToolbarDrawerTabStyle &m_drawer;
   virtual void GetOffArse(int &val);
}TAB_TOP_OFFSET;

Note the name of my const.  The int can be calculated from the m_drawer.  The great thing is, CLazyValue can be used whenever lazy evaluation is required.  I fear this may be rather obvious but it looks good.

Does the file exists

After about 16 years of writing C++ on Windows I’m sure there’s been many an occasion with the need to test if a file exists.  Today, I discovered a new way to check!

bool FileExists(const extra::tstring &file)
{
   OFSTRUCT of = {sizeof(of)};
   return (OpenFile(CT2CA(file.c_str()),&of,OF_EXIST)!=HFILE_ERROR);
}

Where an extra::tstring is declared such (part of my library of code):

typedef std::basic_string<TCHAR>tstring;

Apparently it closes the handle (see docs), but I still get nervous ignoring a handle like that.  The downside (handle anxieties aside) is that this OpenFile function, which I don’t recall ever using before, does not have a Unicode version (hence the need for CT2CA).

Nice! C# for_each

The C++ STL for_each is very useful.  This C# equivalent is even better: 


void Method()
{
  // assuming string[] strings;
  Action stringAction = delegate(string stringParam)
  {
  // do stuff with stringParam and whatever else available in Method()
  };
  Array.ForEach(strings,stringAction);
}

See other ForEaches too.

Glass Bead Look – Photoshop

Interesting: Glass Bead tutorial.  My attempt:

My go

Then try say a 300 x 75 strip.  Use brushes:

Brush 1: Solid #121212

Brush 2: Gradient#445282 Offset 0%, #29314D Offset 53%, #12131D Offset 95% 

Brush 3: Gradient #393F4D Offset 0%, #4A5367  Offset 33%, #5F6A87″ Offset 98%, #626C88″ Offset 100%

Use brush 1 to solid fill lowest layer.  On new layer, create a selection on bottom 28.57 % of image and use brush 2 from bottom to top.  On third layer, select the top 48.57 % of the image and use brush 3 from bottom to top.  Set opacity to 80% or slightly less.  You have a nice glass bead thing.

dark glass button

Try edit the colours to your desired shade by going to each one (bottom solid and each step on the gradients) and movng the second colour slider up and down on the photoshop colour picker.

Green thing

The next release of pmgconnect is bound to have glass bead somewhere.

SMTP Woes

Situation: Web server that sends out mail.  Configured with SMTP service for this purpose.

Problem 1: Some of emails being relayed by the local SMTP service were failing with “550 not local host gmail.com, not a gateway” (where gmail.com is the domain of the mail in this example).  This was domain specific.

Problem 2: Some relay SMTP servers were refusing to take mail with a “greylist” warning.  (They would work on subsequent tries).

Firstly, I made sure the “from” domain had valid ANAME Records.  No result. 

Then, I made sure the MX records of the “from” domain corresponded to the SMTP server.  My logic was that the destination SMTP server was checking the MX record for the domain and failing when none in the list corresponded with the IP address that was trying to send it mail.  No result.  But I did get incoming mail on my pmgconnect.com and pmgconnect.co.uk domains to route through my web server (downside I had to open up POP3 port in the firewall).

Then I investigated and found that the SMTP server was getting a different MX record for the domain (in this case gmail.com) than any this MX record lookup tool gave me.  As I was writing an email to the dedicated server host to tell them that something was fishy with their DNS lookup, I decided to check their site for the correct settings… 

Yes, all this because I had the wrong DNS settings on my network connection.  Probably in an email from the hosting company that I ignored.  Well, it all works now. 

I’ll watch the “greylist” problem but I suspect the MX record of the sending server may be responsible.  Not sure.  Could be because the emails being sent had no “from” as they were automaticlly forwarded error reports.  Not only will I be getting far less of them, but thier destination domain pmgconnect.com, is now the local server so they just sit and wait for my POP3 pickup.