HomeC&C++WainTutorialsSamplesTip & TrickTools


Windows has GetDlgItemInt and SetDlgItemInt, but no functions for float, double, etc. Today I'll show how to make these.
The two functions will behave more or less like GetDlgItemInt and SetDlgItemInt, but they can be used with any type of number, int, float, double, etc.
The function to read a number:
template <typename T>
bool GetDlgItemNumber(HWND aHwndDlg, int aDlgItemId, T &aVal)
{
   char Buffer[256];
   if(!GetDlgItemText(aHwndDlg,
                      aDlgItemId,
                      Buffer,
                      sizeof(Buffer)))
      return false;
   std::stringstream ss(Buffer);
   return ss >> aVal;
}
This is a template function, meaning that it can be for any type T. First the text is read from the control, if that function fails we return false to indicate failure.
Then a stringstream is created, initialized with the text from the control, from this stringstream the value is extracted. If the conversion fails the function return false, true is returned otherwice.
The function for setting the number:
template <typename T>
bool SetDlgItemNumber(HWND aHwndDlg,
                      int aDlgItemId,
                      const T &aValue)
{
   std::stringstream ss;
   ss << aValue;
   return SetDlgItemText(aHwndDlg, aDlgItemId, ss.str().c_str());
}
Again a stringstream is used to do the conversion. Our function will return true if it managed to set the value, false otherwice.
To use the functions:
   double First;
   double Second;
   GetDlgItemNumber(hwndDlg, FirstEditId, First);
   GetDlgItemNumber(hwndDlg, SecondEditId, Second);
   double Result = First + Second;
   SetDlgItemNumber(hwndDlg, ResultEditId, Result);
Or if you want to add error checks:
   double First;
   double Second;
   if(!GetDlgItemNumber(hwndDlg, FirstEditId, First))
   {
      MessageBox(hwndDlg,
                 "Failed to convert first string",
                 "Calculator",
                 MB_OK);
   }
   else
   {
      if(!GetDlgItemNumber(hwndDlg, SecondEditId, Second))
      {
          MessageBox(hwndDlg,
                     "Failed to convert second string",
                     "Calculator",
                     MB_OK);
      }
      else
      {
         double Result = First + Second;
         if(!SetDlgItemNumber(hwndDlg, ResultEditId, Result))
         {
            MessageBox(hwndDlg,
                       "Failed to set result",
                       "Calculator",
                       MB_OK);
         }
      }
   }
A application which uses these functions can be found here.

As we prefer to use std::string when writing C++ programs, and not char arrays, a function to read a text from an dialog item, e.g. an edit-box, as a std::string could be handy, so let's make one:
std::string GetDlgItemString(HWND aHwnd, int aItemId)
{
   HWND HwndCtrl = GetDlgItem(aHwnd, aItemId);
   if(!HwndCtrl)
      return "";
   int Len = GetWindowTextLength(HwndCtrl) + 1;
   char *s = new char [Len];
   GetWindowText(HwndCtrl, s, Len);
   std::string Text(s);
   delete [] s;
   return Text;
}
We need to know the length of the text, to do that we must use GetWindowTextLength, which requres a HWND for the control; we get one from GetDlgItem.
When we know the length of the text we can allocate space for the text with new. Remember to add one char for the terminating 0.
Then we get the text with GetWindowText, we could use GetDlgItemText which would do the same thing.
Then a std::string is created with a copy of the text, and our temporary buffer is deleted.
And finally the std::string is returned.
To use it:
   std::string Text = GetDlgItemString(hwndDlg, IDC_MY_EDIT);