Have you given the PB samples a good look lately? Just add a few lines and what seems like a contrived example becomes something useful.

Code:
'====================================================================
'
'   SyncList.bas example for PowerBASIC for Windows
'   Copyright (c) 2005 PowerBASIC, Inc.
'   All Rights Reserved.
'
'   Synchronize 2 ListBoxes and trap double-clicks.
'
'   Adapted for use as a TV channel guide by
'   Erich Schulman (KT4VOL/KTN4CA)
'====================================================================

#COMPILE EXE
#COMPILER PBWIN
#DIM ALL

%USEMACROS = 1
#INCLUDE "WIN32API.INC"

%IDC_LIST1  = 131
%IDC_LIST2  = 132


'====================================================================
FUNCTION PBMAIN () AS LONG
'--------------------------------------------------------------------
  ' Main program entrance
  '------------------------------------------------------------------
  LOCAL c AS LONG, hDlg AS DWORD
  LOCAL rcount AS LONG
  LOCAL sArray() AS STRING
  LOCAL ChNums(),ChNames() AS STRING

  OPEN "channels.tsv" FOR INPUT AS #1
  FILESCAN #1, RECORDS TO rcount
  DIM sArray(1 TO rcount) AS STRING
  LINE INPUT #1, sArray() TO rcount
  CLOSE #1
  DIM ChNums(1 TO rcount) AS STRING
  DIM ChNames(1 TO rcount) AS STRING
  

  DIALOG NEW 0, "Synchronized ListBoxes",,, 160, 155, _
             %WS_CAPTION OR %WS_SYSMENU, 0 TO hDlg

  '------------------------------------------------------------------
  FOR c = 1 TO rcount
      ChNums(c) = PARSE$(sArray(c),$TAB,1)
  NEXT c
  CONTROL ADD LISTBOX, hDlg, %IDC_LIST1, ChNums(), 5, 5, 150, 65, _
                       %WS_VSCROLL OR %WS_TABSTOP, %WS_EX_CLIENTEDGE 'Do not use %LBS_SORT here!

  '------------------------------------------------------------------
  FOR c = 1 TO rcount
      ChNames(c) = PARSE$(sArray(c),$TAB,2)
  NEXT c
  CONTROL ADD LISTBOX, hDlg, %IDC_LIST2, ChNames(), 5, 75, 150, 65, _
                       %WS_VSCROLL OR %WS_TABSTOP, %WS_EX_CLIENTEDGE 'Do not use %LBS_SORT here!

  '------------------------------------------------------------------
  CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Cancel", 105, 137, 50, 14

  '------------------------------------------------------------------
  DIALOG SHOW MODAL hDlg CALL DlgProc

END FUNCTION


'====================================================================
CALLBACK FUNCTION DlgProc() AS LONG
'--------------------------------------------------------------------
  ' Callback procedure for the main dialog
  '------------------------------------------------------------------
  LOCAL ln1, ln2 AS LONG, hList1, hList2 AS DWORD
  LOCAL sText1, sText2 AS STRING
  STATIC NoUpdate AS LONG 'for preventing eternal update loops

  SELECT CASE AS LONG CBMSG
  '------------------------------------------------------------------
  CASE %WM_CTLCOLORLISTBOX
      ' The %WM_CTLCOLORLISTBOX message is sent by the system when a ListBox
      ' is to be redrawn, so it can be used for monitoring visual changes.
      IF NoUpdate THEN EXIT FUNCTION  ' prevent eternal update loops
      NoUpdate = %TRUE

      CONTROL HANDLE CBHNDL, %IDC_LIST1 TO hList1
      CONTROL HANDLE CBHNDL, %IDC_LIST2 TO hList2
      IF CBLPARAM = hList2 THEN SWAP hList1, hList2      'hList is the one with focus..

      'SYNCHRONIZE SELECTED LINE (if needed, otherwise rem out)
      ln1 = SendMessage(hList1, %LB_GETCURSEL, 0, 0)     '<- get seleced line
      ln2 = SendMessage(hList2, %LB_GETCURSEL, 0, 0)     '<- get seleced line
      IF ln1 <> ln2 THEN
         CALL SendMessage(hList2, %LB_SETCURSEL, ln1, 0) '<- set selected line
      END IF

      'SYNCHRONIZE TOP LINE (if needed, otherwise rem out)
      ln1 = SendMessage(hList1, %LB_GETTOPINDEX, 0, 0)  '<- get first visible line in 1
      ln2 = SendMessage(hList2, %LB_GETTOPINDEX, 0, 0)  '<- get first visible line in 2
      IF ln1 <> ln2 THEN
         SendMessage hList2, %LB_SETTOPINDEX, ln1, 0    '<- amount to scroll textbox 1
      END IF

      NoUpdate = %FALSE

  '------------------------------------------------------------------
  CASE %WM_COMMAND                ' <- a control is calling
      SELECT CASE AS LONG CBCTL   ' <- look at control's id
      CASE %IDC_LIST1, %IDC_LIST2
          IF CBCTLMSG = %LBN_DBLCLK THEN  ' on double-click in any ListBox
              LISTBOX GET TEXT CBHNDL, %IDC_LIST1 TO sText1
              LISTBOX GET TEXT CBHNDL, %IDC_LIST2 TO sText2
              MSGBOX "List1 text:  " + sText1 + $CRLF + _
                     "List2 text:  " + sText2, _
                     %MB_TASKMODAL, "Selected item's text"
          END IF

      CASE %IDCANCEL              ' <- Cancel or Esc key was pressed
          IF CBCTLMSG = %BN_CLICKED THEN
              DIALOG END CBHNDL
          END IF
      END SELECT

  END SELECT

END FUNCTION
Of course, improvements can be made to this program. But the moral of this story is a little thought can make even these little samples come to life.
Attached Files