' What got me wonder why dnoyon's code worked using
' CreateWindowEx and why using RapidQ's Create didn't
' work was that he created a TabControl with a "Style".
' So I searched the internet to see if it was possible
' to change the "Style" of a control (or component)
' during runtime.  I found one website saying it was
' possible... BUT only if the Form was not visible yet.
' (although I found another saying the Form can be visible)
' Anyways that same website said that changing the
' "Style" for a control (or component) doesn't work
' for ALL controls (or components).  I guess it's
' just one of those things you just have to try.
'
' I then proceeded to added an API function call to
' change the QTabControl's "Style" before the Form
' was shown.  And sure enough...
' I was able to add an icon to each tab. :D

$TypeCheck ON
$Include "RapidQ.inc"

' These could alternatively be ".ico" files
$Resource bmp1 As "glad.bmp"
$Resource bmp2 As "sad.bmp"

Type TC_ITEM
    mask As Integer
    lpReserved1 As Long
    lpReserved2 As Long
    pszText As Long
    cchTextMax As Integer
    iImage As Integer
    lParam As Long
End Type

Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
                 (hWnd As Long, nIndex As Long, dwNewLong As Long) As Long

Declare Function SendMessageAPI Lib "user32" Alias "SendMessageA" _
                 (hWnd As Long, Msg As Long, wParam As Long, lParam As Long) As Long

Declare Function GetParent Lib "user32" Alias "GetParent" (hWnd As Long) As Long

Declare Sub Form_OnClose
Declare Sub MenuClick(Sender As QMenuItem)
Declare Sub TabChanged

Const GWL_STYLE = (-16)

' These are the same 4 "Style" constants that dnoyon used.
Const WS_CHILD = &H40000000
Const WS_VISIBLE = &H10000000
Const WS_CLIPSIBLINGS = &H4000000
Const TCS_MULTILINE = &H200

Const WM_SETFONT = &H30

Const TCM_SETIMAGELIST = &H1303
Const TCM_GETITEMCOUNT = &H1304
Const TCM_DELETEITEM   = &H1308
Const TCM_GETCURFOCUS  = &H132F
Const TCM_SETCURFOCUS  = &H1330
Const TCM_SETITEMW     = &H133D

Const TCIF_IMAGE = &H2

DefLng lRet  ' Used to obtain various return values
DefLng hTabCtrl  ' Used to obtain the QTabControl's handle

' Define a variable as LONG, containing the necessary "Styles" needed to add icons to tabs
DefLng NewStyle = WS_CHILD Or WS_VISIBLE Or WS_CLIPSIBLINGS Or TCS_MULTILINE

Dim TCI As TC_ITEM

Dim TabLabelFont As QFont
    TabLabelFont.Name = "Tahoma"
    TabLabelFont.Size = 9
    TabLabelFont.Bold = True

' Created this font for testing.  It can not be used when you
' change the "Style" for QTabControl to the ones I use above.
Dim InactiveTabFont As QFont
    InactiveTabFont.Name = "Arial"
    InactiveTabFont.Color = RGB(255,255,255)
    InactiveTabFont.Bold = True

' You can use ".ico" files.
' You MUST set the width and height to match the image
' exactly otherwise you'll get an system error message.
Dim TabImageList As QImageList
    TabImageList.Width = 18
    TabImageList.Height = 18
    TabImageList.AddBMPhandle(bmp1, RGB(255,000,255))
    TabImageList.AddBMPhandle(bmp2, RGB(255,000,255))

Create Form As QForm
  'BorderStyle = bsSingle
  Caption = " TabControl Icon Demo"
  'DelBorderIcons(biMinimize)
  Width = 320
  Height = 240
  Center
  OnClose = Form_OnClose
  Create MainMenu As QMainMenu
    Create File As QMenuItem
      Caption = "&File"
      Create fNewTab As QMenuItem
        Caption = "New Tab"
        OnClick = MenuClick
      End Create
      Create fLine1 As QMenuItem
        Caption = "-"
      End Create
      Create fCloseTab As QMenuItem
        Caption = "Close Tab"
        OnClick = MenuClick
      End Create
      Create fLine2 As QMenuItem
        Caption = "-"
      End Create
      Create fExit As QMenuItem
        Caption = "Exit"
        OnClick = MenuClick
      End Create
    End Create
  End Create
  Create TabControl As QTabControl
    ' Below I'll comment out those properties that won't
    ' work after you've changed the "Style" to the ones I use in this demo.
    ' Notes: I'm not going to add the Button Style properties.
    '        Why? Because I have never EVER seen an application use them.
    '        I'm already adding the MultiLine "Style" above. So I skipped it.
    '        Using the Font property causes the TabLabelFont to be
    '        inherited by both the QEdit and QLabel.
    '        TabWidth and TabHeight can be set using an API call.
    Align = alClient  ' Makes resizing easier.
    Color = RGB(202,200,196)
    Cursor = crHandPoint
'    Font = TabLabelFont
    Hint = "TabControl with Icons"
'    HotTrack = True  ' You could do this by setting the "Style"
'    ScrollOpposite = True  ' You could do this by setting the "Style"
    ShowHint = True
'    TabInactiveFont = InactiveTabFont
'    TabInactiveColor = RGB(000,000,000)
'    TabPosition = 1  ' You could do this by setting the "Style"
'    VerticalTabs = True  ' You could do this by setting the "Style"
    AddTabs("Tab 1", "Tab 2")
    OnChange = TabChanged
    Create Edit As QEdit  'See Comment below regarding the GetParent
      AutoSize = False
      Align = alClient
      Hint = "QEdit is displayed when Tab 1 is selected"
      Text = "This is a QEdit in "+TabControl.Tab(0)
      ShowHint = True
      Visible = True
    End Create
    Create Label As QLabel
      AutoSize = False
      Align = alClient
      Cursor = crArrow
      Color = RGB(255,255,240)
      Hint = "QLabel is displayed when Tab 2 is selected"
      Caption = "This is a QLabel in "+TabControl.Tab(1)
      ShowHint = True
      Visible = False
    End Create
  End Create
  Create StatusBar As QStatusBar
    SizeGrip = False
    AddPanels ""
    Panel(0).Alignment = taCenter
  End Create
End Create

' Surprisingly not ALL components will return a value for GetParent.
' For instance... if you "only" had a QLabel defined above within
' the QTabControl... the value returned for GetParent is 0 (zero).
' So choose your component (or control) wisely for GetParent.
hTabCtrl = GetParent(Edit.Handle)

' Here's the trick to being able to add an icon to a tab.
' Prior to the form being displayed... change the "Style".
' The "Style" I use here... is the same one that dnoyon used.
SetWindowLong(hTabCtrl, GWL_STYLE, NewStyle)

' Since "Font" won't work properly... use an API function to set it.
SendMessageAPI(hTabCtrl, WM_SETFONT, TabLabelFont.Handle, 1)

' Attach an ImageList to the QTabControl for selecting an icon.
SendMessageAPI(hTabCtrl, TCM_SETIMAGELIST, 0, TabImageList.Handle)

' Now it's possible to add an icon to each tab
TCI.mask = TCIF_IMAGE
TCI.iImage = 0  ' Index into the ImageList
SendMessageAPI(hTabCtrl, TCM_SETITEMW, 0, TCI)

TCI.mask = TCIF_IMAGE
TCI.iImage = 1  ' Index into the ImageList
SendMessageAPI(hTabCtrl, TCM_SETITEMW, 1, TCI)

Form.ShowModal

Sub Form_OnClose
    Application.Terminate
End Sub

Sub MenuClick(Sender As QMenuItem)
    Select Case Sender.Handle

      Case fNewTab.Handle
        lRet = SendmessageAPI(hTabCtrl, TCM_GETITEMCOUNT, 0, 0)
        TabControl.AddTabs("TAB "+Str$(lRet+1))
        TCI.mask = TCIF_IMAGE
        TCI.iImage = lRet Mod 2  ' this will cause TCI.iImage to alternate between 0 and 1
        SendMessageAPI(hTabCtrl, TCM_SETITEMW, lRet, TCI)
        SendMessageAPI(hTabCtrl, TCM_SETCURFOCUS, lRet, 0)  ' Sets focus to the tab (which can't be done with the SetFocus function)

      Case fCloseTab.Handle
        lRet = SendmessageAPI(hTabCtrl, TCM_GETITEMCOUNT, 0, 0)
        ' The following If/Then conditions merely prevent the user
        ' from deleteing the first 2 tabs which display visible components.
        ' Any other tabs created... can be deleted.
        If lRet > 2 Then
          lRet = SendMessageAPI(hTabCtrl, TCM_GETCURFOCUS, 0, 0)  ' Shorter way of determining which tab is currently selected
          If lRet > 1 Then
            SendMessageAPI(hTabCtrl, TCM_DELETEITEM, lRet, 0)
            lRet = SendmessageAPI(hTabCtrl, TCM_GETITEMCOUNT, 0, 0)
            SendMessageAPI(hTabCtrl, TCM_SETCURFOCUS, lRet-1, 0)
          End If
        End If

      Case fExit.Handle
        Application.Terminate
    End Select
End Sub

Sub TabChanged
    lRet = SendmessageAPI(hTabCtrl, TCM_GETCURFOCUS, 0, 0)
    Edit.Visible = IIF(lRet = 0, True, False)
    Label.Visible = IIF(lRet = 1, True, False)
End Sub
