MD Sayem Ahmed
MD Sayem Ahmed

Reputation: 29166

Datawindow field : accept only positive numbers

I want to make a datawindow field accept only positive numbers. How can I do that?

Edit

I know I can validate the column using column specification's validation expression system. But is there any format available which I can put into the Format property and be done with it?

Upvotes: 1

Views: 4319

Answers (3)

Hugh Brackett
Hugh Brackett

Reputation: 2706

Philip Salgannik showed how to intercept keys from a DataWindow in a post to sybase.public.powerbuilder.datawindow on 2004-04-27. This really filters the keys, rather than undoing them.

Declare an external function for PeekMessage (for older PB use PeekMessageA): :

function boolean PeekMessage( Ref blob lpMsg, long hWnd, UINT uMsgFilterMin, UINT  uMsgFilterMax, UINT  wRemoveMsg ) Library "USER32.dll" alias for "PeekMessageW"
//WM_KEYFIRST = 0x0100 // 256 
//WM_KEYLAST  = 0x0108 // 264 
//PM_REMOVE = 1 

Map the pbm_dwnkey event and name it either key or ue_key according to your philosopy. Add this code to the event:

if 0 = keyflags and (key = KeyDash! or key = KeySubtract!) then
   choose case ls_col
      case "col_1", "col_2"   // ... we have many columns in the list
         PeekMessage( Msg, 0, 256, 264, 1 )   // see the declaration for values. this removes the message.
         message.processed=TRUE 
         message.returnvalue=1 
         return
      case else
         // nothing else
   end choose
end if

I tried several times to get this to format correctly with no success.

I'm not sure that setting message.processed and message.returnvalue has any effect. It doesn't normally from this event. I kept them when I used the code because I didn't have time to experiment.

Upvotes: 1

RealHowTo
RealHowTo

Reputation: 35407

No, the simple solution is a validation rule but a more complicated solution to really filter the key pressed is possible.

First you map a userevent (ue_nonnegative) to the datawindow control event pbm_dwnkey.

double ld_value
long  ll_row

if this.getcolumnname() = "value" then
    if key = KeySubtract! or key = KeyDash! then
         ll_row = this.GetRow()
         ld_value = this.getitemnumber(ll_row, "value")
        yield() 
         post event ue_filtervalue(ll_row, ld_value)
    else
        yield() 
        accepttext()
    end if
end if

Here the datawindow has a column named value. I check if the "-" is pressed, if yes I keep the current value and a new event ue_filtervalue is posted. A yield() is necessary to make sure that the ue_filtervalue event will happen after the remaining datawindow event.

The ue_filtervalue event will restore the previous value without the "-".

this.setitem(ad_row, "value", ad_value)
this.SelectText( Len( String(ad_value)) + 1, Len( String(ad_value)) )

Upvotes: 2

Hugh Brackett
Hugh Brackett

Reputation: 2706

If you use an editmask that begins with + it will only accept positive values. The plus sign displays, which you may find undesirable.

Upvotes: 1

Related Questions