'''  Author: David Burkley
'''   Email: burkleyd@yahoo.com
'''    Date: Jan. 3rd, 2010

$Option EXPLICIT
$Include "RapidQ.inc"

''These observations "might" not be 100% correct.
'' If you find that a correction needs to be made...
'' please post a message in the Yahoo! RapidQ group
'' and I'll update this demo with the correction and
'' your name will be added as a co-author.
''
''Visible RapidQ components that DO have a handle property and DO have a Class name.
'' (NOTE: The Help files need to be updated with this information.)
'' QButton, QCheckBox, QComboBox, QEdit, QFileListBox, QForm, QGroupBox, QHeader,
'' QListBox, QListView, QOleContainer, QOutLine, QPanel, QRadioButton, QRichEdit,
'' QScrollBar, QScrollBox, QStatusBar, QStringGrid, QTrackBar, QTreeView
''
''Visible RapidQ components that DO have a handle property but DO NOT have a Class name.
'' QCanvas, QCoolBtn, QGlassFrame, QImage, QLabel, QMainMenu/QMenuItem
'' (NOTE: QCanvas handle is actually the handle to a Device Context)
''
''Visible RapidQ components that DO have a handle property and DO NOT have a Class name BUT handle is non-functional.
'' QOvalBtn
''
''Visible RapidQ components that DO NOT have a handle property but DO have a Class name
'' QDirTree, QTabControl
''
''Visible RapidQ components that DO NOT have a handle property and DO NOT have a Class name
'' (NOTE: Without a handle property and without a Class name... it's not possible to get/use a handle.)
'' QGauge, QSplitter

'The 2 user-defined functions below should work for retrieveing the handle of QDirTree and QTabControl.
' Their Class names are... "TDirTree" and "TTabControls"
'
'GetParentHandle Usage Example:
' DefLng hTabCtrl = GetParentHandle(Panel.Handle)
' If hTabCtrl <> 0 Then DoSomething
'  (NOTE: Some RapidQ components will not work as the parameter. e.g. QLabel)
'  (      The only way to find out is to do a test first.)
'
'GetChildHandle Usage Example:
' DefLng hDirTree = GetChildHandle(hTabCtrl, "TDirTree")
' If hDirTree <> 0 Then DoSomething
'  (NOTE: You can get the Class name of most RQ components by using... SpyInfo3A.)
'  (SpyInfo3A source code found at http://g.mykgb.com/?f=1298)
'  ("SpyInfo3A.exe" found at http://g.2myip.com/?f=2902)
'  (ALSO NOTE: The Class name parameter is case insensitive.)
'  (SPECIAL NOTE: There ARE exceptions. See comments above.)

' Start of get QDirTree or QTabControl handle requirements
Const GW_CHILD    = 5
Const GW_HWNDNEXT = 2

Declare Function GetWindow _
Lib "user32" Alias "GetWindow" _
(ByVal hWnd As Long, ByVal wCmd As Long) As Long

Declare Function GetClassName _
Lib "user32" Alias "GetClassNameA" _
(ByVal hWnd As Long, ByVal lpClassName As Long, _
 ByVal nMaxCount As Long) As Long

Declare Function GetParent _
Lib "user32" Alias "GetParent" _
(ByVal hWnd As Long) As Long

DefLng gWnd = 0 : DefStr gStr = ""

Function GetChildHandle(ByVal hParent As Long, ByVal sClass As String) As Long
    gWnd = GetWindow(hParent, GW_CHILD)
    Do
      gStr = Space$(255)
      GetClassName(gWnd, VarPtr(gStr), 255)
      If LCase$(Left$(gStr, Instr(gStr, Chr$(0))-1)) = LCase$(sClass) Then Exit Do
      gWnd = GetWindow(gWnd, GW_HWNDNEXT)
    Loop Until gWnd = 0
    Result = gWnd
End Function

Function GetParentHandle(ByVal hChild As Long) As Long
    Result = GetParent(hChild)
End Function
' End of get QDirTree or QTabControl handle requirements

Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
        (hWnd As Long, nIndex As Long, dwNewLong As Long) As Long

Declare Sub MainForm_OnShow
Declare Sub MainForm_OnClose

Declare Sub TabControl_OnChange

Const GWL_HWNDPARENT = (-8)
Const HWND_DESKTOP   = 0

'Global variables for the handles
' (they do not have to be global if they'll only be used locally)
DefLng hTabCtrl, hDirTree

Create MainForm As QForm
  DelBorderIcons(biMaximize)
  Caption  = " Get TabControl & DirTree handle"
  Width    = 320
  Height   = 240
  Left     = (Screen.Width\2)-(MainForm.Width\2)
  Top      = (Screen.Height\2)-(MainForm.Height\2)
  OnShow   = MainForm_OnShow
  OnClose  = MainForm_OnClose
  Create TabControl As QTabControl
    Align = alClient
    AddTabs("GetParentHandle Demo", "GetChildHandle Demo")
    OnChange = TabControl_OnChange
    Create Panel As QPanel
      Left       = TabControl.Left + 8
      Top        = TabControl.Top + 28
      Width      = TabControl.ClientWidth - 16
      Height     = TabControl.ClientHeight - 36
      Color      = RGB(255,255,255)
      BevelOuter = bvLowered
      BevelInner = bvLowered
      Visible    = True
    End Create
    Create DirTree As QDirTree
      Left    = TabControl.Left + 8
      Top     = TabControl.Top + 28
      Width   = TabControl.ClientWidth - 16
      Height  = TabControl.ClientHeight - 36
      InitialDir = Command$(0) - Application.Exename
      Visible = False
    End Create
  End Create
End Create

SetWindowLong(MainForm.Handle, GWL_HWNDPARENT, HWND_DESKTOP)
SetWindowLong(Application.Handle, GWL_HWNDPARENT, MainForm.Handle)

MainForm.ShowModal

Sub MainForm_OnShow
    hTabCtrl = GetParentHandle(Panel.Handle)
    If hTabCtrl <> 0 Then
      'Double ampersands are needed in order to display a single ampersand.
      Panel.Caption = "TabControl Handle = &&H" & Hex$(hTabCtrl)
      hDirTree = GetChildHandle(hTabCtrl, "TDirTree")
    End If
End Sub

Sub MainForm_OnClose
    Application.Terminate
End Sub

Sub TabControl_OnChange
    Select Case TabControl.TabIndex
      Case 0
        DirTree.Visible = False
        Panel.Visible = True
      Case 1
        Panel.Visible = False
        DirTree.Visible = True
        If hDirTree <> 0 Then
          'Double ampersands are needed in order to display a single ampersand.
          MessageDlg(Chr$(10) & "DirTree Handle = &&H" & Hex$(hDirTree), mtInformation, mbOk, 0)
        End If
    End Select
End Sub
