Help with (non-mod-based) Scintilla control

Started by chalky, June 10, 2024, 20:56:09

Previous topic - Next topic

chalky

I have had a really enjoyable time trying to create a basic IDE for CVBasic - a BASIC compiler which targets z80 CPUs. To do this I have been using some Scintilla based code which [I'm assuming] I downloaded some time ago from the web. Since it uses "SciLever.dll", I have no idea how old it is, or what version. There is clearly functionality that has been added since the version of "SciLexer.dll" I am using was created, which doesn't help when referring to the current online documentation (which I find very confusing, as I struggle with which function-names should be sent to the editor rather than the lexer and vice-versa).

Unfortunately, try as I might, I have been unable to get the MaxGUI Scintilla mod to compile, and other code examples I have found won't run either due to an "overriding method" differing type error. However, the code I have created now has [rudimentary - the keyword file is bodged, as the 'language' has not been properly defined] colour-coding, load, save, cut, copy, paste, find, replace, undo and redo all working - which I am pretty pleased with considering the fact I [initially] hadn't a clue what I was doing!  :P

I now have only 2 outstanding things I need to add:

1) Functionality to print the contents of the Scintilla textarea (I can export to PDF using code I wrote a while back - but being able to print to a printer would be far better)

2) A language file for CVBasic (this seems incredibly complicated - though I don't totally understand what's required as some people on the web suggest it can be done via an xml file, while others say you need to build a Lexer cxx file [way beyond my capabilities, I think]).

I am struggling with how to do either of these (I looked at the MaxIDE code for inspiration, but it is WAY cleverer than my brain can comprehend and I cannot fathom how it works!) - if anyone can help with either of the above I would be very grateful.

Baggey

I didn't know CVbasic existed. I do now :)

This is just the sort of thing id like to have ago at doing! And integrating it into my emulators. Keep up the good work. Im sure you'll get there in the end.

I look forward to seeing this when it's ready. ;D

Kind Regards Baggey
Running a PC that just Aint fast enough!? i7 4Ghz Quad core 24GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

chalky

Ok - after spending almost 2 days trying to write my own print/printer routines, I have sorted the print functionality simply by cloning the Scintilla textarea and using GadgetPrint (d'oh!)...

However... the printer dialog displayed by GadgetPrint always appears in the top left corner of the screen no matter where my application window is. Can the position at which it opens be changed?

chalky

Quote from: chalky on June 11, 2024, 17:27:36However... the printer dialog displayed by GadgetPrint always appears in the top left corner of the screen no matter where my application window is. Can the position at which it opens be changed?

In case anyone's interested...

Because the print dialog halts execution of my IDE, I could not move its window while it was being displayed. However, I found a way to do it by launching this from within my IDE before the GadgetPrint statement (I had to add a Delay(250) to prevent a nasty flicker as the dialog window appeared at 0,0 before being moved by my program):

SuperStrict

Import maxgui.drivers

Extern "win32"
    Function FindWindowA(lpClassName$z,lpWindowName$z)
EndExtern

Local oHnd:Long=-1
Local wHnd:Long
Local wTxt:String

Repeat
    wHnd=GetForegroundWindow()
    If wHnd<>oHnd Then
        wTxt=GetWindowText(wHnd)
        oHnd=wHnd
        If wTxt="Print" Then
            MovePrintWindow(wHnd)
            Exit
        EndIf
    EndIf
    Delay 1
Forever
End

Function GetWindowText:String(_hWnd:Long)
    Local tLen:Long
    Local strText:Short[]

    tLen=GetWindowTextLengthW(_hWnd)+1    ' must have NULL terminator
    strText=strText[..tLen]
    GetWindowTextW(_hwnd,strText,tLen)
    Return String.FromWString(strText)
EndFunction

Function MovePrintWindow(_hWnd:Long)
    Local cRect:Int[4]                    ' tagRECT structure
    Local cX:Long,cY:Long,cW:Long,cH:Long
    Local crPtr:Int Ptr=Varptr(cRect)     ' pointer to tagRECT structure
    Local cwHnd:Long
    Local dRect:Int[4]                    ' tagRECT structure
    Local dX:Long,dY:Long,dW:Long,dH:Long
    Local drPtr:Int Ptr=Varptr(dRect)     ' pointer to tagRECT structure
    ' get container window info
    cwHnd=FindWindowA(Null,"CVBasic IDE")
    GetWindowRect(cwHnd,crPtr)
    cX=cRect
    cY=cRect[1]
    cW=cRect[2]-cX
    cH=cRect[3]-cY
    ' get printer dialog info
    GetWindowRect(_hWnd,drPtr)
    dW=dRect[2]-dRect
    dH=dRect[3]-dRect[1]
    dX=(cW-dW)/2
    dY=(cH-dH)/2
    ' centralise dialog over container
    MoveWindow(_hWnd,cX+dX,cY+dY,dW,dH,1)
EndFunction

The program only has to run for a second, then exits immediately after moving the dialog. The maxgui import is there because I have come to the comclusion that I am never going to get my head found Extern function declarations ("undefined reference to") and had continual errors trying to define GetWindowTextW and GetWindowTextLengthW without it.

chalky

Quote from: Baggey on June 11, 2024, 13:58:42I look forward to seeing this when it's ready. ;D

Well - it's as ready as I think it's ever going to be, and can be found here: CVBasic IDE

It's pretty basic as editors go, but does the job. If I ever get my head around how to define/call external OS functions from within legacy BlitzMax and work out how to write a proper language file for Scintilla I may revisit this in the future, but until then this is as good as I can do... :)

Baggey

Quote from: chalky on June 16, 2024, 16:20:05
Quote from: Baggey on June 11, 2024, 13:58:42I look forward to seeing this when it's ready. ;D

Well - it's as ready as I think it's ever going to be, and can be found here: CVBasic IDE

It's pretty basic as editors go, but does the job. If I ever get my head around how to define/call external OS functions from within legacy BlitzMax and work out how to write a proper language file for Scintilla I may revisit this in the future, but until then this is as good as I can do... :)
You say it's as ready as it'll ever be  :'(

I had a play with it this afternoon and the IDE is very good. Shame there's no Dark theme? It would be a very nice option.

Im missing the "manual.txt" file.

I have to say if this is Done in BlitzMax it's very professional looking and shame you may not finish it :(

Im looking to have a go at something like this, but integrate it into my SpecMax128K Emulator.

Im starting to get pointers on it but not sure how to get started? :-X

If this is in BlitzMax you may need to post snippets of working code to get help with it!

There are some very talented clever people here! 8) Who may be able to help you complete your quest. I have to say it's looking very good don't give up ;)

Kind Regards Baggey
Running a PC that just Aint fast enough!? i7 4Ghz Quad core 24GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

chalky

Thanks Baggey for your kind words.

The "manual.txt" file is part of cvbasic (the user guide) and should be in your cvbasic installation folder so I'm not sure why you don't have it...

Darkmode: I tried to create a skinnable interface for MaxGUI a few years ago. Unfortunately not all gadgets can be fully configured via SetGadgeColor & SetGadgetTextColor (e.g. comboboxes will still display their button and dropdown list in original background/foreground colours) and I couldn't work out how to subclass these from within BlitzMax. At one point I even considered coding my own set of controls - before realising I didn't have enough years left to finish it! :o

dawlane

Quote from: chalky on June 17, 2024, 08:29:59Unfortunately not all gadgets can be fully configured via SetGadgeColor & SetGadgetTextColor (e.g. comboboxes will still display their button and dropdown list in original background/foreground colours) and I couldn't work out how to subclass these from within BlitzMax.
If I remember the MaxGUI Microsoft Windows relies on the Win32 API, which doesn't support dark mode. You could try to modify the BlitzMax code to try to use the mysterious Dark Mode Win32 API hacks that Microsoft use, but that keeps changing. The only way to effectively change a number of controls would be to subclass those Win32 API controls that do not allow programmatically changing colour, make the changes to do your own drawing routines. You would then have to make the necessary changes to the BlitzMax code.

chalky

Well - thanks to Baggey's encouragement I carried on with this - the latest version can be found here: CVBasic IDE v1.1.6

This was all done in MaxGUI, including a bespoke control which I created to replace the standard ListBox (as I couldn't get LB_SetTopIndex to work no matter what I tried). It's a much better beast than the original, with code-checking and compiler output integration, as well as IDE themes, label pane (bookmarks) and integrated CVBasic help.

I have implemented a tabbed interface in preparation for multi-document handling - which will be the last addition/change I make.

Unfortunately the syntax-highlighting is not great as the CVBasic language is not a defined Lexer. I am therefore very keen to learn how to create a bespoke Lexer file - and then how to integrate (load?) it into the Scintilla object. I have found some information on how to do this (create a Lexer - but not how to integrate it) on the web, but most of it goes over my head - so if anyone can help or steer me in the right direction I would be very grateful.