Subject Re: autodrop in combobox
From Mervyn Bick <invalid@invalid.invalid>
Date Mon, 6 Jun 2022 16:10:33 +0200
Newsgroups dbase.getting-started
Attachment(s) force_combox_drop.wfm

On 2022/06/05 15:09, Mustansir Ghor wrote:
> Dear All
>
> I have set autodrop to true in a combobox. When I press Tab key and the combobox gets focus then popup of items comes up. But when I use combobox.setfocus() to get its focus the autodrop feature does not work.
>
> Can anybody assists me on this how to go about.

A little example form is attached.  To ensure that Windows places the
cursor over the combobox button prior to simulating a left mouse click
the form metric needs to be Pixels.

Most of the Windows API functions needed are contained in
rmMouseEvents.cc in the dUFLP.

When getting or setting a cursor's position or simulating a mouse event
Windows uses the position on the screen rather than the position on the
form.

rmMouseEvents.cc uses a form's onMouseMove event handler to establish
the relationship between a point on a form and the corresponding point
on the screen. Instead of creating an onMouseMove event handler I've
used the ClientToScreen() function from the Windows API to do the
conversion.

Mervyn.




** END HEADER -- do not remove this line
//
// Generated on 2022-06-06
//
parameter bModal
local f
f = new force_combox_dropForm()
if (bModal)
   f.mdi = false // ensure not MDI
   f.readModal()
else
   f.open()
endif

class force_combox_dropForm of FORM
   with (this)
      onOpen = class::FORM_ONOPEN
      metric = 6        // Pixels
      height = 352.0
      left = 514.0
      top = 0.0
      width = 280.0
      text = ""
   endwith

   this.ENTRYFIELD1 = new ENTRYFIELD(this)
   with (this.ENTRYFIELD1)
      height = 22.0
      left = 94.0
      top = 81.0
      width = 84.0
      value = "Entryfield1"
   endwith

   this.COMBOBOX1 = new COMBOBOX(this)
   with (this.COMBOBOX1)
      height = 22.0
      left = 94.0
      top = 132.0
      width = 84.0
      dataSource = 'array {"a","b","c","d"}'
      style = 1        // DropDown
      dropDownHeight = 132.0
      autoDrop = true
   endwith

   this.ENTRYFIELD2 = new ENTRYFIELD(this)
   with (this.ENTRYFIELD2)
      height = 22.0
      left = 94.0
      top = 183.0
      width = 84.0
      value = "Entryfield2"
   endwith

   this.PUSHBUTTON1 = new PUSHBUTTON(this)
   with (this.PUSHBUTTON1)
      onClick = class::PUSHBUTTON1_ONCLICK
      height = 43.0
      left = 85.0
      top = 260.0
      width = 107.0
      text = "Set focus to combobox"
   endwith

   this.TEXT1 = new TEXT(this)
   with (this.TEXT1)
      height = 33.0
      left = 11.0
      top = 7.0
      width = 241.0
      text = "Form metric must be Pixels otherwise Windows can't place the cursor correctly."
   endwith


   function PUSHBUTTON1_onClick()
      form.combobox1.setfocus() // Not really neccessary.
      //The programmed click on the combobox button will set focus anyway.
      form.drop_list()
      return
      

   function drop_list
       //Place form coordinates that will show the cursor over the combobox button into form.point
       //This conversion to screen coordinates needs to be done each time the function is executed
       //in case the user has moved the form on the screen
      form.point.setx(form.combobox1.left+form.combobox1.width-10) //make sure cursor is in button
      form.point.sety(form.combobox1.top+10)
      //Convert point values to position on screen.
      clienttoscreen(form.hwnd,form.point)
      //Get x and y coordinates for drop button on combobox
      form.x_combo = form.point.getx(form.point,0)  
      form.y_combo = form.point.gety(form.point,4)
      form.rmMouse.screenLeftClick(form.x_combo,form.y_combo )  
      return      

   function form_onOpen()
      if type("ClientToScreen") # "FP"
          extern clogical ClientToScreen(chandle,cptr) user32
      endif
      set procedure to :duflp:rmMouseEvents.cc
      form.rmMouse = new rmMouseevents(form)
      form.point =  new point() // point is a structure to hold the cursor's x and y coordinates
      return

endclass