From: Bill Tillick on
Hi Steve, Geoff, etc,
I now have bRegisterByEventHandler(self:oDCbBrowse, self, #KeyChar) in
my PostInit for the owner window.

My KeyChar method is now:-
----------------------------------------------------------------------------------------------------------------
METHOD KeyChar( oKeyEvent ) CLASS Product2List
LOCAL cText as string

IF oKeyEvent:uMsg = WM_CHAR .and. oKeyEvent:window =
self:oDCbBrowse
cText := Upper(CHR(oKeyEvent:wParam)) // get the
key's character and convert to UCase
self:server:SuspendNotification()
IF cText == self:cLastKey // have we got a repeat of previous key
press?
self:server:skip(1) // yes, so skip to next record
IF self:server:ProductName > cText .or. self:server:eof
// does this still have the same initial letter?
self:server:skip(-1) // no, so back up to the previous record
ENDIF
ELSE
// new letter, so do a fresh seek
IF self:server:seek(#ProductName, cText, true )
InfoBox{self,,self:server:ProductName}:show() // check that
we have positioned corrcetly
else
InfoBox{self,,"seek failed"}:show()
endif

self:cLastKey := cText // and save the initial letter
ENDIF
self:server:resetNotification()
self:server:Notify(NOTIFYRECORDCHANGE) // do I need both these
Notifys?
self:server:Notify(NOTIFYFILECHANGE)
self:oDCbBrowse:Refresh()
RETURN true // = SUCCESS
ENDIF
RETURN nil // key not processed
-------------------------------------------------------------------------------------------------------------------------

Using InfoBox and the debugger I have determined that the method is OK
until the point at which the InfoBox shows the ProductName correctly.
BUT when I pause before closing the InfoBox, the bBrowser
automatically refreshes at that point and then every row displayed is
a repeat of the row corresponding to the Seek!
If I increase the auto refresh delay, so that the method sends its own
refresh, then the browse is positioned as expected after the Seek -
UNTIL the subsequent auto refresh which again causes every row to be
displayed as a repeat of the row corresponding to the Seek!

Weird??? or have I missed something?

Thanks for your help,
Bill

From: richard.townsendrose on
Bill

we have been using this code for years ... well since 2002 anyway

it works well ...

it is used for looking at column data - a seek or a locate depending
on indexing

METHOD KeyDown(oKeyEvent) CLASS MySeekbBrowser
LOCAL oActiveColumn AS bDataColumn

SUPER:KeyDown(oKeyEvent)

IF oKeyEvent:ASCIICHAR > 30 .AND. oKeyEvent:ASCIICHAR < 128 .AND. !
GetKeyState(KEYCONTROL)<0 .AND. !GetKeyState(VK_MENU)<0 .AND. !
SELF:InEdit()
oActiveColumn:=SELF:GetActiveColumn()
oActiveColumn:PropertyPut(#aNextFound,{})
SELF:cSTRING:=SELF:cSTRING+Upper(CHR(oKeyEvent:ASCIICHAR))
SELF:Seek(oActiveColumn)
ENDIF

RETURN NIL


and here is the "seek" method - it depends on the statyus of all sorts
of things ...

METHOD Seek(oActiveColumn) CLASS MySeekbBrowser
LOCAL cExpression,cNotFound AS STRING
LOCAL cCodeBlock AS USUAL
LOCAL cSearch AS STRING
LOCAL liOldRecno,liRecno AS DWORD
LOCAL lOK AS LOGIC
LOCAL oMyHandler AS CODEBLOCK
LOCAL ObjInfo
LOCAL lFound AS LOGIC

IF SLen(SELF:cSTRING)>0
IF !SELF:lInLocate
oMyHandler := ErrorBlock( { |e| _Break( e ) } ) //CAL 020802
ENDIF

BEGIN SEQUENCE

IF SLen(SELF:cSTRING)=1
AAdd(oActiveColumn:PropertyGet(#ASearchRecno,
{}),SELF:Server:Recno)
ENDIF

IF oActiveColumn:PropertyGet(#ActiveColumnIndex,FALSE)
IF !Empty(oActiveColumn:PropertyGet(#SearchExpression,''))
cExpression:="{|
oSelf,cSTR|"+oActiveColumn:PropertyGet(#SearchExpression,'')+"}"
cCODEBLOCK:=&(cExpression)
cSearch:=Eval(cCodeBlock,SELF,SELF:cSTRING)
ELSE
cSearch:=SELF:cSTRING
ENDIF
SELF:CaptionUpdate(SELF:cSTRING)

IF oActiveColumn:PropertyGet(#PadLSeekLenght,0)>0

lFound:=SELF:PadLSeek(oActiveColumn,Eval(cCodeBlock,SELF,Space(0)))
ELSE
lFound:=SELF:Server:seek(cSearch,TRUE)
ENDIF

IF lFound
AAdd(oActiveColumn:PropertyGet(#ASearchRecno,
{}),SELF:Server:Recno)
SELF:CaptionFound(SELF:cSTRING)
ELSE
cNotFound:=SELF:cSTRING
SELF:cSTRING:=Left(SELF:cSTRING,SLen(SELF:cSTRING)-1)
SELF:CaptionNotFound(SELF:cSTRING,cNotFound)
SELF:Server:Goto(ATail(oActiveColumn:PropertyGet(#ASearchRecno,
{})))
ENDIF

ELSE //LOCATE SEEK
SELF:nInLocate:=SELF:nInLocate+1 //CAL 050702
//SELF:lInLocate:=TRUE
SELF:StopSearch:=FALSE
SELF:lInNext:=TRUE
SELF:ForceModal(TRUE)
SysObject():Pointer := Pointer{POINTERHOURGLASS}
liOldRecno:=SELF:Server:recno
SELF:CaptionLocateUpdate(SELF:cSTRING)
IF IsInstanceOf(SELF:server,#bSkipperDBServer)
IF SELF:Server:UniqueLength>0

liRecno:=SELF:LocateTextInServerUnique(SELF:server,oActiveColumn)
ELSEIF SELF:server:RecordFilter!=NIL

liRecno:=SELF:LocateTextInFilteredServer(SELF:server,oActiveColumn)
ELSE

liRecno:=SELF:LocateTextInServer(SELF:server,oActiveColumn)
ENDIF
ELSEIF IsInstanceOf(SELF:server,#bArrayServer)

liRecno:=SELF:LocateTextInbArrayServer(SELF:server,oActiveColumn)
ELSE
liRecno:=SELF:LocateTextInServer(SELF:server,oActiveColumn)
ENDIF

IF liRecno>0
SELF:CaptionFound(SELF:cSTRING)
AAdd(oActiveColumn:PropertyGet(#ASearchRecno,{}),liRecno)
lOK:=TRUE
ELSE
cNotFound:=SELF:cSTRING
SELF:cSTRING:=Left(SELF:cSTRING,SLen(SELF:cSTRING)-1)
SELF:CaptionNotFound(SELF:cSTRING,cNotFound)
liRecno:=liOldRecno
ENDIF

SELF:server:goto(lirecno)
SysObject():Pointer := Pointer{POINTERARROW}
//SELF:lInLocate:=FALSE
SELF:nInLocate:=SELF:nInLocate-1 //CAL 050702
SELF:StopSearch:=TRUE
SELF:lInNext:=FALSE
SELF:ForceModal(FALSE)
ENDIF

RECOVER USING ObjInfo //CAL 020802
SELF:nInLocate:=0
SELF:StopSearch:=TRUE
SELF:lInNext:=FALSE
SELF:ForceModal(FALSE)
WarningBox{SysObject(),LoadResString('Error
Locating',IDG_ERRORLOCATING,nPLH),LoadResString('Error',IDG_ERROR,nPLH)
+' :'+ObjInfo}:show()

END SEQUENCE

IF ! SELF:lInLocate
ErrorBlock( oMyHandler )
ENDIF
ELSE
SELF:CaptionClear()
ENDIF

RETURN NIL

regards

richard
From: BillT on
Further to my previous post ..... the Auto Refresh appears not to be
affecting the behaviour, because I have now eliminated it but still
get the duplication problem described above.
So that was bit of red herring and I am still getting duplication!

Bill
From: Stephen Quinn on
Bill

You simply shouldn't be opening any dialogs in a callback event, your taking
focus away from the window with the bBrowser on it - hence the weird stuff.

With focus moved from the bBrowser window your ResetNotification() call is
never processed so the current record is repeated for every row.

CYA
Steve



From: Gerhard Bunzel on
Bill,

>IF self:server:seek(#ProductName, cText, true )

I think, that should be:

IF self:server:seek(cText, true )



Have you checked your current index file for seeking?



HTH

Gerhard




"Bill Tillick" <wtillick(a)gmail.com> schrieb im Newsbeitrag
news:ed61113d-6c3c-4f8d-9245-f6c689c1d19c(a)l25g2000prn.googlegroups.com...
> Hi Steve, Geoff, etc,
> I now have bRegisterByEventHandler(self:oDCbBrowse, self, #KeyChar) in
> my PostInit for the owner window.
>
> My KeyChar method is now:-
> ----------------------------------------------------------------------------------------------------------------
> METHOD KeyChar( oKeyEvent ) CLASS Product2List
> LOCAL cText as string
>
> IF oKeyEvent:uMsg = WM_CHAR .and. oKeyEvent:window =
> self:oDCbBrowse
> cText := Upper(CHR(oKeyEvent:wParam)) // get the
> key's character and convert to UCase
> self:server:SuspendNotification()
> IF cText == self:cLastKey // have we got a repeat of previous key
> press?
> self:server:skip(1) // yes, so skip to next record
> IF self:server:ProductName > cText .or. self:server:eof
> // does this still have the same initial letter?
> self:server:skip(-1) // no, so back up to the previous record
> ENDIF
> ELSE
> // new letter, so do a fresh seek
> IF self:server:seek(#ProductName, cText, true )
> InfoBox{self,,self:server:ProductName}:show() // check that
> we have positioned corrcetly
> else
> InfoBox{self,,"seek failed"}:show()
> endif
>
> self:cLastKey := cText // and save the initial letter
> ENDIF
> self:server:resetNotification()
> self:server:Notify(NOTIFYRECORDCHANGE) // do I need both these
> Notifys?
> self:server:Notify(NOTIFYFILECHANGE)
> self:oDCbBrowse:Refresh()
> RETURN true // = SUCCESS
> ENDIF
> RETURN nil // key not processed
> -------------------------------------------------------------------------------------------------------------------------
>
> Using InfoBox and the debugger I have determined that the method is OK
> until the point at which the InfoBox shows the ProductName correctly.
> BUT when I pause before closing the InfoBox, the bBrowser
> automatically refreshes at that point and then every row displayed is
> a repeat of the row corresponding to the Seek!
> If I increase the auto refresh delay, so that the method sends its own
> refresh, then the browse is positioned as expected after the Seek -
> UNTIL the subsequent auto refresh which again causes every row to be
> displayed as a repeat of the row corresponding to the Seek!
>
> Weird??? or have I missed something?
>
> Thanks for your help,
> Bill
>