PowerBASIC Forums
  PowerBASIC for Windows
  Catching keypress in listbox

Post New Topic  Post A Reply
profile | register | preferences | faq | search

UBBFriend: Email This Page to Someone! next newest topic | next oldest topic
Author Topic:   Catching keypress in listbox
Oliver Copp
Member
posted August 16, 2003 02:22 PM     Click Here to See the Profile for Oliver Copp     Edit/Delete Message   Reply w/Quote
After extensive research of previous messages posted in this forum, I think I'm more confused than before looking for a pointer as to how to solve my problem *g*

The problem seems trivial: I have a listbox and want to catch the DEL key so I can delete an item. This is a lot more natural than having to click a "Delete Item" button, at least to me.

Looking for %WM_KEYUP messages, the listbox doesn't seem to be given any.

My question now is: do I need to subclass the listbox control (I hope not... never really understood the concept) or is there an easier route to take here?

Thanks in advance... again :-)

Oliver

------------------

IP: Logged

Raymond King
Member
posted August 16, 2003 02:35 PM     Click Here to See the Profile for Raymond King     Edit/Delete Message   Reply w/Quote
Hi Oliver,

In you callback procedure add:


CASE %WM_KEYDOWN
IF wParam = 46 THEN
'= Delete Key Pressed
END IF

------------------
Raymond L. King
Custom Software Designers.

rayking@csdsoft.com http://www.csdsoft.com

[This message has been edited by Raymond King (edited August 16, 2003).]

IP: Logged

Oliver Copp
Member
posted August 16, 2003 03:54 PM     Click Here to See the Profile for Oliver Copp     Edit/Delete Message   Reply w/Quote
Thanks, Raymond, but this isn't do the trick for me. CBMSG should be %WM_KEYDOWN, right?

I'm not even checking for the proper keycode - just checking for CBMSG %WM_KEYDOWN and no such messages seem to be arriving, regardless of the control, in the callback.


SELECT CASE CBMSG
CASE %WM_COMMAND
' ...
CASE %WM_KEYDOWN
MSGBOX "xxx"
CASE %WM_NOTIFY
SELECT CASE LOWRD(CBWPARAM)
CASE %IDC_SYSTREEVIEW32_1
LOCAL tTVITEM AS TV_ITEM
' ...

Am I not seeing the forest for the trees :-) ? I thought that when pressing any key anywhere on the form, I should be getting a message box.

TIA !

Oliver

------------------

IP: Logged

Raymond King
Member
posted August 17, 2003 04:47 AM     Click Here to See the Profile for Raymond King     Edit/Delete Message   Reply w/Quote
Sorry Oliver that one is for SDK here is how to do it in DDT.


CASE %WM_KEYDOWN
IF CBWPARAM = %VK_DELETE THEN
MSGBOX STR$(CBWPARAM)
END IF

Enjoy
Ray

------------------
Raymond L. King
Custom Software Designers.

rayking@csdsoft.com http://www.csdsoft.com

IP: Logged

Edwin Knoppert
Member
posted August 17, 2003 05:24 AM     Click Here to See the Profile for Edwin Knoppert     Edit/Delete Message   Reply w/Quote
I see no other way than a hook on the control.

Simpliest version:


#Compile Exe

Option Explicit

#Include "win32api.inc"

Function wnd_Proc( ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long ) As Long

Dim nCurSel As Long
Dim pPrevListBoxProc As Long

pPrevListBoxProc = GetProp( hWnd, "WPROC" )

Select Case wMsg
Case %WM_KEYDOWN

Select Case wParam
Case %VK_DELETE

nCurSel = SendMessage( hWnd, %LB_GETCURSEL, 0, ByVal 0& )
If nCurSel >= 0 Then
SendMessage( hWnd, %LB_DELETESTRING, nCurSel, ByVal 0& )
End If

End Select
End Select

Function = CallWindowProc( pPrevListBoxProc, hWnd, wMsg, wParam, lParam )

End Function

CallBack Function DlgProc() As Long

Dim hWndc As Long
Dim s() As String

Select Case CbMsg
Case %WM_INITDIALOG

ReDim S( 0 To 3 )
s( 0 ) = "Whatever"
s( 1 ) = "you"
s( 2 ) = "do!"
s( 3 ) = "Don't press delete!"
Control Add ListBox, CbHndl, 100, S(), 2, 2, 140, 114

hWndc = GetDlgItem( CbHndl, 100 )
SetProp hWndc, "WPROC", SetWindowLong( hWndc, %GWL_WNDPROC, CodePtr( wnd_proc ) )

End Select

End Function

Function WinMain ( ByVal hCurInstance As Long, _
ByVal hPrevInstance As Long, _
lpszCmdLine As Asciiz Ptr, _
ByVal nCmdShow As Long ) As Long

Dim a As Long
Dim hDlg As Long
Dim Result As Long

Dialog New 0, "DDT Skeleton",,, 240, 180 _
, %WS_OVERLAPPED _
Or %WS_SYSMENU _
Or %WS_MINIMIZEBOX _
Or %WS_MAXIMIZEBOX _
Or %WS_THICKFRAME _
Or %WS_CLIPSIBLINGS _
Or %WS_CLIPCHILDREN _
To hDlg

If hDlg = 0 Then Exit Function

Dialog Show Modal hDlg Call DlgProc To Result

End Function


------------------
http://www.hellobasic.com

IP: Logged

Kev Peel
Member
posted August 17, 2003 06:04 AM     Click Here to See the Profile for Kev Peel     Edit/Delete Message   Reply w/Quote
quote:

I see no other way than a hook on the control.

#Include "WIN32API.INC"


%IDC_DELKEY = 100


CallBack Function dlgMain

If (CbMsg = %WM_COMMAND) And (CbCtl = %IDC_DELKEY) Then Dialog End CbHndl

End Function

Function PBMain

Dim ac(0) As ACCELAPI, hDlg As Dword, dummy As Long

ac(0).fvirt = %FVIRTKEY
ac(0).key = %VK_DELETE
ac(0).cmd = %IDC_DELKEY

Dialog New 0, "Press delete to exit...", ,,200, 150, %WS_OVERLAPPEDWINDOW To hDlg

Accel Attach hDlg, ac() To dummy

Dialog Show Modal hDlg Call dlgMain

End Function

------------------
Kev Peel
KGP Software
http://www.kgpsoftware.com

IP: Logged

Dave Biggs
Member
posted August 17, 2003 09:21 AM     Click Here to See the Profile for Dave Biggs     Edit/Delete Message   Reply w/Quote
quote:
Originally posted by Oliver Copp:
...
My question now is: do I need to subclass the listbox control
(I hope not... never really understood the concept) or is there an easier route to take here?
...


As Kev shows you don't need to subclass the listbox.
Attaching accelerator key definitions to your dialog can get the job done with little fuss.
Sometimes subclassing can be very usefull though, so it's worth 'sussing out'.

I'm by no means expert here - mine is more a "Monkey see - Monkey do" kind of understanding
The way I see it, the reason that either technique is required has to do with which messages the
operating system passes to a dialog's callback procedure. (Is there a list somewhere?)
Subclassing gives access to those messages that don't normally get seen by the dialog's procedure.

Subclassing means using the 'SetWindowLong' API function, which changes attributes of a specified
window (AKA "Control" eg listbox):
The function is called with three parameters: the handle of the control, %GWL_WNDPROC (which says
we are changing the address of the window procedure) and CODEPTR(SubClassProc)- which is the new
address.


CallBack Function DialogProc()
Global gOldSubClassProc as Long
Case %WM_INITDIALOG
'Get handle of control to subclass
CONTROL HANDLE CBHNDL, %LVC_SYSLISTVIEW32_1 TO hList
'set up diversion
gOldSubClassProc = SetWindowLong(hList, %GWL_WNDPROC, CODEPTR(SubClassProc))

gOldSubClassProc is returned - it's the address of the original procedure for this control.

In the SubClassProc those 'missing' messages are available for processing.


Function SubClassProc (BYVAL hWnd AS LONG, BYVAL wMsg AS LONG, _
BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
Select Case wMsg
CASE %WM_KEYDOWN
MsgBox "Any key"
Select Case LOWRD(wParam)
Case %VK_DELETE
MsgBox "Process Del key here"
End Select
End Select
'return from diversion, pass messages and parameters on to original procedure.
Function = CallWindowProc(gOldSubClassProc, hWnd, wMsg, wParam, lParam)
End Function

Note: Avoid problems by destroying diversion at Dialog End.

CASE %WM_DESTROY
SetWindowLong hList, %GWL_WNDPROC, gOldSubClassProc

Hope that helps!
Regards Dave

------------------

[This message has been edited by Dave Biggs (edited August 17, 2003).]

IP: Logged

Oliver Copp
Member
posted August 17, 2003 12:56 PM     Click Here to See the Profile for Oliver Copp     Edit/Delete Message   Reply w/Quote
Thank you very much Raymond, Edwin and Kev, I really appreciate your helpful advice.

But Dave, I have to tell you - I would kiss your feet now if I could ;-)

You've managed to explain to me in a few paragraphs what I've been tryíng to find out for a few years now and (maybe due to the language barrier) never got a grip of.

Thank you, thank you, thank you!

Only one quick question: wouldn't it be more sensible processing the WM_KEYUP message instead of WM_KEYDOWN? I want to use the DEL key to delete entries from a listbox and I fear that if the user keeps his finger on the key just a bit too long, he'll delete multiple entries with WM_KEYDOWN.

Thanks again, you guys are great.

------------------

IP: Logged

Dave Biggs
Member
posted August 17, 2003 04:21 PM     Click Here to See the Profile for Dave Biggs     Edit/Delete Message   Reply w/Quote

Stop that Oliver!
I'm realy glad to help, but the kudos more rightly belongs to Semen, Lance, Tom et al - not forgetting
a certain ageless hippie somewhere on a farm in Sweden!!
All I've learned so far is through osmosis, lurking here and benefitting from their posts

That said there are probably holes in my explanation and I would like to know if there is a list of the
messages that don't ordinarily get passed to a Dialog?

BTW I think you are right, %WM_KEYUP does look like a better choice.

Regards Dave

------------------

[This message has been edited by Dave Biggs (edited August 17, 2003).]

IP: Logged

All times are EasternTime (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply
Hop to:

Contact Us | PowerBASIC BASIC Compilers

Copyright © 1999-2007 PowerBASIC, Inc. All Rights Reserved.


Ultimate Bulletin Board 5.45c