title: Add Controls To Specific Tab Page in TabControl in C++ Win32
body: <p>I want to add some controls to the tab page in tabcontrol but it seems that it will be added to all pages and there is not tab page in tabcontrol by default.</p>
  
  <p>I have read these links below but they did not help me and in some parts of them, confused me.</p>
  
  <p><a href="https://stackoverflow.com/questions/4701974/how-to-add-controls-to-a-tab-control">How to add controls to a Tab control</a></p>
  
  <p><a href="http://www.cplusplus.com/forum/windows/37161/" rel="nofollow">http://www.cplusplus.com/forum/windows/37161/</a></p>
  
  <p><a href="https://msdn.microsoft.com/en-us/library/bb760551.aspx" rel="nofollow">https://msdn.microsoft.com/en-us/library/bb760551.aspx</a></p>
  
  <p><a href="https://msdn.microsoft.com/en-us/library/hh298366.aspx" rel="nofollow">https://msdn.microsoft.com/en-us/library/hh298366.aspx</a></p>
  
  <p><a href="https://msdn.microsoft.com/en-us/library/ms645398.aspx" rel="nofollow">https://msdn.microsoft.com/en-us/library/ms645398.aspx</a></p>
  
  <p>Here is my code :</p>
  
  <p>[Code]:</p>
  
  <pre><code>#define ID_LBL 500              
  #define ID_BTN 501              
  #define ID_TBC 502              
  
  HWND hWnd;
  
  void InserTabItem(HWND handle, LPWSTR text, int id)
  {
  TCITEM tci = { 0 };
  tci.mask = TCIF_TEXT;
  tci.pszText = text;
  tci.cchTextMax = wcslen(text);
  SendMessage(handle, TCM_INSERTITEM, id, LPARAM(&amp;tci));
  }
  
  LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  {
  switch (Msg)
  {
  case WM_CREATE:
  {
      HWND button_handle = 0;
      HWND label_handle = 0;
      HWND tab_handle = 0;
      tab_handle = CreateWindowEx(WS_EX_CONTROLPARENT, WC_TABCONTROL, 0, WS_VISIBLE | WS_CHILD, 10, 10, 200, 150, hWnd, HMENU(ID_TBC), 0, 0);
      InserTabItem(tab_handle, L"page1", 0);
      InserTabItem(tab_handle, L"page2", 1);
      button_handle = CreateWindowEx(0, WC_BUTTON, L"test-button-page2", WS_VISIBLE | WS_CHILD, 10, 50, 150, 30, tab_handle, HMENU(ID_BTN), 0, 0);
      label_handle = CreateWindowEx(0, WC_STATIC, L"test-label-page1", WS_VISIBLE | WS_CHILD, 10, 100, 150, 30, tab_handle, HMENU(ID_LBL), 0, 0);
  }
  break;
  case WM_CLOSE:
      DestroyWindow(hWnd);
      break;
  case WM_DESTROY:
      PostQuitMessage(0);
      break;
  default:
      return DefWindowProc(hWnd, Msg, wParam, lParam);
      break;
  }
  
  return 0;
  }
  
  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreviewInstance, LPSTR lpcmdline, int ncmdshow)
  {
  WNDCLASSEX wndexcls;
  wndexcls.lpszClassName = L"win";
  wndexcls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  wndexcls.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  wndexcls.hCursor = LoadCursor(NULL, IDC_ARROW);
  wndexcls.hbrBackground = (HBRUSH)(COLOR_3DSHADOW + 1);
  wndexcls.lpszMenuName = NULL;
  wndexcls.style = NULL;
  wndexcls.hInstance = hInstance;
  wndexcls.cbSize = sizeof(WNDCLASSEX);
  wndexcls.cbClsExtra = 0;
  wndexcls.cbWndExtra = 0;
  wndexcls.lpfnWndProc = WndProc;
  RegisterClassEx(&amp;wndexcls);
  
  hWnd = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT, L"win", L"TestApp", WS_OVERLAPPEDWINDOW, 100, 100, 640, 380, 0, 0, hInstance, 0);
  ShowWindow(hWnd, ncmdshow);
  UpdateWindow(hWnd);
  
  
  
  MSG wnd_msg;
  while (GetMessage(&amp;wnd_msg, NULL, 0, 0)&gt;0)
  {
      TranslateMessage(&amp;wnd_msg);
      DispatchMessage(&amp;wnd_msg);
  }
  return (int)wnd_msg.wParam;
  </code></pre>
  
  <p>}</p>
  
  <p>I am looking for a safe and proper implementation.</p>
  
  <p>Thanks for any help</p>
  
  <p>========================================================</p>
  
  <p><b>[Update]:</b>   </p>
  
  <p>Thanks for comments but no answer in detail :(</p>
  
  <p>Although that is not the implementation I am looking for(NotDialogBased), But from the forth link I mentioned :</p>
  
  <p>How to Create a Tabbed Dialog Box :    </p>
  
  <p><a href="https://msdn.microsoft.com/en-us/library/hh298366.aspx" rel="nofollow">https://msdn.microsoft.com/en-us/library/hh298366.aspx</a></p>
  
  <p>Here is my code of that page :</p>
  
  <p>[resource.h]:</p>
  
  <pre><code>#define IDD_Page1                       101
  #define IDD_Page2                       102
  #define IDD_Page3                       103
  #define IDD_Main_Dialog                 104
  #define IDC_BTN_Page1                   1001
  #define IDC_BTN2_Page1                  1002
  #define IDC_BTN_Page2                   1013
  #define IDC_BTN_Page3                   1014
  </code></pre>
  
  <p>[Resource.rc]:</p>
  
  <pre><code>#include "resource.h"
  
  #define APSTUDIO_READONLY_SYMBOLS
  #include "winres.h"
  #undef APSTUDIO_READONLY_SYMBOLS
  #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
  LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
  
   //////////////////////////////////////////////////
   //
   // Dialog
    //
  
   IDD_Page1 DIALOGEX 0, 0, 313, 178
   STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD
   FONT 8, "MS Shell Dlg", 400, 0, 0x1
   BEGIN
   PUSHBUTTON      "Button2-Page1",IDC_BTN2_Page1,129,107,67,22
   PUSHBUTTON      "Button-Page1",IDC_BTN_Page1,127,77,67,22
   END
  
   IDD_Page2 DIALOGEX 0, 0, 309, 177
   STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD
   FONT 8, "MS Shell Dlg", 400, 0, 0x1
   BEGIN
   PUSHBUTTON      "Button-Page2",IDC_BTN_Page2,120,77,60,18
   END
  
   IDD_Page3 DIALOGEX 0, 0, 309, 177
   STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD
   FONT 8, "MS Shell Dlg", 400, 0, 0x1
   BEGIN
   PUSHBUTTON      "Button-Page3",IDC_BTN_Page3,120,73,64,25
   END
  
   IDD_Main_Dialog DIALOGEX 0, 0, 309, 177
   STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD
   FONT 8, "MS Shell Dlg", 400, 0, 0x1
   BEGIN
   END
  
  
  ////////////////////////////////////////////
  //
  // DESIGNINFO
   //
  
   #ifdef APSTUDIO_INVOKED
   GUIDELINES DESIGNINFO
   BEGIN
   IDD_Page1, DIALOG
   BEGIN
      LEFTMARGIN, 7
      RIGHTMARGIN, 306
      TOPMARGIN, 7
      BOTTOMMARGIN, 171
  END
  
  IDD_Page2, DIALOG
  BEGIN
      LEFTMARGIN, 7
      RIGHTMARGIN, 302
      TOPMARGIN, 7
      BOTTOMMARGIN, 170
  END
  
  IDD_Page3, DIALOG
  BEGIN
      LEFTMARGIN, 7
      RIGHTMARGIN, 302
      TOPMARGIN, 7
      BOTTOMMARGIN, 170
  END
  
  IDD_Main_Dialog, DIALOG
  BEGIN
      LEFTMARGIN, 7
      RIGHTMARGIN, 302
      TOPMARGIN, 7
      BOTTOMMARGIN, 170
  END
  END
  #endif    // APSTUDIO_INVOKED
  
  #endif    
  </code></pre>
  
  <p>[Main.cpp]:</p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;CommCtrl.h&gt;
  #include "resource.h"
  #pragma comment(lib, "ComCtl32.lib")
  #define C_PAGES 3 
  
  INT_PTR CALLBACK DialogProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  
  HWND Win_Handle;
  HWND Dailog_Handle;
  HINSTANCE hInstance_Win_Global;
  
  typedef struct {
  WORD      dlgVer;
  WORD      signature;
  DWORD     helpID;
  DWORD     exStyle;
  DWORD     style;
  WORD      cDlgItems;
  short     x;
  short     y;
  short     cx;
  short     cy;
  WORD      pointsize;
  WORD      weight;
  BYTE      italic;
  BYTE      charset;
  } DLGTEMPLATEEX;
  
  typedef struct tag_dlghdr {
  HWND hwndTab;       // tab control 
  HWND hwndDisplay;   // current child dialog box 
  RECT rcDisplay;     // display rectangle for the tab control 
  DLGTEMPLATEEX *apRes[C_PAGES];
  } DLGHDR;
  
  void InserTabItem(HWND handle, LPWSTR text, int id)
  {
  TCITEM tci = { 0 };
  tci.mask = TCIF_TEXT;
  tci.pszText = text;
  tci.cchTextMax = wcslen(text);
  SendMessage(handle, TCM_INSERTITEM, id, LPARAM(&amp;tci));
  }
  
  DLGTEMPLATEEX* DoLockDlgRes(LPCTSTR lpszResName)
  {
  HRSRC hrsrc = FindResource(NULL, lpszResName, RT_DIALOG);
  HGLOBAL hglb = LoadResource(hInstance_Win_Global, hrsrc);
  return (DLGTEMPLATEEX *)LockResource(hglb);
  }
  
  VOID WINAPI OnChildDialogInit(HWND hwndDlg)
  {
  HWND hwndParent = GetParent(hwndDlg);
  DLGHDR *pHdr = (DLGHDR *)GetWindowLong(
      hwndParent, GWL_USERDATA);
  SetWindowPos(hwndDlg, NULL, pHdr-&gt;rcDisplay.left,
      pHdr-&gt;rcDisplay.top,//-2,
      (pHdr-&gt;rcDisplay.right - pHdr-&gt;rcDisplay.left),
      (pHdr-&gt;rcDisplay.bottom - pHdr-&gt;rcDisplay.top),
      SWP_SHOWWINDOW);
  
  return;
  } 
  VOID OnSelChanged(HWND hwndDlg)
  {
  DLGHDR *pHdr = (DLGHDR *)GetWindowLong(hwndDlg, GWL_USERDATA);
  int iSel = TabCtrl_GetCurSel(pHdr-&gt;hwndTab);
  if (pHdr-&gt;hwndDisplay != NULL)
      DestroyWindow(pHdr-&gt;hwndDisplay);
  pHdr-&gt;hwndDisplay = CreateDialogIndirect(hInstance_Win_Global,
      (DLGTEMPLATE *)pHdr-&gt;apRes[iSel], hwndDlg,DialogProc);
  }
  HRESULT OnTabbedDialogInit(HWND hwndDlg)
  {
  INITCOMMONCONTROLSEX iccex;
  DWORD dwDlgBase = GetDialogBaseUnits();
  int cxMargin = LOWORD(dwDlgBase) / 4;
  int cyMargin = HIWORD(dwDlgBase) / 8;
  
  TCITEM tie;
  RECT rcTab;
  HWND hwndButton;
  RECT rcButton;
  int i;
  
  iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  iccex.dwICC = ICC_TAB_CLASSES;
  InitCommonControlsEx(&amp;iccex);
  
  DLGHDR *pHdr = (DLGHDR *)LocalAlloc(LPTR, sizeof(DLGHDR));
  SetWindowLong(hwndDlg, GWL_USERDATA, (LONG)pHdr);
  
  pHdr-&gt;hwndTab = CreateWindow(
      WC_TABCONTROL, L"",
      WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
      0, 0, 300, 200,
      hwndDlg, NULL, hInstance_Win_Global, NULL
      );
  if (pHdr-&gt;hwndTab == NULL)
  {
      return HRESULT_FROM_WIN32(GetLastError());
  }
  
  tie.mask = TCIF_TEXT | TCIF_IMAGE;
  tie.iImage = -1;
  tie.pszText = L"First";
  TabCtrl_InsertItem(pHdr-&gt;hwndTab, 0, &amp;tie);
  tie.pszText = L"Second";
  TabCtrl_InsertItem(pHdr-&gt;hwndTab, 1, &amp;tie);
  tie.pszText = L"Third";
  TabCtrl_InsertItem(pHdr-&gt;hwndTab, 2, &amp;tie);
  
  pHdr-&gt;apRes[0] = DoLockDlgRes(MAKEINTRESOURCE(IDD_Page1));
  pHdr-&gt;apRes[1] = DoLockDlgRes(MAKEINTRESOURCE(IDD_Page2));
  pHdr-&gt;apRes[2] = DoLockDlgRes(MAKEINTRESOURCE(IDD_Page3));
  
  SetRectEmpty(&amp;rcTab);
  for (i = 0; i &lt; C_PAGES; i++)
  {
      if (pHdr-&gt;apRes[i]-&gt;cx &gt; rcTab.right)
          rcTab.right = pHdr-&gt;apRes[i]-&gt;cx;
      if (pHdr-&gt;apRes[i]-&gt;cy &gt; rcTab.bottom)
          rcTab.bottom = pHdr-&gt;apRes[i]-&gt;cy;
  }
  
  MapDialogRect(hwndDlg, &amp;rcTab);
  
  TabCtrl_AdjustRect(pHdr-&gt;hwndTab, TRUE, &amp;rcTab);
  OffsetRect(&amp;rcTab, cxMargin - rcTab.left, cyMargin - rcTab.top);
  
  CopyRect(&amp;pHdr-&gt;rcDisplay, &amp;rcTab);
  TabCtrl_AdjustRect(pHdr-&gt;hwndTab, FALSE, &amp;pHdr-&gt;rcDisplay);
  
  SetWindowPos(pHdr-&gt;hwndTab, NULL, rcTab.left, rcTab.top,
      rcTab.right - rcTab.left, rcTab.bottom - rcTab.top,
      SWP_NOZORDER);
  
  hwndButton = GetDlgItem(hwndDlg, IDC_BTN_Page1);
  SetWindowPos(hwndButton, NULL,
      rcTab.left, rcTab.bottom + cyMargin, 0, 0,
      SWP_NOSIZE | SWP_NOZORDER);
  
  GetWindowRect(hwndButton, &amp;rcButton);
  rcButton.right -= rcButton.left;
  rcButton.bottom -= rcButton.top;
  
  hwndButton = GetDlgItem(hwndDlg, IDC_BTN2_Page1);
  SetWindowPos(hwndButton, NULL,
      rcTab.left + rcButton.right + cxMargin,
      rcTab.bottom + cyMargin, 0, 0,
      SWP_NOSIZE | SWP_NOZORDER);
  
  SetWindowPos(hwndDlg, NULL, 0, 0,
      rcTab.right + cyMargin + (2 * GetSystemMetrics(SM_CXDLGFRAME)),
      rcTab.bottom + rcButton.bottom + (2 * cyMargin)
      + (2 * GetSystemMetrics(SM_CYDLGFRAME))
      + GetSystemMetrics(SM_CYCAPTION),
      SWP_NOMOVE | SWP_NOZORDER);
  
  OnSelChanged(hwndDlg);
  
  return S_OK;
  }
  
  LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  {
  switch (Msg)
  {
  case WM_CREATE:
  {
      Dailog_Handle = CreateDialogParam(hInstance_Win_Global, MAKEINTRESOURCE(IDD_Main_Dialog), hWnd, DialogProc, 0);
      ShowWindow(Dailog_Handle, SW_SHOWDEFAULT);
      UpdateWindow(Dailog_Handle);
      SetWindowPos(Dailog_Handle, 0, 10, 10, 500, 300, SWP_NOZORDER);
  
  }
  break;
  case WM_CLOSE:
      DestroyWindow(hWnd);
      break;
  case WM_DESTROY:
      PostQuitMessage(0);
      break;
  default:
      return DefWindowProc(hWnd, Msg, wParam, lParam);
      break;
  }
  
  return 0;
  }
  INT_PTR CALLBACK DialogProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  {
  switch (Msg)
  {
  case WM_INITDIALOG:
  {
  
      OnTabbedDialogInit(hWnd);
      OnChildDialogInit(hWnd);
  
      return (INT_PTR)TRUE;
  }
      break;
  case WM_NOTIFY:
  {
      switch (((LPNMHDR)lParam)-&gt;code)
      {
      case TCN_SELCHANGE:
      {
          OnSelChanged(hWnd);
      }
      break;
      default:
          break;
      }
  
  }
  break;
  case WM_CLOSE:
      DestroyWindow(hWnd);
      break;
  case WM_DESTROY:
      PostQuitMessage(0);
      break;
  }
  return (INT_PTR)FALSE;
  }
  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreviewInstance, LPSTR lpcmdline, int ncmdshow)
    {
    WNDCLASSEX wndexcls;
    wndexcls.lpszClassName = L"win";
    wndexcls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndexcls.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wndexcls.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndexcls.hbrBackground = (HBRUSH)(COLOR_3DSHADOW + 1);
    wndexcls.lpszMenuName = NULL;
    wndexcls.style = NULL;
    wndexcls.hInstance = hInstance;
    wndexcls.cbSize = sizeof(WNDCLASSEX);
    wndexcls.cbClsExtra = 0;
    wndexcls.cbWndExtra = 0;
    wndexcls.lpfnWndProc = WndProc;
    RegisterClassEx(&amp;wndexcls);
  
   Win_Handle = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT, L"win", L"TestApp", WS_OVERLAPPEDWINDOW, 100, 100, 640, 380, 0, 0, hInstance, 0);
   hInstance_Win_Global = hInstance;
   ShowWindow(Win_Handle, SW_SHOWDEFAULT);
   UpdateWindow(Win_Handle);
  
  
  MSG wnd_msg;
  while (GetMessage(&amp;wnd_msg, NULL, 0, 0)&gt;0)
  {
      TranslateMessage(&amp;wnd_msg);
      DispatchMessage(&amp;wnd_msg);
  }
  return (int)wnd_msg.wParam;
  }
  </code></pre>
  
  <p>The Problem is that , after debugging , the application exites and does not show anything. if I comment the OnSelChanged(hWnd) and OnChildDialogInit(hWnd)
  the application starts normally and shows the tabcontrol but not the controls on the pages. it seems that the problem is here.</p>
  
  <p>the output log :   </p>
  
  <pre><code>  First-chance exception at 0x00BE1886 in testcppapp.exe: 0xC0000005: Access violation reading location 0x00000014.
   The program '[16220] testcppapp.exe' has exited with code 0 (0x0).
  </code></pre>
  
  <p>I have Read the link below about Access violation reading location:  </p>
  
  <p><a href="http://www.cplusplus.com/forum/general/17094/" rel="nofollow">http://www.cplusplus.com/forum/general/17094/</a>  </p>
  
  <p>But I can not fix the problem.</p>
  
  <p>Please Post your Answer and Explain about it , not just brief in comments !</p>
  
  <p>Thanks for any help.</p>