How Do I Create Controls on the Fly?

The basic creation code looks like this:

HWND CreateList (HWND hWndParent, RECT rcl)
{
   HWND hL;
   hL = CreateWindowEx (WS_EX_CLIENTEDGE,
                        "LISTBOX",
                        "",
                        WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP,
                        rcl.left, rcl.top,
                        rcl.right - rcl.left, rcl.bottom - rcl.top,
                        hWndParent,
                        (HMENU) NULL,
                        g_hInstance,
                        NULL);
   return (hL);
}

You can use the same code to create a tree, simply by substituting the macro WC_TREEVIEW where it says "LISTBOX" above, and adding the appropriate styles. The RECT is in client coordinates for the parent window. See the help for CreateWindowEx for details of all the parameters.

Incidentally, if you're doing this for a dialog, here's a neat way of doing it maintainably. You create an (invisible) frame in the dialog (called IDC_LIST_FRAME here), convert the coords of that from screen to client, and pass that as the rect into the above function. That way, if you need the listbox resizing, you can do it at design time without any tedious faffing about with coordinate trial and error:

void OnDrawTheDamnThing (HWND hDlg)
{
   RECT rScreen ;
   RECT rClient ;
   HWND hFrame ;
   POINT pTL;
   POINT pBR;

   hFrame = GetDlgItem (hDlg, IDC_LIST_FRAME);
   if (hFrame)
   {
      GetWindowRect  (hFrame, &rScreen);
      pTL.x = rScreen.left;
      pTL.y = rScreen.top;
      pBR.x = rScreen.right;
      pBR.y = rScreen.bottom;

      ScreenToClient (hDlg, &pTL);
      ScreenToClient (hDlg, &pBR);

      rClient.left   = pTL.x;
      rClient.top    = pTL.y;
      rClient.right  = pBR.x;
      rClient.bottom = pBR.y;

      CreateList (hDlg, rClient);
   }
   else
      OutputDebugString ("ERROR - Can't access list frame");
}

For those of you using MFC, consider replacing the POINT tomfoolery above with calls to the overloaded CWnd::ScreenToClient which takes a RECT.

Download