Caret position in a dialog

Technical support and scripting issues

Moderators: Dorian (MJT support), JRL

Post Reply
User avatar
JRL
Automation Wizard
Posts: 3504
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Caret position in a dialog

Post by JRL » Mon Jun 12, 2006 8:29 pm

Anyone know how to determine the caret position in a Macro Scheduler dialog. I'm not having any luck. I get the same results no matter which field I select and in fact I get the same results if I pick anywhere on the dialog box. If I make selections in a notepad text window, the caret positions change and look correct.

I also tried using a libfunc> technique described here. But I'm not certain I've altered it correctly for my application.

What I want to accomplish is to know which field a user is currently visiting and to perform a task based solely on the fact that the cursor is active in that field. I thought about using GetCursorPos> but that will fail if the user tabs through the dialog.

Here is a sample dialog with multiple fields, followed by another sample dialog that incorporates a test for GetCaretPos>:

Code: Select all

Dialog>Dialog1
   Caption=Purchase Requisition
   Width=291
   Height=237
   Top=174
   Left=150
   Max=1
   Min=1
   Close=0
   Resize=1
   Edit=msEdit1,80,0,121,msEdit1
   Edit=msEdit2,80,24,121,msEdit2
   Edit=msEdit3,80,48,121,msEdit3
   Edit=msEdit4,80,72,121,msEdit4
   Edit=msEdit5,80,96,121,msEdit5
   Edit=msEdit6,80,120,121,msEdit6
   Button=Close,96,168,75,25,2
EndDialog>Dialog1

Show>dialog1

Label>start
wait>0.5
GDA>dialog1,r1
If>r1=2,end
Goto>start
Label>end

Code: Select all

OnEvent>KEY_DOWN,VK1,0,KeyPress
OnEvent>WINDOW_NEWACTIVE,0,0,KeyPress

SRT>CPos
Show>dialogcp
Label>startcp
GDA>dialogcp,rcp
If>rcp=2,endcp
Wait>0.01
Goto>startcp
Label>endcp
END>CPos

SRT>KeyPress
Let>WIN_USEHANDLE=0
GAW>winname,winX,winY
//Let>WIN_USEHANDLE=0
//LibFunc>user32,FindWindowA,WinVar,Tedit,msEdit1
GTP>qX,qY,0
GTP>kX,kY,1
Let>deltaX=%qX%-%winX%
Let>deltaY=%qY%-%winY%
Let>dialogcp.mslabel0=Caret position rel= %kX%,%kY%%CRLF%Caret position absolute= %qX%,%qY%%CRLF%Caret position absolute-window pos= %deltaX%,%deltaY%%CRLF%Window Name= %winname%%CRLF%Window Position= %winX%,%winY%%CRLF%
RDA>dialogcp
END>KeyPress

Dialog>Dialogcp
   Caption=Caret position
   Width=230
   Height=250
   Top=288
   Left=500
   Close=0
   Label=pick on a field of a window%CRLF%to see relative caret position,5,8
   Button=Close,72,184,75,25,2
EndDialog>Dialogcp

Dialog>DialogPR
   Caption=Purchase Requisition
   Width=302
   Height=304
   Top=174
   Left=150
   Max=1
   Min=1
   Close=0
   Resize=1
   Edit=msEdit1,80,0,121,ms
   Edit=msEdit2,80,24,121,msE
   Edit=msEdit3,80,48,121,msEd
   Edit=msEdit4,80,72,121,msEdi
   Edit=msEdit5,80,96,121,msEdit
   Edit=msEdit6,80,120,121,msEdit6
   Memo=msMemo1,80,144,185,89,msMemo1
EndDialog>DialogPR

Show>DialogPR

Label>start
wait>0.5
GDA>DialogPR,r1
Gosub>CPos
If>rcp=2,end
Goto>start
Label>end


If this is not clear or if I should add more info, let me know.

Any help will be appreciated,
Dick
Last edited by JRL on Tue Jun 13, 2006 4:46 pm, edited 2 times in total.

User avatar
Rain
Automation Wizard
Posts: 550
Joined: Tue Aug 09, 2005 5:02 pm
Contact:

Post by Rain » Tue Jun 13, 2006 2:50 pm

I’m not having any luck either. I did notice when I move all your edit boxed to the far left of your dialog window and move your dialog to 0,0 the GetCaretPos command returns the correct value but only for the first edit box.
I’ve modified your first script and when I hit the tab button to go to the next edit box the mouse moves to the correct X position but not the Y position. I have done another test and used a memo box and had no problem at all getting the correct X,Y coordinates. Correct me if I’m wrong but it looks as Macro Scheduler can’t distinguish the different edit boxed and it can't read the position of the edit box relative to the dialog.

Don't quote me on this I'm no expert.

This the modified script I used

Code: Select all

Dialog>Dialog1
   Caption=Purchase Requisition
   Width=291
   Height=237
   Top=0
   Left=0
   Max=1
   Min=1
   Close=0
   Resize=1
   Edit=msEdit1,0,0,121,1
   Edit=msEdit2,0,24,121, 2
   Edit=msEdit3,0,48,121,  3
   Edit=msEdit4,0,72,121,   4
   Edit=msEdit5,0,96,121,    5
   Edit=msEdit6,0,120,121,     6
   Button=Close,96,168,75,25,2
EndDialog>Dialog1

Show>dialog1

Label>start
wait>0.5
GDA>dialog1,r1
If>r1=2,end
gtp>X,Y,0
mou>X,Y
Goto>start
Label>end

User avatar
JRL
Automation Wizard
Posts: 3504
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Tue Jun 13, 2006 3:35 pm

Rain,

Thanks for taking the time to look at this. When I started on this it seemed straightforward. Your first observation about moving the edit box all the way left imay be true but isn't very practical. This affects all Windows dialog boxes not just Macro Scheduler dialog boxes. For example try selecting fields in an icon properties dialog box and you'll get the same results. I haven't tried the memo box yet, I'll try that and see what happens.

Added
I tried the memo box and I get the same result as with the edit box. Maybe I'm missing something?

Edited the next paragraph
The way the I'm interpreting this is that the edit boxes are individual windows within the dialog box window so the caret position within an individual edit box will be relative to that edit box if the command used is GetCaretPos>x,y,1. Using this interpretation the command seems to work. However, using the command GetCaretPos>x,y,0 the coordinates returned are supposed to be relative to the entire screen. This doesn't seem to work. As you said, the "Y" coordinate doesn't change no matter where you select. I also tried using the libfunc> process to try and get the name of the window so that hopefully, I could with the name, acquire its location. But my modified example libfunc> doesn't get the window name. But I don't know that I've made valid changes to the command. I can get the edit box names by using the "View System Windows" utility. Using the names found there with GetWindowPos> doesn't work for me either.

Added
I've altered the second script that I originally posted.

Perhaps I'm taking the wrong approach altogether. As I stated earlier, my goal is to spawn an event when the cursor lands in a specific field. Perhaps there is another method of doing this?

Thank you for your consideration of my problem,
Dick

User avatar
Marcus Tettmar
Site Admin
Posts: 7380
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Post by Marcus Tettmar » Tue Jun 13, 2006 6:40 pm

One way to determine which field the user is in is to use the Win32 API function GetFocus. This retrieves the handle of the object that has the keyboard focus. So if we get the handles of each of the edit boxes when we first show the dialog we can then compare these to the handle of the focused object and determine which box has the focus. So try this:

Code: Select all

Dialog>Dialog1
   Caption=Purchase Requisition
   Width=291
   Height=237
   Top=241
   Left=189
   Max=1
   Min=1
   Close=0
   Resize=1
   Edit=msEdit1,80,0,121,msEdit1
   Edit=msEdit2,80,24,121,msEdit2
   Edit=msEdit3,80,48,121,msEdit3
   Edit=msEdit4,80,72,121,msEdit4
   Edit=msEdit5,80,96,121,msEdit5
   Edit=msEdit6,80,120,121,msEdit6
   Button=Close,96,168,75,25,2
   Edit=msEdit7,80,144,121,msEdit7
EndDialog>Dialog1

Show>dialog1

GoSub>GetFieldHandles

Label>start
wait>0.5
GDA>dialog1,r1

//which field is active?
GoSub>GetActiveField

If>r1=2,end
Goto>start
Label>end

//Gets the handles of the edit boxes and presets them
SRT>GetFieldHandles
   //Uses preset edit values to determine handles of the edit fields
   GetWindowHandle>Purchase Requisition,dlgHwnd
   LibFunc>user32,FindWindowExA,msEdit1.hwnd,dlgHwnd,0,TEdit,msEdit1
   LibFunc>user32,FindWindowExA,msEdit2.hwnd,dlgHwnd,0,TEdit,msEdit2
   LibFunc>user32,FindWindowExA,msEdit3.hwnd,dlgHwnd,0,TEdit,msEdit3
   LibFunc>user32,FindWindowExA,msEdit4.hwnd,dlgHwnd,0,TEdit,msEdit4
   LibFunc>user32,FindWindowExA,msEdit5.hwnd,dlgHwnd,0,TEdit,msEdit5
   LibFunc>user32,FindWindowExA,msEdit6.hwnd,dlgHwnd,0,TEdit,msEdit6
   //Optionally we can now clear the edits
   Let>Dialog1.msEdit1=
   Let>Dialog1.msEdit2=
   Let>Dialog1.msEdit3=
   Let>Dialog1.msEdit4=
   Let>Dialog1.msEdit5=
   Let>Dialog1.msEdit6=
   ResetDialogAction>Dialog1
End>GetFieldHandles

//Determines which is the active field
SRT>GetActiveField
  //get handle of window with keyboard focus
  //Workaround for LibFunc bug!
  Let>hwnd={"hwnd"}
  LibFunc>user32,GetFocus,hwnd
  //we have handle of active field, which is it?
  if>hwnd=msEdit1.hwnd
    Let>Dialog1.msEdit7=msEdit1
  endif
  if>hwnd=msEdit2.hwnd
    Let>Dialog1.msEdit7=msEdit2
  endif
  if>hwnd=msEdit3.hwnd
    Let>Dialog1.msEdit7=msEdit3
  endif
  if>hwnd=msEdit4.hwnd
    Let>Dialog1.msEdit7=msEdit4
  endif
  if>hwnd=msEdit5.hwnd
    Let>Dialog1.msEdit7=msEdit5
  endif
  if>hwnd=msEdit6.hwnd
    Let>Dialog1.msEdit7=msEdit6
  endif
  ResetDialogAction>dialog1
End>GetActiveField
Enjoy
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

User avatar
JRL
Automation Wizard
Posts: 3504
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Tue Jun 13, 2006 6:45 pm

Thank you Marcus,

It looks to be exactly what I was looking for. I'l post a sample of what I'm doing when I get it done.

I still wonder about GetCaretPos>. Is it working as it is supposed to work? If it is, I think the help file is misleading



Later,
Dick

User avatar
JRL
Automation Wizard
Posts: 3504
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Tue Jun 13, 2006 8:17 pm

I think I've figured out the GetCaretPos> problem.

GetCaretPos>X,Y,0 gives an X and a Y that are each the pixel count from the screen 0,0 to the dialog box X and Y position plus the pixel count from the caret to a zero point for the edit box.

What is missing from the equation is the distance from the source of the dialog box to the source of the edit box. And that information is in the dialog definition as the top and left parameters for the each edit box. Still can't use the information without knowing the names of each edit box.

Hope this makes sense,
Dick

User avatar
JRL
Automation Wizard
Posts: 3504
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Tue Jun 13, 2006 10:41 pm

Here's an example of what I've been trying to accomplish. When you pick on the DESCRIPTION field a larger memo box opens.

Thank you Marcus.

Later,
Dick

Code: Select all

Dialog>EditDialog
   Caption=Part Description
   Width=883
   Height=647
   Top=152
   Left=29
   Label=Enter your multiple lines of text here where you can see them,16,8
   Memo=msMemo1,16,32,841,529,
   Button=OK,16,576,75,25,3
   Button=Cancel,784,576,75,25,2
EndDialog>EditDialog

Dialog>Dialog1
   Caption=Purchase Requisition
   Width=310
   Height=216
   Top=238
   Left=328
   Max=1
   Min=1
   Close=0
   Resize=1
   Label=REQ NUMBER,64,8
   Label=VENDOR,88,32
   Label=DEPARTMENT,64,56
   Label=DESCRIPTION,64,80
   Label=DATE REQUIRED,48,104
   Edit=msEdit1,144,8,121,msEdit1
   Edit=msEdit2,144,32,121,msEdit2
   Edit=msEdit3,144,56,121,msEdit3
   Edit=msEdit4,144,80,121,msEdit4
   Edit=msEdit5,144,104,121,msEdit5
   Button=Close,96,144,75,25,2
EndDialog>Dialog1

Show>dialog1

GoSub>GetFieldHandles

Label>start
wait>0.5
GDA>dialog1,r1

//which field is active?
GoSub>GetActiveField

If>r1=2,end
Goto>start
Label>end

//Gets the handles of the edit boxes and presets them
SRT>GetFieldHandles
   //Uses preset edit values to determine handles of the edit fields
   GetWindowHandle>Purchase Requisition,dlgHwnd
   LibFunc>user32,FindWindowExA,msEdit1.hwnd,dlgHwnd,0,TEdit,msEdit1
   LibFunc>user32,FindWindowExA,msEdit2.hwnd,dlgHwnd,0,TEdit,msEdit2
   LibFunc>user32,FindWindowExA,msEdit3.hwnd,dlgHwnd,0,TEdit,msEdit3
   LibFunc>user32,FindWindowExA,msEdit4.hwnd,dlgHwnd,0,TEdit,msEdit4
   LibFunc>user32,FindWindowExA,msEdit5.hwnd,dlgHwnd,0,TMemo,msEdit5

   //Optionally we can now clear the edits
   Let>Dialog1.msEdit1=
   Let>Dialog1.msEdit2=
   Let>Dialog1.msEdit3=
   Let>Dialog1.msEdit4=
   Let>Dialog1.msEdit5=
   ResetDialogAction>Dialog1
End>GetFieldHandles

//Determines which is the active field
SRT>GetActiveField
  //get handle of window with keyboard focus
  //Workaround for LibFunc bug!
  Let>hwnd={"hwnd"}
  LibFunc>user32,GetFocus,hwnd
  //we have handle of active field, which is it?
  if>hwnd=msEdit4.hwnd
        Show>EditDialog,R_edit
	If>R_edit=2,no_edit
	If>R_edit=3
	  Let>Dialog1.msEdit4=%EditDialog.msMemo1%
  	  Label>no_edit
	  Set>Purchase Requisition
	  Wait>0.5
	  Press TAB
	  EndIf
        RDA>dialog1
	RDA>EditDialog
  endif
End>GetActiveField
Oops... left off the line RDA>EditDialog so the spawned memo box would lose any text if it was called a second time.

Sorry,
Dick
Last edited by JRL on Wed Jun 14, 2006 12:28 pm, edited 1 time in total.

User avatar
Marcus Tettmar
Site Admin
Posts: 7380
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Post by Marcus Tettmar » Wed Jun 14, 2006 7:51 am

Neat!
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts