home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BUG 4
/
BUGCD1997_05.BIN
/
aplic
/
clip4win
/
clip4win.exe
/
C4W30E.HUF
/
SOURCE
/
LISTBOX.PRG
< prev
next >
Wrap
Text File
|
1995-01-13
|
14KB
|
547 lines
////////////////////////////
//
// Clip-4-Win listbox demo
//
// Copyright (C) 1992,1993,1994 Skelton Software, Kendal Cottage, Hillam, Leeds, UK.
// All Rights Reserved.
//
// Compile: listbox /n /w
// Link: /se:600 listbox,,,clip4win,clip4win.def
//
// NOTE: Look at achoice.prg for a sample dialog with a listbox.
//
// ALSO: See the code below for how to make a simple browser.
//
////////////////////////////
#ifndef LIB_ONLY
#define WIN_WANT_ALL // to get WM_SETREDRAW
#endif // LIB_ONLY
#define WIN_WANT_LBS
#define WIN_WANT_LB
#include "windows.ch"
#define MAKELPARAM(nLow, nHigh) ((nLow) + (nHigh) * 65536)
#ifndef LIB_ONLY
#define TAB chr(9)
#define CR chr(13)
#define ID_LBOX 1 // unique id (used for the listbox)
static hWnd, hInst, cText, hLBox, cAppName := "Clip-4-Win"
static bEvent := {|nEvent| nil} // current event handler
function main()
local hMenu, nEvent
hWnd = WinSetup(cAppName, "Clip-4-Win ListBox Demo", , , 550, 400, , , , ;
WS_OVERLAPPEDWINDOW + WS_CLIPCHILDREN)
hInst = _GetInstance()
hMenu = MenuSetup()
HideCaret(hWnd)
do while .t.
do while (nEvent := ChkEvent()) == EVENT_NONE
// some "background" processing could go here
enddo
eval(bEvent, nEvent) // give the event to the right handler
enddo
return 0
procedure DoAbout()
MessageBox( , "Written by John Skelton.", "Info", MB_OK)
return
procedure DoExit()
quit
return
// This one is non-modal, but you have to send/receive messages.
//
// It also shows how to use Tab Stops to make columns, which makes
// a simple browser. You put tabs between the items you want the
// listbox to align in columns. Remember to use LBS_USETABSTOPS.
procedure DoLBox()
local aList := ;
{ ;
"Record 1" + TAB + "Column 2" + TAB + "Column 3" + TAB + "Column 4",;
"Record 2" + TAB + "a ListBox" + TAB + "with columns" + TAB + "for you",;
"Record 3" + TAB + " " + TAB + " " + TAB + " ",;
"Record 4" + TAB + " " + TAB + " " + TAB + " ",;
"Record 5" + TAB + " " + TAB + " " + TAB + " ",;
"Record 6" + TAB + "A" + TAB + "Simple" + TAB + "Browser!",;
"Record 7" + TAB + " " + TAB + " " + TAB + " ",;
"Record 8" + TAB + " " + TAB + " " + TAB + " ",;
"Record 9" + TAB + " " + TAB + " " + TAB + " ",;
"Record 10" + TAB + " " + TAB + " " + TAB + " ",;
"Record 11" + TAB + " " + TAB + " " + TAB + " " ;
}
local aTabs := {0, 50, 100, 150} // the columns
if hLBox != nil
DestroyWindow(hLBox)
endif
hLBox = CreateWindow("listbox", ; // window class
"title", ; // caption for title bar
;// LBS_STANDARD would sort the items, as it includes LBS_SORT (see windows.ch)
;// LBS_NOTIFY means the parent is sent LBN_* messages as things happen
;// (a more complex version of this function would SKIP in a database and
;// alter the listbox contents)
LBS_USETABSTOPS + LBS_NOTIFY ;//
+ WS_VSCROLL + WS_BORDER ;//
+ WS_CHILD + WS_VISIBLE,; // window style
20, ; // x co-ordinate
20, ; // y co-ordinate
500, ; // width
150, ; // height
hWnd, ; // hWnd of parent
ID_LBOX, ; // id for child control to use
hInst) // our own app instance
// set up the tab stops (note: len(aTabs) == 3, so the last param is "int[3]")
SendMessage(hLBox, LB_SETTABSTOPS, len(aTabs), a2bin(aTabs, "int[" + str(len(aTabs)) + "]"))
// it's faster to fill with re-drawing turned off
SendMessage(hLBox, WM_SETREDRAW, 0, 0)
aeval(aList, {|cStr| SendMessage(hLBox, LB_ADDSTRING, 0, cStr)} )
#define LBLINE 5
SendMessage(hLBox, LB_SETCURSEL, LBLINE, 0) // select the interesting one
cText = LBGetText(hLBox, LBLINE) // fetch the line
SetFocus(hLBox)
// now set redrawing on, and force a redraw
SendMessage(hLBox, WM_SETREDRAW, 1, 0)
InvalidateRect(hLBox)
bEvent = {|nEvent| LBoxEvent(nEvent)}
return
procedure LBoxEvent(nEvent)
local i
do case
case nEvent == EVENT_CONTROL
if _lastwParam() == ID_LBOX // child id
if _lastHilParam() == LBN_SELCHANGE
// the user changed the selected item
i = SendMessage(hLBox, LB_GETCURSEL, 0, 0)
cText = LBGetText(hLBox, i)
// MessageBox( , nstr(i) + cText, "LBGetText", MB_OK)
InvalidateRect(hWnd) // send ourself a redraw event
endif
endif
case nEvent == EVENT_REDRAW
SetPos(13, 1)
? "Text chosen:" ; ? ; ? strtran(cText, TAB, " ")
endcase
return
// This one is modal
procedure DoLBoxDlog()
local aDlg, aChoices := {"List Box", "Sorted automatically", "A standard"}
if hLBox != nil
DestroyWindow(hLBox)
hLBox = nil
endif
aDlg = CreateDialog("Sample Dialog", ;
WS_CAPTION + WS_SYSMENU + WS_GROUP + WS_TABSTOP ;
+ WS_THICKFRAME + WS_VISIBLE + WS_POPUP, ;
100, 30, 100, 100)
aDlg = AppendDialog(aDlg, "ok", DLG_BUTTON, ;
BS_DEFPUSHBUTTON + WS_TABSTOP + WS_CHILD + WS_VISIBLE, ;
10, 75, 35, 15, ;
"&Ok")
aDlg = AppendDialog(aDlg, "cancel", DLG_BUTTON, ;
BS_PUSHBUTTON + WS_TABSTOP + WS_CHILD + WS_VISIBLE, ;
55, 75, 35, 15, ;
"&Cancel")
aDlg = AppendDialog(aDlg, "listbox", DLG_LISTBOX, ;
LBS_STANDARD + WS_CHILD + WS_VISIBLE, ;
10, 10, 80, 60, ;
aChoices)
if ModalDialog(aDlg, hInst, hWnd) = 0 .or. GetDialogResult(aDlg, "cancel") = .T.
cText = "<cancelled>"
else
cText = GetDialogResult(aDlg, "listbox")
endif
bEvent = {|nEvent| LBoxDlogEvent(nEvent)}
InvalidateRect(hWnd) // send ourself a redraw event
return
procedure LBoxDlogEvent(nEvent)
do case
case nEvent == EVENT_REDRAW
SetPos(10, 15)
if cText == nil
? "No text chosen"
else
? "Text chosen:" ; ? ; ? cText
endif
endcase
return
function nstr(n)
return alltrim(str(n)) + " "
#endif // !LIB_ONLY
/////////
//
// LBAddString( <hLBox>, <cNewStr> ) --> nLine
//
// Add a new string to a list box
//
// Returns the position of the string added, or LB_ERR if an
// error occurs (but LB_ERRSPACE if not enough room)
//
/////////
function LBAddString(hLBox, cNewStr)
return SendMessage(hLBox, LB_ADDSTRING, 0, cNewStr)
/////////
//
// LBDeleteString( <hLBox>, <nLine> ) --> nCount
//
// Deletes a string from a list box.
// <nLine> is the position of the string to delete
//
// Returns the the number of strings left, or LB_ERR if an
// error occurs
//
/////////
function LBDeleteString(hLBox, nLine)
return SendMessage(hLBox, LB_DELETESTRING, nLine, 0)
/////////
//
// LBDir( <hLBox>, <nAttr>, <cFileSpec> ) --> nLine
//
// Add a list of filenames to a list box
//
// Returns the position of the last filename added, or LB_ERR if an
// error occurs (but LB_ERRSPACE if not enough room)
//
/////////
function LBDir(hLBox, nAttr, cFileSpec)
return SendMessage(hLBox, LB_DIR, nAttr, cFileSpec)
/////////
//
// LBFindString( <hLBox>, <cStr>, [ <nStart> ] ) --> nLine
//
// Find a string in a list box.
// <nStart> optionally specifies the start of the search
//
// Returns the position of the string found, or LB_ERR if not found
//
// See Also: LBFindStrExact()
//
/////////
function LBFindString(hLBox, cStr, nStart)
if nStart == nil
nStart = -1 // search from the start
endif
return SendMessage(hLBox, LB_FINDSTRING, nStart, cStr)
/////////
//
// LBFindStrExact( <hLBox>, <cStr>, [ <nStart> ] ) --> nLine
//
// Find a string in a list box.
// <nStart> optionally specifies the start of the search
//
// Returns the position of the string found, or LB_ERR if not found
//
// See Also: LBFindString()
//
/////////
function LBFindStrExact(hLBox, cStr, nStart)
if nStart == nil
nStart = -1 // search from the start
endif
return SendMessage(hLBox, LB_FINDSTRINGEXACT, nStart, cStr)
/////////
//
// LBGetCount( <hLBox> ) --> nCount
//
// Returns the number of items in a list box
//
/////////
function LBGetCount(hLBox)
return SendMessage(hLBox, LB_GETCOUNT, 0, 0)
/////////
//
// LBGetCurSel( <hLBox> ) --> nLine
//
// Returns the position of the currently selected item in a list box
// (or LB_ERR if nothing is selected)
//
/////////
function LBGetCurSel(hLBox)
return SendMessage(hLBox, LB_GETCURSEL, 0, 0)
/////////
//
// LBGetItemRect( <hLBox>, <nLine> ) --> aRect
//
// Returns the client co-ordinates of the rectangle that bounds
// an item as it is currently displayed in a list box, in
// the form {left, top, right, bottom}
//
/////////
function LBGetItemRect(hLBox, nLine)
local cRect := space(8) // room for int[4]
SendMessage(hLBox, LB_GETITEMRECT, nLine, @cRect)
return bin2a(cRect, "int[4]")
/////////
//
// LBGetSel( <hLBox>, <nLine> ) --> nRet
//
// Returns the selection status of an item in a list box
// (0 if not selected, > 0 if selected, LB_ERR if an error occurs)
//
/////////
function LBGetSel(hLBox, nLine)
return SendMessage(hLBox, LB_GETSEL, nLine, 0)
/////////
//
// LBGetSelCount( <hLBox> ) --> nCount
//
// Returns the number of selected items in a multiple selection list box
//
/////////
function LBGetSelCount(hLBox)
return SendMessage(hLBox, LB_GETSELCOUNT, 0, 0)
/////////
//
// LBGetSelItems( <hLBox> ) --> aPositions
//
// Returns the positions of selected items in a multiple selection list box
//
/////////
function LBGetSelItems(hLBox)
local n := SendMessage(hLBox, LB_GETSELCOUNT, 0, 0)
local cBuf := space(n * 2) // space for n integers
SendMessage(hLBox, LB_GETSELITEMS, n, @cBuf)
return bin2a(cBuf, "int[" + str(n) + "]")
/////////
//
// LBGetSelLines( <hLBox> ) --> aItems
//
// Returns the selected lines in a multiple selection list box
//
/////////
function LBGetSelLines(hLBox)
local i, a := LBGetSelItems(hLBox)
for i = 1 to len(a)
a[i] = LBGetText(hLBox, a[i])
next i
return a
/////////
//
// LBGetText( <hLBox>, <nLine> ) --> cLine or nil
//
// Returns the specified line from within a list box
// (<nLine> starts at 0)
//
/////////
function LBGetText(hLBox, nLine)
local nLen, cBuf := space(SendMessage(hLBox, LB_GETTEXTLEN, nLine, 0) + 1)
nLen = SendMessage(hLBox, LB_GETTEXT, nLine, @cBuf)
return iif(nLen == LB_ERR, nil, left(cBuf, nLen))
/////////
//
// LBGetTextLen( <hLBox>, <nLine> ) --> nLen
//
// Returns the length of a line in a list box
//
// <nLine> counts from zero.
//
/////////
function LBGetTextLen(hLBox, nLine)
return SendMessage(hLBox, LB_GETTEXTLEN, nLine, 0)
/////////
//
// LBInsertString( <hLBox>, <cNewStr>, <nLine> ) --> nLen
//
// Insert a new string in a list box
//
// Returns the length of the string added, or LB_ERR if an
// error occurs (but LB_ERRSPACE if not enough room)
//
/////////
function LBInsertString(hLBox, cNewStr, nLine)
return SendMessage(hLBox, LB_INSERTSTRING, nLine, cNewStr)
/////////
//
// LBResetContent( <hLBox> ) --> nil
//
// Empty a list box
//
/////////
procedure LBResetContent(hLBox)
SendMessage(hLBox, LB_RESETCONTENT, 0, 0)
return
/////////
//
// LBSelectString( <hLBox>, <cStr>, [ <nStart> ] ) --> nLine
//
// Find a string in a list box, and (if found) select it
// <nStart> optionally specifies the start of the search
//
// Returns the position of the string found, or LB_ERR if not found
//
/////////
function LBSelectString(hLBox, cStr, nStart)
if nStart == nil
nStart = -1 // search from the start
endif
return SendMessage(hLBox, LB_SELECTSTRING, nStart, cStr)
/////////
//
// LBSetCurSel( <hLBox>, <nLine> ) --> nRet
//
// Sets the position of the currently selected item in a list box
//
// <nLine> can be -1 to remove any selection
//
// Returns <nLine> (or LB_ERR if <nLine> is too big or -1)
//
/////////
function LBSetCurSel(hLBox, nLine)
return SendMessage(hLBox, LB_SETCURSEL, nLine, 0)
/////////
//
// LBSetSel( <hLBox>, <nLine>, <lSelect> ) --> nRet
//
// Sets whether a string is selected in a multiple-selection list box
//
// Special values:
//
// nLine = -1 all strings are selected/unselected
// (according to lSelect)
//
// Returns <nLine> (or LB_ERR if <nLine> is invalid)
//
/////////
function LBSetSel(hLBox, nLine, lSelect)
return SendMessage(hLBox, LB_SETSEL, iif(lSelect,1,0), MAKELPARAM(nLine, 0))
/////////
//
// LBSetTabStops( <hLBox>, <aTabs> ) --> lSuccess
//
// Sets the tab-stop positions in a list box
//
/////////
function LBSetTabStops(hLBox, aTabs)
local nLen, cTabs := ""
if aTabs == nil
cTabs := nLen := 0 // Windows default is 2 dialog units
else
nLen = len(aTabs)
aeval(aTabs, {|n| cTabs += i2bin(n)})
endif
return SendMessage(hLBox, LB_SETTABSTOPS, nLen, cTabs) != 0
#ifndef LIB_ONLY
function MenuSetup()
local hWnd := SelectWindow(), hMenu, hPopupMenu
if (hMenu := GetMenu(hWnd)) != nil
DestroyMenu(hMenu)
endif
// do new one (forget old value)
hMenu = CreateMenu()
hPopupMenu = CreatePopupMenu()
AppendMenu(hMenu, "file", MF_ENABLED + MF_POPUP, "&File", hPopupMenu)
AppendMenu(hPopupMenu, "exit", MF_ENABLED + MF_STRING, "E&xit", {|| Alert("Thanks for running this demo"), DoExit()})
hPopupMenu = CreatePopupMenu()
AppendMenu(hMenu, "demo", MF_ENABLED + MF_POPUP, "&Demo", hPopupMenu)
AppendMenu(hPopupMenu, "list1", MF_ENABLED + MF_STRING, "&Dialog", {|c| DoLBoxDlog()})
AppendMenu(hPopupMenu, "list2", MF_ENABLED + MF_STRING, "&Listbox", {|c| DoLBox()})
hPopupMenu = CreatePopupMenu()
AppendMenu(hMenu, "help", MF_ENABLED + MF_POPUP, "&Help", hPopupMenu)
AppendMenu(hPopupMenu, "about", MF_ENABLED + MF_STRING, "&About", {|| DoAbout()})
SetMenu(hWnd, hMenu)
return hMenu
#endif // !LIB_ONLY