Author |
Topic: Searching in the IDE (Read 992 times) |
|
Hans
Guest
|
 |
Searching in the IDE
« Thread started on: Apr 11th, 2011, 08:27am » |
|
When I am searching in the IDE for a specific piece of text, the line with that text is always shown on the very last line of the window. That makes only half of the context around the search string immediately visible. I would like the search string to be placed on the middle line in the IDE, so that as much as possible of the context is visible in the window.
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Searching in the IDE
« Reply #1 on: Apr 11th, 2011, 09:11am » |
|
on Apr 11th, 2011, 08:27am, Guest-Hans wrote:When I am searching in the IDE for a specific piece of text, the line with that text is always shown on the very last line of the window. |
|
That's not strictly true. The algorithm used is that the minimum amount of scrolling is performed. So if the item you are searching for is already visible the display won't scroll at all. If the item is below the current visible window the display will scroll until it is on the bottom line. If the item is above the current visible window the display will scroll until it is on the top line.
Quote:I would like the search string to be placed on the middle line in the IDE, so that as much as possible of the context is visible in the window. |
|
The simplest approach is to define a macro key which moves the text cursor up (say) 12 lines, down 24 lines, and then back up 12 lines. The effect will be to return the cursor (caret) to its original position, but if necessary the display will scroll so that it is at least 12 lines from the top or the bottom of the window.
You can easily do this using the supplied Macro Recorder utility. Once you have defined the macro key, you need only press it after you have performed the Find operation in order to move the item nearer to the middle of the window (the highlighting will be cleared as a side-effect).
A more complex solution would be to write an add-in utility which performs the required operation, but that's non-trivial!
Richard.
|
« Last Edit: Apr 11th, 2011, 11:17am by admin » |
Logged
|
|
|
|
hans
New Member
member is offline


Gender: 
Posts: 6
|
 |
Re: Searching in the IDE
« Reply #2 on: Apr 13th, 2011, 8:13pm » |
|
Yes, it's easy to make such a macro, but it doesn't really help because you need even more mouseclicks to get the line with the found string somewhere in the middle of the window and you lose the highlighting. What I wanted to achieve is that you can keep your mouse on the button in the little search window on the search next button and with each click see the next found string highlighted somewhere in the middle of the screen. That would minimise the mouseclicks and scrolls during the search.
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Searching in the IDE
« Reply #3 on: Apr 13th, 2011, 9:35pm » |
|
on Apr 13th, 2011, 8:13pm, hans wrote:What I wanted to achieve is that you can keep your mouse on the button in the little search window on the search next button and with each click see the next found string highlighted somewhere in the middle of the screen. |
|
To do that would require an 'external' (e.g. 'add-in') utility to be written. Since the fundamental issue is how the editor responds to the EMU_SETSEL message (which is responsible for highlighting the text and scrolling the screen) the minimum-effort solution would be to intercept that message and replace it with, for example, the following sequence of operations:
Forward the original EMU_SETSEL message. Perform the 12-up, 24-down, 12-up cursor movement. Repeat the EMU_SETSEL message to re-establish the highlight. Subclassing the window procedure in another process is an advanced technique (requiring some assembler code), but it's how the Module Viewer utility works so it's definitely possible.
Richard.
|
« Last Edit: Apr 13th, 2011, 9:38pm by admin » |
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Searching in the IDE
« Reply #4 on: Apr 14th, 2011, 10:11pm » |
|
Here's an 'in-process' program which does it. You need only execute that once, after starting BB4W, and your preferred highlighting behaviour will happen for the rest of the session.
Richard.
Code: REM Program to cause 'found' text to be highlighted near middle of screen
INSTALL @lib$+"CALLBACK"
ContextGap% = 14
REM!WC Windows Constants:
EMU_SETSEL = 1041
GWL_WNDPROC = -4
MEM_COMMIT = 4096
PAGE_EXECUTE_READWRITE = 64
VK_DOWN = 40
VK_UP = 38
WM_KEYDOWN = 256
SYS "GetWindowThreadProcessId", @hwnd%, ^pid%
SYS FN_syscalls("EnumWindows"), FN_callback(FNenumwinfunc(), 2), pid%
res% = FN_sysresult
SYS "FindWindowEx", hMain%, 0, "BBCEdit", 0 TO hEdit%
IF hEdit% = 0 ERROR 0, "Failed to find edit window handle"
SYS "VirtualAlloc", 0, 256, MEM_COMMIT, PAGE_EXECUTE_READWRITE TO P%
[OPT 2
.oldeditwndproc
dd 0
;
.defeditwndproc
pop eax : push [oldeditwndproc] : push eax
jmp "CallWindowProc"
;
.neweditwndproc
mov eax,[esp+8] ; iMsg
cmp eax,EMU_SETSEL
jnz defeditwndproc
push dword [esp+16] ; lParam
push dword [esp+16] ; wParam
push dword [esp+16] ; iMsg
push dword [esp+16] ; hWnd
call defeditwndproc ; forward EMU_SETSEL
mov ecx,ContextGap%
.up1
push ecx
push 0 ; lParam
push VK_UP ; wParam
push WM_KEYDOWN ; iMsg
push dword [esp+20] ; hWnd
call defeditwndproc ; cursor up
pop ecx
loop up1
mov ecx,ContextGap%*2
.down
push ecx
push 0 ; lParam
push VK_DOWN ; wParam
push WM_KEYDOWN ; iMsg
push dword [esp+20] ; hWnd
call defeditwndproc ; cursor down
pop ecx
loop down
mov ecx,ContextGap%
.up2
push ecx
push 0 ; lParam
push VK_UP ; wParam
push WM_KEYDOWN ; iMsg
push dword [esp+20] ; hWnd
call defeditwndproc ; cursor up
pop ecx
loop up2
push dword [esp+16] ; lParam
push dword [esp+16] ; wParam
push dword [esp+16] ; iMsg
push dword [esp+16] ; hWnd
call defeditwndproc ; forward EMU_SETSEL again
ret 16
]
SYS "GetWindowLong", hEdit%, GWL_WNDPROC TO !oldeditwndproc
SYS "SetWindowLong", hEdit%, GWL_WNDPROC, neweditwndproc
END
DEF FNenumwinfunc(hwnd%, param%)
LOCAL pid%, class%
SYS "GetWindowThreadProcessId", hwnd%, ^pid%
IF pid% = param% THEN
DIM class% LOCAL 255
SYS "GetClassName", hwnd%, class%, 255
IF $$class% = "BBCWin" THEN hMain% = hwnd% : = 0
ENDIF
= 1
|
|
Logged
|
|
|
|
hans
New Member
member is offline


Gender: 
Posts: 6
|
 |
Re: Searching in the IDE
« Reply #5 on: Apr 15th, 2011, 12:04pm » |
|
Thanks for this program. It does exactly what I wanted to achieve. I did change the END in QUIT and as long as the program is mentioned in the 'last opened' list, it now only takes 2 mouseclicks at the beginning of the session.
I have also made another method: I put the program in a procedure and saved it in the library folder. From within my program I call it with: INSTALL @lib$+"IDE.bbc" : PROC_IDE(20) (The 20 is the value for ContextGap%)
In this manner I can avoid the 2 mouseclicks in the beginning, but the program is run many times during 1 session. Might this be a problem? Is there a way to let the program know that in the current session this already has been done, so it returns faster from IDE.bbc?
Hans
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Searching in the IDE
« Reply #6 on: Apr 15th, 2011, 1:50pm » |
|
on Apr 15th, 2011, 12:04pm, hans wrote:From within my program I call it with: INSTALL @lib$+"IDE.bbc" : PROC_IDE(20) |
|
Remember that you can run a program from another program (with the END changed to RETURN) just by doing:
Code: Quote:the program is run many times during 1 session. Might this be a problem? |
|
Yes, a major problem!! Each time you run the program you add an extra level of subclassing, so if you run it twice the sequence you get is:
EMU_SETSEL cursor up 12 cursor down 24 cursor up 12 EMU_SETSEL cursor up 12 cursor down 24 cursor up 12 EMU_SETSEL cursor up 12 cursor down 24 cursor up 12 EMU_SETSEL
This will rapidly proliferate to hundreds or thousands of calls as the result of a single EMU_SETSEL! This will at best make the IDE slow, and at worst will crash the entire system.
Quote:Is there a way to let the program know that in the current session this already has been done, so it returns faster from IDE.bbc? |
|
You'd need to create something like a MUTEX.
In your position I'd program up a macro key to run the program (enter immediate mode; CALL the program from the immediate prompt; QUIT), then you only have to press one key once at the start of a session to install it.
Richard.
|
« Last Edit: Apr 15th, 2011, 2:26pm by admin » |
Logged
|
|
|
|
hans
New Member
member is offline


Gender: 
Posts: 6
|
 |
Re: Searching in the IDE
« Reply #7 on: Apr 15th, 2011, 8:06pm » |
|
Okay, I will not do it more than once per session. I was trying to create such a macro, as you described, but I don't get it working as you suggested. What I do is: Start the macro recording. Go to immediate mode. Type CALL @lib$+"IDE" : QUIT press enter. Stop recording. When I now press shift-F1, the text CALL @lib$+"IDE" : QUIT appears in the ide, but it is not executed automatically. When I press F9 to run it, it does run and functions as intended. Am I doing something wrong now?
Hans
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Searching in the IDE
« Reply #8 on: Apr 15th, 2011, 9:25pm » |
|
on Apr 15th, 2011, 8:06pm, hans wrote:Am I doing something wrong now? |
|
I can't be certain from your description, but it sounds as though you're not entering immediate mode using the keyboard. Keyboard macros only record keystrokes, not mouse operations, so it's essential that everything you need to record is done using the keyboard.
So entering immediate mode must be done using Alt-RI. If that's what you used, I don't know why it didn't work.
Richard.
|
|
Logged
|
|
|
|
hans
New Member
member is offline


Gender: 
Posts: 6
|
 |
Re: Searching in the IDE
« Reply #9 on: Apr 16th, 2011, 07:48am » |
|
Yes Richard, you were right. Entering immediate mode the wrong way was my problem. I wasn't even aware of the possibility to do it via Alt-RI, but I did now and it works perfectly.
Thsank you fol all of your terrific help,
Hans
|
|
Logged
|
|
|
|
|