BBC BASIC for Windows
« Searching in the IDE »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 9:52pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Searching in the IDE  (Read 992 times)
Hans
Guest
xx 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.
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx 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 » User IP Logged

hans
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 6
xx 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.
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx 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:

  1. Forward the original EMU_SETSEL message.
  2. Perform the 12-up, 24-down, 12-up cursor movement.
  3. 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 » User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx 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
 
User IP Logged

hans
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 6
xx 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
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx 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:
      CALL @lib$+"IDE" 

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 » User IP Logged

hans
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 6
xx 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
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx 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.
User IP Logged

hans
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 6
xx 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
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls