Page 1 of 1

Get the IDE to display a message from a tool

Posted: Wed Sep 07, 2016 9:37 pm
by the.weavster
I've created a console app/tool that on compile/run generates Declares for all files that are currently open in the IDE (including Modules using a naming convention*). I had hoped that I would be able to output narrative using PrintN() and it would appear in the lower pane of the IDE but it doesn't. Is there a way to send strings from a tool for the IDE to display?


*The convention is simple.
For a Module:

Code: Select all

;-mod-name.pb
DeclareModule myModule
  XIncludeFile "mod-name-public.pb" ; this file is generated by the tool
EndDeclareModule


Module myModule
  XIncludeFile "mod-name-private.pb" ; this file is generated by the tool

  ; leading underscore means private, declare is created in *-private.pb
  Procedure.i _MyPrivateFunction() 
    ; ...
  EndProcedure

  ; no leading underscore, declare is created in *-public.pb
  Procedure.i MyPublicFunction()
    ; ...
  EndProcedure

EndModule
And for a standard source file:

Code: Select all

;-my-code.pb
XIncludeFile "my-code-declares.pb" ; this file is generated by the tool

Re: Get the IDE to display a message from a tool

Posted: Thu Sep 08, 2016 6:55 pm
by freak
I don't think i ever officially documented this, but the following code works with any recent PB version (Windows only):

Compile this and run it as a tool:

Code: Select all

Procedure WriteIDELog(Message$)
  Protected CopyData.COPYDATASTRUCT
  Protected IDEWindow = Val(GetEnvironmentVariable("PB_Tool_MainWindow"))
  
  If IDEWindow And Message$
    CopyData\dwData = ('L' << 16) | ('O' << 8) | 'G'
    CopyData\cbData = StringByteLength(Message$, #PB_Ascii)
    CopyData\lpData = AllocateMemory(CopyData\cbData + 1)
    If CopyData\lpData 
      PokeS(CopyData\lpData, Message$, -1, #PB_Ascii)
      SendMessage_(IDEWindow, #WM_COPYDATA, #Null, @CopyData)
      FreeMemory(CopyData\lpData)
    EndIf    
  EndIf
EndProcedure


WriteIDELog("This is the tool speaking!")
WriteIDELog("Another message from the tool.")

Re: Get the IDE to display a message from a tool

Posted: Thu Sep 08, 2016 10:12 pm
by bbanelli
IDEWindow is 0 for both x86 and x64 PB 5.5, W7 x64. :(

Re: Get the IDE to display a message from a tool

Posted: Thu Sep 08, 2016 10:20 pm
by Bisonte
bbanelli wrote:IDEWindow is 0 for both x86 and x64 PB 5.5, W7 x64. :(
This will only work if you compile it and execute it from the IDE as a tool....

Re: Get the IDE to display a message from a tool

Posted: Thu Sep 08, 2016 10:35 pm
by bbanelli
Bisonte wrote:
bbanelli wrote:IDEWindow is 0 for both x86 and x64 PB 5.5, W7 x64. :(
This will only work if you compile it and execute it from the IDE as a tool....
Oh. I see. So this can't really be used instead of somewhat annoying feature of DebuggerWarning() which switches IDE's tab to the line warning occurred, instead of only displaying it in message box of PB's IDE? Since this is quite inconvenient feature while testing software and having multiple IDE tabs opened, only to be forcefully switched to DebuggerWarning() line...

http://imgur.com/a/yCAq5

Re: Get the IDE to display a message from a tool

Posted: Thu Sep 08, 2016 10:47 pm
by freak
It also works if it is not a tool. You just need another way to find the target IDE window in this case as the environment variable is only available for tools.

Re: Get the IDE to display a message from a tool

Posted: Fri Sep 09, 2016 9:49 am
by infratec

Code: Select all

Procedure.l EnumWindowCallback(hWnd.l, lParam.l)
  
  Protected Result.l
  Protected CopyData.COPYDATASTRUCT
  Protected Message$
  
  Result = #True
  
  If hWnd
    *Buffer = AllocateMemory(256)
    If *Buffer
      GetWindowText_(hWnd, *Buffer, MemorySize(*Buffer))
      
      WindowTitle$ = PeekS(*Buffer)
      ;Debug WindowTitle$
      If FindString(WindowTitle$, "PureBasic " + Left(Str(#PB_Compiler_Version), 1))
        
        Message$ = PeekS(lParam)

        
        CopyData\dwData = ('L' << 16) | ('O' << 8) | 'G'
        CopyData\cbData = StringByteLength(Message$, #PB_Ascii)
        CopyData\lpData = AllocateMemory(CopyData\cbData + 1)
        If CopyData\lpData
          PokeS(CopyData\lpData, Message$, -1, #PB_Ascii)
          SendMessage_(hWnd, #WM_COPYDATA, #Null, @CopyData)
          FreeMemory(CopyData\lpData)
        EndIf
        
        Result = #False
      EndIf
      
      FreeMemory(*Buffer)
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


Procedure WriteIDELog(Message$)

  EnumWindows_(@EnumWindowCallback(), @Message$)
  
EndProcedure


WriteIDELog("Hello World!")
Bernd

Re: Get the IDE to display a message from a tool

Posted: Wed Jan 31, 2018 11:46 am
by Taz
freak wrote:I don't think i ever officially documented this, but the following code works with any recent PB version (Windows only):

Compile this and run it as a tool:

Code: Select all

Procedure WriteIDELog(Message$)
  Protected CopyData.COPYDATASTRUCT
  Protected IDEWindow = Val(GetEnvironmentVariable("PB_Tool_MainWindow"))
  
  If IDEWindow And Message$
    CopyData\dwData = ('L' << 16) | ('O' << 8) | 'G'
    CopyData\cbData = StringByteLength(Message$, #PB_Ascii)
    CopyData\lpData = AllocateMemory(CopyData\cbData + 1)
    If CopyData\lpData 
      PokeS(CopyData\lpData, Message$, -1, #PB_Ascii)
      SendMessage_(IDEWindow, #WM_COPYDATA, #Null, @CopyData)
      FreeMemory(CopyData\lpData)
    EndIf    
  EndIf
EndProcedure


WriteIDELog("This is the tool speaking!")
WriteIDELog("Another message from the tool.")
Thank you. :mrgreen:
I searched/tried for hours for this possibility.
Maybe you should do it natively as a function in PB?

One question: How can I delete the log from a tool?

Re: Get the IDE to display a message from a tool

Posted: Wed Jan 31, 2018 2:29 pm
by oO0XX0Oo
@infratec

When I compile your code and start the exe while the PureBasic IDE
is NOT running, I get a windows message dialog:

"...exe doesn't work anymore"

Code: Select all

Problemsignatur:
  Problemereignisname:	APPCRASH
  Anwendungsname:	Test.exe
  Anwendungsversion:	0.0.0.0
  Anwendungszeitstempel:	5a71c278
  Fehlermodulname:	ntdll.dll
  Fehlermodulversion:	6.3.9600.17415
  Fehlermodulzeitstempel:	54504b0d
  Ausnahmecode:	c0000005
  Ausnahmeoffset:	0004298d
  Betriebsystemversion:	6.3.9600.2.0.0.400.8
  Gebietsschema-ID:	1031
  Zusatzinformation 1:	5861
  Zusatzinformation 2:	5861822e1919d7c014bbb064c64908b2
  Zusatzinformation 3:	a10f
  Zusatzinformation 4:	a10ff7d2bb2516fdc753f9c34fc3b069

Lesen Sie unsere Datenschutzbestimmungen online:
  http://go.microsoft.com/fwlink/?linkid=280262

Wenn die Onlinedatenschutzbestimmungen nicht verfügbar sind, lesen Sie unsere Datenschutzbestimmungen offline:
  C:\Windows\system32\de-DE\erofflps.txt

If the IDE IS running, everything works fine

Re: Get the IDE to display a message from a tool

Posted: Wed Jan 31, 2018 8:18 pm
by Kwai chang caine
Too much strong FREAK and INFRATEC, that works for me (W10 x86 v5.61 x86)
Thanks for sharing 8)

Re: Get the IDE to display a message from a tool

Posted: Sun Mar 11, 2018 8:13 am
by Taz
freak wrote:I don't think i ever officially documented this, but the following code works with any recent PB version (Windows only):

Compile this and run it as a tool:

Code: Select all

Procedure WriteIDELog(Message$)
  Protected CopyData.COPYDATASTRUCT
  Protected IDEWindow = Val(GetEnvironmentVariable("PB_Tool_MainWindow"))
  
  If IDEWindow And Message$
    CopyData\dwData = ('L' << 16) | ('O' << 8) | 'G'
    CopyData\cbData = StringByteLength(Message$, #PB_Ascii)
    CopyData\lpData = AllocateMemory(CopyData\cbData + 1)
    If CopyData\lpData 
      PokeS(CopyData\lpData, Message$, -1, #PB_Ascii)
      SendMessage_(IDEWindow, #WM_COPYDATA, #Null, @CopyData)
      FreeMemory(CopyData\lpData)
    EndIf    
  EndIf
EndProcedure


WriteIDELog("This is the tool speaking!")
WriteIDELog("Another message from the tool.")
How can this be done with Linux?