wxMax: single instance,drag and drop,scintilla

BlitzMax Forums/Brucey's Modules/wxMax: single instance,drag and drop,scintilla

UNZ(Posted 2013) [#1]
Hi folks,

I pretty much like wxMax/wxWidgets but I need some help here:
The single instance example blocks the first instance too...
Am I missing something obvious? :)

Can someone write a little example of how to make an app which accept drag and drop files from the OS? I'm pretty sure this is a quest that can be achieved with such a powerful framework... but I don't get it.

Scintilla
----------
Is it possible to override the autocomplete function of scintilla?
I add strings which contain some extra info about the keywords
but the extra info shouldn't be added to the editor so I have to modify the string before autocomplete.
Is this possible? I already tried to override AutoCompComplete() but this had no effect.

thx and regards^^


Derron(Posted 2013) [#2]
AutoComplete should trigger some events you could use to your advantage.

Eg. you could replace Autocomplete with your own with stopping the event from traversing along the list of listeners (don't know the events method - maybe something like event.StopPropagation(), there is also event.Skip() which can be useful ).

The same way you could draw an additional tooltip for the highlighted command - which could be styled independently from the autocomplete list.
To hook into typed strings (eg you clicked on a keyword in the source)
you could use the "Dwell"-events.
-> ConnectAny(wxEVT_SCI_DWELLEND, onDwellEnd)
-> ConnectAny(wxEVT_SCI_DWELLSTART, onDwellStart)

To draw to the textarea, hook to the DrawEvent ConnectAny(wxEVT_SCI_PAINTED , OnAfterPaint)


Above code is leaving out some steps which are calling longer method chains I did not want to post here for their length.

Also this does not exactly answer your question regarding the autocomplete list - but as I did not want to customize things which are "system wide" used. I added them in a different way.
Another reason is: autocomplete uses a default "listbox" which makes it harder to "style" it as you want.


Ok just read some texts... it does not seem that scintilla enables modification of the autocomplete element. So the best way to customize is to use your own - means you will have to copypaste some code.


@single instance:
This should not happen, maybe brucey forgot something (haven't updated my wxmax-codebase for a long time as my wx-projects are on hold).

DnD:
have a look at "wxdroptarget". Never used that but should do the trick.
In your case you should also have a look at "wxFileDropTarget" which is an extension to wxdroptarget.


bye
Ron


UNZ(Posted 2013) [#3]
Thanks.

DragAndDrop
---------------
It works perfectly.
See
http://www.blitzbasic.com/Community/posts.php?topic=86023
for an example.

Autocompletion
------------------
Found a way to modify the autocompletion string before it is inserted.
I added
ConnectAny(wxEVT_SCI_AUTOCOMP_SELECTION,OnAutoCompSel,self)

in the OnInit of the editor. (The event is fired before autocompletion)
A possible callback function could be
	Function OnAutoCompSel(event:wxEvent)
		local edt:TEdit= TEdit(event.userData)
		local evt:wxScintillaEvent = wxScintillaEvent(event)
		assert edt
		assert evt
		
		local txt$= evt.GetText()'get autocompletion text
		edt.AddText(txt.toUpper() )'add modified version
		edt.AutoCompCancel()'stop autocompletion by scintilla
	end Function 

where TEdit is the extended wxScintilla type.


Single instance
--------------------
Would be great if someone could fix it...


Brucey(Posted 2013) [#4]
Single instance should be working now (in SVN).
The IsAnotherRunning() method was returning a 'bool' - which is a problem between C/C++ and BlitzMax on Windows… ho hum.

I added a singleinstance sample too.


UNZ(Posted 2013) [#5]
Single instance is working :)

But is it possible to send the first instance a message?
I want my application to open files associated with it in no extra instance. Can I somehow send the AppArgs from the second instance to the first?


Brucey(Posted 2013) [#6]
You want some kind of interprocess communication?

BaH.Interprocess can do that kind of thing. It uses Boost's interprocess library.


UNZ(Posted 2013) [#7]
I just checked it out via svn and it runs on my linux.
Sadly interprocess has some linker errors on windows although the module compiles.
F:/Spiele/Proggen/BlitzMax/mod/bah.mod/interprocess.mod/interprocess.debug.win32.x86.a(glue.cpp.debug.win32.x86.o):glue.cpp:(.text$_ZN5boost12interprocess6winapi16co_uninitializerD1Ev[__ZN5boost12interprocess6winapi16co_uninitializerD1Ev]+0x13): undefined reference to `_imp__CoUninitialize@0'
F:/Spiele/Proggen/BlitzMax/mod/bah.mod/interprocess.mod/interprocess.debug.win32.x86.a(glue.cpp.debug.win32.x86.o):glue.cpp:(.text$_ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_[__ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_]+0x4e): undefined reference to `_imp__CoInitializeEx@8'
F:/Spiele/Proggen/BlitzMax/mod/bah.mod/interprocess.mod/interprocess.debug.win32.x86.a(glue.cpp.debug.win32.x86.o):glue.cpp:(.text$_ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_[__ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_]+0xef): undefined reference to `_imp__CoInitializeSecurity@36'
F:/Spiele/Proggen/BlitzMax/mod/bah.mod/interprocess.mod/interprocess.debug.win32.x86.a(glue.cpp.debug.win32.x86.o):glue.cpp:(.text$_ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_[__ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_]+0x14d): undefined reference to `_imp__CoCreateInstance@20'
F:/Spiele/Proggen/BlitzMax/mod/bah.mod/interprocess.mod/interprocess.debug.win32.x86.a(glue.cpp.debug.win32.x86.o):glue.cpp:(.text$_ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_[__ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_]+0x24a): undefined reference to `_imp__CoSetProxyBlanket@32'
F:/Spiele/Proggen/BlitzMax/mod/bah.mod/interprocess.mod/interprocess.debug.win32.x86.a(glue.cpp.debug.win32.x86.o):glue.cpp:(.text$_ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_[__ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_]+0x3fd): undefined reference to `_imp__VariantClear@4'
Build Error: Failed to link F:/Spiele/Proggen/BlitzMax/tmp/untitled2.debug.exe


What's wrong?


Brucey(Posted 2013) [#8]
Cross-platform is fun :-)

Added some recently required libs for Win32 (ole32 and oleaut32).


UNZ(Posted 2013) [#9]
Great,
but I have to admit, that I don't know how to use this.

I found this simple example of how to create an app that checks for other instances:
SuperStrict

Import bah.interprocess

Local mutex:TNamedMutex = New TNamedMutex.Create(OPEN_OR_CREATE , "app")

If Not mutex.trylock()
	Notify "Process already running"
	TNamedMutex.remove("app")
	TNamedMutex.
	End
EndIf

Notify "App started"


But I don't know how to send the first process a message that it can react to because there will be no event fired in wxMax...

My idea would be to create a timer to frequently check a file/shared memory in which the other processes could write their AppArgs to. But I don't need interprocess then. wxSingleInstanceChecker would be good enough.

Any advice?


Brucey(Posted 2013) [#10]
Interprocess uses shared memory.
I've used Boost interprocess on Linux to control several slave programs with a master program, with the master populating a circular buffer in shared memory, and the slaves reading from it. Works very well with little effort. :-)


UNZ(Posted 2013) [#11]
Hey there!

The single instance stuff is working quite well now.
But I think I have a compiler error:
Type TAbc
	method abc()
	endmethod
	method delete()
	endmethod
end type

new TAbc.abc()
new TAbc.delete()

The Method abc() is OK but delete() is a predefined keyword and throws an error on compiling.

This is not a big deal but sadly the method to free a wxSingleInstanceChecker is named Delete()
...


Brucey(Posted 2013) [#12]
You don't call Delete(). It is called automatically when the object is garbage collected.

So, if you really want to free the object, simply forget any references to it and it will be freed later.


UNZ(Posted 2013) [#13]
OK, but

on Linux I get a message each time I close and then start my application:
Deleted stalte lock file 'Path to lock file is here'

Do I have to manually remove the file on Linux?


Brucey(Posted 2013) [#14]
Ah, then you should probably call the newly added Free() method before you close the application :-)

A problem (feature?) of BlitzMax's garbage collection is that it doesn't guarantee to free all resources before program termination…


UNZ(Posted 2013) [#15]
Great!
I'll give it a try^^


UNZ(Posted 2013) [#16]
About the Scintilla Lexer for BlitzMax:

First there is a constant missing. Something like wxSCI_B_REM would be great. I thought that rem... end rem is not supported in general but only the constant is missing. It's 19.

Second is about the line comment. It looks like ; is interpreted as line comment mark and not '
Could you change it please?


Brucey(Posted 2013) [#17]
I've added the const wxSCI_B_COMMENTREM, and fixed the line comment character.