| View previous topic :: View next topic |
| Author |
Message |
Skit3000 Admin Team

Joined: 11 May 2002 Posts: 2166 Location: The Netherlands
|
Posted: Sat Nov 22, 2003 8:33 pm Post subject: Caret position bug |
|
|
Hello,
I am trying to make a little tool for the VDS IDE. But when I try to get the caret's position, it only works when I run it from the IDE. If I compile it, it will stay on one spot...
| Code: | option errortrap,error
DIALOG CREATE,VDS Autocomplete,-1,0,300,15,NOTITLE,ONTOP,COLOR YELLOW,CLASS VDSCOMPLETE
DIALOG ADD,TEXT,TEXT1,0,5,,,TEXT1
dialog show
:Evloop
wait event,0.0001
goto @event()
:Timer
%%Active = @winactive(C)
if @equal(%%Active,TMainWin)@equal(%%Active,VDSCOMPLETE)
if @unequal(%%Visible,TRUE)
dialog show
%%Visible = TRUE
end
else
if @unequal(%%Visible,FALSE)
dialog hide
%%Visible = FALSE
end
end
if @equal(%%Active,TMainWin)
%a = @binary(DWORD,0)@binary(DWORD,0)
loadlib user32
%%Temp = @lib(user32,GetCaretPos,BOOL:,INT:@addr("%a"))
freelib user32
%x = @val(@substr(%a,1,4))
%y = @val(@substr(%a,5, )
%%TSyntaxMemoHandle = "#TMainWin"
repeat
%%TSyntaxMemoHandle = @window(%%TSyntaxMemoHandle,CHILD)
until @equal(@winclass(%%TSyntaxMemoHandle),TSyntaxMemo)
%%TSyntaxMemoX = @winpos(%%TSyntaxMemoHandle,L)
%%TSyntaxMemoY = @winpos(%%TSyntaxMemoHandle,T)
%%LineNumber = @succ(@sendmsg(%%TSyntaxMemoHandle,$0C9,@sendmsg(%%TSyntaxMemoHandle,$0BB,-1,0),0))
%%Temp = @sendmsg(%%TSyntaxMemoHandle,$0B0,@addr("%a"))
%%BeginSelection = @val(@substr(%a,1,4))
list create,1
list assign,1,@wintext(%%TSyntaxMemoHandle)
dialog set,text1,Line: %%LineNumber Value: @item(1,@pred(%%LineNumber))
list close,1
dialog setpos,,@sum(%y,%%TSyntaxMemoY,-@dlgpos(,H)),@sum(%x,%%TSyntaxMemoX),@sum(@dlgpos(TEXT1,W),10)
end
goto Evloop
:Close
exit
:Error
warn error @error(e) on line @error(n)
exit |
_________________ [ Add autocomplete functionality to your VDS IDE windows! ]
Voor Nederlandse beginners met VDS: bekijk ook eens deze tutorial! |
|
| Back to top |
|
 |
CodeScript Moderator Team

Joined: 08 Jun 2003 Posts: 1060 Location: India
|
Posted: Sun Nov 23, 2003 2:16 am Post subject: |
|
|
Caret position is returned relative to the application window that has th caret rather than screen coordinates.
| Win32 Programmer's Reference wrote: | | The caret position is always given in the client coordinates of the window that contains the caret. |
BTW I have never been able to get this API working properly due to unknown reasons  _________________ Regards
- CodeScript
Give your application a professional look with the VDSGUI Extension |
|
| Back to top |
|
 |
CodeScript Moderator Team

Joined: 08 Jun 2003 Posts: 1060 Location: India
|
Posted: Sun Nov 23, 2003 6:42 am Post subject: |
|
|
| msdn wrote: | | A window can move a caret only if it already owns the caret. |
Probably (as it appears by testing) this applies to GetCaretPos too.
So when U run the script from the IDE your window owns it but when from a exe it doesnot ?? though I may be wrong. _________________ Regards
- CodeScript
Give your application a professional look with the VDSGUI Extension |
|
| Back to top |
|
 |
Serge Professional Member


Joined: 04 Mar 2002 Posts: 1480 Location: Australia
|
Posted: Sun Nov 23, 2003 7:48 am Post subject: |
|
|
hi skit,
| Code: | :Evloop
wait event,0.0001
goto @event() |
is that a good idea to use 0.0001? doesn't it make the vds program take up a lot of unnecessary cpu time? and is there a limit as to how many milliseconds we can stipulate with the WAIT EVENT command?
just wondering...
serge _________________
|
|
| Back to top |
|
 |
Skit3000 Admin Team

Joined: 11 May 2002 Posts: 2166 Location: The Netherlands
|
Posted: Sun Nov 23, 2003 9:57 am Post subject: |
|
|
Serge, I always just add some zeros to the wait command. I believe Mac or Garrett once made a program to test, and the minimum wait time was about 0.001, if you have three zeros or one hundred...
CodeScript, I thought about the owner of the window too, but MSDN says that it is returning the position relative to the application window which has the focus. So it shouldn't matter if you run it compiled or in the IDE...
| CodeScript wrote: | | So when U run the script from the IDE your window owns it but when from a exe it doesnot ?? though I may be wrong. |
You are right here. When you run it from the IDE window, it works (the yellow dialog follows the caret), but when you run it as a compiled exe, it stays in the upper-left corner of VDS...  _________________ [ Add autocomplete functionality to your VDS IDE windows! ]
Voor Nederlandse beginners met VDS: bekijk ook eens deze tutorial! |
|
| Back to top |
|
 |
CodeScript Moderator Team

Joined: 08 Jun 2003 Posts: 1060 Location: India
|
Posted: Sun Nov 23, 2003 11:43 am Post subject: |
|
|
Hi Skit
I think you can do away with GetCaretPos API.
Tsyntax memo supports RTF API and so U can get the
current caret position in terms of line (and column) number
Get the height of each line.
Get the first visible line.
Add the values of the (left and) upper coorinates of
the Tsyntax memo and Ht of each line * number of lines from the first visible line.
A bit convoluted and a lot of math involved.
I was exactly on a project like U - VDS autocomplete and
spell checker to add to my tray helper but I abandoned that
due to these and some more difficulties and time constraints.
Another even more complicated method may be to inject a dll
to the VDS process space to get the value.
BTW I will check if I can change the proceess thread ID
and this may help - only ray of hope  _________________ Regards
- CodeScript
Give your application a professional look with the VDSGUI Extension |
|
| Back to top |
|
 |
CodeScript Moderator Team

Joined: 08 Jun 2003 Posts: 1060 Location: India
|
Posted: Sun Nov 23, 2003 1:27 pm Post subject: |
|
|
Finally I think AttachThreadInput should do the trick (works fine on XP)
Let me know if it works
BTW it is not a vds bug (typical msdn )
I think additionally you need to use SetWindowPos
with SWP_NOACTIVATE rather than "dialog setpos"
to position your window else one cannot type
into the IDE. Thus the script is going to be a
bag of API.
May be better to move it to Advanced VDS 5 Help
| Code: | option errortrap,error
DIALOG CREATE,VDS Autocomplete,-1,0,300,15,NOTITLE,ONTOP,COLOR YELLOW,CLASS VDSCOMPLETE
DIALOG ADD,TEXT,TEXT1,0,5,,,TEXT1
dialog show
LOADLIB KERNEL32
loadlib user32
:Evloop
wait event,0.0001
goto @event()
:Timer
%%Active = @winactive(C)
if @equal(%%Active,TMainWin)@equal(%%Active,VDSCOMPLETE)
if @unequal(%%Visible,TRUE)
dialog show
%%Visible = TRUE
end
else
if @unequal(%%Visible,FALSE)
dialog hide
%%Visible = FALSE
GOTO EVLOOP
end
end
if @equal(%%Active,TMainWin)
REM Get the main VDS window which is active
%%foregroundwin = @LIB(USER32,GetForegroundWindow,int:,)
%%VDSCOMPLETE = @STRDEL(@WINEXISTS(#VDSCOMPLETE),1,1)
%%desktopwin = @LIB(USER32,GetDesktopWindow,int:,)
REM Set the parent of the #VDSCOMPLETE to desktop to prevent conflicts
REM in case the IDE is minimized/not active at startup
%Z = @LIB(USER32,SetParent,int:,%%VDSCOMPLETE,%%desktopwin)
%%WindowThreadID = @LIB(USER32,GetWindowThreadProcessId,int:,%%foregroundwin,0)
%%CurrentThreadID = @LIB(KERNEL32,GetCurrentThreadId,int:,)
REM Share the Input with VDS IDE so that we can see it's cursor
%Z = @LIB(USER32,AttachThreadInput,int:,%%CurrentThreadID,%%WindowThreadID,1)
IF %Z
%a = @binary(DWORD,0)@binary(DWORD,0)
%%Temp = @lib(user32,GetCaretPos,BOOL:,INT:@addr("%a"))
%x = @val(@substr(%a,1,4))
%y = @val(@substr(%a,5, )
REM Stop sharing as we want other events to be processed independently
%z = @LIB(USER32,AttachThreadInput,int:,%%CurrentThreadID,%%WindowThreadID,0)
END
%%TSyntaxMemoHandle = "#TMainWin"
repeat
%%TSyntaxMemoHandle = @window(%%TSyntaxMemoHandle,CHILD)
until @equal(@winclass(%%TSyntaxMemoHandle),TSyntaxMemo)
%%TSyntaxMemoX = @winpos(%%TSyntaxMemoHandle,L)
%%TSyntaxMemoY = @winpos(%%TSyntaxMemoHandle,T)
%%LineNumber = @succ(@sendmsg(%%TSyntaxMemoHandle,$0C9,@sendmsg(%%TSyntaxMemoHandle,$0BB,-1,0),0))
%%Temp = @sendmsg(%%TSyntaxMemoHandle,$0B0,@addr("%a"))
%%BeginSelection = @val(@substr(%a,1,4))
list create,1
list assign,1,@wintext(%%TSyntaxMemoHandle)
dialog set,text1,Line: %%LineNumber Value: @item(1,@pred(%%LineNumber))
list close,1
dialog setpos,,@sum(%y,%%TSyntaxMemoY,-@dlgpos(,H)),@sum(%x,%%TSyntaxMemoX),@sum(@dlgpos(TEXT1,W),10)
end
goto Evloop
:Close
FREELIB kernel32
freelib user32
exit
:Error
warn error @error(e) on line @error(n)
exit |
_________________ Regards
- CodeScript
Give your application a professional look with the VDSGUI Extension |
|
| Back to top |
|
 |
vdsalchemist Admin Team

Joined: 23 Oct 2001 Posts: 1448 Location: Florida, USA
|
Posted: Sun Nov 23, 2003 3:30 pm Post subject: |
|
|
CodeScript,
This is pretty cool stuff but I have some reservations about changing the parent of a control to the desktop window. First it would be better to set the parent to your own window. Second you should always return the control to it's original parent. Also if for some reason this script goes nuts it could leave a users IDE locked in memory. So Thread lightly Anyway before the timer is finished return the control to it's original parent and everything should work great. _________________ Home of
Give VDS a new purpose!
 |
|
| Back to top |
|
 |
FreezingFire Admin Team

Joined: 23 Jun 2002 Posts: 3508
|
Posted: Sun Nov 23, 2003 3:31 pm Post subject: |
|
|
| Serge wrote: | | is that a good idea to use 0.0001? doesn't it make the vds program take up a lot of unnecessary cpu time? |
Serge, I've checked out using WAIT EVENT,0 and it still doesn't use 100%
CPU, and I'm very glad that this was corrected in VDS 5. Using wait 0.01
will show almost a 0% CPU usage in Task Manager.  _________________ FreezingFire
VDSWORLD.com
Site Admin Team |
|
| Back to top |
|
 |
CodeScript Moderator Team

Joined: 08 Jun 2003 Posts: 1060 Location: India
|
Posted: Sun Nov 23, 2003 5:16 pm Post subject: |
|
|
| mindpower wrote: | | some reservations about changing the parent of a control to the desktop window. First it would be better to set the parent to your own window. |
mindpower
I have changed the Parent of the entire autocomplete window to Desktop window (not of any controls in it) and I don't think that's harmful. (?? all Top level windows are anyway descendants of Desktop I think)
| mindpower wrote: | | Also if for some reason this script goes nuts it could leave a users IDE locked in memory. |
I am detaching the thread from the VDS IDE by this code line soon after the caret position is retrieved:
| Code: | | %z = @LIB(USER32,AttachThreadInput,int:,%%CurrentThreadID,%%WindowThreadID,0) |
| Code: | BOOL AttachThreadInput(
DWORD idAttach, // thread to attach
DWORD idAttachTo, // thread to attach to
BOOL fAttach // attach or detach
); |
So I did not understand what U meant  _________________ Regards
- CodeScript
Give your application a professional look with the VDSGUI Extension |
|
| Back to top |
|
 |
Skit3000 Admin Team

Joined: 11 May 2002 Posts: 2166 Location: The Netherlands
|
Posted: Sun Nov 23, 2003 7:10 pm Post subject: |
|
|
The dialog keeps on getting the focus... I just want it to be a kind of 'hint'. Can anybody see what I do wrong?
| Code: | option errortrap,error
DIALOG CREATE,VDS Autocomplete,-1,0,300,15,NOTITLE,ONTOP,COLOR YELLOW,CLASS VDSCOMPLETE
DIALOG ADD,TEXT,TEXT1,0,5,,,TEXT1
dialog show
LOADLIB KERNEL32
loadlib user32
:Evloop
wait event,0.0001
goto @event()
:Timer
%%Active = @winactive(C)
if @equal(%%Active,TMainWin)@equal(%%Active,VDSCOMPLETE)
if @unequal(%%Visible,TRUE)
dialog show
%%Visible = TRUE
end
else
if @unequal(%%Visible,FALSE)
dialog hide
%%Visible = FALSE
GOTO EVLOOP
end
end
if @equal(%%Active,TMainWin)
rem Get the main VDS window which is active
%%foregroundwin = @LIB(USER32,GetForegroundWindow,int:,)
%%VDSCOMPLETE = @STRDEL(@WINEXISTS(#VDSCOMPLETE),1,1)
%%desktopwin = @LIB(USER32,GetDesktopWindow,int:,)
rem Set the parent of the #VDSCOMPLETE to desktop to prevent conflicts
rem in case the IDE is minimized/not active at startup
%Z = @LIB(USER32,SetParent,int:,%%VDSCOMPLETE,%%desktopwin)
%%WindowThreadID = @LIB(USER32,GetWindowThreadProcessId,int:,%%foregroundwin,0)
%%CurrentThreadID = @LIB(KERNEL32,GetCurrentThreadId,int:,)
rem Share the Input with VDS IDE so that we can see it's cursor
%Z = @LIB(USER32,AttachThreadInput,int:,%%CurrentThreadID,%%WindowThreadID,1)
IF %Z
%a = @binary(DWORD,0)@binary(DWORD,0)
%%Temp = @lib(user32,GetCaretPos,BOOL:,INT:@addr("%a"))
%x = @val(@substr(%a,1,4))
%y = @val(@substr(%a,5, )
rem Stop sharing as we want other events to be processed independently
%z = @LIB(USER32,AttachThreadInput,int:,%%CurrentThreadID,%%WindowThreadID,0)
END
%%TSyntaxMemoHandle = "#TMainWin"
repeat
%%TSyntaxMemoHandle = @window(%%TSyntaxMemoHandle,CHILD)
until @equal(@winclass(%%TSyntaxMemoHandle),TSyntaxMemo)
%%TSyntaxMemoX = @winpos(%%TSyntaxMemoHandle,L)
%%TSyntaxMemoY = @winpos(%%TSyntaxMemoHandle,T)
%%LineNumber = @succ(@sendmsg(%%TSyntaxMemoHandle,$0C9,@sendmsg(%%TSyntaxMemoHandle,$0BB,-1,0),0))
%%Temp = @sendmsg(%%TSyntaxMemoHandle,$0B0,@addr("%a"))
%%BeginSelection = @val(@substr(%a,1,4))
list create,1
list assign,1,@wintext(%%TSyntaxMemoHandle)
dialog set,text1,Line: %%LineNumber Value: @item(1,@pred(%%LineNumber))
list close,1
# Code to position the dialog...
%x = @sum(%x,%%TSyntaxMemoX)
%y = @sum(%y,%%TSyntaxMemoY,-@dlgpos(,H))
%%cx = @sum(@dlgpos(TEXT1,W),10)
%%cy = @dlgpos(,H)
%%Temp = @lib(user32,SetWindowPos,BOOL:,@strdel(@winexists(@dlgtext()),1,1),"-1",%x,%y,%%cx,%%cy,$10)
# Old line of code I used:
# dialog setpos,,@sum(%y,%%TSyntaxMemoY,-@dlgpos(,H)),@sum(%x,%%TSyntaxMemoX),@sum(@dlgpos(TEXT1,W),10)
end
goto Evloop
:Close
FREELIB kernel32
freelib user32
exit
:Error
warn error @error(e) on line @error(n)
exit |
_________________ [ Add autocomplete functionality to your VDS IDE windows! ]
Voor Nederlandse beginners met VDS: bekijk ook eens deze tutorial! |
|
| Back to top |
|
 |
FreezingFire Admin Team

Joined: 23 Jun 2002 Posts: 3508
|
Posted: Sun Nov 23, 2003 10:34 pm Post subject: |
|
|
What if you just reactivated the IDE when after you create your hint window?  _________________ FreezingFire
VDSWORLD.com
Site Admin Team |
|
| Back to top |
|
 |
Serge Professional Member


Joined: 04 Mar 2002 Posts: 1480 Location: Australia
|
Posted: Mon Nov 24, 2003 6:35 am Post subject: |
|
|
thanks for your reply ff and skit...i naturally assumed that if the event loop occurs every thousandth of a second, then it would take up a lot of cpu time...good to hear that it is not the case
serge _________________
|
|
| Back to top |
|
 |
CodeScript Moderator Team

Joined: 08 Jun 2003 Posts: 1060 Location: India
|
Posted: Mon Nov 24, 2003 9:25 am Post subject: |
|
|
| FreezingFire wrote: | What if you just reactivated the IDE when after you create your hint window?  |
Repeated activation/deactivation of IDE may drive user crazy
I think I have fixed the culprits:
1.SetParent will now be called only once when
the VDS IDE is restored.
2.Dialog Hide and Dialog Show replaced by Window Hide and Window Normal.
3.SWP_NOZORDER flag added to SetWindowPos (because U don't want to change the ontop
style of the hint window I suppose).
4."Dialog set" Called only if a line changes - as too frequent calls can change the focus to the autocomplete window.
Finally I have implemented something which is actually condemned.
I am not detaching the thread from IDE till app exit.
But even on repeated "test crashes" of the app there were
neither any errors in VDS IDE nor any GPFs or memory locks.
After all I don't think Skit is going to design a app that
crashes every now and then
(I did this becuse no other method could work as reliably)
There are other ways if U don't want the hint dialog to ever
get focus (but i suppose U need it because - U might be adding
a Rt click menu/buttons etc for autocorrect options)
Here is the modified script. Hope it works well.
| Code: | option errortrap,error
DIALOG CREATE,VDS Autocomplete,-1,0,300,15,NOTITLE,ONTOP,COLOR YELLOW,CLASS VDSCOMPLETE
DIALOG ADD,TEXT,TEXT1,0,5,,,
dialog show
LOADLIB KERNEL32
loadlib user32
:Tryagain
%%foregroundwin = @LIB(USER32,GetForegroundWindow,int:,)
%%VDSCOMPLETE = @STRDEL(@WINEXISTS(#VDSCOMPLETE),1,1)
if @equal(@WINCLASS("%"%%foregroundwin),TMainWin)
rem Get the main VDS window which is active
%%WindowThreadID = @LIB(USER32,GetWindowThreadProcessId,int:,%%foregroundwin,0)
IF %%WindowThreadID
REM %%CurrentThreadID = @LIB(KERNEL32,GetCurrentThreadId,int:,)
%%CurrentThreadID = @LIB(USER32,GetWindowThreadProcessId,int:,%%VDSCOMPLETE,0)
END
rem Share the Input with VDS IDE so that we can see it's cursor
IF %%CurrentThreadID
REM %Z = @SENDMSG("%"%%foregroundwin,$203,$1,0)
WINDOW SEND,"%"%%foregroundwin,@KEY(ESC)
%Z = @LIB(USER32,AttachThreadInput,int:,%%CurrentThreadID,%%WindowThreadID,1)
END
GOTO EVLOOP
ELSE
WAIT 0.5
GOTO Tryagain
END
:Evloop
wait event,0.0001
goto @event()
:Timer
%%Active = @winactive(C)
if @equal(%%Active,TMainWin)@equal(%%Active,VDSCOMPLETE)
if @unequal(%%Visible,TRUE)
%%Visible = TRUE
%%desktopwin = @LIB(USER32,GetDesktopWindow,int:,)
rem Set the parent of the #VDSCOMPLETE to desktop to prevent conflicts
rem in case the IDE is minimized/not active at startup
%Z = @LIB(USER32,SetParent,int:,%%VDSCOMPLETE,%%desktopwin)
WINDOW NORMAL,#VDSCOMPLETE
end
else
if @unequal(%%Visible,FALSE)
WINDOW HIDE,#VDSCOMPLETE
%%Visible = FALSE
%Z = @LIB(USER32,SetParent,int:,%%VDSCOMPLETE,%%desktopwin)
GOTO EVLOOP
end
end
%%foregroundwin = @LIB(USER32,GetForegroundWindow,int:,)
if @equal(@WINCLASS("%"%%foregroundwin),TMainWin)
%a = @binary(DWORD,0)@binary(DWORD,0)
%%Temp = @lib(user32,GetCaretPos,BOOL:,INT:@addr("%a"))
%x = @val(@substr(%a,1,4))
%y = @val(@substr(%a,5, )
%%TSyntaxMemoHandle = "#TMainWin"
repeat
%%TSyntaxMemoHandle = @window(%%TSyntaxMemoHandle,CHILD)
until @equal(@winclass(%%TSyntaxMemoHandle),TSyntaxMemo)
%%TSyntaxMemoX = @winpos(%%TSyntaxMemoHandle,L)
%%TSyntaxMemoY = @winpos(%%TSyntaxMemoHandle,T)
%%LineNumber = @succ(@sendmsg(%%TSyntaxMemoHandle,$0C9,@sendmsg(%%TSyntaxMemoHandle,$0BB,-1,0),0))
%%Temp = @sendmsg(%%TSyntaxMemoHandle,$0B0,@addr("%a"))
%%BeginSelection = @val(@substr(%a,1,4))
list create,1
list assign,1,@wintext(%%TSyntaxMemoHandle)
REM Only if a new value is there set it
REM Bombarding the "dialog set" will activate
REM this window !
IF @unequal(%%oldtext,@item(1,@pred(%%LineNumber)))
dialog set,text1,Line: %%LineNumber Value: @item(1,@pred(%%LineNumber))
%%oldtext = @item(1,@pred(%%LineNumber)))
END
list close,1
# Code to position the dialog...
%x = @sum(%x,%%TSyntaxMemoX)
%y = @sum(%y,%%TSyntaxMemoY,-@dlgpos(,H))
%%cx = @sum(@dlgpos(TEXT1,W),10)
%%cy = @dlgpos(,H)
%%Temp = @lib(user32,SetWindowPos,BOOL:,@strdel(@winexists(#VDSCOMPLETE),1,1),0,%x,%y,%%cx,%%cy,@SUM($10,$4))
end
goto Evloop
:Close
REM Detach the Thread to prevent a crash!
%Z = @LIB(USER32,AttachThreadInput,int:,%%CurrentThreadID,%%WindowThreadID,0)
FREELIB kernel32
freelib user32
exit
:Error
warn error @error(e) on line @error(n)
REM No Exit here - Go to close label and cleanup!
GOTO CLOSE |
_________________ Regards
- CodeScript
Give your application a professional look with the VDSGUI Extension |
|
| Back to top |
|
 |
Skit3000 Admin Team

Joined: 11 May 2002 Posts: 2166 Location: The Netherlands
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You can attach files in this forum You can download files in this forum
|
|