• Welcome to Jose's Read Only Forum 2023.

CSED - Modification

Started by Gary Beene, October 17, 2013, 02:31:56 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Gary Beene

I was looking at CSED and wanted to see if I could modify it highlight the name of a function/method, then have CSED jump to that function/method - regardless of which file/TAB it is in.  Perhaps a context menu with "GoTo Function Under Cursor", or something like that.   I don't see that feature  right now.

Has anyone already done a mod like that?

Doesn't seem like it would be terribly hard, but it's always best to see if the job's already been done!

José Roca

I remember that I implemented it in the old SED editor. There was also a shortcut key to go back. That editor had more features than CSED, but as it was my first SDK application it was not as well structured as CSED. Besides, there were apportations of several people that later left the project and was a nightmare to me to update the code with each new version of PB. I write CSED from scratch and decided to implement only the features that I use and allow others to use it to make their own versions if they wish.

I also used CSED to test my CWindows class and wrappers and the beta versions of the new compilers. It was the first PB application to be fully unicode and High DPI aware.

Gary Beene

I downloaded v1.03 (that's the latest, yes) and tried to compile with PBWin10.

This line fails (line #963 in CSED.bas):
If hwndClient Then AfxShowFileProperties(hwnd, AfxGetWindowText(MdiGetActive(hwndClient))), %TRUE)

Looking at your afxshell.inc file, the AfxShowFileProperties requires only 2 arguments, but you have 3 in the CSED.bas code.

It looks like the %True show be removed. Is that true?

Pierre Bellisle

Hey Gary,

I got this...

••• CSED103_Source\CSED.BAS
IF hwndClient THEN AfxShowFileProperties(hwnd, AfxGetWindowText(MdiGetActive(hwndClient)), %TRUE)

••• José\Windows API Headers\2.05\AfxShell.inc

••• José\Windows API Headers\\AfxShell.inc

So I guess it's true that %true should be thrown away...   ;D

Gary Beene

Howdy Pierre!
Always good to hear from you!

I compiled it successfully without the %TRUE. I'll watch for any obnoxious behaviour.  But based on what 2.05 says it was for, looks like its a no-impact change!

Pierre Bellisle

According to 2.05 this was a flag to generate a messagebox in case of a ShellExecuteEx error,
like "File not found", "Path not found", "Access denied", etc.

So, no big deal I guess....


José Roca

There are not side effects. Just remove the %TRUE parameter.

Theo Gottwald

Gary, there are a few more bits that you can change in CSED.
I remember that i changed a setting that influences the quality of the font-drawing.
Possibly Jose remembers the exact parameters. It had to do with the scintilla control.

José Roca

In the file CSED_SCI.INC, after

' ========================================================================================
' Set Scintilla Edit Control's options
' ========================================================================================
SUB CSED_SetScintillaOptions (BYVAL hSci AS DWORD, BYVAL strFileExt AS STRING)

   LOCAL bitsNeeded AS LONG   ' // Number of bits needed by the lexer for styling

   ' // Get direct pointer for faster access
   LOCAL pSci AS DWORD   ' // Scintilla's direct pointer
   pSci = SCI_GetDirectPointer(hSci)
   IF pSci = 0 THEN EXIT SUB


   ' // If Vista/Windows 7, use Direct Write for higher quality antialiased drawing
   IF AfxGetWindowsVersion => 6 THEN
      SCIP_SetBufferedDraw(pSci, 0)

But you need to download the latest version of SciLexer.dll. Older versions were buggy and it did not worked.

Gary Beene

I've completed the mod (well, still testing, but good so far). Other than some code to add a new context menu, "Find Procedure", I was able to keep the change down to a single function which I placed in csed.bas

User action is like this:
1. Highlight text (a function/sub/method/fastproc name)
2. Right click and select a new context menu item , "Find Procedure"
3. Click the menu item to search open files for a procedure by the name of the selected text
4. If found, matching TAB/text is selected/highlighted. Document scrolls to the matching procedure.
5. If not found, a MsgBox pops up with "Procedure NOT found ..." + selectedtext

There's no Find Next - I assume there's only one procedure by the selected name.

Here's the function I added. It's called when the context menu is selected. I pulled the basic enumeration code from CSED_TabCtrl.INC, then added the search lines from some code I already had on hand.

Jose, the pSed.hEdit values seems to get updated by the enumeration code (MDIActive, I'd guess). Is that right?

If there's any obvious problem with this code being compatible with the rest of the CSED code, please let me know! 

Sub LocateProcedure_BEENE(temp$)        'temp$ is highlighted text
   Local i,j,iResult,nTAB As Long, hMDI As Dword
   Local vPath As Variant, tmp$, FindStructure As SCI_TextToFind

   'strings to look for--------------------------------
   tmp$ = LTrim$(LCase$(temp$))
   Dim target(6) As StringZ * 65
   target(0) = "sub " + tmp$               : target(1) = "function " + tmp$
   target(2) = "static sub " + tmp$        : target(3) = "static function " + tmp$
   target(4) = "callback function " + tmp$ : target(5) = "fastproc function " + tmp$
   target(6) = "method " + tmp$

   'enumerate Edit windows-----------------------------
   AfxDisableWindowRedraw pSed.hwndClient                   'disable redraw
   hMDI = GetWindow(pSed.hwndClient, %GW_Child)
   While hMDI
      vPath = AfxGetWindowText(hMdi)                        'get path from the collection
      nTab = CSED_GetTabNumberFromPath(Variant$$(vPath))    'get TAB number from Path
      TabCtrl_SetCurSel(pSed.hTabMdi, nTab)                 'select the TAB
      MDIActivate(pSed.hwndClient, hMdi)                    'activate this MDI child window
      '---highlight search string, if found, in newly activated TAB edit control ----------
         For j = 0 To UBound(target)
            FindStructure.Chrg.cpMin = 0
            FindStructure.Chrg.cpMax = SendMessage(pSed.hEdit,%SCI_GetLength,0,0)
            FindStructure.lpstrText = VarPtr(target(j))
            iResult = SendMessage (pSed.hEdit, %SCI_FindText, 0, VarPtr(FindStructure))
            If iResult > -1 Then
               SendMessage pSed.hEdit, %SCI_SetSel, FindStructure.ChrgText.cpMin, FindStructure.ChrgText.cpMax
               AfxEnableWindowRedraw pSed.hwndClient        'enable redraw
               If pSed.hEdit Then RedrawWindow pSed.hEdit, ByVal %NULL, %NULL, %RDW_ERASE Or %RDW_FRAME Or %RDW_INVALIDATE
               Exit Loop
            End If
         Next j
      hMDI = GetWindow(hMDI, %GW_HWNDNEXT)
   If iResult = - 1 Then MsgBox "Procedure NOT found ...  " + tmp$, %MB_Ok + %MB_IconExclamation, "Search for Procedure"
End Sub

José Roca

When you call pSed.hEdit, you always get the handle of the active scintilla control, because it does not return you an stored value, but is a property that retrieves it by calling GetDlgItem(MdiGetActive(m_hwndClient), %IDC_EDIT).

Gary Beene

Thanks for that explanation. Now that you describe where hEdit comes from, I can see that in your code.

It occurred to me that there should be a simpler way to enumerate the TABs/Scintilla controls than what I used up above, one that doesn't require the use of the vpath approach.

This snippet is what I'm thinking ...
   TABCount = SendMessage(pSed.hTabMdi, %TCM_GetItemCount,0,0)
   For i = 0 To TabCount
      TabCtrl_SetCurSel(pSed.hTabMdi, i)       'select the TAB
      hMDI = ?????                             '<---- how to get hMDI of i-th TAB
      MDIActivate(pSed.hwndClient, hMdi)       'activate this MDI child window
      '--- search/highlight code goes here
   Next i

But I haven't been able to figure out the line that gets the hMDI value in each pass of the loop.  Would you point me in the right direction? 

José Roca

I'm afraid not. The scintilla controls are not children of the tab controls. Therefore, selecting a tab does not activate any window. To get hMdi you have to call MdiGetActive, but as the active window has not changed, you will always get the same handle (the one of the last activated MDI child window) no mather of which tab you select.

Paul Squires

Just a suggestion:
Instead of highlighting the text and then selecting from a menu to search for the procedure, try getting the word at the current cursor position and then select the find procedure from the menu. Eliminating the need to highlight the word first is common in most editors/IDE's.
Paul Squires
FireFly Visual Designer SQLitening Database System JellyFish Pro Editor

Aslan Babakhanov

BTW, this option is available in QB (4.5, 7.1) ide's. You just move cursor to the sub/function name and pressing F2, then immediately getting in to the list of subroutines with highlighted function/sub. You only need to press ENTER key to jump. If I'm not mistaken, that worked even with included files. Say you have main.bas and two included files incl1.inc and incl2.inc. Function AAA placed in incl2.inc file and called from main.bas. You move cursor to AAA sub in main.bas and pressing F2 - Ide immediately showing the list of all subs and moving cursor to the AAA sub in incl2.inc file... Pretty easy and helpful, if you want to tap onto desired sub right from cursor, without touching the mouse.